Getting error when working with poll watermarking in mule - mule

I have sfdc (salesforce connector) inside poller and enabled the watermarking for it after then getting data from sfdc and loading it to Database.
<flow name="loadData" processingStrategy="synchronous">
<poll doc:name="Poll">
<fixed-frequency-scheduler frequency="2" timeUnit="MINUTES"/>
<watermark variable="timestamp" default-expression="#[server.dateTime.format("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")]" selector="MAX" selector-expression="#[payload.LastModifiedDate]" object-store-ref="sfdcStore"/>
<processor-chain doc:name="Processor Chain">
<logger message="poller started at #[server.dateTime]" level="INFO" doc:name="start"/>
<sfdc:query config-ref="svccloud_salesforce_configuration" query="SELECT Name, , Id, BillingStreet, BillingCity, BillingState, BillingCountry, BillingPostalCode, Phone, Pathway_Status__c FROM Account where LastModifiedDate < #[flowVars['timestamp']] and RecordTypeId IN (SELECT Id FROM RecordType where Name = 'Customer')" doc:name="Querying Customer Details"/>
</processor-chain>
</poll>
<logger message="process to DB" level="INFO"/>
</flow>
Data is getting and loading properly to DB but latest Date is not getting stored in the timestamp variable. I am getting below info message. If timestamp value is stored what is message we will get. Can you please help on this
INFO 2017-08-28 15:06:26,795 [pool-13-thread-1] org.mule.transport.polling.watermark.Watermark: Watermark value will not be updated since poll processor returned no results

The query doesn't actually select LastModifiedDate, so when the poll tries to update it, it will allways be null and will not update.
The query selects only records that are before the timestamp, meaning that the MAX watermark will never be updated.

You have to clear your application Data, to resolve this. If you run in studio, the watermark variable gets stored in Object store locally.
If you clear application data, it will work as expected.
Please follow below image to clear Application data.
Right click on project--> Run As --> Run Congiguration --> General Tab--> change Clear Application Data to Always(you need to scroll down to see this option).
enter image description here

Related

Mule: How to print the file name in logger?

