Friday, December 31, 2010

Create a node in Oracle Hyperion Data Relation Ship Management (DRM)

LiveJournal Tags:
In this post I am trying to show how we can create a node in Oracle Data Relation Ship Management using in build API’s for DRM . Before proceeding for actual development we need to make our project ready so that it will able to get all In build API’s. First of all we need to download Oracle DRM SDK using below link http://www.oracle.com/technetwork/middleware/bi-foundation/downloads/hyperion-data-relationship-111120-089726.html.
DRM sdk provides below artifacts
image Figure 1
but we need only jar files belongs to dist/lib and thirdparty to create below libraries for our Jdeveloper Project. Jdeveloper 11.1.1.3 is the IDE I am using for developing the project.
image Figure 2 
where library “Thirdparty” contains below jar files.I prefer those jar files needs to be copied to project folder, I mean from DRM SDK zip file (from figure 1) to project folder.
image
DRMAPI library contains dist/lib/hdrm-proxy-api.jar and xerces library contains thirdparty/xerces/xerces.jar. After doing all setups we can move for development.
please follow below code block for adding a node in DRM.


public class AddDRMNode { //declare variables that needs to be initialized and //used through out the class Identify the DRM server //to which we are trying to make request String aUrl = "<Url of DRM server>"; //Initialize master data management IMasterDataManagement masterDataManagement = null ; //Initialize TRemSessionInfo TRemSessionInfo sessionInfo = null ; //Initialize Current Version String CurrentVersion = null ; //Initialize list of hierarchy Objects ArrayOfStringHolder hierobjects= null ; public AddDRMNode(){} public void addNode( String <DRM UserId>, String <DRM Password>, Sring node) { //get instance of mdm masterDataManagement = MasterDataManagementUtils . getMasterDataManagementFacade ( new URL (aUrl)); //get session try{ sessionInfo = masterDataManagement. getSessionMgr (). createSession (<DRM Server User ID>, <DRM Server Password>, "ProductVersion=11.1.1,CleartextPassword=True"); } catch ( Exception e) { logger. info ("unable to get session");} //get hold of current version currentversion = "Current"; //get list of all hierarchies under Current version. here listHierObjects //is a method which returns list of hierarchies.Defined later in my post try { hierobjects = listHierObjects(this.sessionInfo, currentversion); logger. info ("there are [" + hierobjects.value.length + "] hierarchy objects for version [" + currentversion + "]"); } catch ( Exception e) { logger. info ("Hierarchies are not found"); } //looping through the Current Hierarchy for ( int i = 0; i < hierobjects. value . length ; i++) { logger. info ("[" + i + "] hierarchy value is [" + hierobjects. value [i] + "]"); //Obtain a hierarchy locator using version and current hierarchy value hierlocator = getHierLocator(currentversion, hierobjects. value [i]); //get hold of hierarchy prefix using the hierarchy locator try { prefix = getHierarchyPrefix(hierlocator); //update passed argument node as a concat with prefix node = prefix+ node; logger. info ("Customer to be added :[" + node + "]"); } catch ( Exception e) { logger. info ("Problem retrieving Hierarchy Prefix"); e. printStackTrace (); } //get IHier_PortyType for node addition ihierpt = this .masterDataManagement. getHier (); //get hold of parent node try { parentnode = ihierpt. nodeByAbbrev (hierlocator, <Parrent node name>); logger. info ("ID of Unmapped node is" + parentnode. getID() ); } catch ( Exception e) { logger. info ("parent node does not exist"); e. printStackTrace() ; break ; } //get hold of nodelocator object for parent node TRemLocalNodeLocator nodelocator = getTremLocalNodeLocator(currentversion, hierobjects.value[i], localnode. getDisplayByString ()); try { //check whether passed node is existed, isnodeExist is //defined later. passed argument is //locator of parent node,Local node object,node to be added if (isnodeExist(nodelocator, this.masterDataManagement. getLocalNode (), node)) { logger. info ("Node Exists in UNMAPPED"); } else { logger. info ("Node does not exist, going to add"); //addNode passed arguments are hierarchy locator //node to be added,parent node ID,boolean value to decide //whether added node is leaf or limb ihierpt. addNode (hierlocator, node, parentnode.getID(), true); } } catch ( Exception e) { logger. info ("Exception odue to node handling, It may be mapped earlier in parent Node"); } } } private boolean isNodeExist( TRemLocalNodeLocator nodelocator, ILocalNode localnode, String node ) { //obtain list of descendent nodes for parent node TRemLocalNode [] descendentArray = localnode. fillChildrenSorted (nodelocator); boolean flagExist = false ; for ( int i=0;i<=descendentArray. length ;i++) { //if parent nodes display equals to passed node //then set flag equals to true if (descendentArray[i]. equals (). getDisplayByString (). equals (node)) { flagExist = true ; } } //return flag return flagExist; } //This method take session and version as input and returns list of hierarchies as output //private ArrayOfStringHolder listHierObjects(TRemSessionInfo sessionInfo, String versionId) throws Exception { //Get IVersion object to invoke methods for retriving list of hierarchies IVersion versionOfInterest = this.masterDataManagement. getVersion (); ArrayOfStringHolder hierarchies = new ArrayOfStringHolder() ; //obtain list of hierarchies versionOfInterest.listHiers(sessionInfo. getSession (), versionId, hierarchies); return hierarchies; } //This method takes version and hierarchy name as input and returns //TRemHierarchy locator as output public TRemHierLocator getHierLocator( String versionID, String hierarchyname) { TRemHierLocator tremhierlocator = new TRemHierLocator (); tremhierlocator. setSession ( this .sessionInfo. getSession ()); tremhierlocator. setVersion (versionID); tremhierlocator. setHier (hierarchyname); return tremhierlocator; } //This procedure takes hierarchy locator object as input and //returns valid prefix stringfor that hierarchy as output private String getHierarchyPrefix( TRemHierLocator hierLocator) throws Exception { logger . info ("Hierarchy prefix for " + hierLocator. getHier ()); String prefix = this .masterDataManagement. getHier (). fillStrPropValue (hierLocator, DRM_HIERARCHY_PREFIX_FINDER); return prefix; } }

Monday, November 1, 2010

Customizing standard Input output of BPEL Process

Modifying Input XSD:
BPEL designer by default uses string for input as well as output. while dealing with complex interfaces we need to update input and output structure in such a way that it will meet all requirements. By default the schema looks like below. 
<schema attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://xmlns.oracle.com/DatabaseToFileAdapter" xmlns="http://www.w3.org/2001/XMLSchema"> <element name="DatabaseToFileAdapterProcessRequest"> <complexType> <sequence> //Input Element <element name="input" type="string"/> </sequence> </complexType> </element> //Output Element <element name="DatabaseToFileAdapterProcessResponse"> <complexType> <sequence> <element name="result" type="string"/> </sequence></complexType> </element> </schema>
The example I have shown here is to take ProjectName, Status and Role as input and after querying database it will show other project details like hostname,port, location,domain etc. Please refer below Figure 1 and Figure 2 for input and Output.
image  Figure 1
image
Figure 2
Figure 1 is used to describe input and Figure 2 is used to describe Output format.
we can edit “DatabaseToFileAdapterProcessRequest” element like below instead of a simple string.
image
After querying database fetched data structure looks like below.
image
Figure 2
Our next step will be incorporating those structures in BPEL file by Creating variables and using those variables in rest of the files. Please note down below things
  • Make sure that used targetnamespace for xsd also present in BPEL process. Check Process section of the BPEL process for below entry
    <process name="DatabaseToFileAdapter" targetNamespace="http://xmlns.oracle.com/DatabaseToFileAdapter" xmlns:client="http://xmlns.oracle.com/DatabaseToFileAdapter"
  • Make sure Input and Output variable is referring modified input and output element of xsd via default message types of wsdl.
    <variables> <!-- Reference to the message passed as input during initiation --> <!-- Reference to the message that will be returned to the requester--> <variable name="inputVariable" messageType="client:DatabaseToFileAdapterRequestMessage"/> <variablename="outputVariable" messageType="client:DatabaseToFileAdapterResponseMessage"/> </variables>
  • messageType specified above refers message from WSDL file.Please see belowimage
  • Similarly the response message is using “DatabaseToFileAdapterResponse” element of the xsd.

Modifying BPEL standard WSDL:
  • Another way of achieving above objective is to import another xsd in wsdl file.
image
  • Make sure that the targetnamespace for imported xsd is used in WSDL definition as xml namespace prefix.
  • <definitions name="DatabaseToFileAdapter" targetNamespace="http://xmlns.oracle.com/DatabaseToFileAdapter" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:client="http://xmlns.oracle.com/DatabaseToFileAdapter" //below name space prefix needs to be added in order to utilize defined elements in that schema xmlns:db="http://xmlns.oracle.com/pcbpel/adapter/db/SlectProjDetailsByProjName" xmlns:plnk="http://schemas.xmlsoap.org/ws/2003/05/partner-link/">
  • We need to modify the Message element for “DatabaseToFileAdapterResponseMessage” in such a way that it will refer element belongs to imported xsd.
image
  • Make sure that InputVariable and OutputVariable referring to newly modified xsd rather than old default xsd.
image   expand the outputVariable node and make sure that you will get modified structure instead of the old structure.
image

Saturday, October 23, 2010

ServletException in BPELProcessManagerBean class for getDefaultRevision method and Work Around

I met below error

