I have below XML
<response>
<data-table filter="XXX" count="26">
<columns>
<column>sampm</column>
<column>sampn</column>
</columns>
<rows>
<row attr="535545">
<field>sampx</field>
<field>sampy</field>
</row>
<row attr="535548">
<field>samp1</field>
<field>samp2</field>
</row>
</rows>
</data-table>
</response>
From this response I have to loop over rows i.e; /response/data-table/rows/row
So here is my mule code snippet with for each
<http:request config-ref="HTTP_REQUEST" path="api/query" method="GET" doc:name="HTTP" followRedirects="true">
</http:request>
<object-to-string-transformer doc:name="Object to String"/>
<foreach collection="#[xpath3('//response/data-table/rows')]" doc:name="For Each">
<logger message="#[payload]" level="INFO" doc:name="Logger"/>
</foreach>
But I am getting a warning "The expression does not evaluate to a type that can be split: java.lang.String"
Is there any work around this problem
Rows would return you an object, try changing your expression to xpath3('//query-response/data-table/rows/row')
Specify the xpath3 return type to be a NODESET:
<foreach
collection="#[xpath3('//query-response/data-table/rows', payload, 'NODESET')]"
This should be iterable.
Related
I have an async flow with JSON payload (Payload Type as java.lang.String) and trying to do a POST to HTTP Request Connector but I am getting a 400 error. When I run the app in debugger, the payload type changes to org.glassfish.grizzly.utils.BufferInputStream from JSON string which I believe is the issue.
How do I resolve this issue?
Thanks
If you use a Dataweave transformer, using JAVA output returns that Object of type "org.glassfish.grizzly.utils.BufferInputStream", e.g:
%dw 1.0
%output application/java
---
payload
Try adding the Object to JSON after your Dataweave transformation!
<object-to-string-transformer doc:name="Object to String"/>
<flow name="createFlow">
<vm:inbound-endpoint exchange-pattern="one-way" path="createApi" connector-ref="VMConfiguration" doc:name="VM"/>
<enricher doc:name="Message Enricher" source="payload" target="#[flowVars.createApiPayload]">
<flow-ref name="createBomCollection" doc:name="createBomCollection"/>
</enricher>
<logger message="Payload after Create Api Call: #[message.payloadAs(java.lang.String)]" level="INFO" doc:name="Logger"/>
<set-payload value="#[message.payload]" mimeType="application/json" doc:name="Set Payload"/>
<dw:transform-message doc:name="Transform Message">
<dw:set-payload><![CDATA[%dw 1.0
%output application/json
---
{
(createApi: payload.createApi) when (payload.createApi != null)
}]]></dw:set-payload>
</dw:transform-message>
</flow>
<sub-flow name="createApiCollection">
<set-session-variable variableName="retryCount" value="#[new java.util.concurrent.atomic.AtomicInteger(0)]" doc:name="initialize retryCount"/>
<logger message="Payload before system Post: #[message.payload]" level="INFO" doc:name="Logger"/>
<http:request config-ref="System_HTTP_Request_Configuration" path="/bom1" method="POST" doc:name="HTTP">
<http:request-builder>
<http:header headerName="Content-Type" value="application/json"/>
<http:header headerName="requestID" value="#[sessionVars.requestID]"/>
<http:header headerName="transactionID" value="#[sessionVars.transactionID]"/>
<http:header headerName="quoteID" value="#[sessionVars.quoteID]"/>
<http:header headerName="operationName" value="#[sessionVars.operationName]"/>
</http:request-builder>
</http:request>
</sub-flow>
My cache block never works, always the http request is made for same values.
<ee:object-store-caching-strategy name="eventIdCachingStrategy" doc:name="Autobulk EventID Caching Strategy" keyGenerationExpression="#[flowVars['ablMapEventToListingParameters']]">
<managed-store storeName="${xyz.eventid.cache.store.name}" persistent="true" maxEntries="${xyz.eventid.cache.max.entries}" entryTTL="${xyz.eventid.cache.entry.timetolive}" expirationInterval="${xyz.eventid.cache.expiration.interval}" />
</ee:object-store-caching-strategy>
<sub-flow name="mapEventsForListings" doc:name="mapEventsForListings">
<logger message="Entering mapEventsForListings flow..." level="INFO" doc:name="Logger"/>
<set-variable variableName="mapEventsForListingsTimeInMillis" value="#[new java.util.Date().getTime()]" doc:name="Set Entry Time In Millis"/>
<foreach doc:name="Map Event ID to each listing">
<choice doc:name="Choice">
<when expression="#[payload.getEvent().getVenue().isEmpty() || payload.getEvent().getDate().isEmpty() || payload.getExternalListingId().isEmpty() || payload.getPricePerProduct().getAmount()==0]">
<logger message="Missing input data for Payload" level="INFO" doc:name="Listing Missing Data Fields"/>
<set-variable variableName="noOfIncompleteListings" value="#[noOfIncompleteListings + 1]" doc:name="Increment Incomplete Listings Error Count"/>
</when>
<otherwise>
<set-variable variableName="ablMapEventToListingParameters" value="/?locale=en_US&venueName=#[payload.getEvent().getVenue()]&eventDateLocal=#[payload.getEvent().getDate()]" doc:name="Autobulk Event Search Parameters"/>
<set-variable variableName="originalListingRequest" value="#[payload]" doc:name="Variable"/>
<set-payload value="#[null]" doc:name="Set Payload"/>
<ee:cache doc:name="Cache" cachingStrategy-ref="eventIdCachingStrategy">
<https:outbound-endpoint exchange-pattern="request-response" method="GET" connector-ref="HttpsClientConnector" address="${xyz.search.catalog.events.ship.api.url}#[flowVars['ablMapEventToListingParameters']]" contentType="application/json" doc:name="HTTP Outbound Call to BulkCreateListing API">
<message-properties-transformer scope="outbound">
<add-message-property key="TARGET_HOST" value="${target.host}"/>
<add-message-property key="Authorization" value="#[flowVars['shUserBearerToken']]"/>
<add-message-property key="Content-Type" value="application/json"/>
</message-properties-transformer>
</https:outbound-endpoint>
<echo-component doc:name="Echo"/>
</ee:cache>
</otherwise>
</choice>
</flow>
Value of flowVars['ablMapToListingParameters'] = www.api-dev.xyz.com/search/catalog/events/ship/v3/?locale=en_US&venueName=SAPCenter&eventDateLocal=2015-07-16T20:00
Try with the following config :-
<ee:object-store-caching-strategy name="cachingStrategy" doc:name="cachingStrategy">
<managed-store storeName="myNonPersistentManagedObjectStore" maxEntries="-1" entryTTL="20000" expirationInterval="5000"/>
</ee:object-store-caching-strategy>
Also, you are setting the payload null before your cache scope ... cache scope require the payload to determine if the response can be cached or not.
For same payload it will make a cache-hit and provide the response from cache else it will process the message and store it in cache
ref:- https://docs.mulesoft.com/mule-user-guide/v/3.7/cache-scope
I have this xml file
<Collections xmlns:foo="http://www.foo.org/" xmlns:bar="http://www.bar.org">
<Collection value="bob">
<Environments>
<Environment>amazon</Environment>
</Environments>
<ContentTypes>
<Type>Standard:ShowVideo</Type>
<Type>Standard:VideoPlaylist</Type>
<Type>Blog</Type>
</ContentTypes>
</Collection>
<Collection value="sandy">
<Environments>
<Environment>amazon</Environment>
</Environments>
<ContentTypes>
<Type>Blog</Type>
</ContentTypes>
</Collection>
and am executing this xpath query in my Mule flow. It uses 2 flowVars 'environment' and 'contentType' which come from a Redis message.
<set-variable variableName="collectionQuery" value="/Collections/Collection[Environments/Environment='#[environment]' and ContentTypes/Type='#[contentType]']/#value" />
<logger message="collectionQuery is #[collectionQuery]" level="INFO" />
<set-payload value="#[xpath(collectionQuery)]" />
<logger message="payload is #[payload]" level="INFO" />
Here you can see the fully instantiated query and the result.
INFO] org.mule.api.processor.LoggerMessageProcessor: collectionQuery is /Collections/Collection[Environments/Environment='amazon' and ContentTypes/Type='Blog']/#value
INFO] org.mule.api.processor.LoggerMessageProcessor: payload is [org.dom4j.tree.DefaultAttribute#140207e0 [Attribute: name value value "bob"], org.dom4j.tree.DefaultAttribute#11530d63 [Attribute: name value value "sandy"]]
The result is what looks like an array of 2 org.dom4j.tree objects. I just need an ArrayList of attribute 'value' such as this
[bob,sandy]
I can do this in Groovy but not using Mule's xpath functionality.
only this worked for me
<set-variable variableName="collectionName" value="#[payload.getText()]" doc:name="collectionName"/>
<logger message="now processing #[collectionName]" level="INFO" doc:name="Logger"/>
My xpath expression returned an array of DefaultAttribute. To get the actual value of the attribute, as a String, I needed to call the getValue() method with my foreach loop.
<foreach doc:name="For Each">
<set-variable variableName="collectionName" value="#[payload.getValue()]" doc:name="collectionName"/>
<logger message="now processing #[collectionName]" level="INFO" doc:name="Logger"/>
</foreach>
output:
INFO] org.mule.api.processor.LoggerMessageProcessor: now processing bob
INFO] org.mule.api.processor.LoggerMessageProcessor: now processing sandy
I have a Mule flow in which I have a Database delete operation :-
<jdbc-ee:connector name="Database_Global" dataSource-ref="DB_Source" validateConnections="true" queryTimeout="-1" pollingFrequency="0" doc:name="Database">
<jdbc-ee:query key="DeleteQuery" value="delete from getData where ID=10"/>
</jdbc-ee:connector>
<flow name="DeleteFlow" doc:name="restFlow1">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8082" doc:name="HTTP"/>
<jdbc-ee:outbound-endpoint exchange-pattern="request-response" queryKey="DeleteQuery" queryTimeout="-1" connector-ref="Database_Global" doc:name="Database (JDBC)"/>
<logger message="Deleted #[flowVars['MULE_JDBC_UDATE_COUNT']] rows" level="INFO" doc:name="Logger"/>
<set-payload value="Deleted #[flowVars['MULE_JDBC_UDATE_COUNT']] rows" doc:name="Set Payload"/>
</flow>
Now the issue is flowVars['MULE_JDBC_UDATE_COUNT'] is returning null even the row exists and is deleted from Database ... I am using Mule 3.5 anypoint studio with JDBC ee connector ..
One more issue I like to address ... I need something like :-
<choice doc:name="Choice">
<when expression="#[flowVars['MULE_JDBC_UDATE_COUNT']==null] ">
<logger message="Deleted #[flowVars['MULE_JDBC_UDATE_COUNT']] rows... Failed!!!" level="INFO" doc:name="Logger"/>
<set-payload value="Deleted #[flowVars['MULE_JDBC_UDATE_COUNT']] rows ...Failed!!!" doc:name="Set Payload"/>
</when>
<otherwise>
<set-payload value="Deleted Successfully !!!" doc:name="Set Payload"/>
</otherwise>
</choice>
just after the jdbc-ee:outbound-endpoint where I can display success message if row is deleted and failure message if not ... But I am getting error like :-
Root Exception stack trace:
[Error: unresolvable property or identifier: ]]
[Near : {... flowVars['MULE_JDBC_UDATE_COUNT']==null] ....}]
How can I achieve it ... Please help
You have a typo: it's MULE_JDBC_UPDATE_COUNT not MULE_JDBC_UDATE_COUNT.
Finally the working code is MULE_JDBC_UPDATE_COUNT :-
<choice doc:name="Choice">
<when expression="#[flowVars['MULE_JDBC_UPDATE_COUNT']==null] ">
<logger message="Deleted #[flowVars['MULE_JDBC_UDATE_COUNT']] rows... Failed!!!" level="INFO" doc:name="Logger"/>
<set-payload value="Deleted #[flowVars['MULE_JDBC_UDATE_COUNT']] rows ...Failed!!!" doc:name="Set Payload"/>
</when>
<otherwise>
<set-payload value="Deleted Successfully !!!" doc:name="Set Payload"/>
</otherwise>
</choice>
I have tried creating Megento connector example program as given in the Megento connector vedio link.http://www.youtube.com/watch?v=GCbuqHLCiOg
My flow is:
<magento:config name="MagentoConnector" username="${magento.username}" password="${magento.password}" address="${magento.address}" doc:name="Magento">
<magento:connection-pooling-profile initialisationPolicy="INITIALISE_ONE" exhaustedAction="WHEN_EXHAUSTED_GROW"/>
</magento:config>
<flow name="ShoppingCartOPerations" doc:name="ShoppingCartOPerations">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8081" path="shoppingCartOperation" doc:name="HTTP"/>
<flow-ref name="CreateProduct" doc:name="Flow Reference"/>
<set-payload value="Product Id is #[groovy:message.getProperty('productId')]" doc:name="Set Payload"/>
</flow>
<sub-flow name="CreateProduct" doc:name="CreateProduct">
<magento:create-product config-ref="MagentoConnector" type="simple" set="1" sku="simple_sku" storeViewIdOrCode="4" doc:name="Create Product" address="https://sashistore.gostorego.com/api/v2_soap" password="gdskey" username="gdssrao">
<magento:attributes name="SampleProduct" description="TestProduct" short_description="creating sample product" weight="100" status="1" visibility="4" price="100" tax_class_id="1"/>
</magento:create-product>
<set-property propertyName="productId" value="#[payload]" doc:name="Store Product id"/>
<magento:update-inventory-stock-item config-ref="MagentoConnector" productId="#[groovy:message.getProperty('productId')]" doc:name="Update Stock">
<magento:catalog-inventory-stock-item qty="33" is_in_stock="100" min_qty="10"/>
</magento:update-inventory-stock-item>
</sub-flow>
ERROR 2014-01-29 23:48:48,521 [[magentotest].connector.http.mule.default.receiver.02] org.mule.retry.notifiers.ConnectNotifier: Failed to connect/reconnect: Work Descriptor. Root Exception was: null. Type: class org.mule.api.ConnectionException
ERROR 2014-01-29 23:48:48,524 [[magentotest].connector.http.mule.default.receiver.02] org.mule.exception.DefaultMessagingExceptionStrategy:
<magento:config name="MagentoConnector" username="gdssrao" password="gdskey" address="https://sashistore.gostorego.com/api/v2_soap" doc:name="Magento">
<magento:connection-pooling-profile initialisationPolicy="INITIALISE_ONE" exhaustedAction="WHEN_EXHAUSTED_GROW"/>
</magento:config>
<flow name="ShoppingCartOPerationsFlow" doc:name="ShoppingCartOPerationsFlow">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8081" path="shoppingCartOperation" doc:name="HTTP"/>
<logger level="INFO" doc:name="Logger"/>
<flow-ref name="CreateProductFlow" doc:name="Flow Reference"/>
<logger level="INFO" doc:name="Logger"/>
<set-payload value="Product Id is #[groovy:message.getProperty('productId')]" doc:name="Set Payload"/>
</flow>
<sub-flow name="CreateProductFlow" doc:name="CreateProductFlow">
<magento:create-product config-ref="MagentoConnector" type="simple" set="1" sku="simple_sku" storeViewIdOrCode="4" doc:name="Create Product">
<magento:attributes name="SampleProduct" description="TestProduct" short_description="creating sample product" weight="100" visibility="4" />
</magento:create-product>
<logger level="INFO" doc:name="Logger"/>
<set-property propertyName="productId" value="#[payload]" doc:name="Store Product id"/>
<logger level="INFO" doc:name="Logger"/>
<magento:update-inventory-stock-item config-ref="MagentoConnector" productId="#[groovy:message.getProperty('productId')]" doc:name="Update Stock">
<magento:catalog-inventory-stock-item />
</magento:update-inventory-stock-item>
</sub-flow>
You have defined your plaintext connection attributes (username, password, address) in magento:create-product and then you have them as application properties in magento:config. That does not really make sense, as you only need to define the attributes once (in the config element) when you use config-ref in the other elements. Since you are having a connection failure, I would guess that you have incorrect properties in the config element. Try using the attributes from magento:create-product, instead.
EDIT: I checked the WSDL for your Magento API, and it seems that you have incorrect address
Try using https://sashistore.gostorego.com/index.php/api/v2_soap/index/ instead.
EDIT2: I got the WSDL URL for Magento API v2 from the Magento documentation. See this page for explanation on how to get the address for Web services from WSDL.