I have a scenario where I need to delete complete data from a Salesforce object.
TO achieve, first, all the Ids from that object are fetched and saved in a file in .csv format. Once the data is uploaded into the file, need to delete the record by records in using batch.
I'm able to query on the object and save the data in .csv but while deleting the data sometimes getting below error.
Message : null (java.nio.BufferUnderflowException).
Element : /batch-delete-genericFlow/processors/3 # apl-sfa-batch-interface-v44:batch-delete-all.xml:48 (Transform Message)
--------------------------------------------------------------------------------
Exception stack is:
null (java.nio.BufferUnderflowException). (org.mule.api.MessagingException)
java.nio.Buffer.nextGetIndex(Buffer.java:500)
java.nio.HeapCharBuffer.get(HeapCharBuffer.java:135)
com.mulesoft.weave.reader.UTF8StreamSourceReader.decode$1(SeekableStreamSourceReader.scala:147)
com.mulesoft.weave.reader.UTF8StreamSourceReader.read(SeekableStreamSourceReader.scala:167)
com.mulesoft.weave.reader.csv.parser.StreamingCSVParser.read(StreamingCSVParser.scala:61)
(66 more...)
(set debug level logging or '-Dmule.verbose.exceptions=true' for everything)
********************************************************************************
PFB delete Batch code Code:
<batch:job name="batch-delete-genericBatch" max-failed-records="-1">
<batch:input>
<enricher target="#[flowVars['jobInfo_delete']]" doc:name="Enricher jobId">
<sfdc:create-job config-ref="SFA_MSBI" type="#[flowVars.sObjectName]" concurrencyMode="Serial" contentType="CSV" operation="delete" doc:name="Create Job"/>
</enricher>
<expression-component doc:name="Save Job ID"><![CDATA[sessionVars.jobInfo_delete = flowVars.jobInfo_delete.id
]]></expression-component>
</batch:input>
<batch:process-records>
<batch:step name="Batch_Step" >
<batch:commit doc:name="Batch Commit" size="5000">
<processor-chain doc:name="Processor Chain">
<dw:transform-message metadata:id="df884737f2bc" doc:name="Transform Message">
<dw:set-payload><![CDATA[%dw 1.0
%output application/java
---
payload map {
Id: $.Id
}]]></dw:set-payload>
</dw:transform-message>
<sfdc:create-batch config-ref="SFA_MSBI" doc:name="Salesforce">
<sfdc:job-info ref="#[flowVars.jobInfo_delete]"/>
<sfdc:objects ref="#[payload]"/>
</sfdc:create-batch>
</processor-chain>
</batch:commit>
</batch:step>
</batch:process-records>
<batch:on-complete>
<async doc:name="Async">
<sfdc:close-job config-ref="SFA_MSBI" jobId="#[sessionVars.jobInfo_delete]" doc:name="Salesforce"/>
</async>
</batch:on-complete>
</batch:job>
Please advise.
Seems like Error is causing with some Value.
Please post more code to have some context.
In mean time following is a proper way of deleting SFOs.
<sfdc:delete config-ref="mySalesforceConfig">
<sfdc:ids>
<sfdc:id>001...</sfdc:id>
</sfdc:ids>
</sfdc:delete>
http://mulesoft.github.io/salesforce-connector/8.3.1/apidocs/apidoc.html#_delete
Related
In my flow in Mule 4 I am trying to query a database for specific data.
For example I want to run a query like this:
SELECT * FROM mulesoft WHERE plant = CCCNNB;
The thing is both plant and CCNNB need to be dynamic. They will come through an API request. I can handle the value to be dynamic, but I get empty results whenever I try to make the field dynamic.
I first create a variable which stores the json from the request:
set-variable value="#[payload]" doc:name="Set Variable" doc:id="8ed26865-d722-4fdb-9407-1f629b45d318" variableName="SORT_KEY"/>
Request looks like this:
{
"FILTER_KEY": "plant",
"FILTER_VALS": "CCNNB"
}
Afterwards in the db connector I configure the following:
<db:select doc:name="Select" doc:id="13a66f51-2a4e-4949-b383-86c43056f7a3" config-ref="Database_Config">
<db:sql><![CDATA[SELECT * FROM mulesoft WHERE :filter_key = :filter_val;]]></db:sql>
<db:input-parameters ><![CDATA[#[{
"filter_val": vars.SORT_KEY.FILTER_VALS,
"filter_key": vars.SORT_KEY.FILTER_KEY
}]]]></db:input-parameters>
Replacing :filter_key with plant works but as soon as I try to make it dynamic I get nothing in the response. It does not fail though, response code is 200 but I get nothing inside it.
How can I make this work?
You can directly use the stored variables in the query itself.
Query Should be an expression in DataWeave.
#["SELECT * FROM $(vars.table) WHERE $(vars.SORT_KEY.FILTER_KEY) = :filter_val"]
<db:select config-ref="Database_Config">
<db:sql><![CDATA[#["SELECT * FROM $(vars.table) WHERE $(vars.SORT_KEY.FILTER_KEY) = :filter_val"]]]></db:sql>
<db:input-parameters ><![CDATA[#[{
"filter_val": vars.SORT_KEY.FILTER_VALS
}]]]>
</db:input-parameters>
</db:select>
There is another way also to read values from payload to build a dynamic query as below
#["SELECT * FROM mulesoft
WHERE " ++ vars.SORT_KEY.FILTER_KEY ++ " = '" ++ vars.SORT_KEY.FILTER_VALS ++ "'"]
Below is the XML that is created for this, as a POC
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:os="http://www.mulesoft.org/schema/mule/os"
xmlns:salesforce="http://www.mulesoft.org/schema/mule/salesforce"
xmlns:db="http://www.mulesoft.org/schema/mule/db"
xmlns:xml-module="http://www.mulesoft.org/schema/mule/xml-module"
xmlns:http="http://www.mulesoft.org/schema/mule/http"
xmlns:ee="http://www.mulesoft.org/schema/mule/ee/core"
xmlns="http://www.mulesoft.org/schema/mule/core"
xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/ee/core http://www.mulesoft.org/schema/mule/ee/core/current/mule-ee.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd
http://www.mulesoft.org/schema/mule/db http://www.mulesoft.org/schema/mule/db/current/mule-db.xsd
http://www.mulesoft.org/schema/mule/os http://www.mulesoft.org/schema/mule/os/current/mule-os.xsd">
<http:listener-config name="HTTP_Listener_config1"
doc:name="HTTP Listener config"
doc:id="6d5de64b-1355-4967-9352-4b324f02c7ad">
<http:listener-connection host="0.0.0.0"
port="8081" />
</http:listener-config>
<db:config name="Database_Config" doc:name="Database Config"
doc:id="d5c4d49c-aef3-4d4a-a7b5-470da3354127">
<db:my-sql-connection host="localhost"
port="3306" user="root" password="admin123" database="Mysql" />
</db:config>
<flow name="testFlow"
doc:id="8cfea1b0-d244-40d9-989c-e136af0d9f80" initialState="started">
<http:listener doc:name="Listener"
doc:id="265e671b-7d2f-4f3a-908c-8065a5f36a07"
config-ref="HTTP_Listener_config1" path="test" />
<set-variable value="#[payload]" doc:name="Set Variable"
doc:id="265a16c5-68d4-4217-8626-c4ab0a3e38e5" variableName="SORT_KEY" />
<db:select doc:name="Select"
doc:id="bdf4a59c-0bcc-46ac-8258-f1f1762c4e7f"
config-ref="Database_Config">
<db:sql><![CDATA[#["SELECT * FROM mulesoft.mulesoft WHERE " ++ vars.SORT_KEY.FILTER_KEY ++ " = '" ++ vars.SORT_KEY.FILTER_VALS ++ "'"]]]></db:sql>
</db:select>
<ee:transform doc:name="Transform Message"
doc:id="72cbe69f-c52e-4df9-ba5b-dd751990bc08">
<ee:message>
<ee:set-payload><![CDATA[%dw 2.0
output application/json
---
payload]]></ee:set-payload>
</ee:message>
</ee:transform>
</flow>
</mule>
Explanation of the Flow
I am using the payload that is in Question
Seting a variable name "SORT_KEY", value of this varibale is complete payload that we receive.
then creating a dynamic query inside the Db connector
using transform message sending the data as response, that we received from DataBase
So, there are several issues here. One, the creation of the sql statement.
You can do DW inside the DB:SELECT component if you want, as shown by previous answers. Either the
#["SELECT * FROM myTable" ++ vars.myWhere]
OR
#["SELECT * FROM myTable $(vars.myWhere)"]
work.
The problem you will run into is that DataSense doesn't like this. Without the literal text for the column names, DataSense can't figure out what columns to retrieve so it raises an error "Unable to resolve value for the prameter: sql". This leaves an error in your code, which always gives me angst. I wish Mulesoft would resolve this problem.
BTW, if you do dynamic SQL, you should STILL use input parameters for each value to avoid SQL injections.
I have an "Idea" posted here to fix the bogus error: https://help.mulesoft.com/s/ideas#0872T000000XbjkQAC
This is my main mule flow:
HTTP > Payload > File (Create) > Property (File Name) JMS
And that JMS calls to other flow that starts with JMS
JMS > JSON TO XML > File (Delete by file name)
Firstly, I create a file with the JSON message.
And finally, when JSON message is transformed to XML, I try to delete the file by name calling a property that tell me the name.
But the files doesn't delete. Its output this action by log:
Writing file to: C:\errors\91fa03a0-dd33-11e5-a0d9-408d5c4c1bf3.dat
How can I do to delete it?
I tried with the option autoDelete in the Connector Configuration but it doesn't delete.
<file:connector name="File1" outputPattern="#[message.inboundProperties.fileName]" autoDelete="true" streaming="false" validateConnections="true" doc:name="File"/>
You can't use this file outbound endpoint to delete a file.
If you would use something like S3 for example you can, but those connectors are 'operation-based'.
It's meant to write an new file or append data to an existing one.
The autoDelete option is for deleting the file once it has been read by a file inbound endpoint.
More info:
https://docs.mulesoft.com/mule-user-guide/v/3.7/file-transport-reference
If you want to delete and for your usecase you should use a piece of JAVA code and use methods from the File Class:
https://docs.oracle.com/javase/7/docs/api/java/io/File.html
I am trying to delete list of records from Salesforce via Mulesoft ESB.
I have already create an example project on github and the flow xml can be found here.
The xml snippet for deleting records is below:
<sfdc:delete config-ref="Salesforce__Basic_authentication" doc:name="Salesforce">
<sfdc:ids ref="#[payload]" />
</sfdc:delete>
where, payload data type is List of string.
While deleting the records I am getting below exception:
ERROR 2015-11-05 23:39:39,755 [[tutorial].HTTP_Listener_Configuration.worker.01] org.mule.exception.DefaultMessagingExceptionStrategy:
********************************************************************************
Message : Could not serialize object (org.mule.api.serialization.SerializationException)
Type : org.mule.api.transformer.TransformerException
Code : MULE_ERROR--2
JavaDoc : http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/transformer/TransformerException.html
Transformer : ObjectToByteArray{this=7be7e15, name='_ObjectToByteArray', ignoreBadInput=false, returnClass=SimpleDataType{type=[B, mimeType='*/*', encoding='null'}, sourceTypes=[SimpleDataType{type=java.io.Serializable, mimeType='*/*', encoding='null'}, SimpleDataType{type=java.io.InputStream, mimeType='*/*', encoding='null'}, SimpleDataType{type=java.lang.String, mimeType='*/*', encoding='null'}, SimpleDataType{type=org.mule.api.transport.OutputHandler, mimeType='*/*', encoding='null'}]}
********************************************************************************
Exception stack is:
1. com.sforce.soap.partner.DeleteResult (java.io.NotSerializableException)
java.io.ObjectOutputStream:1184 (null)
2. java.io.NotSerializableException: com.sforce.soap.partner.DeleteResult (org.apache.commons.lang.SerializationException)
org.apache.commons.lang.SerializationUtils:111 (null)
3. Could not serialize object (org.mule.api.serialization.SerializationException)
org.mule.serialization.internal.AbstractObjectSerializer:68 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/serialization/SerializationException.html)
4. Could not serialize object (org.mule.api.serialization.SerializationException) (org.mule.api.transformer.TransformerException)
org.mule.transformer.simple.SerializableToByteArray:66 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/transformer/TransformerException.html)
********************************************************************************
Root Exception stack trace:
java.io.NotSerializableException: com.sforce.soap.partner.DeleteResult
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
at java.io.ObjectOutputStream.writeArray(ObjectOutputStream.java:1378)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
at org.apache.commons.lang.SerializationUtils.serialize(SerializationUtils.java:108)
at org.apache.commons.lang.SerializationUtils.serialize(SerializationUtils.java:133)
at org.mule.serialization.internal.JavaObjectSerializer.doSerialize(JavaObjectSerializer.java:44)
at org.mule.serialization.internal.AbstractObjectSerializer.serialize(AbstractObjectSerializer.java:64)
at org.mule.transformer.simple.SerializableToByteArray.doTransform(SerializableToByteArray.java:62)
at org.mule.transformer.simple.ObjectToByteArray.doTransform(ObjectToByteArray.java:78)
at org.mule.transformer.AbstractTransformer.transform(AbstractTransformer.java:415)
at org.mule.DefaultMuleMessage.getPayload(DefaultMuleMessage.java:425)
at org.mule.DefaultMuleMessage.getPayload(DefaultMuleMessage.java:373)
at org.mule.DefaultMuleMessage.getPayloadAsBytes(DefaultMuleMessage.java:714)
at org.mule.module.http.internal.listener.HttpResponseBuilder.build(HttpResponseBuilder.java:175)
at org.mule.module.http.internal.listener.HttpMessageProcessorTemplate.sendResponseToClient(HttpMessageProcessorTemplate.java:97)
at org.mule.execution.AsyncResponseFlowProcessingPhase.runPhase(AsyncResponseFlowProcessingPhase.java:83)
at org.mule.execution.AsyncResponseFlowProcessingPhase.runPhase(AsyncResponseFlowProcessingPhase.java:38)
at org.mule.execution.PhaseExecutionEngine$InternalPhaseExecutionEngine.phaseSuccessfully(PhaseExecutionEngine.java:65)
at org.mule.execution.PhaseExecutionEngine$InternalPhaseExecutionEngine.phaseSuccessfully(PhaseExecutionEngine.java:69)
at com.mulesoft.mule.throttling.ThrottlingPhase.runPhase(ThrottlingPhase.java:185)
at com.mulesoft.mule.throttling.ThrottlingPhase.runPhase(ThrottlingPhase.java:1)
at org.mule.execution.PhaseExecutionEngine$InternalPhaseExecutionEngine.process(PhaseExecutionEngine.java:114)
at org.mule.execution.PhaseExecutionEngine.process(PhaseExecutionEngine.java:41)
at org.mule.execution.MuleMessageProcessingManager.processMessage(MuleMessageProcessingManager.java:32)
at org.mule.module.http.internal.listener.DefaultHttpListener$1.handleRequest(DefaultHttpListener.java:126)
at org.mule.module.http.internal.listener.grizzly.GrizzlyRequestDispatcherFilter.handleRead(GrizzlyRequestDispatcherFilter.java:83)
at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:283)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:200)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:132)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:111)
at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:536)
at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
at org.mule.module.http.internal.listener.grizzly.ExecutorPerServerAddressIOStrategy.run0(ExecutorPerServerAddressIOStrategy.java:102)
at org.mule.module.http.internal.listener.grizzly.ExecutorPerServerAddressIOStrategy.access$100(ExecutorPerServerAddressIOStrategy.java:30)
at org.mule.module.http.internal.listener.grizzly.ExecutorPerServerAddressIOStrategy$WorkerThreadRunnable.run(ExecutorPerServerAddressIOStrategy.java:125)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
You are actually deleting successfully. The problem is that your Mule flow ends after making the Salesforce call, and by default it tries to return the current payload. That payload is the result of the SF call, which is of type com.sforce.soap.partner.DeleteResult, and Mule doesn't know how to serialize it.
To start, try simply adding a "Set payload" component after the SF call and set payload to anything you want, say "hello world". Once you understand what's happening, you can add a groovy script to process the DeleteResult and actually determine if the deletion was successful or not, and possibly do something if it wasn't.
In this case, if you don't want to explicitly change the payload and want the exact payload being sent out of the SFDC connector, then try having an object to json connector after the sfdc connector and a logger to log the payload in this case.
I have a Mule application that is writing a file in an outbound endpoint, with the config below:
<file:outbound-endpoint path="${Outbound}" outputPattern="outputFile_#[function:datestamp:yyyyMMddHHmmss].csv" doc:name="Output File"/>
Following this point in the flow I need to display a log message along the lines of "Successfully created file {filename}".
The issue I'm having is that I can't find a way of displaying the name of the file I have just created. I could put: Successfully created file outputFile_#[function:datestamp:yyyyMMddHHmmss].csv, but there is a chance that the datestamp may differ by one second.
Is there a way in Mule that I can display the name of the file I've just written?
UPDATE
Following the response from #til_b, I've achieved this using the following:
<set-variable value="outputFile_#[function:datestamp:yyyyMMddHHmmss].csv" variableName="Filename" doc:name="Variable"/>
<file:outbound-endpoint path="${Outbound}" outputPattern="#[variable:Filename]" doc:name="Output File"/>
<logger level="INFO" message="Successfully created file #[variable:Filename]" doc:name="Logger" />
I dont know about mule, but when i encounter such a problem while programming i store the generated filename in a variable, and then use that variable to actually create the file and display the message.
In Pseudocode:
var filename = #yyyymmddhhMMss.csv
create_file(filename)
log_message(filename + ' successfully created')
When creating a new bulk job through the API, I am getting an InvalidEntity as an exception code which isn't in SFDC's docs (pdf)
I'm making the following request
https://na13-api.salesforce.com/services/async/24.0/job
<?xml version="1.0" encoding="UTF-8"?>
<jobInfo xmlns="http://www.force.com/2009/06/asyncapi/dataload">
<operation>query</operation>
<object>Campaign</object>
<concurrencyMode>Parallel</concurrencyMode>
<contentType>CSV</contentType>
</jobInfo>
And I get this response:
<?xml version="1.0" encoding="UTF-8"?><error
xmlns="http://www.force.com/2009/06/asyncapi/dataload">
<exceptionCode>InvalidEntity</exceptionCode>
<exceptionMessage>Entity 'Campaign' is not supported by the Bulk API.</exceptionMessage>
</error>
I've excluded the headers but I do have accept & content encoding specified as gzip and the content is gzipped when it is sent and received.
The requests work correctly for
Lead
Contact
Opportunity
Task
Event
OpportunityContactRole
Account
CampaignMember
Note
Profile
RecordType
User
I only get the exception shown above for:
Campaign
UserLicense
OpportunityStage
OpportunityHistory
LeadHistory
I'm only using the bulk api to download csv's out of salesforce and I've only tried the above entities because I don't need any others.
It has been a very long time, but I think you can get this exception if one of your foreign key relationships is incorrect.