Showing posts with label Webservice. Show all posts
Showing posts with label Webservice. Show all posts

Friday, April 8, 2016

Oracle Sales Cloud: Getting around OSC’s WSDL parsing , Siebel UCM

 

Recently working on getting Oracle Sales Cloud integrated to Siebel UCM for Accounts. Oracle Sales Cloud can read a WSDL specification from a URL, but you still have to build the request message using Groovy script (would be nice to shoot whoever designed this). So you have to use Groovy script and write a global function to build up the message. Turns out, you can only add elements and attributes to the message which is already in the parsed WSDL. Nothing new can be added. © 2016 cleartext.blogspot.com

The problem here is that for integrations to Siebel UCM, a hidden attribute named ExternalSystemId has to be populated in the incoming message. This attribute is not in the WSDL when it gets generated from Siebel UCM. But it has to be sent in the SOAP request (would also be nice to shoot whoever designed this).  © 2016 cleartext.blogspot.com

Error invoking service 'UCM Transaction Manager', method 'SOAPExecute' at step 'Transaction Manager'.(SBL-BPR-00162)
--
<?> Failed to find ExternalSystemId in input message(SBL-IAI-00436)

 

This is what you get when you consume the UCM WSDL in SOAP UI.

image

The actual message has to be (see highlighted changes) © 2016 cleartext.blogspot.com

image

 

If you add the groovy script to add this attribute, OSC will simply ignore it, and the attribute is not send to UCM. The only viable workaround is to Edit the WSDL AFTER it is generated, but BEFORE it is given to Sales Cloud !  © 2016 cleartext.blogspot.com

1: Generate the WSDL from UCM.

2: Open it in an XML editor , use XMLSPY if you have it. © 2016 cleartext.blogspot.com

3: Find the definition of the top container element int the WSDL: © 2016 cleartext.blogspot.com

image

4: Add this text (highlighted) : © 2016 cleartext.blogspot.com

image

<xsd:attribute name="ExternalSystemId" type="xsd:string"/>

5: Now validate, save and upload this WSDL to your public folder from where OSC can read it. OSC does not consume WSDLs, but reads the definition on the fly. © 2016 cleartext.blogspot.com

6: Now add the groovy script to populate this new attribute with the registered SystemId Name.

 

Phew !!

image

© 2016 cleartext.blogspot.com© 2016 cleartext.blogspot.com

Thursday, March 31, 2016

TCC: Handling Encoding

 

Aahh…multilingual. That word increases the complexity of any project intantly. When your enterprise application is multilingual, it means users will be able to add and edit data in different languages, and that the data can no longer be stored in ASII/ANSI format. East Asian, and Middle Eastern and some European languages require more than one byte for a single charachter, so it has to be stored in Unicode format. While working on Taleo’s TCC scripts, I recently hit a roadblock with multilingual data, but the fantastic folks at Taleo had already solved the problem. © cleartext.blogspot.com 2016

TCC’s pipelines handle data in UTF-8 format, but many enterprise systems will produce output in UTF-16. So which one is better ? There is a common misconception that UTF-8 can not store all language charachters, and that UTF-16 is required. That’s not true. UTF-8 has an amazing awesome format, and it can depict every Unicode charachter, same as UTF-16. Here is a spectucular explanation of this miracle.

So if you get data in UTF-16 (or any of the other formats), how do you load them via TCC ?  In the configuration  file, TCC provides an option to set the encoding of the source file. © cleartext.blogspot.com 2016

image

If you know the encoding of the source, you enter it here.  This will work for standard Import files. There is also an option to set the response encoding.

image

But some complicated TCC configurations, like NetChange, require the pipeline data to be in UTF-8. So how do you get around that ?

The encoding can be changed in the configuration file. Go to Pre-Processing tab, and add a new step.

There is an option to add an ‘Convert Encoding’ step. © cleartext.blogspot.com 2016

image

Choose the source encoding, and set the target as UTF-8. This step has to be the first step in your NetChange configuration file.

image

Thats it ! cleartext.blogspot.com

Wednesday, March 2, 2016

.NET : No endpoint element matching this contract could be found in the client element

 

If you are using .NET and trying to integrate to Oracle Fusion Cloud service, any service, HCM,Sales Cloud, Service Cloud.., after consuming the WSDL and writing the first bits of code, you will get to this error:

cleartext.blogspot.com

Could not find default endpoint element that references contract ….' in the ServiceModel client configuration section. This might be because no configuration file was found for your application, or because no endpoint element matching this contract could be found in the client element.

image

You will get the error wether you try importing as Web Reference or Service Reference. The reason for this is that even after successfully consuming the WSDL, .NET does not add the end point configuration into the app.config file.

 

1: Possible workaround: When you write the code to create the client object, (SalesCloud account, in my case), instead of going with the default no parameter initialization,  add parameters for Binding and Endpoints.cleartext.blogspot.com

 

VB.NET : Add this code to your project source:

Public Class UsernameTokenOverSslBinding : Inherits CustomBinding
    Public Sub New()
        MyBase.New()
    End Sub
    Public Overrides Function CreateBindingElements() As BindingElementCollection
        Dim bindingElements As BindingElementCollection = New BindingElementCollection
        bindingElements.Add(SecurityBindingElement.CreateUserNameOverTransportBindingElement())cleartext.blogspot.com
        Dim messageEncoding As MtomMessageEncodingBindingElement = New MtomMessageEncodingBindingElement
        messageEncoding.MessageVersion = MessageVersion.Soap11
        bindingElements.Add(messageEncoding)
        Dim transport As HttpsTransportBindingElement = New HttpsTransportBindingElement
        bindingElements.Add(transport)

        Return bindingElements.Clone()
    End Function
End Class

 

C# .NET: Add this code

 

 public class UsernameTokenOverSslBinding : CustomBinding     {         public override BindingElementCollection CreateBindingElements()         {
cleartext.blogspot.com
            BindingElementCollection bindingElements = new BindingElementCollection();             bindingElements.Add(SecurityBindingElement.CreateUserNameOverTransportBindingElement());             MtomMessageEncodingBindingElement messageEncoding = new MtomMessageEncodingBindingElement();             messageEncoding.MessageVersion = MessageVersion.Soap11;             bindingElements.Add(messageEncoding);             HttpsTransportBindingElement transport = new HttpsTransportBindingElement();             bindingElements.Add(transport);             return bindingElements.Clone();         }     }
 
Now pass this class object as the first parameter to your Interface Object Initialization.
Example: Previous code:
Dim accountclient As New OSC.AccountServiceClient()cleartext.blogspot.com
New code