  1. javax.servlet.ServletException -
  2. com.collaxa.cube.ejb.impl.BPELProcessManagerBean.
  3. getDefaultRevision
while upgrading my SOA server 10.1.3.4 to 10.1.3.4MLR by applying the patch 7586063.While log in to my BPEL console I got below error screen

image

while looking to the log file(%ORACLE_HOME%/opmn/logs/default_group~oc4j_soa~default_group~1.log) I figured out the method named getDefaultRevision() is missed or some problem occurs in that.

  1. <2010-10-23 11:12:25,781> <FATAL> <default.collaxa.cube.activation> <AdapterFramework::Inbound>
  2. java.lang.NoSuchMethodException:
  3. com.collaxa.cube.ejb.impl.BPELProcessManagerBean.getDefaultRevision(com.oracle.bpel.client.BPELProcessId,
  4. com.oracle.bpel.client.auth.DomainAuth)
        at
  5. com.oracle.bpel.client.util.ExceptionUtils.handleServerException(ExceptionUtils.java:91)
        at
  6. com.oracle.bpel.client.BPELProcessHandle.getDescriptor(BPELProcessHandle.java:208)
        at
  7. oracle.tip.adapter.fw.jca.AdapterFrameworkListenerImpl.onInit(AdapterFrameworkListenerImpl.java:160)
       
