Mule Collection aggregator - esb

I am trying to use Mule 3.2.0 s Collection Aggregator. I tried using Mule Studio but seems it is still not available in Mule studio for configuration though the icon does appear in the "Flow Control" section.
My use case is -
I get a message from a VM Inbound endpoint. I now want to pass that to 3 different flows - all using the same request object but performing different operations - say A,B,C. All of them update their respective databases but they are all part of a common Order_ID(somethig internal to our application). The 3 processes may take different processing times but once done each of them return the same success response. I want to use an aggregator which will aggregate all these responses without timing out and then forward that to a Java component or another VM Endpoint for further processing.
The Mule documentation for Collection Aggregator doesn't seem to be very informative so if some one who has used Collection Agg can help me out with the xml config for the above scenario it will be very helpful

Instead of Collection Aggregator use All message processor. It sends the same message to every processor inside it and aggregates the results after they finish.
http://www.mulesoft.org/documentation/display/MULE3USER/Routing+Message+Processors#RoutingMessageProcessors-All
Sample config: (I send "foo" to the vm endpoint)
<flow name="main" processingStrategy="asynchronous">
<vm:inbound-endpoint path="in"/>
<all>
<flow-ref name="flow1"/>
<flow-ref name="flow2"/>
</all>
<logger message="#[payload:]" level="INFO"/>
</flow>
<flow name="flow1">
<append-string-transformer message="bar1"/>
</flow>
<flow name="flow2">
<append-string-transformer message="bar2"/>
</flow>
Console output:
INFO 2012-08-15 17:26:01,749 [main.stage1.02] org.mule.api.processor.LoggerMessageProcessor: [foobar1, foobar2]
HTH

I would go with to use ALL component and the endpoint you use should be request-response (two-way where the flow waits for the response).
Thus the ALL component will aggregate the response an then returns you a CopyOnWriteArrayList with all the response from the flows A,B and C. This Array list you can transform in any desired way using a custom transformer by extending AbstractTransformer in your java class.
Cheers,
Naveen Raj

Related

Talend - ESB - SOAP webservice

I need to realize a Talend ESB project that basically have an input SOAP WS ,based on a parameter it needs to execute different subjobs.
This is the SOAP Request
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://www.talend.org/service/">
<soapenv:Header/>
<soapenv:Body>
<ser:test_callOperationRequest>
<user>user</user>
<password>psw/password>
<id_customer>test ESB</id_customer>
<query>test mirror quality</query>
<command>JOB1</command>
</ser:test_callOperationRequest>
</soapenv:Body>
</soapenv:Envelope>
So I'd like to call specific subjob based on "command" parameter (i.e.:JOB1).
This is my actual project structure:
Any suggestion on right Talend component to use? Shall I include Routes?
Thanks in advance.
You can use the option "Use dynamic job" of tRunJob component :
Once you check the option, you get a field called "Context job", in which you specify the name of the child job you want to run, from a list of jobs that you choose by clicking "..." next to the Job field.
You can connect tJavaRow_1 to tRunJob_1 by a main flow, and in the Context job field, specify the incoming flow's column containing the name of the job to run (in my example it's row2.JobToRun).
The corresponding childjob is then called for each incoming row.

WSO2 API Gateway convert JSON to JSON

I need to configure JSON to JSON transformations with API Manager 2.0 very efficiently.
By default, WSO2 API Manager makes transformations JSON-> XML-> and after processing -> XML->JSON
I'd like to know how can I do so directly in JSON to reduce latencies.
Thank you for your help!!
By default, APIM uses PassThrough transport which does not build your message unless it needs to access your message body. So, your json won't be converted to XML in that case.
For example, if you have configured custom mediation and have a content-aware mediator like <log level="full"/>, APIM has to build (i.e. convert to XML) your message body so that it can log the entire message.
If you don't try to access the message body like that, json will be sent to backend as it is.

Mule - How to respond after receiving a request collection. (Mule Requester )