I want to print the mule configuration file name, in the logger in the flow, how can I get it?
Suppose the configuration file name in test.xml, inside that a flow is having logger, which prints test.xml, how can I get this?
<flow name="filenameFlow">
<http:listener config-ref="HTTP_Listener_Configuration" path="/Hello" doc:name="HTTP"/>
<logger message="#[app.name.toString()]" level="INFO" doc:name="Logger"/>
</flow>
[name.flow] is not correct one.
you should go with #[flow.name] which is the correct form. Don't mislead by your answers.
Thanks,
Should print out the name of your application, in you case "test". This is not however the name of the xml file. #[flow.name] will give you the name of the flow currently executing.
Try these expressions:
1) #[message.outboundProperties['originalFileName']]
2) #[header:originalFilename]
I have done almost the same thing a few days ago.
Add a global element of type property placeholder, give location: mule-deploy.properties.
In logger, use ${config.resources}.
It will work if there is only one config file.
Just as #dlb explained, I am also wondering you may have better solution for your requirement, basically I am asuming that you want to make log more transparent, and easier to locate which flow caused any event/error.
As such, it makes more sense to log flow name rather than the config file name, which may contain multiple flows.You can utilize the catagory in log component for this purpose:
<logger level="INFO" category="${application-prefix}.myMainFlow" doc:name="Logger" message="#['payload is ---\n' + payload]"/>
In each and every log component (logs should be used in important places kind of milestones), input ${application-prefix}.flowName in catagory (property is used for reusing application's name in all logs, and flowName should be hardcoded), then you will find logs like below in runtime:
INFO 2016-09-07 17:00:27,566 [[test].HTTP_Listener_Configuration.worker.01] com.myOrg.myApp.myMainFlow: payload is ---
Hello World
#[message.outboundproperties[originalFilename]]
Try this expression.

To create multiple records in salesforce using mule salescloud connector

I am trying to upload many records to salesforce via mule using (create bulk) operation.
I created the flow as below
<flow name="bulk_salesFlow1" doc:name="bulk_salesFlow1">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8081" doc:name="HTTP"/>
<sfdc:create-bulk config-ref="Salesforce12" type="BulkMule__c" doc:name="Salesforce">
<sfdc:objects>
<sfdc:object>
<sfdc:inner-object key="Component__c">Transformer</sfdc:inner-object>
<sfdc:inner-object key="Use__c">Transforms the payload</sfdc:inner-object>
</sfdc:object>
<sfdc:object>
<sfdc:inner-object key="Use__c">Iterator</sfdc:inner-object>
<sfdc:inner-object key="Component__c">ForEach</sfdc:inner-object>
</sfdc:object>
</sfdc:objects>
</sfdc:create-bulk>
<logger message="#[payload]" level="INFO" doc:name="Logger"/>
</flow>
I am getting error "Element: Object is not allowed to be repeated". I would like to know if I'm trying in the right way, if so what is wrong in the above flow.
Thank you in advance
I think this is just a problem with Mule Studio, and you should be able to run your flow if you just ignore the warnings.
If the warnings bother you, you can always use <sfdc:objects ref="#[something]"/> with a list of maps with field names corresponding to your SF object.

Parsing multiple records after Polling in Mule and pushing every single record in the queue

As of now ,when I poll the database with a query,It will fetch me multiple records during a specified duration.Problem is ,these multiple records will be pushed as a single message into the queue.How do I push every record from the set of records as an individual message?
As you have explained the JDBC endpoint is fetching a collection of records and sending them as one single message to the queue. Solution for this is two options.
Using Mule's For-Each message processor. This helps in iterating through the collection object and processes each item as one message.
Using Mule's collection splitter to iterate through the collection of records.
Solution for option 1 looks like as shown in the image below.
The code for this flow loks like this.
<flow name="JDBC-For-Each-JMS-Flow" >
<jdbc-ee:inbound-endpoint queryKey="SelectAll" mimeType="text/javascript" queryTimeout="500000" pollingFrequency="1000" doc:name="Database">
<jdbc-ee:query key="SelectAll" value="select * from users"/>
</jdbc-ee:inbound-endpoint>
<foreach doc:name="For Each" collection="#[payload]" >
<jms:outbound-endpoint doc:name="JMS"/>
</foreach>
<catch-exception-strategy doc:name="Catch Exception Strategy"/>
</flow>
Note: This is a sample flow.
Hope this helps.

How to update NetSuite "sales order status" using Mule NetSuite Connector

I am very new to Mule NetSuite Connector. I am trying to update NetSuite Sales Order status using NetSuite Connector.
I have written configuration xml like below to update the sales order.
<flow name="netsuite-create-sales-orderFlow2" doc:name="netsuite-create-sales-orderFlow2">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8084" path="UpdateSalesOrder" doc:name="HTTP"/>
<netsuite:update-record config-ref="Netsuite" recordType="SALES_ORDER" doc:name="Netsuite">
<netsuite:attributes>
<tranId>299</tranId>
<orderStatus>_pendingFulfillment</orderStatus>
</netsuite:attributes>
</netsuite:update-record>
</flow>
In the above code '299' is my sales order number and I am trying update that sales order status from "_pendingApproval" to "_pendingFulfillment". But I am getting 'IllegalArgumentException".
java.lang.IllegalArgumentException: No enum const class com.netsuite.webservices.transactions.sales_2013_2.types.SalesOrderOrderStatus._pendingFulfillment
Can some one please correct me Where I am doing wrong.
Change your code with
<netsuite:attribute key="orderStatus" value="PENDING_FULFILLMENT"/>
Use : PENDING_FULFILLMENT Or #[com.netsuite.webservices.transactions.sales_2013_2.types.SalesOrderOrderStatus.SalesOrderOrderStatus.PENDING_FULFILLMENT] (You can use global imports to hide that verbose pacakge - http://www.mulesoft.org/documentation/display/current/Mule+Expression+Language+Tips)
You can refer to the possible enum values here (Under "Summary"):http://mulesoft.github.io/netsuite-connector/java/com/netsuite/webservices/transactions/sales_2013_2/types/SalesOrderOrderStatus.html

Mule Message Enricher Target Expression

I have a flow that takes a pair of dates inbound and then uses a message enricher to get a list of employees that worked on a specific job between those two dates. The result is a simple list of maps returned from a JDBC database. I got that saved into a flow variable without any trouble. The next enrichment is causing me trouble. I setup a for each loop that uses the employees list from the flow variable. This works great and I then need to execute another JDBC query for each of these employees to get all the time tickets they turned in between the two dates passed to the flow. The query works but I am having trouble defining the target expression to hold the result. I would like to see the target be a map with the employee id as the key and the tickets for the period (list of maps) be the value. Is there any way to do this? Is there a better way to save these results? After I get all the tickets, I need to summarize them in various ways and generate a report showing the detail as well as the analysis.
I am currently developing this in mule studio for the community runtime version 3.4.
Is this like something that you are looking for?
<set-variable variableName="maplistmap" value="#[new java.util.HashMap()]"/>
<foreach>
<jdbc-ee:outbound-endpoint exchange-pattern="request-response" queryKey="selekt" queryTimeout="-1" connector-ref="Database">
<jdbc-ee:query key="selekt" value="select * from mytable where id = #[payload]"/>
</jdbc-ee:outbound-endpoint>
<scripting:component>
<scripting:script engine="Groovy"><![CDATA[
flowVars["maplistmap"].put(payload[0].id, payload)
]]></scripting:script>
</scripting:component>
</foreach>
<logger message="#[flowVars.maplistmap]" level="INFO"/>