0
votes

We are having a mule message (a web service response) which is too lengthy. Looks like follows

<root>
    <record></record>
    <record></record>
    .
    .
    .
    .
    3000 like this
</root>

We are using mule for-each with a batch size of 1000. So we will send the message to next message processors in 3 batches. For each batch if we check the payload of type ElementNsImpl (Apache xerces). Now we want to act on each batch as follows.

Each batch (which contains 1000 records) must be split again into 1000 records, so that we act on one record at a time. (We can't do this with 3000 records as we are having other constraints).

To cut the batch to 1000 individual records, we want to use for-each or splitter again. But this batch is a set of 1000 records with no root node.So for-each or splitter or anything that works on XPath is not working on it. Is there any safest way in mule to break the 1000 record set without root node to 1000 induvidual records?

2

2 Answers

1
votes

the problem is as follows...

<flow name="foreachFlow">
    <http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="81" path="foreachtest" />
    <mulexml:dom-to-xml-transformer />
    <async>
        <foreach batchSize="3" counterVariableName="counter" collection="#[xpath://messageTO]">
            <logger level="INFO" message="#[groovy:message.getPayloadForLogging()]"/>
            <flow-ref name="nextFlow" />
        </foreach>
    </async>
    <set-payload value="some payload sent back"/>
</flow>

<flow name="nextFlow">
    <foreach batchSize="2" counterVariableName="counter" collection="#[xpath://messageTO]">
        <flow-ref name="nextFlow1" />
    </foreach>
</flow>

<flow name="nextFlow1">
    <foreach batchSize="1" counterVariableName="counter" collection="#[xpath://messageTO]">
        <logger level="INFO" message="#[groovy:message.getPayloadForLogging()]"/>
    </foreach>
</flow>

foreachFlow receives payload like below shown

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://www.webserviceX.NET">
   <soapenv:Header/>
   <soapenv:Body>
      <web:GetCitiesByCountry>
         <messageTO>1</messageTO>
         <messageTO>2</messageTO>
         <messageTO>3</messageTO>
         <messageTO>4</messageTO>
         <messageTO>5</messageTO>
         <messageTO>6</messageTO>
         <messageTO>7</messageTO>
         <messageTO>8</messageTO>
         <messageTO>9</messageTO>
         <messageTO>10</messageTO>
      </web:GetCitiesByCountry>
   </soapenv:Body>
</soapenv:Envelope>   

and the payload inside first foreach is arraylist with elementnsimpl objects as shown below

INFO  2015-01-24 14:49:14,663 [[testmuleproject].foreachFlow.1.02]         org.mule.api.processor.LoggerMessageProcessor: [
org.mule.DefaultMuleMessage
{
  id=1042f970-a3aa-11e4-829b-74d435d3375f
  payload=org.apache.xerces.dom.ElementNSImpl
  correlationId=<not set>
  correlationGroup=-1
  correlationSeq=-1
  encoding=UTF-8
  exceptionPayload=<not set>

Message properties:
  INVOCATION scoped properties:
  INBOUND scoped properties:
  OUTBOUND scoped properties:
  SESSION scoped properties:
}, 
org.mule.DefaultMuleMessage
{
  id=1042f971-a3aa-11e4-829b-74d435d3375f
  payload=org.apache.xerces.dom.ElementNSImpl
  correlationId=<not set>
  correlationGroup=-1
  correlationSeq=-1
  encoding=UTF-8
  exceptionPayload=<not set>

Message properties:
  INVOCATION scoped properties:
  INBOUND scoped properties:
  OUTBOUND scoped properties:
  SESSION scoped properties:
}, 
org.mule.DefaultMuleMessage
{
  id=1042f972-a3aa-11e4-829b-74d435d3375f
  payload=org.apache.xerces.dom.ElementNSImpl
  correlationId=<not set>
  correlationGroup=-1
  correlationSeq=-1
  encoding=UTF-8
  exceptionPayload=<not set>

Message properties:
  INVOCATION scoped properties:
  INBOUND scoped properties:
  OUTBOUND scoped properties:
  SESSION scoped properties:
}]

so the final question is how to get these processed in batch down till nextFlow1 and finally i should get messageTO payload printed in nextFlow1

currently mule throws exception for this design as shown below

    ERROR 2015-01-24 15:12:20,635 [[testmuleproject].nextFlow.stage1.05] org.mule.exception.DefaultMessagingExceptionStrategy: 
********************************************************************************
Message               : Could not find a transformer to transform "CollectionDataType{type=java.util.ArrayList, itemType=java.lang.Object, mimeType='text/xml'}" to "SimpleDataType{type=org.w3c.dom.Document, mimeType='*/*'}".
Code                  : MULE_ERROR-236
--------------------------------------------------------------------------------
Exception stack is:
1. Could not find a transformer to transform "CollectionDataType{type=java.util.ArrayList, itemType=java.lang.Object, mimeType='text/xml'}" to "SimpleDataType{type=org.w3c.dom.Document, mimeType='*/*'}". (org.mule.api.transformer.TransformerException)
  org.mule.registry.MuleRegistryHelper:268 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/transformer/TransformerException.html)
--------------------------------------------------------------------------------
Root Exception stack trace:
org.mule.api.transformer.TransformerException: Could not find a transformer to transform "CollectionDataType{type=java.util.ArrayList, itemType=java.lang.Object, mimeType='text/xml'}" to "SimpleDataType{type=org.w3c.dom.Document, mimeType='*/*'}".
    at org.mule.registry.MuleRegistryHelper.lookupTransformer(MuleRegistryHelper.java:268)
    at org.mule.DefaultMuleMessage.getPayload(DefaultMuleMessage.java:368)
    at org.mule.DefaultMuleMessage.getPayload(DefaultMuleMessage.java:323)
    + 3 more (set debug level logging or '-Dmule.verbose.exceptions=true' for everything)
********************************************************************************
0
votes

Use expression component to convert the current payload to have a root node like below

<expression-component >payload = "&lt;someRoot>"+payload+"&lt;/someRoot>"</expression-component>

This will just consider ur payload as string and append root element. Now you will be able to apply xpath over it.