I am using the Mule Requestor to receive a collection of files via FTP.
In order to do this with a collection I am using the Collection Splitter which works great. The only problem is that when I am returning to the HTTP Connector it throws the following exception:
java.lang.UnsupportedOperationException: getPayloadAsBytes(), use
getPayload(DataType.BYTE_ARRAY_DATA_TYPE)
I am guessing this has something to do with the payload type that is trying to be inserted into the response, but I am fairly new in the Mule arena. Any idea what could be causing this and what I should do to resolve the issue?
I have tried setting the payload after the logger, that didn't work.
Code:
<flow name="fileGetter">
<http:listener config-ref="HTTP_Listener_Configuration" path="/test" doc:name="HTTP" allowedMethods="GET"></http:listener>
<mulerequester:request-collection config-ref="Mule_Requester" resource="ftp_For_Requester_Dependent" doc:name="Mule Requester</mulerequester:request-collection>
<collection-splitter doc:name="Collection Splitter"></collection-splitter>
<logger level="INFO" doc:name="Logger" message="#[message.inboundProperties.originalFilename]"></logger>
</flow>
The reason you are getting java.lang.UnsupportedOperationException: getPayloadAsBytes(), use getPayload(DataType.BYTE_ARRAY_DATA_TYPE) is obvious, since you are splitting the payload, at the end your HTTP in causing the issue as there will be a split response .
One solution would be, use an aggregator at the end of your flow and that will prevent this exception.
A <collection-aggregator/> at the end will be a good choice and help to prevent this
UPDATE
Keep it under <async> block and it will run successfully

WSO2 ESB service orchestration

