Well im trying to use the GCalendar connector in MuleStudio, the conector recibes an instance of org.mule.module.google.calendar.model.Event (See Doc)
How can i create an instance of the Event and pass it to the connector for it to create the event in GCalendar?
Here an image of the case
See Image
You can use MEL(Mule Expression Language) using standard Java syntax or expressions to create an instance of the Event class or you can use Spring etc. Here's a rough example that builds a list with an event and sets it as the payload:
<expression-component>
event = new org.mule.module.google.calendar.model.Event();
event.location = "America";
eventTime = org.mule.module.google.calendar.model.EventDateTime();
eventTime.date = "2015-12-16"'
event.start = eventTime;
event.end = eventTime;
message.payload = [event]
</expression-component>
You can then pass it by reference tot the connector using #[payload]
<google-calendars:batch-insert-event calendarId="bla#gmail.com" calendarEvents="#[payload]" />
Related
we need publish multiple event as json string from DB. publish this json event by masstransit like this:
using var scope = _serviceScopeFactory.CreateScope();
var sendEndpointProvider = scope.ServiceProvider.GetService<ISendEndpointProvider>();
var endpoint = await sendEndpointProvider.GetSendEndpoint(new System.Uri("exchange:IntegrationEvents.DynamicEvent:DynamicEvent"))
var json = JsonConvert.SerializeObject(dynamicObject, Newtonsoft.Json.Formatting.None);// sample
var obj = JsonConvert.DeserializeObject(json, new JsonSerializerSettings { });
await endpoint.Send(obj,i=>i.Serializer.ContentType.MediaType= "application/json");
and in config we use this config:
cfg.UseRawJsonSerializer();
when use this config, json event is successful published but we have strange problem : "all" event consumer is called by empty message data ! ... in Rabbitmq jsut published our "Dynamic Event", but in masstrasit all consumers called !!
Thank you for letting us know if we made a mistake
You don't need all of that JSON manipulation, just send the message object using the endpoint with the serializer configured for RawJson. I cover JSON interoperability in this video.
Also, MassTransit does not allow anonymous types to be published. You might be able to publish dynamic or Expando objects.
I used ExpandoObject like this and get this exception "Messages types must not be in the System namespace: System.Dynamic.ExpandoObject" :
dynamic dynamicObject = new ExpandoObject();
dynamicObject.Id = 1;
dynamicObject.Name = "NameForName";
await endpoint.Send(dynamicObject);
and using like this we get same result as "all consumers called":
var dynamicObject = new ExpandoObject() as IDictionary<string, object>;
dynamicObject.Add("Id", 1);
dynamicObject.Add("Name", "NameForName");
I watch your great video, you used from rabbitmq directly .. how "send the message object using the endpoint with the serializer configured for RawJson" in C# code.
We use ServiceStack.RabbitMq and I could not find a way to put a custom attribute on the rabbit mq message. I want the publisher to set the attribute on the message and the worker to read it.
A variant is to move that attribute as part of request body but I have a lot of requests and in all honesty the request should not know at all about this kind of information - as that is metadata of the message.
Any idea how this can be achieved?
You can use the Message Filters in RabbitMqServer to add and introspect message properties, e.g:
var mqServer = new RabbitMqServer("localhost")
{
PublishMessageFilter = (queueName, properties, msg) => {
properties.AppId = "app:{0}".Fmt(queueName);
},
GetMessageFilter = (queueName, basicMsg) => {
var props = basicMsg.BasicProperties;
receivedMsgType = props.Type; //automatically added by RabbitMqProducer
receivedMsgApp = props.AppId;
}
};
You could either add the custom attribute to the object you are pushing down the queue or add that attribute to the rabbit message metadata header table. RabbitMQ messages have various metadata attributes that can be set when a message is published.
Check this
I would like to programmatically add new RSS Connector flows while Mule is running (after the context has been initialized). When I try to do this, I get a Lifecycle Exception saying that the context is already initialized.
Is there a way to do this without restarting the whole context?
I figured out a solution on my own. It turned out that creating a new Mule context, adding my flow, and then starting the context worked just fine. In fact, this ended up being simpler, faster, and cleaner than the other path I was going down.
Creating a default Mule context worked just fine for me. You might need to add a ConfigurationBuilder to yours if you have special needs.
MuleContext newMuleContext = new DefaultMuleContextFactory().createMuleContext();
MuleRegistry registry = newMuleContext.getRegistry();
Flow flow = createFlow();
registry.registerFlowConstruct(flow);
newMuleContext.start();
Edit. Here's the createFlow method. Your specifics will be different based on the needs of your app.
protected Flow createFlow(MuleContext context, RssBean feed) throws Exception {
MuleRegistry registry = context.getRegistry();
String feedName = feed.getName();
HttpPollingConnector connector = getHttpPollingConnector(context, registry, feedName);
EndpointURIEndpointBuilder endpointBuilder = getEndpointBuilder(context, feed, registry, shortName, connector);
registry.registerEndpointBuilder(feedName + ".in", endpointBuilder);
MessagePropertiesTransformer transformer = getTransformer(context, feedName);
MessageProcessor mp = getOutboundFlowRef(context);
Flow flow = getFlow(context, shortName, endpointBuilder, transformer, mp);
registry.registerFlowConstruct(flow);
return flow;
}
I want to create a flow or model dynamically without using mule-config.xml for tcp with remote machines.
It should be something like this:
MuleContext context = new DefaultMuleContextFactory().createMuleContext();
MuleRegistry registry = context.getRegistry();
EndpointBuilder testEndpointBuilder = new EndpointURIEndpointBuilder("vm://testFlow.in",
context);
testEndpointBuilder.setExchangePattern(MessageExchangePattern.REQUEST_RESPONSE);
registry.registerEndpointBuilder("testFlow.in", testEndpointBuilder);
InboundEndpoint vmInboundEndpoint = testEndpointBuilder.buildInboundEndpoint();
registry.registerEndpoint(vmInboundEndpoint);
StringAppendTransformer stringAppendTransformer = new StringAppendTransformer(" world");
stringAppendTransformer.setMuleContext(context);
Flow testFlow = new Flow("testFlow", context);
testFlow.setMessageSource(vmInboundEndpoint);
testFlow.setMessageProcessors(Arrays.asList((MessageProcessor) stringAppendTransformer));
registry.registerFlowConstruct(testFlow);
context.start();
MuleClient muleClient = new MuleClient(context);
MuleMessage response = muleClient.send("vm://testFlow.in", "hello", null);
Validate.isTrue(response.getPayloadAsString().equals("hello world"));
muleClient.dispose();
context.stop();
Not sure if I understand your problem, but if you need a tcp outbound endpoint in your flow, you just create it similarly like the inbound vm endpoint in the example, but you then add it to a certain point in the flow in a list with all the processors with setMessageProcessors, like in the example where stringAppendTransformer is wrapped inside a list and added to the flow.
The code to create your tcp outbound would be something like this:
String address = "tcp://localhost:1234";
EndpointURIEndpointBuilder builder = new
EndpointURIEndpointBuilder(new URIBuilder(address), context);
builder.setExchangePattern(MessageExchangePattern.REQUEST_RESPONSE);
registry.registerEndpointBuilder("testFlow.out", builder);
OutboundEndpoint tcpOutboundEndpoint = builder.buildOutboundEndpoint();
registry.registerEndpoint(tcpOutboundEndpoint);
UPDATE regarding your new comment:
using a Java component:
//object factory for your Java class
PrototypeObjectFactory objectFactory = new PrototypeObjectFactory(MyClass.class);
objectFactory.initialise();
//the actual component
DefaultJavaComponent component = new DefaultJavaComponent(objectFactory);
//entry point resolver to determine the called method
EntryPointResolver resolver = new ExplicitMethodEntryPointResolver();
((ExplicitMethodEntryPointResolver)resolver).addMethod("myMethod");
component.setEntryPointResolvers(Arrays.asList(resolver));
Then add the component in the list like you add all the other processors
How do you set message properties in Mule using Groovy?
I need to set a message property from within a Groovy Scripting Component. Documentation on the subject does not appear to be easy to find.
You can set individual properties as follows:
message.setInvocationProperty('myFlowVariable', 'value') // sets a flow variable, like <set-variable/>
message.setOutboundProperty('myProperty', 'value') // sets an outbound message property, like <set-property/>
message.setProperty('myInboundProperty', 'value', PropertyScope.INBOUND) // sets an inbound property
In the scripting component you have available the message binding that is an instance of org.mule.api.MuleMessage, thus you can use the method org.mule.api.MuleMessage.addProperties(Map, PropertyScope) to add any property you need.
It depends on which version of Mule EE (and so then Groovy) you are using, but in recent versions of Mule (3.7.x) the easiest way is:
flowVars ['name_of_variable'] = 'value'
flowVars ['name_of_variable'] = 14
This for variables with Invocation scope, if you wan to store variable for Session scope, then:
sessionVars ['name_of_variable'] = 'value'
sessionVars ['name_of_variable'] = 14
Please use this site from Mulesoft for Scripting as reference.
https://docs.mulesoft.com/mule-user-guide/v/3.7/script-component-reference
Here is how I figured it out:
add schema to your flow if missing:
xmlns:scripting="http://www.mulesoft.org/schema/mule/scripting"
http://www.mulesoft.org/schema/mule/scripting http://www.mulesoft.org/schema/mule/scripting/current/mule-scripting.xsd
now let's set session-variable 'account' with a custom Foo object using Groovy:
<scripting:transformer doc:name="Script">
<scripting:script engine="groovy"><![CDATA[
com.test.Foo f = new com.test.Foo();
f.setAccountId('333');
return message.setSessionProperty('account',f);]]>
</scripting:script>
</scripting:transformer>
above script will turn your Payload to NullPayload, because it is a transformer. If that' a concern, try this instead:
<enricher target="#[sessionVars['account']]">
<scripting:transformer doc:name="Script">
<scripting:script engine="groovy"><![CDATA[
com.test.Foo f = new com.test.Foo();
f.setAccountId('333');
return f;]]>
</scripting:script>
</scripting:transformer>
</enricher>
Enjoy. :)