Sunday, February 28, 2010

Regenerating Web Service Proxy in Self-Service Model

Regenerating the web service proxy in Self-service is required after the web service has been modified, typically to retrieve more data from Siebel.

One set of instructions to follow would be from the Self-Service Developer’s Guide (Chapter 8 'Customizing the Model Layer…' > Recreating the new Web service client proxy)

Oracle recommends the following steps to replace the vanilla proxy classes with your new proxy classes
a.    Locate the vanilla Jar file into which the original proxy classes belong. E.g. the proxies for the Account web services are inside ‘SelfService_ROOT\Model\lib\commoncomp-ws-proxies.jar’
b.    Unjar this jar into a temporary directory
c.    Replace the vanilla proxy classes with the corresponding new ones
d.    Jar the classes in the temporary directory, use the vanilla Jar file name and use this instead of the vanilla jar.

This works, but there are a few issues. Step (a) above is tricky, since there are three vanilla Jar files in the horizontal application – possibly more in the vertical versions. Step (c) wants you to be extra careful and not to miss out any class. Step (d) is not upgrade friendly.

Another Suggestion
An alternate suggestion is to create a Jar file for all the customized proxy classes (or more Jars if you prefer a logical classification or if you hit a technical limit). I will list the steps below, but I have not tried this myself. I would be very happy to get your comments - if it worked or failed and why in the latter case.

a. The vanilla package for the proxy classes for Account web services is:
oracle.apps.ss.base.model.um.proxies.account.<…>.
This path must be used for creating the new proxy classes as well.
So while recreating the web service proxy (Chapter 8 of Dev Guide), at step 10 you would use paths similar to the vanilla package names. You would leave other options to default, ensuring ‘Reuse existing type classes’ is UNCHECKED.

For Account web services the package names are:
Package name: oracle.apps.ss.base.model.um.proxies.account
Root package for types: oracle.apps.ss.base.model.um.proxies.account.types

The paths to use for your specific web service can be identified from import statements in the ‘*UserData.java’ class for the VO. Check out steps 5 and 7 of the post ‘Identifying the Web Service and Java proxy classes behind a Self-Service ADF View Object’.

AccountUserData.java has the following imports
import oracle.apps.ss.base.model.um.proxies.account.types.com.siebel.selfservice.common.allaccountlist.data.ListOfSSAllAccountData;
import oracle.apps.ss.base.model.um.proxies.account.types.com.siebel.selfservice.common.allaccountlist.data.SSAllAccountListData;
import oracle.apps.ss.base.model.um.proxies.account.types.com.siebel.selfservice.common.allaccountlist.query.ListOfSSAllAccountQuery;
import oracle.apps.ss.base.model.um.proxies.account.types.com.siebel.selfservice.common.allaccountlist.query.SSAllAccountListQuery;
import oracle.apps.ss.base.model.um.proxies.contact.types.com.siebel.selfservice.common.contact.data.AccountData;
import oracle.apps.ss.base.model.um.proxies.contact.types.com.siebel.selfservice.common.contact.data.ListOfSSContactData;
import oracle.apps.ss.base.model.um.proxies.contact.types.com.siebel.selfservice.common.contact.query.AccountQuery;
import oracle.apps.ss.base.model.um.proxies.contact.types.com.siebel.selfservice.common.contact.query.ContactQuery;
import oracle.apps.ss.base.model.um.proxies.contact.types.com.siebel.selfservice.common.contact.query.ListOfAccountQuery;
import oracle.apps.ss.base.model.um.proxies.contact.types.com.siebel.selfservice.common.contact.query.ListOfSSContactQuery; 

b. One the classes are generated; you would then move these to a temp directory and jar them into ‘ABC_SS_WS_Proxies_1.jar’ or a name you think is more appropriate.

c. Add the new jar to the project libraries.
Right-click the ‘Model’ project and select ‘Properties’
Select ‘Libraries’ in the left tree and click ‘Add Jar/Directory’ to browse and add your new jar file, ABC_SS_WS_Proxies_1.jar, to the project

IMPORTANT:  Use the ‘Move Up/Down’ buttons to move the newly added jar to be placed above the vanilla jar files ‘commoncomp-ws-proxies.jar’, ‘eservice-ws-proxies.jar’ and ‘ecommerce-ws-proxies.jar


d. Compile the ‘Model’ project to ensure there are no errors.

As you can see,
  • This approach is cleaner and would require minimal ‘import’ corrections in the related VOImpl and UserData classes.
  • Since you are not touching the vanilla Jar files, your work is upgrade friendly