  8. at oracle.tip.adapter.fw.agent.jca.JCAActivationAgent.setupEndpoint(JCAActivationAgent.java:1041)
        at
  9. oracle.tip.adapter.fw.agent.jca.JCAActivationAgent.initiateInboundJcaEndpoint(JCAActivationAgent.java:941)

While investigating I came across few brainstorming facts.

  1. This error comes while loading all domains,more preciously after loading all Processes.
  2. Activation Agent is throwing error and the dependent classes too.

As BPEL Console shows error in com.collaxa.cube.ejb.impl.BpelProcessManagerBean it comes to my mind about ejb-ob-engine.jar and we can find the jar file in %SOA_HOME%\j2ee\<AS_Instance>\applications\orabpel but after applying the patch upgraded jar file got created in %SOA_HOME%\bpel\system\j2ee\ejb directory with oc4j as suffix in file name and old ejb-ob-engine.jar should be replaced by the new jar file. But it may not happen while applying the patch.

As a workaround

I have stopped Oracle SOA server first using opmnctl stopall and then I have copied  'ejb_ob_engine_oc4j.jar' file from
%SOA_HOME%\bpel\system\j2ee\ejb\ejb_ob_engine_oc4j.jar to %SOA_HOME%\j2ee\<AS_Instance>\applications\orabpel and renamed it to ‘ejb_ob_engine.jar’.

image

I have restarted the server using opmnctl startall and BPEL Console works like a charm.

image

Monday, October 18, 2010

Working with ADF Choice Elements

Asking user to enter data based on ADF choice element is not a tricky one

where as capturing the data selected by user and use it to fulfill other purpose is really a tricky task. We can drag an exposed view object from Data control and drop it in our webpage then automatically we will be asked for the “Selection Type”. After Selecting a type it will create underlying iterator and Bindings and the page got displayed with proper selection types.But if user wants to display some other details based upon selected data then how we can use this selected data.

In this post I am trying to implement how entered data using choice element
got captured in backing bean.

Single Selection Choice Elements:

image

Figure 1

As above figure shows three types of single choice element is available in ADF and they are “select one list box”(refer figure 2),“select one choice” (refer figure 3) and “select one radio”(refer figure 4)

image  Figure 2

imageFigure 3 image Figure 4

I have used command link and as user clicks on it, backing bean method get invoked and selected data is shown as output. To achieve that we need to follow below steps.

  1. Define the action listener for command link where user needs to click to
    view the output

