Showing posts with label Cloud. Show all posts
Showing posts with label Cloud. Show all posts

Wednesday, 11 November 2015

Oracle ServiceCloud Rightnow Integration, XSLT Transformations!

I've just roll out to a live environment, a SOA Integration project with Oracle Service Cloud Rightnow.

The customer needed to migrate from a in-house CRM to Oracle Service Cloud and with my company Infomentum we have helped them in taking this big step. Since that I have made lots of experience with OSC WebServices.

Here I just want to share the complex XSLT Transformation which we have implemented to communicate with the OSC WebServices, hopefully these can speed up any other SC integration projects.

There are 6 transformation in the ZIP package (we have implemented more):

XSLT NameSC ObjectOut of the box Object?Operation Type
xsltContact2UpdateCONTACTYesUPDATE
xsltOrganisationToUpdateORGANIZATIONYesUPDATE
xsltProgrammeToUpdateCO.PROGRAMMENoUPDATE
xsltProgrammeTypeToUpdateCO.PROGRAMMETYPENoUPDATE
xsltCourseToUpdate2CO.COURSENoUPDATE
xsltSessionToUpdateCO.SESSIONNoUPDATE

In the XSLTs you'll find all the details about the TARGET columns (Oracle Service Cloud ones).

Here are some important concepts I want to highlight:

  • SC Columns in the XSLT are sometimes out of the box column, in some other cases they are custom ones. In the XSLT the latter will be identified with the tag GenericFields.

             <rng_v1_2:GenericFields dataType="OBJECT" name="C">
                <rng_v1_2:DataValue>
                  <rng_v1_2:ObjectValue xsi:type="rng_v1_2:GenericObject">
                    <rng_v1_2:ObjectType>
                      <rng_v1_2:TypeName>ContactCustomFieldsc</rng_v1_2:TypeName>
                    </rng_v1_2:ObjectType>
                    <rng_v1_2:GenericFields dataType="BOOLEAN" name="yp_surveydeclined_mail_bol">
                        <rng_v1_2:DataValue>
                          <rng_v1_2:BooleanValue>
                            <xsl:value-of select="/ns0:contact/ns0:isMailOptionSur"/>
                          </rng_v1_2:BooleanValue>
                        </rng_v1_2:DataValue>
                    </rng_v1_2:GenericFields>
                  </rng_v1_2:ObjectValue>
                </rng_v1_2:DataValue>
              </rng_v1_2:GenericFields>

  • Custom fields can be in the subPackage C or CO (you'll find this package in the attribute NAME of the GenericFields tag). The former is used for custom fields, the latter for custom object relationship fields. In this case the data type might be something like dataType="NAMED_ID", which means this is related to a complex object

          <rng_v1_2:GenericFields dataType="OBJECT" name="CO">
            <rng_v1_2:DataValue>
              <rng_v1_2:ObjectValue xsi:type="rng_v1_2:GenericObject">
                <rng_v1_2:ObjectType>
                  <rng_v1_2:TypeName>ContactCustomFieldsc</rng_v1_2:TypeName>
                </rng_v1_2:ObjectType>
                <rng_v1_2:GenericFields dataType="NAMED_ID" name="all_addr_region_lst">
                    <rng_v1_2:DataValue>
                      <rng_v1_2:NamedIDValue>
                        <rnb_v1_2:Name>
                          <xsl:value-of select="/ns0:contact/ns0:Region"/>
                        </rnb_v1_2:Name>
                      </rng_v1_2:NamedIDValue>
                    </rng_v1_2:DataValue>
                </rng_v1_2:GenericFields>
              </rng_v1_2:ObjectValue>
            </rng_v1_2:DataValue>
          </rng_v1_2:GenericFields>

  • In order to blank any field in SC the client must pass the attribute xsi:nil="true" in the attribute tag or in the DataValue tag for the custom field.

          <rng_v1_2:GenericFields dataType="OBJECT" name="CO">
            <rng_v1_2:DataValue>
              <rng_v1_2:ObjectValue xsi:type="rng_v1_2:GenericObject">
                <rng_v1_2:ObjectType>
                  <rng_v1_2:TypeName>ContactCustomFieldsc</rng_v1_2:TypeName>
                </rng_v1_2:ObjectType>
                <rng_v1_2:GenericFields dataType="NAMED_ID" name="all_addr_region_lst">
                    <rng_v1_2:DataValue xsi:nil="true">
                      <rng_v1_2:NamedIDValue>
                        <rnb_v1_2:Name></rnb_v1_2:Name>
                      </rng_v1_2:NamedIDValue>
                    </rng_v1_2:DataValue>
                </rng_v1_2:GenericFields>
              </rng_v1_2:ObjectValue>
            </rng_v1_2:DataValue>
          </rng_v1_2:GenericFields>

  • PhoneList and EmailList attribute needs to be managed via the ACTION (update, add, remove) attribute in the XSLT and via the TYPE ID (the ID of the Phone, since they might be multiple, like Mobile1, Work, Landline, etc, same applies to the Email)

           <rno_v1_2:Phones>
              <rno_v1_2:PhoneList action="update">
                <rno_v1_2:Number>
                  <xsl:value-of select="/ns0:contact/ns0:TelWork"/>
                </rno_v1_2:Number>
                <rno_v1_2:PhoneType>
                  <rnb_v1_2:ID id="{0}"/>
                </rno_v1_2:PhoneType>
              </rno_v1_2:PhoneList>


              <rno_v1_2:PhoneList action="remove">
                <rno_v1_2:PhoneType>
                  <rnb_v1_2:ID id="{1}"/>
                </rno_v1_2:PhoneType>
              </rno_v1_2:PhoneList>

              <rno_v1_2:PhoneList action="remove">
                <rno_v1_2:PhoneType>
                  <rnb_v1_2:ID id="{2}"/>
                </rno_v1_2:PhoneType>
              </rno_v1_2:PhoneList>



Below is an easy transformation used for the Programme CustomObject Update

    <ns1:Update>
      <ns1:RNObjects xsi:type="rng_v1_2:GenericObject">
        <rnb_v1_2:ID id="{$InvokeGetProgramme_QueryCSV_OutputVariable.parameters/ns1:QueryCSVResponse/ns1:CSVTableSet/ns1:CSVTables/ns1:CSVTable/ns1:Rows/ns1:Row}"/>
        <rng_v1_2:ObjectType>
          <rng_v1_2:Namespace>CO</rng_v1_2:Namespace>
          <rng_v1_2:TypeName>Programme</rng_v1_2:TypeName>
        </rng_v1_2:ObjectType>
        <rng_v1_2:GenericFields dataType="INTEGER" name="all_soa_totcodeid_int">
          <rng_v1_2:DataValue>
            <rng_v1_2:IntegerValue>
              <xsl:value-of select="/ns0:programme/ns0:CodeID"/>
            </rng_v1_2:IntegerValue>
          </rng_v1_2:DataValue>
        </rng_v1_2:GenericFields>
        <rng_v1_2:GenericFields dataType="STRING" name="all_all_name_txt">
          <rng_v1_2:DataValue>
            <rng_v1_2:StringValue>
              <xsl:value-of select="/ns0:programme/ns0:Description"/>
            </rng_v1_2:StringValue>
          </rng_v1_2:DataValue>
        </rng_v1_2:GenericFields>
        <rng_v1_2:GenericFields dataType="BOOLEAN" name="all_all_deleted_bol">
          <rng_v1_2:DataValue>
            <rng_v1_2:BooleanValue>
              <xsl:value-of select="/ns0:programme/ns0:Deleted"/>
            </rng_v1_2:BooleanValue>
          </rng_v1_2:DataValue>
        </rng_v1_2:GenericFields>
        <rng_v1_2:GenericFields name="all_soa_modified_dt" dataType="DATETIME">
          <rng_v1_2:DataValue>
            <rng_v1_2:DateTimeValue>
              <xsl:value-of select="ptutlGmt:getCurrentDateInGMT(string(/ns0:programme/ns0:SOA_ModifiedDate))"/>
            </rng_v1_2:DateTimeValue>
          </rng_v1_2:DataValue>
        </rng_v1_2:GenericFields>
        <rng_v1_2:GenericFields dataType="BOOLEAN" name="all_all_fromsoa_bol">
          <rng_v1_2:DataValue>
            <rng_v1_2:BooleanValue>1</rng_v1_2:BooleanValue>
          </rng_v1_2:DataValue>
        </rng_v1_2:GenericFields>
      </ns1:RNObjects>
    </ns1:Update>

Please download the transformation from here!

Also find here more information about this challenging project:
http://www.computing.co.uk/ctg/news/2433947/princes-trust-opts-for-oracle-for-digital-transformation
http://www.infomentum.com/uk/about-us/media-centre/news/princes-trust-golive

Let me know for any issues!!!




Tuesday, 28 April 2015

Connect and consume data with Oracle RightNowCX using the new SOA12c RightNow adapter


The  Oracle RightNow adapter has been released for the SOA 12.1.3 just couple of months ago, and I tested as soon as I've heard of it!

What it is needed for this tip

  • JDeveloper 12.1.3
  • An account with read right on the WebServices exposed by an Oracle Rightnow instance

Before starting!

Make sure the following patch bundle has been applied to your SOA/jdev Home.

Bundle Patch for Bug: 20423408

The patch can be downloaded from Oracle support of course, and installed using opatch apply.
The patch must be applied to both, the SOA Server home (if not in the jdev home) and Jdev home, since the new plugin which will shows the RightNow adapter wizard, must be configured into JDeveloper.
Remember to perform the post-installation steps (patch READ-ME for details):


1. Log in to Fusion Middleware Control Enterprise Manager.
2. Expand "Weblogic Domain" in the left panel
3. Right click on the domain you want to modify and select Security > System Policies to display the page System Policies.
4. In the System Policies page, expand "Search". For "Type" select "Codebase", for "Includes" enter "jca" and click the arrow button.
5. Select "jca-binding-api.jar" in the search returned result and click "Edit".
6. In the "Edit System Grant" page, click on "Add".
7. In the "Add Permission" page, click on "Select here to enter details for a new permission" and enter the following:
  • Permission Class:oracle.security.jps.service.credstore.CredentialAccessPermission
  • Resource Name: context=SYSTEM,mapName=SOA,keyName=*
  • Permission Action: *
8. Click on "OK" to save the new permission.


In order to verify the installation went well please double check you'got the RightNow Adapter in the Cloud Adapter Component palette:



After the installation start JDeveloper with the option "jdev.exe -clean"

Hands on!

  • Generate one SOA application with an empty SOA project.
  • Drag and drop an Oracle Rightnow component in the External reference lane and the wizard will pop up
  • Insert the WSDL url (the WSDL and XSD schemas will be downloaded), also create a new csf key in Jdeveloper with your username and password for Oracle Rightnow. 


  • Select the Create WSDL operation and the Contact business object



  • Click FINISH
  • Now add a WIRE from the BPEL process to the Rightnow adapter
  • Edit the composite input XSD adding the following fields:
<element name="process">
<complexType>
<sequence>
<element name="Name" type="string"/>
<element name="LastName" type="string"/>
<element name="Address" type="string"/>
<element name="PostCode" type="string"/>
</sequence>
</complexType>
</element> 

  • Open the BPEL process and add an invoke to the adapter (create input and output variables)
  • Add a transformation which will be used to set properly the invoke input variable for the Rightnow adapter.
  • Edit the transformation as showed below. The left variable is the composite input variable, while the right one is the Rightnow input one 

  • So the BPEL process will look like this below
  • Deploy it top the integrated SOA Server
  • Last step, configure the username and password in the EM console using the CSF key MyRightNowUser configured in the JCA adapter in WeblogicDomain => Security => Credentials in the Credential Map SOA, as showed below



The SOA Composite can now be tested and hopefully an account will be created in Oracle Rightnow SC!
Let me know for any issue (see Possible problems below)!

Tip: instead of configuring the credentials in the SOA-EM, the csfkey property parameter in the jca-properties definition can be omitted and replaced with username and password parameters

Possible problems

  • In case the WebService invocation fails with this:
"Exception occurred during invocation of JCA binding: "JCA Binding execute of Reference operation 'Create' failed due to: Unable to create Cloud Operation:
The invoked JCA adapter raised a resource exception.
Please examine the above error message carefully to determine a resolution "

Then replace in the Rightnow JCA the targetWSDLURL local WSDL with the remote one, as explained here and redeploy it!


  • In case the WebService invocation fails with this:
"Exception occurred during invocation of JCA binding: "JCA Binding execute of Reference operation 'Create' failed due to: Client received SOAP Fault from server : Username is not specified in UsernameToken."

Then the credential key is not configured correctly in the credential store or the process can't see it. Review it!


  • In case the WebService invocation fails with this:
"Exception occurred during invocation of JCA binding: "JCA Binding execute of Reference operation 'Create' failed due to: Client received SOAP Fault from server : Access Denied."

Then the user-password are not correct in the credential key. Review it!


Please find the RightNow Cloud Service Adapter documentation here!
The source code of the composite created here