Identifying the Web Service and Java proxy classes behind a Self-Service ADF View Object

 If you are tasked to customize an VO used in Siebel Self-Service 8.1.1 application, you need to identify the Siebel web service and Java proxy classes that are used by your VO to fetch data from Siebel. This is a typical customization requirement one would encounter in SSA 8.1.1 and I don’t think there’s one set of steps that can listed here to get this done. The steps would depend on various factors which I would hint as I explain further. On the ADF side it has mostly to do with the design chosen by the original engineer and on the Siebel side this would depend on how the web service is implemented.

 My assumptions regarding posts on Siebel SSA customizations can be found at the end of this post.

I’ll use a hypothetical requirement to extend the ‘ContactInboxItemVO’. A row in this VO is an item in the inbox visible to an SSA delegated administrator, about a contact’s registration request that the former has to approve or reject. For example, the extension required is an ‘action by’ date to be displayed to the administrator beyond which the item will be automatically rejected by a Siebel batch job.

Let's Go: Inspecting the SSA Model project in JDeveloper I have the following information (see picture below)
1)    My VO is oracle.apps.ss.base.model.um.ContactInboxItemsVO

2)    From the structure window, I can see the custom implementation class   oracle.apps.ss.base.model.um.ContactInboxItemVOImpl.java.

3)    This class has an overridden method ‘executeQueryForCollection’ which gets executed every time the ‘executeQuery’ method of the VO is called (e.g. when the related ADF page loads).

4)    The method ‘executeQueryForCollection’ refers to the user data object used by this VO: oracle.apps.ss.base.model.um.ContactInboxItemsUserData


(To quickly load this class in editor, right-click the class name and select ‘Go to Declaration’ from the context menu)

Most VOs in SSA will use a user data object to cache the web service response and to support pagination of records (next set <–> previous set) on the UI. Comments in ‘ContactInboxItemsUserData.java’ may help understand its usage better. Note though, that not all classes may have enough comments and use of methods would vary slightly depending on the specific VO.

5)    The import statements in this class indicates the web service client proxy and type classes used by my VO.

import oracle.apps.ss.base.model.um.proxies.approval.types.com.siebel.xml.uinboxcontactitem.data.ListOfUinboxcontactitemData;
import oracle.apps.ss.base.model.um.proxies.approval.types.com.siebel.xml.uinboxcontactitem.data.UinboxItemTaskData;
import oracle.apps.ss.base.model.um.proxies.approval.types.com.siebel.xml.uinboxcontactitem.query.ContactQuery;
import oracle.apps.ss.base.model.um.proxies.approval.types.com.siebel.xml.uinboxcontactitem.query.ListOfContactQuery;
import oracle.apps.ss.base.model.um.proxies.approval.types.com.siebel.xml.uinboxcontactitem.query.ListOfUinboxcontactitemQuery;
import oracle.apps.ss.base.model.um.proxies.approval.types.com.siebel.xml.uinboxcontactitem.query.QueryType;
import oracle.apps.ss.base.model.um.proxies.approval.types.com.siebel.xml.uinboxcontactitem.query.UinboxItemTaskQuery; 


Generated Types package: oracle.apps.ss.base.model.um.proxies.approval.types.<..> - The type objects used in the WS request response messages reside here.

We need to further locate the proxy client class (use to invoke the web service) and the Siebel web service itself.

6)    The method ‘getNextResultSet’ of the user data class in step (d) further uses the ‘SiebelInboxManager’ class to call the web service and retrieve the response.
         //invoke the web-service
        //ListOfUinboxitemcontactData  inboxItemsDataList;
        ListOfUinboxcontactitemData  inboxItemsDataList;
        logger.info("Calling SiebelInboxManager.queryContactApprovalItems");
        try {
            inboxItemsDataList = SiebelInboxManager.queryContactApprovalItems(inboxItemsQueryList);
        } catch (ValidationException ve) {
            //setInboxItems(null);    //No items were retrieved
            logger.severe("ERROR: Error in calling web-service. Exception:" + ve.toString()); 
            throw ve;                 //The exception is already wrapped.
        }
        logger.info("Web service call completed");
This class hides the actual client proxy class behind its method ‘queryContactApprovalItems’ (To see the code in this method, right-click the method name and select ‘Go to Declaration’ from the context menu). You’ll see that most other user data classes choose to call the client directly.