    <af:commandLink text="view Output"id="cmdlnk2" actionListener="#{viewScope.TestADFBean.viewOPSelOneLB}"/>

    Bind the element for showing output as a backing bean property using binding
    attribute

    <af:inputText value="" binding="#{viewScope.TestADFBean.outputBinding1}"label="Select Country"id="it1"></af:inputText>


  2. Backing bean procedure is as follows

    1. public void viewOPSelOneLB( ActionEvent actionEvent) { //Get the specific binding Container
    2. BindingContainer bindings = BindingContext . getCurrent (). getCurrentBindingsEntry (); //Get the sepecific list binding using the binding name passed as argument to the get method of binding container
    3. JUCtrlListBinding listBinding = ( JUCtrlListBinding )bindings. get ("CountryEntityObjectView11"); //Get selected value
    4. Object sel = listBinding. getSelectedValue ();
    5. System.out. println (sel);
    6. outputBinding1. setVisible (true); //Set selected value to already binded property
    7. outputBinding1. setValue ("Output From SelectOneListBox [" + sel + "]");
    8. }

Multiple Selection Choice Elements:

image

Figure 5

As above picture depicts ADF Multiple selection consists of “Select Many Choice” (refer to Figure 7), “Select Many Shuttle”(refer to Figure 6),”Select Many List Box”(refer to Figure2),Select Many Check Box is same as “Select One Radio” as shown in Figure 4 but the difference is Check Box(please refer the drop down element of Figure 7) occurs instead of Radio button and user can select more
than one value which is not possible in Radio button.
image image
Figure6 Select Many Shuttle                                        Figure 7 ADF select Many Choice

For displaying data selected by user using multiple choice selection is exactly same except the backing bean method(Step 1 and Step 2 is same as above).

Backing bean method is as follows.