Dim endpointAddress = New EndpointAddress(New Uri("URL”))  ‘ give the url here.
Dim accountclient As New OSC.AccountServiceClient(New UsernameTokenOverSslBinding(), endpointAddress)

 

…And thats it ! The object will now be able to connect to the server via a webservice call.

cleartext.blogspot.com

2: Possible workaround:  The other possible workaround is to add these lines to app.config file.

 

image

cleartext.blogspot.com

 

Any of these workarounds, and you should start seeing the response object:

image

Saturday, September 5, 2015

HCM: WebService integrations

 

I am turning over a new leaf and starting with Oracle's Fusion HCM Cloud Service, looking into its integration system. Looks like Oracle does not want developers to use its webservices, because there seems to be no concise document available on how to set up a simple webservice integration. After sifting through numerous blogs and forums, I finally decided to explore the Oracle Enterprise Repository for information. And this seems to be the unwritten golden rule for Fusion applications: if you need information, go to OER.

After logging into OER as guest, run a quick query in the left pane to get started. If you want to know about Fusion HCMs webservices, select "ADF Service" under Type, and "Human Capital Management" under Product Family. You can also choose an appropriate Version, though everyone will be on the latest version anyway.

cleartext.blogspot.com

tmpFC7B

Running the query gives a  list of Fusion ADF services which can be used for external integrations. For main Employee related webservices, choose the Worker services at the end of the list.

cleartext.blogspot.com

tmp44A3

To find the WSDL address of this service, choose the detail tab and go to the end of the page.

tmpC152

tmpD2

And there, right at the end of the page, is the logical address of the service. You will have to replace the <hcm server> part with the actual hostname of your cloud service.

Simply entering this URL in a browser gives us the WSDL:

cleartext.blogspot.com

tmp688B

And providing this URL in SOAPUI downloads the WSDL and schema. The WSDL is very big, SOAP UI takes a couple of minutes to completely consume the WSDL and generate the sample messages.

cleartext.blogspot.com

image

 

And now for the really tricky part. The search request has to be built in the SOAP message so that the system can respond with data. After trying numerous combinations, I just tried a simple empty SOAP request. And…it returned successfully !

 

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:typ="http://xmlns.oracle.com/apps/hcm/employment/core/workerServiceV2/types/" xmlns:typ1="http://xmlns.oracle.com/adf/svc/types/">
   <soapenv:Header/>
   <soapenv:Body>
      <typ:findWorker>
         <typ:findControl>
       </typ:findControl>
      </typ:findWorker>
   </soapenv:Body>
</soapenv:Envelope>

cleartext.blogspot.com

 

tmpDE5

cleartext.blogspot.com

 

 

Important: The userid and password has to be provided either in the soapenv:Header section, or in the userid/password fields of SOAP UI. If you enter a wrong password, the fusion system does not respond with an error message or exception. Instead, it simply sends back the request which it received. Completely. Without any indication of any error. So if you start getting back your request payload in the response, check the credentials.

Sunday, June 12, 2011

Java integration to Siebel Webservice

 

A few weeks back we had this requirement to have a Java client connect to our Siebel Webservice and do various operations. In this model, the Siebel side was the backend, and a Java applet was the frontend to the system. I setup the inbound Webservice in Siebel in no time, using ASIs. But the Java folks were having problems in setting up a connection to the system. They even said there were problems in the WSDL and Webservice, and that they were getting various parser errors on their side. Guess they were too dependent on eclipse, and they could not find an import WSDL feature on it !!

Truth is, Java is one of those languages which understands webservices very well, and if properly used, could make the integration work easiest to implement. You don’ have to build the SOAP request by hand (though, that is one option) as is done in some scripting languages. You just have to figure out how to generate the stub file, or the necessary class files into the system.

Now there are two ways to import a WSDL into a  Java system, you would use the WSDLtoJava.bat file if you are using the apache axis framework. This is when a Java servlet on Tomcat/Apache is talking to another server. I preferred the easier way to using the wsimport command as this is a simple client talking to a Siebel server. I will be using the Service Request ASI WSDL from a previous post.

You need to have the Java SDK installed and the paths properly configured on your system. Open up a command prompt window and type in  “java  -version” or “javac” to see if the paths have been added correctly.

Go ahead and import the wsdl using the command wsimport SR_WSDL.wsdl. Here I am running the command from the root of C: drive. You will see the importer at work generating class files.

clip_image002[9]

You can ignore any warnings you see as long as you don’t get any errors. wsimport would have created a nested folder structure with multiple class files. Here the path created is C:\com\siebel\xml\sm_servicerequest.

image

Now its time to start writing your main java file which will make an instance of these class files and trigger the integration to siebel. You will have to know which class represents the webservice, here it is SMServiceRequestWS_Service.class. You can also generate the actual java files to see how the class and methods under them have been defined. Inorder to do this, use the command wsimport –keep.

clip_image002[13]

This time wsimport will create the java files for each class file.

clip_image002[15]

Back to our main java file. Import the generated class files using:

import com.siebel.xml.sm_servicerequest.*;

As can be seen, this string is actually the path of the generated class files. This is what my final Client.java file looked like :

///////////////////////////////////////////////////////////////////////////////////////////////////////////////

import com.siebel.xml.sm_servicerequest.*;

import java.io.Writer;

//the above namespace is from the generated code from the wsdl.

public class Client

{

static SMServiceRequestWS_Service service = new SMServiceRequestWS_Service();

public static void main(String[] args)

{

try

{

Client client = new Client();

client.doTest(args);

}

catch(Exception e)

{

e.printStackTrace();

}

}

public void doTest(String[] args)

{

try

{

SMServiceRequestWS pm = service.getSMServiceRequestWS();

// Building the Request hierachy

QueryPageSRInput req = new QueryPageSRInput();

req.setPageSize("10");

req.setViewMode("All");

req.setStartRowNum("0");

ListOfSmServicerequest list = new ListOfSmServicerequest();

ServiceRequest SR =new ServiceRequest();

list.getServiceRequest().add(SR);

req.setListOfSmServicerequest(list);

// Variable to store Response hierarchy

QueryPageSROutput res = new QueryPageSROutput();

// Invoke the service

System.out.println("Invoking the Webservice ");

res =pm.queryPageSR(req);

System.out.println(res.getLastPage());

for (int i = 0; i < res.getListOfSmServicerequest().getServiceRequest().size(); i++)

{

System.out.print(res.getListOfSmServicerequest().getServiceRequest().get(i).getStatus() + "\t");

System.out.print(res.getListOfSmServicerequest().getServiceRequest().get(i).getSRNumber() + "\t");

System.out.println(res.getListOfSmServicerequest().getServiceRequest().get(i).getOwner());

}

}

catch(Exception e)

{

e.printStackTrace();

}

}

}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

All the information you need to build up the request and parse out the response is in the .java files created by wsimport. As can be seen, the final code does not have any variables for the URL,namespace or SOAPAction. These details are taken care of in the .java files.

Time to compile and run the Client.java file. Commands are:

javac Client.java

java Client

The client instance should connect to the Siebel Webservice now :

image

This code runs a  Query and prints out the Service Request Status, RowId and Owner details.

That’s it !! This is all you need to have a java client invoking a Siebel Webservice.

Friday, June 10, 2011

Inbound ASI–Keeping it simple

 

What is the easiest way to setup a new inbound web service in Siebel ? Well, a lot depends on the actual requirement, the complexity of the schema, error handling features etc. If the requirement is really simple, I try to go for an Application Service Interface or ASI. And specially if the requirement calls for multiple operations at a single web service, then ASI is the way to go.

An Application Services Interface (ASI) is a release-independent interface published by Oracle that allows you to integrate Siebel applications with external applications. An ASI is a collection of related methods; each method contains input and output parameters. The methods and parameters are listed on the business service definition. Simple method parameters (such as a string or number) are defined directly in the service definition. Hierarchical method parameters are defined using integration objects

Lets assume that the requirement here is to expose a query operation as a web service. The end point would invoke a Siebel web service which would extract data in a schema. Simple query operation. Here is how to do it in an ASI.

Step 1 : Define your schema. Decide upon an already present Integration Object or design a new IO from scratch. Here I’m choosing a custom Service Request IO, with attachments as the child IC. Don’t forget to decide upon the user keys and status keys.

clip_image002[9]

 

Step 2: Define the ASI business service. Create a new business service, and set the class as CSSEAIDataSyncService. Define a method for this BS as QueryPage. Here I have added one more method for InsertOrUpdate.

 

clip_image002[11]

Define the arguments of the methods. There has to be at least one argument of type Integration Object. Mention the IO name you had chosen in Step1

clip_image002[13]

Two Business Service User properties are required.

clip_image002[15]

Instead of creating the BS, an existing ASI can be simply cloned, in which case you would only need to change the IO name.

 

Step 3: Expose the BS as an Inbound web service.  Compile the IO and BS. On Siebel 8, simply right click the BS and choose deploy as web service. Or you could setup the service yourself.

In the application, go to Sitemap > Administration – Webservices > Inbound Webservice.

clip_image002

In service name, give any name and set the namespace. The namespace can be taken from the IO userproperties.

In Service Port, choose the newly created BS. Set the binding and transport values. Here I have chosen SOAP_DOC_LITERAL and HTTP Transport

In the Operations applet, the methods of the custom BS will be available. Set them up, and clear the cache.

That’s it, your done !!  You can generate the WSDL, and this can be consumed by the end point. The end system will get to see the various operations exposed under the service.

Here is how the WSDL looks when consumed in XML Spy:

clip_image002[17]

And on choosing QueryPage method, XML Spy will generate this SOAP Request.

clip_image002[19]

Regarding the different methods that can be exposed, there are six to choose from. And if needed, you can also provide datamappers for the request or response.

ASIs implement error handling in their own way and return SOAP fault codes back to the calling system.

Siebel ASIs are prebuilt and can be used immediately. ASIs provide a release-independent integration interface to the Siebel application, which remains unchanged with each upgrade to a new release. This is one of those few areas in Siebel where there is an upgrade-proof guarantee from Siebel/Oracle.