Thursday, October 22, 2015

Interesting Web Service approach

I was recently working on a client where all the integration used HTTP Web Services but were not implemented using what I think most Siebel Developers would think of as the "Best Practice".  Basically, the payloads were created using XSLT and the actual call to the Web Service was invoked using 'EAI HTTP Transport' rather than a custom WS Proxy BS created using the Tools wizard. 

The reasoning provided to me behind using XSLT to create the payload is that it was more flexible.  What do I mean by that?  Well assume an outbound interface is needed where the "Best Practice" alternative would be to use 'EAI Siebel Adapter' to query an Integration Objects , then to use 'EAI Data Transformation Engine' to transform the payload into an IO (that was initially created by consuming a WSDL) recognizable by the Web Service.  The limitation in this approach is around a couple pieces that Siebel Tools wizards have trouble with.  The first is that some modern standards compliant  WSDL definitions that use recursive data types cannot be imported at all.  The second is that the SOAP Header follows a standard that is somewhat outdated, is not configurable, and basically requires scripting to create a custom header anyway.  So the question is whether it is better to create the custom header using a scripted Filter Service, or to create the payload using XSLT.  Once you go down the path of using XSLT, you basically cant use a Proxy Service anymore (since the proxy would be adding the SOAP envelope) so 'EAI HTTP Transport' is used instead.

I can think of a number of downsides to this approach:
  • Deployment Complexity increases
    • XSLT files must be deployed to the File System and kept in sync across however many app servers (and failover servers) are used by EAI in the respective environments
    • No WSDL is actually consumed in this approach so web service end points must be stored somewhere which will likely be different in each environment
  • More Steps in the WF
    • 'EAI XSLT Service'  uses UTF-16 input so it is likely Encoding will need to occur both to and from using 'Transcode Service'
    • Reading the XSL File from the file system
  • Mainainability
    • Siebel resources that know XSLT are presumably more rare than Siebel resources familiar with more "Best Practice" approaches
  • Performance
    • Calls to the File System to get the XSLT file might add significant load to a high volume interface
  • Data Integrity
    • The integrity of the outbound message data structure is not really enforceable in Siebel. Using XSLT requires the developer to create a payload that is correct as only the external system would be able to validate it.  This is perhaps debateable because ultimately the developer will probably need to resolve this one way or the other during development.  While I personally believe it is easier to troubleshoot problems that are actually identified within Siebel due to the strict defintion of the messages maintained in Siebel, I will concede that might be personal preference.
I am curious what others think and whether developers that use this approach can defend it better than I can.  Ultimately, I think a scripted filter service is a better solution to the custom Soap Header issue, though I think this approach seems reasonable if the WSDL cannot be consumed, and modifying it is not possible.

Scriptless OK/Cancel popup

In the early days of configuring in Siebel, if a user wanted a confirmation or warning message before proceeding, it would require Browser Script to implement and most Siebel configurators would try to discourage the requirement on purely technical grounds.  And to be fair, an application littered with popup warnings may not be a great idea on functional grounds either, but there are probably good reasons to implement a warning message on occasion and it would be nice if it could be done in a way that does not have technical repercussions.  So here you go.

On a BC, configure a 'Named Method' user property with value:
"YourMethodName", "INVOKESVC", "FDNS IDENT Encounter", "LS Pharma Signature UI Service", "ShowConfirmDialog", "'Cancel Method Name'", "YourCancelMethodName", "'OK Method Name'", "YourOKMethodName", "'Confirm Text'", "'Are you sure you want to Proceed or some other message?'"

The method 'YourMethodName' would be invoked according to your requirements.  In a simple case, a custom action button on an applet could invoke this method but it could really be invoked anywhere.

The methods 'YourOKMethodName' and 'YourCancelMethodName' need to be callable methods, either that you also configured as additional Named Methods, or vanilla methods (or scripted ones defined in PreInvoke but that would sort of defeat the point). 

When 'YourMethodName' is invoked, a popup message containing the message parameter is shown with an Ok and Cancel button.  Clicking either button calls the methods defined.  Enjoy

Vanilla Merge Behavior

I recently encountered an issue when adding a DB View based EBC to a BO.  When I attempted to perform a MergeRecords operation on two records in the primary BC (Contact in this case), I got an error:

[1] An error has occurred writing to a record
Please continue or ask your system administrator to check your application configuration if the problem persists.(SBL-DBC-00111)
[2]ORA-06550: line 137, column 15:
PL/SQL: ORA-01031: insufficient privleges
ORA-06550: line 137, column 1:
PL/SQL: SQL Statement ignored

It turns out this error is caused because siebel is attempting to update a column in a DB View.  Why would it try to do that you might ask?

If we reverse engineer what is happening, we find that when performing a MergeRecords operation, Siebel determines the underlying table of the active business component and uses the SRF to find all links where the identified table is shared with the source business component of the Link and the source field is ‘Id’ (or null which is the same thing).  The merge algorithm then takes this list to write the SQL to update the appropriate destination field to the new value of the Id field on the Source BC.  Since merge is a data integrity operation, the use of Links using the ‘Id’ field is a proxy for those links configured to have a data integrity implication. 

Ideally, Siebel would provide a configurable mechanism to exclude a particular link from a Merge, or, at a minimum, to recognize that when a link points to a destination BC that is based on a table object whose type is ‘External View’, no update is possible and hence should not be attempted.  Alas that is not the case. 

Therefore a way to trick the algorithm into excluding this link is to define the link on one which is not based on data integrity, and instead make it just informational.  This can be done by making the Source field of the link something other than Id.  But since we do not want to actually change the definition of the view this link points to, a column whose value matches the ROW_ID column is desireable.  In the case of the Contact BC, there are a couple of potential options.  PERSON_UID defaults to the Id field but since this column might be populated by EIM to be a value other than it’s ultimate row id, the values may not match on that data set.  But since Contact is based on the Party model, the PAR_ROW_ID should always match since this points to the S_PARTY record and the same ROW_ID is always used. This column is not exposed on the Contact BC though so it needs to first be exposed and then the new BC field can be used in the links.