Hello WSO2 community and hello Stackoverflow,
my testing of the SOA suite starting from the ESB is going good: now the ESB recognises external services, create correct proxies that return correct results.
SOLVED
About that, I have two issues: the first is that the "try it"
functionality raises the exception:
"Cannot find dispatch method for {http://schemas.xmlsoap.org/soap/envelope/}Envelope
[tagOpened]/soapenv:Text[tagClosed]"
when i try to send a SOAP enveloped created for the mock service of
the web service proxied.
Anyway, if I try the proxy service from an external client (created on
Netbeans) it works great.
ANSWER
For the first part, the reason is most probably the cross domain issue as try-it is sending messages through a java script stub from
the browser. You will notice that this works great when the service
itself is hosted in the ESB itself, because the request passes through
the same domain. This is why, although, it works perfectly through a
normal client invocation, it does not work through try-it.
The second issue is that I'm not able to orchestrate two services. My objective is sending the input of the first service to the second service, and then to the user.
I'm working on the tutorial Tharindu Mathew suggested: everything now makes sense to me except on one thing: the XSLT transformation.
Here is the out sequence the tutorial suggests you to create:
<outSequence xmlns="http://ws.apache.org/ns/synapse">
<switch source="get-property('STATE')">
<case regex="PERSON_INFO_REQUEST">
<log level="full">
<property name="sequence" value="outSequence - STATE 01 - response from PersonInfoService" />
</log>
<xslt key="xslt">
<property name="amount" expression="get-property('ORG_AMOUNT')" />
</xslt>
<log level="full">
<property name="sequence" value="outSequence - STATE 01 - request for CreditService" />
</log>
<property name="STATE" value="CREDIT_REQUEST" />
<send>
<endpoint key="CreditEpr" />
</send>
</case>
<case regex="CREDIT_REQUEST">
<log level="full">
<property name="sequence" value="outSequence - STATE 02 - response from CreditService" />
</log>
<send />
</case>
</switch>
</outSequence>
Now, focusing on the XSLT node of the first case of the switch, you can see that there's just a get for the amount property.
So that I think we have an XML from the in sequence that states the ID, and this get on the amount property (and I don't know what it does).
The tutorial then suggests:
To create the request to this CrediService, we use the following XSLT with the XSLT mediator. Note, we are using the ORG_ID that we stored in this XSLT as a XSLT parameter and using the XSLT mediator as well.
And here is the XSLT showed in the tutorial:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fn="http://www.w3.org/2005/02/xpath-functions"
xmlns:ns="http://samples.esb.wso2.org"
xmlns:ax21="http://samples.esb.wso2.org/xsd"
exclude-result-prefixes="ns fn">
<xsl:param name="amount"/>
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:apply-templates select="//ns:getResponse" />
</xsl:template>
<xsl:template match="ns:getResponse" xmlns:ns="http://samples.esb.wso2.org">
<sam:credit xmlns:sam="http://samples.esb.wso2.org" xmlns:xsd="http://samples.esb.wso2.org/xsd">
<sam:info>
<xsd:amount><xsl:value-of select="$amount"/></xsd:amount>
<xsd:personInfo>
<xsd:address><xsl:value-of select="ns:return/ax21:address"/></xsd:address>
<xsd:id><xsl:value-of select="ns:return/ax21:id"/></xsd:id>
<xsd:name><xsl:value-of select="ns:return/ax21:name"/></xsd:name>
</xsd:personInfo>
</sam:info>
</sam:credit>
</xsl:template>
</xsl:stylesheet>
I was asked to put a similar file into the resources directory of WSO2 ESB, but this file is never used in the tutorial:
Copy the personToCredit.xslt in the sample zip to resources directory of WSO2 ESB.
---------LITTLE PARENTHESIS-----------
The WSDL file was not used either after it was stated:
Copy the CreditProxy.wsdl in the sample zip to the resources directory of the WSO2 ESB.
I cannot find the WSDL file in the Configuration/Governance Registry, and I don't know how to address it, so I chose to specify it inline instead.
---------LITTLE PARENTHESIS END-----------
This sentence is followed by the XSLT file text. My main question now is:
Where should I put this XSLT? I do not know where to put the XSLT mediator, neither how to build it.
Should I rely on registries?
A perfect answer could be the code of the out sequence, and the specified connection with the XSLT mediator suggested.
OverTheBitStair
Hi OverTheBitStair (nice nick!),
For the first part, the reason is most probably the cross domain issue as try-it is sending messages through a java script stub from the browser. You will notice that this works great when the service itself is hosted in the ESB itself, because the request passes through the same domain. This is why, although, it works perfectly through a normal client invocation, it does not work through try-it.
For the second part, the short answer is yes, it is possible. In terms of the ESB, we refer to it as a light-weight orchestration engine in addition to being a mediation engine. This means for light-weight and short-lived (<1 day) processes we can solve the orchestration requirements using the ESB without bringing in the Business Process Server.
To do this, we use this method called service chaining. What it does is introduce a method to get some output out of the initial service invocation and use it in a subsequent invocation. The article WSO2 ESB by example - Service Chaining should help you with implementation details on what you are looking for.
Hope this helps.
If you create a service chaining scenario where your proxy service calls two other services and return the result to the caller of the proxy service, it would look something like this:
Caller --> Proxy Service -- seq_A --> Service1 -- seq_B --> Service2 -- seq_C --> (proxy serviced response) --> Caller
In this case, seq_A would be the in sequence of the proxy service, seq_C the out sequence of the proxy service and seq_B another named sequence.
Input, i.e. the message body, to seq_A would be the input to proxy service. seq_A would contain a send mediator at the end and at that point in the sequence the message context would be the input to Service1. The send mediator also points to seq_B to be executed for the reply.
At start of seq_B the message body contains the output from Service1. If you want to keep some message data from before the service call you need to save that in properties in the context.
At the end of seq_B you would have a send mediator; at that point the message body should contain the input to Service2, The send mediator would in this case not need to point to an explicit reply sequence, if seq_C is the out sequence of the proxy service - that one will be used by default then.
When seq_C is executing the message body at that point is the response from Service2. Again, if you need to use/combine with some data prior to the call to Service2, you need that to be saved into properties.
Depending on the particular needs for the input and transformations needed at each step it can be fairly straightforward or a bit cumbersome to handle.
What also should taken into consideration is what needs to happen in error scenarios, as this may add some additional complexity, depending on the requirements.

WCF not returning JSON data or error with large amount of data

I have a WCF web service that is building up data into classes and then serialized automatically by WCF to JSON ( [WebGet(ResponseFormat = WebMessageFormat.Json,...)] and returning to the client. Everything works great until I have a very large amount of data. I have the web config settings maxed as 2147438647. The odd thing is that the classes are populated and are not null just before being passed back by the WCF service. However the client never receives the data nor an error message and IIS/WCF do not throw any type of exception. It is as if the data just disappears in thin air.
What do you mean by "the client never receives the data"? The connection is dropped? It receives a response with 0 bytes?
There are many quotas in WCF, but they're mostly for incoming data. There's one for outgoing data, which you may be hitting, which is the maxItemsInObjectGraph, which could be triggered for large object graphs. You should enable tracing in the server, and the traces should have an exception event which could shed some light on what the problem is.
check the in your web.config..make sure you have this
<system.webServer>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="4294967295"/>
</requestFiltering>
</security>
</system.webServer>
the maxAllowedContentLength limits/sets the uploading size..