Jay Smith
Jay Smith

Reputation: 481

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>

Upvotes: 13

Views: 2392

Answers (4)

Malaka Silva
Malaka Silva

Reputation: 142

Reason for this error is there is a new line character after the xpath param given for the connector.

In the attached config,

        <sobjects
            xmlns:sfdc="sfdc">{//sfdc:sObjects}
        </sobjects>

Correct once should be

        <sobjects xmlns:sfdc="sfdc">{//sfdc:sObjects}</sobjects>

When this happens [1] will get the XPATH expression not the evaluate value, that causes this issue. Tested and find the working proxy.

<?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>

[1] https://github.com/wso2-extensions/esb-connector-salesforce/blob/master/connector/src/main/java/org/wso2/carbon/connector/salesforce/SalesforceUtil.java#L72

Upvotes: 0

Muralidharan.rade
Muralidharan.rade

Reputation: 2336

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.

Upvotes: 3

Hariprasath
Hariprasath

Reputation: 539

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>

Upvotes: 1

HM.Rajjaz
HM.Rajjaz

Reputation: 389

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

Upvotes: 1

Related Questions