  1. public void SelectInputLsnrForShuttle( ActionEvent actionEvent) { //Get Binding Conatiner
  2. BindingContainer bindings = BindingContext . getCurrent (). getCurrentBindingsEntry (); //Get the sepecific list binding
  3. JUCtrlListBinding listBinding = ( JUCtrlListBinding )bindings. get ("CountryEntityObjView_LOV1"); //Get all Selected Values
  4. Object[] str = ( Object[] )listBinding. getSelectedValues ();
  5. StringBuffer buf = new StringBuffer (); //Append all Selected objects to a buffer
  6. for ( int i =0;i<str. length ();i++){
  7. buf. append (" ");
  8. buf. append (str[i]);
  9. buf. append (" ");
  10. System.out. println (buf. toString() );
  11. }
  12. opBindingForShuttle. setVisible (true); //Set selected value
  13. opBindingForShuttle. setValue (buf. toString() );
  14. }

Wednesday, October 13, 2010

Customizing ExecuteWithParams : Executing a view Runtime Based on User Input

Step1: Create a view with input parameter based on which the query needs to be fired



Step2: Implement the view implementation class and wrap it with an application module





Step3:
Crate a custom method in Application Module Implementation class for executing the view object.




Step 4: Create a client interface for that Implementation class and make sure that the newly created custom method is included.

Step 5: Make sure that the custom method is exposed in Data Control.


Step 6: Create a method binding in Page definition xml file.


Step 7: Create an Input box in your webpage and bind that one with Managed Bean.

Step 8: Create a button and set Action listener on that to execute the custom method.


Action Listener is defined as

Step 9: Create a dynamic table which used as a container for output

Step 10: view Output

Thursday, October 7, 2010

autoSuggestBehavior using Database Query

autoSuggestBehavior is new addition in oracle ADF 11g used to display suggestedItems in a drop down box for an editable component in webpage based on user input on that. In this post what I am trying to show is an implementation of autoSuggestBehavior. Weblog for the AMIS Technology corner has a very good post for that. I am trying to leverage database persistence with autoSuggestBehavior. Data which is displayed as suggestedItems can be taken from backing bean (we can refer (http://technology.amis.nl/blog/6581/adf-11g-the-native-autosuggest-behavior for that methodology) or we can use data from database tables. In this post I have implemented that.

Below is the output of that implementation.


I have created a SQL script for creating country table and inserting values to that table. Please refer http://www.box.net/shared/g6hm06lbvd for downloading that script.

To achieve this only unlike other ADF projects we need not to create any Entity object, view object, Application Module. We can directly start working on webpage. As discussed earlier autosuggestBehavior shows suggestedItems for editable component in webpage. So we have used an inputText and attach viewscope managed bean procedure to the suggestedItems.



The Procedure is as follows


Used getCountries () procedure is as follows


I have used JDBC connection from managed bean to retrieve all country details. Below procedure is used for that.


Above method shows the Implementation without using any ADF Components like Entity, View, and ApplicationModule. But we can achieve same using a view object named "CountryEntityObjectView" and expose that view in Application Module. So that It will reflect in data control.


After that we need to create an Iterator in Page Definition file like below


Make sure that Its Range Size is Sufficient enough to capture all country names. We need to use this Iterator in our Managed Bean Procedure for suggestedItems (showed in 3rd Screen Shot here) as below


download link for Managed Bean java code is http://www.box.net/shared/or2olv7ftz , for webpage is http://www.box.net/shared/g71rrk6lc2and for page definition file is http://www.box.net/shared/zmpt2fh0ms/

Thursday, September 23, 2010

ADF Coding Standard Document Template

I have created an ADF coding standard document template,please refer below URL for that. Hope it will help and please give your feedback about that.

http://www.box.net/shared/na4o2rvtdm

Friday, August 27, 2010

Bounded Task Flow In Popup and Resetting Field data in Popup using popupFetchListener

In my older post (Insert Into Multiple Tables using Bounded TaskFlow in ADF ) the use case I had shown is having a drawback like data from table got automatically populated (as Shown Below) as user navigates to the bounded taskflow region from main page for creating a new Employee. In this blog I am trying to make some modification in my ViewController project so that the issue got resolved.



Step1: Create a Bounded task flow and make sure that 'Create Train' is selected.


Step 2: Drag View from Component palate and rename it likes below. Please follow my previous post (Insert Into Multiple Tables using Bounded TaskFlow in ADF and refer Figure 2 to Figure 6 ) to create those pages. Make sure those page extension should be *.jsff instead of *.jspx.

Add train Button and Train Button Bar for all pages in Task Flow like below


After completing all jsff pages bounded task flow will look like below.



Add valid name for all View id in Task Flow document source (task-flow-definition.xml)



Step 3: Modify Employee.jspx page

In my previous post (Insert Into Multiple Tables using Bounded TaskFlow in ADF) we have used Command Links for creating Employees Please refer to Figure 1 for this post. Now we can make it more fancy by using images and user can click on it to navigate to taskflows.

I have used images like for (AddProfile.PNG) Adding Employee, for searching Employee, for editing Employee


We can use popupFetchListener and attach it to our managed Bean using a method so that the method will execute at the time the popup rendered


  1. public void fetchPopupListener( PopupFetchEvent popupFetchEvent) {
  2. System.out. println ("In Fetch PopUP Listener"); //Create Insert For Baisc Info
  3. BindingContainer bindingsbasic = BindingContext . getCurrent() . getCurrentBindingsEntry() ;
  4. OperationBinding operationBindingbasic = bindingsbasic. getOperationBinding ("CreateInsertBasic");
  5. Object resultbasic = operationBindingbasic. execute() ; //Create Insert For Contact Info
  6. BindingContainer bindingscontact = BindingContext . getCurrent() . getCurrentBindingsEntry() ;
  7. OperationBinding operationBindingcontact = bindingscontact. getOperationBinding ("CreateInsertContact");
  8. Object resultcontact = operationBindingcontact. execute() ; //Create Insert For Master Info
  9. BindingContainer bindingsmaster = BindingContext . getCurrent() . getCurrentBindingsEntry() ;
  10. OperationBinding operationBindingmaster = bindingsmaster. getOperationBinding ("CreateInsertMaster");
  11. Object resultmaster = operationBindingmaster. execute() ; //Create Insert For Baisc Info
  12. BindingContainer bindingsedu = BindingContext . getCurrent() . getCurrentBindingsEntry() ;
  13. OperationBinding operationBindingedu = bindingsedu. getOperationBinding ("CreateInsertEducation");
  14. Object resultedu = operationBindingedu. execute() ; //Create Insert For Job Info
  15. BindingContainer bindingsjob = BindingContext . getCurrent() . getCurrentBindingsEntry() ;
  16. OperationBinding operationBindingjob = bindingsjob. getOperationBinding ("CreateInsertJob");
  17. Object resultjob = operationBindingjob. execute() ;
  18. }

But Make sure that you are having below bindings created in


Drag newly created task-flow-definition to the dialog and it will display the dialog below


We can test the page and it comes like this