Friday, October 29, 2010

A Basic Interface - Web Service Workflow

Just about every interface consists of two basic components: the integration object(s) and the workflow or business service. I will demonstrate a workflow approach which will give you more opportunity to customize down the road.

It is here that we begin to differentiate the integration by the communication mechanism. Because I am designating this integration as a Web Service, that will drive the type of data this workflow will expect as an input and output. The workflow I build will eventually be exposed as a WSDL to be consumed by an external program. That WSDL should have the definition of the message it is expecting, in this case, the XSD, or definition of the Integration Object we just built. How we accomplish this is to set the Input Process Property to a Data Type of 'Integration Object' and to actually specify the integration object we built, in the Integration Object attribute of the process property.


You can also see my place holder for the SR Number that I want to return to the external system in the response message. The 'IncomingXML' property is already in the format needed to be passed to the EAI Siebel Adapter, so there is no conversion necessary. And we are assuming that the data being passed is exactly as it should be applied. You will create the following steps which I will explain (other than Start and End which are self explanatory):
The 'Upsert SR' is a Business Service calling 'EAI Siebel Adapter'. Now here is the another design decision to be made. Each of the available methods differentiate exactly how the data should be applied. But there are two broad determinations. If we were to use the Execute method, then the 'operation' element which exists in each component of the IO would be used to determine how the data should be applied. This gives more control the calling system (or a data map which I will discuss later). The other set of methods essentially comprise a One Size Fit All to applying all the data uniformly. I will use the latter approach here and set the method to 'Upsert'. There is only one component in my IO, so if it exists, it will be updated, otherwise it will be inserted. The input arguments for this step are the IncomingXML message from the external system and a parameter telling the EAI Siebel Adapter to create the Status Object.

There is one Output Argument. We no longer care about the input message at this point because it will have been applied so we just overwrite it with the return, which in this case will be the status key.
The last step in the WF is another Business Service step calling 'PRM ANI Utility Service', 'GetProperty' method. This business service has a plethora of useful methods for manipulating property sets. This particular method will extract the value of a field from an integration object instance. Here are the inputs:
The output is to set the process property 'SRNumber' with the Output Argument, 'Property Value'. When the return message is sent back to the calling system, this property will exist with the generated SR Number.

Simulating/Troubleshooting this WF from within tools is difficult as built so I sometimes add a bypass step off the start branch to read the integration object from a file. I may talk about this later but want to keep this post pretty straightforward. So for now, this workflow can just be deployed, checked in and activated.

A Basic Interface - Building the Integration Object

I am not sure how easy it will be to summarize EAI in a couple of blog posts as there are definately a lot of ifs and buts in the design process. Nevertheless, I think it wold be useful to show how to build a basic interface using a couple of different techniques. Frequently you client's enterprise architecture will drive which to use.

Integration generally takes one of three forms
  • Query - Returns a data set of source data to be displayed in the target system
  • Schema Update - Takes a hierarchical data structure and applies it to the target system
  • Functional Action - Triggers a service to perform some set of business rules
There is perhaps some overlap here and any of these can be inbound or outbound to siebel, but this is a general way of categorizing your interfaces. And within each there are several different ways to implement more specific requirements.

Regardless of approach, the basic component of most interfaces is the structure of how data is viewed or applied. Let's say we need to Upsert a Service Request. A Schema Update assumes a hierarchical organization of data using the Integration Object data structure. Bookshelf provides extensive instruction on how these are built and configured to achieve certain goals so I will only touch on the highlights.

First, create an Integration Object in Siebel: from the Tools File Menu, New Object Wizard, EAI Tab, choose Integration Object. In the wizard, select the Project and choose 'EAI Siebel Wizard' from the second dropdown, and click Next. For the purpose of this example, we can just use the Service Request business object as the source object and the root BC will be Service Request. Enter a name of your choosing and click Next. In the next wizard page, deselect all child objects for which there are no fields to set. In this case that will be all of them except for the root as the more objects and fields in the message, the longer it will take the various architecture components to parse and translate the message. Click Next, then Finish on the next page.

Your Integration Object has been created. The next step is to verify the user keys. An integration object needs to have a valid user key in order to do an upsert. This basically specifies which key fields to use to find a record to update. In my example for Service Request, a key was not generated by the wizard so I will create one. Navigate to Integration Component Key in the explorer under the Service Request Integration Component. Create a new record, provide a name, set the sequence number to 1 and the key type to 'User key'. Create a child record in Integration Component Key Fields, provide a name and set the Field Name to 'Id'.

Another optional step we will use in this example is the Status Key. After creating a service request, I want to return the service request number to the external system as verification of success and so this SR can be referenced later by the customer. To do this we use the Status Key. This is basically a structure of the data set we wish to return from the EAI Siebel Adapter call and pass back to the calling system. A Status Key can be specified for each Integration Component so the final data set is the structure of all the keys combined hierarchically. In this case, navigate to Integration Component Key in the explorer under the Service Request Integration Component, create another new record, provide a name, 'StatusKey, set the sequence number to 1 and the key type to 'Status key'. Create a child record in Integration Component Key Fields, provide a name and set the Field Name to 'SR Number'.

Finally, while not absolutely necessary, you should inactivate all fields you are not using for each Integration Component. For an inbound upsert to Siebel, the calling system does not need to provide all the fields that are active in the IO schema, but if the field is active in the IO, then the external system Could send that data element which may have undesired affects depending on the interface. Make sure all fields used in the key are activated as well as all fields being passed from the external system. Unlike BC field lengths, the length property of an Integration Component Field is more important as when an XSD is generated and provided to the external system, this property will frequently be used by the web development tool to validate the data entered into that field. You can also change the XML Tag attribute to a label recognized by the external system (so long as spaces are removed).

One thing to keep in mind is that if an insert is desired, then the calling system should just pass a constant to the user key field, 'Id' so that Siebel will not find a record and a new one will be created. A value like '_New_Record_' is a safe value because the '_' will never be part of a generated row id.