Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WSO2 ESB: Unexpected Character Error when using Salesforce Connector

When attempting to follow the WSO2 directions to update a salesforce record I am getting the following error.

Saleforce adaptor - error injecting sObjects to payload : org.apache.axiom.om.OMException: com.ctc.wstx.exc.WstxUnexpectedCharException: Unexpected character '{' (code 123) in prolog; expected '<'

<?xml version="1.0" encoding="UTF-8"?>
<proxy
    xmlns="http://ws.apache.org/ns/synapse"
    xmlns:sfdc="sfdc" name="SalesforceUpdateTest" startOnLoad="true" statistics="enable" trace="enable" transports="http,https">
    <target>
        <inSequence>
            <sequence key="conf:/SalesforceLoginInfo"/>
            <payloadFactory>
                <format>
                    <sfdc:sObjects
                        xmlns:sfdc="sfdc" type="Account">
                        <sfdc:sObject>
                            <sfdc:Id>TestId1</sfdc:Id>
                            <sfdc:ValueToChange>Yes</sfdc:ValueToChange>
                        </sfdc:sObject>
                    </sfdc:sObjects>
                </format>
                <args/>
            </payloadFactory>
            <salesforce.update>
                <allOrNone>0</allOrNone>
                <allowFieldTruncate>0</allowFieldTruncate>
                <sobjects
                    xmlns:sfdc="sfdc">{//sfdc:sObjects}
                </sobjects>
            </salesforce.update>
        </inSequence>
        <outSequence>
            <send/>
        </outSequence>
    </target>
</proxy>

I am using WSO2 EI 6.1.0 and the salesforce connector 2.0.1. The Salesforce ID TestId1 exists as does the field ValueToChange. My SalesforceLoginInfo is correct (I can do Salesforce queries, just not updates).

Attempting to solve the problem I saw this very similar question. But I've added the lines to the axis2.xml according to the Solution, restarted, and the problem still exists.

<messageBuilder contentType="application/json" class="org.wso2.carbon.integrator.core.json.JsonStreamBuilder"/>
<messageBuilder contentType="text/javascript" class="org.wso2.carbon.integrator.core.json.JsonStreamBuilder"/>

<messageFormatter contentType="application/json" class="org.wso2.carbon.integrator.core.json.JsonStreamFormatter"/>
<messageFormatter contentType="text/javascript" class="org.wso2.carbon.integrator.core.json.JsonStreamFormatter"/>

Does anyone know how to fix this problem? I feel like I'm just following a tutorial (my code is nearly exactly the given wso2 salesforce example) and yet the problem continues.

UPDATE: To reduce confusion about the SalesforceLoginInfo call, I removed that and put the salesforce.init in the code. The error is still the same.

<?xml version="1.0" encoding="UTF-8"?>
<proxy
    xmlns="http://ws.apache.org/ns/synapse"
    xmlns:sfdc="sfdc" name="SalesforceUpdateTest" startOnLoad="true" statistics="enable" trace="enable" transports="http,https">
    <target>
        <inSequence>
            <salesforce.init>
                <username>[email protected]</username>
                <password>mypasswordandmytoken</password>
                <loginUrl>https://test.salesforce.com/services/Soap/u/27.0</loginUrl>
                <blocking>true</blocking>
            </salesforce.init>

            <payloadFactory>
                <format>
                    <sfdc:sObjects
                        xmlns:sfdc="sfdc" type="Account">
                        <sfdc:sObject>
                            <sfdc:Id>TestId1</sfdc:Id>
                            <sfdc:ValueToChange>Yes</sfdc:ValueToChange>
                        </sfdc:sObject>
                    </sfdc:sObjects>
                </format>
                <args/>
            </payloadFactory>
            <salesforce.update>
                <allOrNone>0</allOrNone>
                <allowFieldTruncate>0</allowFieldTruncate>
                <sobjects
                    xmlns:sfdc="sfdc">{//sfdc:sObjects}
                </sobjects>
            </salesforce.update>
        </inSequence>
        <outSequence>
            <send/>
        </outSequence>
    </target>
</proxy>
like image 632
Jay Smith Avatar asked Aug 08 '17 21:08

Jay Smith


3 Answers

Was able to replicate the below behavior with WSO2 EI 6.1.0 and the salesforce connector 2.0.1.

Saleforce adaptor - error injecting sObjects to payload : org.apache.axiom.om.OMException: com.ctc.wstx.exc.WstxUnexpectedCharException: Unexpected character '{' (code 123) in prolog; expected '<'

Find the below proxy sequence used to fix it. The workaround was to load the payload into a property and pass the same to salesforce operation <salesforce.update> through Synapse XPath variable $ctx

          <payloadFactory media-type="xml">
            <format>
               <sfdc:sObjects xmlns:sfdc="sfdc" type="Account">
                  <sfdc:sObject>
                     <sfdc:Id>0011I001102zk24PZA</sfdc:Id>
                     <sfdc:Description>Account1</sfdc:Description>
                  </sfdc:sObject>
               </sfdc:sObjects>
            </format>
            <args/>
         </payloadFactory>
         <log level="full"/>
         <log>
            <property xmlns:sfdc="sfdc" expression="//sfdc:sObjects" name="n****n"/>
         </log>
         <property xmlns:sfdc="sfdc"
                   expression="//sfdc:sObjects"
                   name="sobjectPayload"
                   scope="default"
                   type="OM"/>
         <log>
            <property expression="get-property('sobjectPayload')"
                      name="fromProp****"/>
         </log>
         <salesforce.update>
            <allOrNone>0</allOrNone>
            <allowFieldTruncate>1</allowFieldTruncate>
            <sobjects>{$ctx:sobjectPayload}</sobjects>
         </salesforce.update>

The salesforce record was updated, in this case Account Object record's Description property.

Also there is no need to add new messageBuilder or messageFormatter into the axis2.xml as messageType is : text/xml in Salesforce connector templates, which is included by default in Axis2 configuration.

like image 196
Muralidharan.rade Avatar answered Nov 20 '22 20:11

Muralidharan.rade


I can reproduce the error by removing the init operation.

[2017-08-12 09:39:17,315] ERROR - SetupUpdateSobjects Saleforce adaptor - error injecting sObjects to payload : org.apache.axiom.om.OMException: com.ctc.wstx.exc.WstxUnexpectedCharException: Unexpected character '{' (code 123) in prolog; expected '<'

Please add the init operation top of the update method.

            <salesforce.init>
            <loginUrl>{$ctx:loginUrl}</loginUrl>
            <username>{$ctx:username}</username>
            <password>{$ctx:password}</password>
            <blocking>{$ctx:blocking}</blocking>
        </salesforce.init>
                <payloadFactory>
                    <format>
                        <sfdc:sObjects xmlns:sfdc="sfdc" type="Account">
                            <sfdc:sObject>
                                <sfdc:Id>$1</sfdc:Id>
                                <sfdc:Name>$2</sfdc:Name>
                            </sfdc:sObject>
                        </sfdc:sObjects>
                    </format>
                    <args>
                        <arg expression="get-property('id')"/>
                        <arg expression="get-property('newName')"/>
                    </args>
                </payloadFactory>
                <salesforce.update>
                    <allOrNone>{$ctx:allOrNone}</allOrNone>
                    <allowFieldTruncate>{$ctx:allowFieldTruncate}</allowFieldTruncate>
                    <sobjects xmlns:sfdc="sfdc">{//sfdc:sObjects}</sobjects>
                </salesforce.update>

or you create local entry for init and call it in the proxy[1].

                <payloadFactory>
                <format>
                    <sfdc:sObjects xmlns:sfdc="sfdc" type="Account">
                        <sfdc:sObject>
                            <sfdc:Id>$1</sfdc:Id>
                            <sfdc:Name>$2</sfdc:Name>
                        </sfdc:sObject>
                    </sfdc:sObjects>
                </format>
                <args>
                    <arg expression="get-property('id')"/>
                    <arg expression="get-property('newName')"/>
                </args>
            </payloadFactory>
            <salesforce.update configkey="sf_init">
                <allOrNone>{$ctx:allOrNone}</allOrNone>
                <allowFieldTruncate>{$ctx:allowFieldTruncate}</allowFieldTruncate>
                <sobjects xmlns:sfdc="sfdc">{//sfdc:sObjects}</sobjects>
            </salesforce.update>

[1] https://docs.wso2.com/display/ESB500/Using+a+Connector

like image 1
HM.Rajjaz Avatar answered Nov 20 '22 20:11

HM.Rajjaz


I have two questions to understand the issue u getting here.

  1. First, what are you going to update in Account using the below? Do you need to give the record ID to update, if so you must give a valid id?

  2. The second thing is what is "ValueToChange"? Is it a field for Account object(I don't think this is a field of Account Object)?

Can you modify the proxy as below and try.

<?xml version="1.0" encoding="UTF-8"?>
<proxy
    xmlns="http://ws.apache.org/ns/synapse"
    xmlns:sfdc="sfdc" name="SalesforceUpdateTest" startOnLoad="true" statistics="enable" trace="enable" transports="http,https">
    <target>
        <inSequence>
            <salesforce.init>
                <username>[email protected]</username>
                <password>mypasswordandmytoken</password>
                <loginUrl>https://test.salesforce.com/services/Soap/u/27.0</loginUrl>
                <blocking>true</blocking>
            </salesforce.init>

            <payloadFactory>
                <format>
                    <sfdc:sObjects
                        xmlns:sfdc="sfdc" type="Account">
                        <sfdc:sObject>
                            <sfdc:Id>valid salesforce record ID</sfdc:Id>
                            <sfdc:Name>Jay Smith</sfdc:Name>
                        </sfdc:sObject>
                    </sfdc:sObjects>
                </format>
                <args/>
            </payloadFactory>
            <salesforce.update>
                <allOrNone>0</allOrNone>
                <allowFieldTruncate>0</allowFieldTruncate>
                <sobjects
                    xmlns:sfdc="sfdc">{//sfdc:sObjects}
                </sobjects>
            </salesforce.update>
        </inSequence>
        <outSequence>
            <send/>
        </outSequence>
    </target>
</proxy>
like image 1
Hariprasath Avatar answered Nov 20 '22 19:11

Hariprasath