7)    A look at the method ‘SiebelInboxManager.queryContactApprovalItems’ below shows the web service being invoked using the client proxy class: oracle.apps.ss.base.model.um.proxies.approval.UInbox_spcContact_spcItemClient.

             logger.info("Invoking web-service.  Port:'Uinbox Contact Inbox Items' Operation: UInboxContactItemQueryPage");
            
            UInbox_spcContact_spcItemClient myPort = new UInbox_spcContact_spcItemClient();
            logger.info("  Created proxy client");
            
            //Reset end-point
            myPort.setEndpoint(ServerUtil.getEndPointURL());

The package of proxy client classes is: oracle.apps.ss.base.mode.um.proxies.approval

While regenerating the web service proxies (required after a change to the web service), you will be asked to provide the Proxy Client package name and the Generated Types package name (step 5 above). Although by convention, the types path would be Proxy Client path + ".types", I would suggest this is verified before regenerating the proxy.

Name of the Siebel web service
In almost all cases, the name of the client gives away the name of the Siebel web service being used. Here it’s ‘UInbox Contact Item’. To get this name, ignore the suffix ‘Client’ and translate each ‘_spc’ into a space.

Almost all VOs invoke a Siebel web service in this fashion and ultimately results in a call to the ‘QueryPage’ method of the base class of the BS ‘EAI UI Data Service’.

NIK: Siebel Self-Service 8.1.1 Applications

The 8.1.1 version of Siebel Self-Service applications (ECommerce and ESupport) are rebuilt using the newer Application Development Framework (ADF) on top of a Siebel 8.1 business layer. These applications have very few things in common with their counter parts in the previous versions of Siebel (e.g. ECommerce replaces eSales), functionally and technically.

The ADF front-end is a native J2EE/JSF application that interfaces with the Siebel business layer exclusively using web-services. This combination has a lot of advantages including
  • The rich interaction capabilities of ADF, the framework behind the future of Oracle’s applications.
  • The loose coupling with the business layer, enabling a switch to Fusion CRM later
Since Self-Service 8.1 was developed at a time when ADF was maturing as a framework even within Oracle, the customization of these applications present unique challenges. Often an expert Siebel consultant is thrown off guard, now that a new technology stack (Oracle AS + ADF and JDeveloper in place of dear old Tools) has to be tackled – the closest you get to Java in the Siebel world is when you use browser scripts :-)

For an honest confession, the best customization options you can provide as a product engineer often fall short of a consultant’s requirements. I moved to Siebel consulting after being a product engineer at Oracle. Of late I am seeing my colleagues trying to figure out Self-Service applications and when I am involved I feel the need to have done consulting before I did product development. Some of you may call this a variant of the chicken-and-egg question.

I’ve thought of a few posts that would make a ADF-aware Siebel EAI Consultant’s life easier. I’ll try my best not to repeat things provided in the Oracle documentation, especially the Self-Service Developer’s Guide – unless I have an alternative to suggest. The official Oracle documentation on SelfService 8.1.1 is

Siebel E-Commerce Administration Guide
Siebel E-Support Administration Guide
Siebel SelfService 8.1.1 Deployment Guide
Siebel SelfService 8.1.1 Developer's Guide
Oracle SelfService 8.1 Forum

The rules of Fight Club are:
  • You do not talk about Fight Club. :-)
  • You have a good-enough hands-on knowledge of J2EE, ADF, JDeveloper 10g, and Siebel 8.0 EAI. I would type less then.
  • I will desist from explaining the details of ‘how do I do it in Siebel’ since the focus is on the ADF customization, but if you know basics of Siebel EAI this is not hard to figure out
  • I will make assumptions that I don’t know I’m making, so please feel free to point these out. I would be glad to clarify them.

Blog renamed (What on earth for!)

I just renamed this blog. Why on earth?

I found that the old name 'tech-nickels' was very close to 'tech-nickel' which is another blogspot blog! I respect the originality of that blog.

Now I thought of 'technique-alley' and 'technic-alley'! The latter is a web site and is quite a common usage!

Then I cooked up this name 'tech-nik-alley' and here are my lame reasons to go with it..
  • Google did not give me any close matches.
  • 'NIK' is a way of saying "Now I Know" - something I often tell myself.
  • That's original enough - my patience has run out!
So here we go! Welcome to a re-branded world.

Friday, February 5, 2010

A LinkedIn feature that doesn't work!

Linked in seems to have a feature that does not work.

 

It gave me an option to begin with!