X

Recent Posts

Integration

Repository Creation Utility, MDS and Schema Versions

Introduction I recently went through the installation of WebLogic 10.3.6 using the Package Installer "Oracle WebLogic Server 11gR1 (10.3.6) + Coherence + OEPE - Package Installer" (oepe-wls-indigo-installer-11.1.1.8.0.201110211138-10.3.6-win32.exe) from Oracle Technology Network. I was doing a full installation of everything in that package and in the process of creating my domain. During the domain creation one of the dialog boxes was Configure JDBC Component Schema. The installation failed with error message CFGFWK-60853:  A connection was established to the database but no rows were returned from the test SQL statement. Test JDBC Component Schema The configuration process is to supply the necessary parameters in the Configure JDBC Component Schema (seen below) and click next. The next dialog box allows you to test your configuration before moving on to the next step. This is when I had received an error. I was using some schemas that I had created in a previous installation. The connection was valid but the test SQL still failed. Below is what the message was in the log file. Component Schema=OWSM MDS SchemaDriver=oracle.jdbc.OracleDriverURL=jdbc:oracle:thin:@localhost:1521/XEUser=XE_MDSPassword=********SQL Test=select 1 from schema_version_registry whereowner=(select user fromdual) and mr_type='MDS' andversion='11.1.1.6.0'CFGFWK-60850: Test Failed!CFGFWK-60853: A connection was established to the database but no rows were returned from the test SQL statement. Error Resolution The clue in determining the error was in the select statement (seen above) that is targeting version 11.1.1.6.0. In my prior installation of WebCenter I installed BPM 11.1.1.7.0 and that had installed several schemas that had a version number 11.1.1.7.0. I was able to discover this matter using SQL against the schemas. The SQL is: select * from schema_version_registry My findings from the query were: Since the versions were incompatible I decided to drop the existing repository schemas and then recreate them in the Repository Creation Utility. That solved my problem. Downloading the Repository Creation Utility (RCU) I ran into one more difficulty. My RCU was for 11.1.1.7.0 but I needed an RCU for 11.1.1.6.0. If found that the 11.1.1.6.0 version is more difficult to find these days. It was not available in the WebLogic or Fusion Middleware downloads and I did not find it in eDelivery. I was finally able to find it in Oracle Business Intelligence (11.1.1.x) Downloads page in OTN. So, if you are still working in 11.1.1.6.0 you need to use the correct RCU.

Introduction I recently went through the installation of WebLogic 10.3.6 using the Package Installer "Oracle WebLogic Server 11gR1 (10.3.6) + Coherence + OEPE - Package Installer" (oepe-wls-indigo-insta...

Integration

WLST Scripting to Get WebLogic Libraries and Deployed Applications

Abstract Often times you may need to be able to identify the libraries installed on a given WebLogic server. Perhaps you need to compare different installations in different environments. Maybe you want to know if you need to update the libraries such as the ADF Runtime libraries. This article will walk through writing a Python script to run in the WebLogic Scripting Tool (WLST) command line. The script will create 2 files: Listing of Libraries installed on the server Listing of deployed applications on the server Introduction Two technologies that will be used in this effort are: WLST and Python. WLST The WebLogic Scripting Tool (WLST) is a powerful way to work within a WebLogic environment. This is available to you when you do a full installation of WebLogic. WLST is a command line environment that allows you to create, manage, and monitor WebLogic domains. You can do this from your own desktop with the proper credentials.  The WebLogic 12c documentation for WLST is Fusion Middleware Oracle WebLogic Scripting Tool. The command reference is located at Fusion Middleware WebLogic Scripting Tool Command Reference. Python Python is a scripting language and any file written in Python will end in the suffix "py". The python.org website is a great place to turn to for documentation and tutorials. MBeans The navigation that you will perform with this exercise is to navigate the System MBeans tree. A MBean is a managed bean (Java bean) that provides a Java Management Extensions (JMX) interface. WebLogic Server provides a set of MBeans that you can use to configure, monitor, and manage WebLogic Server resources through JMX. For more information please see The WebLogic Server® MBean Reference. Construction WLST Commands The WLST commands used in this script are: Command Description cd Navigate the hierarchy of configuration or runtime beans. ls List all child beans and/or attributes for the current configuration or runtime bean. connect Connect WLST to a WebLogic Server instance. disconnect Disconnect WLST from a WebLogic Server instance. serverConfig Navigate to the last MBean to which you navigated in the configuration MBean hierarchy or to the root of the hierarchy, DomainBean. domainName Name of the WebLogic domain to which WLST is connected. serverName Name of the server for which Node Manager property files are generated. pwd Display the current location in the configuration or runtime bean hierarchy. execfile After invoking WLST, use the execfile() command to run a script. Details The main function of WLST for this script is to sign into a targeted WebLogic domain and navigate the configuration MBean hierarchy. This navigation will target the Libraries and Applications installed on the domain.You can get a visual reference to this navigation by logging into Enterprise Manager Fusion Middleware Control (EM) and navigating the System MBean Browser in EM. Both Libraries and Applications are attributes in the Configuration MBean. Incidentally, when you navigate using EM you are using an application built on the Oracle Application Development Framework (ADF) that heavily uses MBeans to give you a visual reference to everything installed on WebLogic server. EM System MBean Browser The following instructions will walk you through the visual display found in the EM System MBean Browser. Login to EM Expand the WebLogic Domain node in the Navigation Tree Pane on the left Click on the targeted domain node Click on the WebLogic Domain drop down menu and select System MBean Browser By default you are visiting the Configuration MBeans Node in the tree Click on the Binoculars Find icon Choose Attributes in the select one choice drop down Enter "Libraries" and click on the Find icon Slide the MBean Attributes view until you see the Libraries attribute. Then click on Libraries. You should now be viewing the libraries installed on this domain. These will be what should be returned when completing the Python script. Click on one of the libraries. The library you have selected will display a new set of attributes. One of those is the Targets attribute and this will report which of the servers in this domain have the selected library.  Click on the Targets attribute. The elements and values within this display will define which servers have this specific library. Click on the Return button until you return to the Domain view of the configuration MBeans (click on Return 3 times in this example). Slide the Attributes window to view the attributes toward the top of the window (they are alphabetical in order). Do this until you see the AppDeployments attribute. This is our other target value in the Python script. Click on AppDeployments and review what you have on your server domain. You can also determine which servers the applications have been deployed to by clicking on each deployed application and examine the Targets attribute like you did for the libraries. WLST Command Line Before embarking on creating our Python script let's work out the WLST commands that need to be executed to accomplish our goal of identifying the installed libraries and deployed applications. According to the WLST Scripting documentation there are 4 ways to use WLST interactively or as a script: Execute the appropriate shell script for your environment. Execute the java weblogic.WLST command. Run a WLST script. Execute the WebLogic Scripting Tool command from the Start menu (Windows only). I am going to walk through the process of the 4th step above. The prerequisite is that you have WebLogic 10.3.6 or better installed on your Windows computer. Perform the following steps: Open a Windows command window Navigate to your WebLogic WL_HOME/oracle_common/common/bin directory Run the setWlstEnv.cmd script Run the wlst.cmd script. You will see a wls:/offline> prompt. Login to your target server using the connect command. Note: I do not have the SSL port enabled on my WebLogic server therefore I am using port 7001. Navigate the MBean tree using the cd command to the Libraries attribute by entering cd('/Libraries'). The command line prompt conveniently changes as you navigate the MBean tree - letting you know where you are in the navigation. According to the Oracle documentation this is the configuration MBean hierarchy (serverConfig for the DomainBean) and for our example the Libraries attribute in that hierarchy. Now execute the list command ls to view all the values (libraries) in the Libraries attribute Now use the pwd command to confirm where you are in the MBean tree. This will match your current WLST prompt. However, you will not have a prompt when using a script therefore the pwd command adds value to your script if you need to confirm where you are in the navigation. Also test the WLST variables that identify the domain and server you are connected to and navigating. Do this with a print command:  print domainName and print serverName. Finally, let's test the ls command with parameters. According to the documentation you can create a map of the values returned by the ls command. The syntax we will use for this command example is: libraryListing = ls(returnMap='true', returnType='a'). Note that you need to save the returned value to a variable which in this case we will call libraryListing. When you do this on the command line you will still see the list of libraries displayed in the window. What is different now is that you have a map object of those values and can easily access these in a Python script.  Review the size of the map return value with print libraryListing.size(). View a single returned value with a command like print libraryListing[0]. The next step is to navigate the MBean tree to determine which servers were targeted with a specific library. We will use the first library in the listing array we just created. Enter the change director command: cd(libraryListing[0]). The next MBean attribute we want to find is Targets. We will do this with another list command but change the returnType to c which by definition only return child management objects of the specified management object (suppresses the display of other items). Enter the following command at the WLST prompt: childNodeListing = ls(returnMap='true',returnType='c'). Explore the array listing created by this command. You should find that the second position in the array is Targets (print childNodeListing[1]). Now navigate to the Targets node using the cd command: cd('Targets'). Get another array list of the children of the Targets attribute: serverNames = ls(returnMap='true',returnType='c'). Examine the contents of that array and you will find the servers that the library has been deployed to. Complete your testing in WLST with the disconnect command. Then exit the WLST command prompt with the exit command. Python Script All that remains is to write the Python script that will do the work we want. I am providing the source code for the Python script I created. The details of this script are as follows: Global Variables and Initialization There is an initialization section that creates some global variables and defines the output which are text files for the results. This also includes an import section where you can import additional Java libraries to support the work you want to accomplish. Functions Python supports creating custom functions. In my case I have created three functions: getLibraryListing, getAppListing, and getTargetServers. getLibraryListing and getAppListing are very similar and most likely could be replaced with a more common function. The getTargetSevers function navigates the MBean tree from either the application node or the libraries node to identify the targets (target servers). Main Routine getLibraryListing and getAppListing are executed in my main routine at the bottom of the Python script. This has also included some error checking. getTargetServers is called by getLibraryListing and getAppListing. The logic for the script is as follows: """---------------------------------------------------------------------------------------------------Script  : ListLibraries.pyAuthor  : Mark PillerDate    : 2015-01-06Purpose : Create 2 separate files >           1) list of libraries in the targeted WebLogic server          2) List of applications in the targeted serverrun this with > java weblogic.WLST ListLibraries.pyor by execfile('<drive>:<directory>/ListLibraries.py') when in the WLST command prompt---------------------------------------------------------------------------------------------------"""import java.io as javaio """---------------------------------------------------------------------Global Variables---------------------------------------------------------------------"""username = 'weblogic'password = 'welcome1'URL = 't3://<hostName>:7001'outputDir = 'D:/temp'# get the date to add to the file namefrom datetime import datetoday = date.today()filedate = today.isoformat()# libraries output saved to this filelibraryOutputFile = outputDir + "/" + "libraries-in-wls-" + filedate + ".txt"libraryOutputFileWriter=javaio.FileWriter(libraryOutputFile)# applications output saved to this fileappOutputFile = outputDir + "/" + "app-deployments-in-wls-" + filedate + ".txt"appOutputFileWriter=javaio.FileWriter(appOutputFile)"""---------------------------------------------------------------------Function to find the libraries---------------------------------------------------------------------"""def getLibraryListing(mbeanPosition):  cd(mbeanPosition)  libraryListing = ls(returnMap='true', returnType='a')  if libraryListing.size() > 0 :    # print file headings    libraryOutputFileWriter.write("Library Listing " + filedate)    libraryOutputFileWriter.write(System.getProperty("line.separator"))    libraryOutputFileWriter.write(System.getProperty("line.separator"))    libraryOutputFileWriter.write("Domain    : " + domainName)    libraryOutputFileWriter.write(System.getProperty("line.separator"))    libraryOutputFileWriter.write("Server    : " + serverName)    libraryOutputFileWriter.write(System.getProperty("line.separator"))    libraryOutputFileWriter.write("MBean path: " + pwd())    libraryOutputFileWriter.write(System.getProperty("line.separator"))    libraryOutputFileWriter.write(System.getProperty("line.separator"))    libraryOutputFileWriter.write("Libary\tVersion\tServer(s) Deployed To")    libraryOutputFileWriter.write(System.getProperty("line.separator"))    libraryOutputFileWriter.write("-------\t-------\t-----------------------------")    libraryOutputFileWriter.write(System.getProperty("line.separator"))    for library in libraryListing :      # separate the library name from the version number      libraryArray = library.split('#')      myoutput = ""      itemCount = 0      for libraryItem in libraryArray :        itemCount = itemCount + 1        # item 1 is Library Name        # item 2 - if exists - is Library Version        if itemCount > 1:          myoutput = myoutput + "\t"        myoutput = myoutput + libraryItem      # if a library version is not included then add a tab character      if itemCount < 2:        myoutput = myoutput + "\t"      # identify the servers that the library is deployed to      serverArray = getTargetServers(library)      srvrCnt = 0      myoutput = myoutput + "\t"      for srvrNm in serverArray :        srvrCnt = srvrCnt + 1        myoutput = myoutput + srvrNm        if srvrCnt < len(serverArray) :          myoutput = myoutput + ', '       # print to the file      libraryOutputFileWriter.write(myoutput)      libraryOutputFileWriter.write(System.getProperty("line.separator"))  return"""---------------------------------------------------------------------Function to find the applications---------------------------------------------------------------------"""def getAppListing(mbeanPosition):  cd(mbeanPosition)  appListing = ls(returnMap='true', returnType='a')  if appListing.size() > 0 :    # print file headings    appOutputFileWriter.write("Deployed Application Listing " + filedate)    appOutputFileWriter.write(System.getProperty("line.separator"))    appOutputFileWriter.write(System.getProperty("line.separator"))    appOutputFileWriter.write("Domain    : " + domainName)    appOutputFileWriter.write(System.getProperty("line.separator"))    appOutputFileWriter.write("Server    : " + serverName)    appOutputFileWriter.write(System.getProperty("line.separator"))    appOutputFileWriter.write("MBean path: " + pwd())    appOutputFileWriter.write(System.getProperty("line.separator"))    appOutputFileWriter.write(System.getProperty("line.separator"))    appOutputFileWriter.write("Application\tVersion\tServer(s) Deployed To")    appOutputFileWriter.write(System.getProperty("line.separator"))    appOutputFileWriter.write("-----------\t-------\t-----------------------------")    appOutputFileWriter.write(System.getProperty("line.separator"))    for app in appListing :      # separate the app name from the version number      appArray = app.split('#')      myoutput = ""      itemCount = 0      for appItem in appArray :        itemCount = itemCount + 1        # item 1 is the application name        # item 2 is the application version        if itemCount > 1:          myoutput = myoutput + "\t"        myoutput = myoutput + appItem      # if a application version is not included then add a tab character      if itemCount < 2:        myoutput = myoutput + "\t"              # identify the servers that the application is deployed to      serverArray = getTargetServers(app)      srvrCnt = 0      myoutput = myoutput + "\t"      for srvrNm in serverArray :        srvrCnt = srvrCnt + 1        myoutput = myoutput + srvrNm        if srvrCnt < len(serverArray) :          myoutput = myoutput + ', '       # print to the file      appOutputFileWriter.write(myoutput)      appOutputFileWriter.write(System.getProperty("line.separator"))  return"""---------------------------------------------------------------------Function to find the servers deployed to---------------------------------------------------------------------"""def getTargetServers(childNodeName):  serverArray = []  cd(childNodeName)  childNodeListing = ls(returnMap='true',returnType='c')  if childNodeListing.size() > 0 :    for childNode in childNodeListing :      if childNode == 'Targets' :        cd('Targets')        serverNames = ls(returnMap='true',returnType='c')        if serverNames.size() > 0 :          for srvrNm in serverNames :            serverArray.append(srvrNm)        # navigate to parent of Targets node        cd('..')  # navigate back to parent attribute  cd('..')  return serverArray"""---------------------------------------------------------------------Main Routine---------------------------------------------------------------------"""try:  try:    connect(username, password, URL)    serverConfig()    getLibraryListing('/Libraries')    getAppListing('/AppDeployments')  except Exception, e:    print 'Unable to print libraries and applications'    print efinally:  disconnect()  libraryOutputFileWriter.close()  appOutputFileWriter.close() Save the above script as ListLibraries.py in a directory of your choice or download and rename the source here: ListLibraries.py.txt. As described in the header of this script you can run the script when in WLST with the command execfile('<yourDrive>:/<yourDir>/ListLibraries.py') or with the java command java weblogic.WLST ListLibraries.py. The output is with a tab delimiter between the library (or application) and the version number. In this way it will be easy to import into Excel with the tab delimiter to separate into columns. Below is a sample of the output: Library Listing 2015-01-26Domain    : dev_domainServer    : AdminServerMBean path: serverConfig:/LibrariesLibary    Version    Server(s) Deployed To-------    -------    -----------------------------UIX    11@11.1.1.1.0    AdfMngServer, AdminServeradf.oracle.businesseditor    1.0@11.1.1.2.0    AdfMngServer, AdminServeradf.oracle.domain    1.0@11.1.1.2.0    AdfMngServer, AdminServeradf.oracle.domain.webapp    1.0@11.1.1.2.0    AdfMngServer, AdminServeremai        AdfMngServer, AdminServeremas        AdfMngServer, AdminServeremcore        AdfMngServer, AdminServerjsf    1.2@1.2.9.0    AdfMngServer, AdminServerjstl    1.2@1.2.0.1    AdfMngServer, AdminServerohw-rcf    5@5.0    AdfMngServer, AdminServerohw-uix    5@5.0    AdfMngServer, AdminServeroracle.adf.dconfigbeans    1.0@11.1.1.2.0    AdfMngServer, AdminServeroracle.adf.desktopintegration    1.0@11.1.1.2.0    AdfMngServer, AdminServeroracle.adf.desktopintegration.model    1.0@11.1.1.2.0    AdfMngServer, AdminServeroracle.adf.management    1.0@11.1.1.2.0    AdfMngServer, AdminServeroracle.bi.adf.model.slib    1.0@11.1.1.2.0    AdfMngServer, AdminServeroracle.bi.adf.view.slib    1.0@11.1.1.2.0    AdfMngServer, AdminServeroracle.bi.adf.webcenter.slib    1.0@11.1.1.2.0    AdfMngServer, AdminServeroracle.bi.composer    11.1.1@0.1    AdfMngServer, AdminServeroracle.bi.jbips    11.1.1@0.1    AdfMngServer, AdminServeroracle.bpm.mgmt    11.1.1@11.1.1    AdfMngServer, AdminServeroracle.dconfig-infra    11@11.1.1.1.0    AdfMngServer, AdminServeroracle.jrf.system.filter        AdfMngServer, AdminServeroracle.jsp.next    11.1.1@11.1.1    AdfMngServer, AdminServeroracle.pwdgen    11.1.1@11.1.1.2.0    AdfMngServer, AdminServeroracle.webcenter.composer    11.1.1@11.1.1    AdfMngServer, AdminServeroracle.webcenter.skin    11.1.1@11.1.1    AdfMngServer, AdminServeroracle.wsm.seedpolicies    11.1.1@11.1.1    AdfMngServer, AdminServerorai18n-adf    11@11.1.1.1.0    AdfMngServer, AdminServer View of Import to Excel Tab Delimited Summary WLST and Python scripts are very powerful tools for working in the WebLogic domain. Many tasks can be automated. One powerful use case for these scripts would be to include them in Jenkins of Hudson to automate continuous integration processes. Once there is a successful compile and test of the checked in code you can deploy it immediately to the targeted environment using WLST and Python. I suggest that you do a directory search of the Python scripts supplied in your installation of WebLogic. These can propel you to more sophisticated and complicated scripting capabilities. There were 749 Python scripts in the WebLogic 10.3.6 installation I performed - a lot of examples that can be used to further explore.

Abstract Often times you may need to be able to identify the libraries installed on a given WebLogic server. Perhaps you need to compare different installations in different environments. Maybe you...

Integration

Webcenter Content (UCM) BPM Integration

This blogs walks through the configurations required in WebCenter Content and BPM to invoke a process deployed on the SOA server from thecontent server workflows. This is a common use case where a BPM or BPEL processhas to be invoked from UCM based on an event like document check in. Prepare the UCM environment for integration with SOA. This step is only required when theUCM and SOA domains were created separately and the UCM domain is not extendedfor SOA. a. Copythe “soa” folder from SOA_ORACLE_HOME to UCM_ORACLE_HOME For example: CopyD:\Oracle\Middleware\Oracle_SOA1\soa to D:\Oracle\Middleware\Oracle_UCM1\soa b. Updatethe class path in setDomainEnv on the UCM server Windows: Edit setDomainEnv.cmd in%DOMAIN_HOME%\bin Add :  set POST_CLASSPATH=%ORACLE_HOME%\soa\modules\oracle.soa.mgmt_11.1.1\soa-infra-mgmt.jar;%POST_CLASSPATH% UNIX Edit SetDomainEnv.sh in$DOMAIN_HOME/bin Add: POST_CLASSPATH="${ORACLE_HOME}/soa/modules/oracle.soa.mgmt_11.1.1/soa-infra-mgmt.jar${CLASSPATHSEP}${POST_CLASSPATH}" c. EnableCross Domain Security Perform thefollowing steps in both UCM and SOA console 1. Loginto the Weblogic server console (http://localhost:7001/console/) 2. Selectthe domain name under Domain Structure. Navigate to the Security Tab 3. Check“Cross Domain Security Enabled” 4. Enterthe same credential for both UCM and SOA d. Restartthe servers 2. Enable UCM-BPEL Integration Component a. Loginto content server, navigate to the Admin Server b. Selectcomponent manager for the server on which the component needs to be installed c. Clickon “Advanced Component Manager” and enable the BPELIntegrationComponent d. Loginto the Weblogic Administration console of UCM. Navigate to servers, select theUCM server and click Restart SSL. 3. Configure connection to SOA server a. Navigateto Administration -> Oracle BPEL Administration -> ConnectionConfiguration b. Fromthe “Connection Menu” select Add connection Enter the following credentials Note: The Provider URL contains the SOA server’s hostname and port.You can test this be running the wlst script in the SOA server and connect to t3://servername:[port] c. Test the connection. If successful you should see thefollowing screen. Revisit   steps 1 – 3 if there is an error. 4. Process Configuration a. Navigateto Administration -> Oracle BPEL Administration -> Process Configuration b. Fromthe process menu select “Add Process” c. Selectthe BPM/BPEL process from the drop down d. ClickSave e. Goto Actions “Upload Payload” Map the process input fields tothe Metadata fields in UCM    5. Update the SOA composite to enable UCM integration a. Addthe following line to Composite.xml in the SOA/BPM project as shown <binding.adf serviceName="YourUniqueServiceName" registryName=""/>         6. Configure Workflow in UCM a. Loginto content server b. Navigateto Administration -> Admin Applets c. Launchthe Workflow Admin Applet d. Adda new Workflow criteria   e. Clickon edit criteria workflow. The following screen is where the event triggercondition is set. In this case the workflow will be triggered for Document Typethat matches “Document” f. Editinitiateprocess               g. Add the users that have access to the workflow anddocument check in for which the workflow is triggered h. Addthe following lines under Exit conditions wfGet("conversationId") and obIsInstanceClosed("BPEL", wfGet("conversationId"))  i. OnEvents tab click Edit for Entry. Add theline <$wfReleaseDocument()$> before <$endif$> to automaticallyapprove the document. If you do not add this step the document state will be“Pending” and the user has to manually go to Content Management -> ActiveWorkflows -> My Workflow Assignments to approve the document. <$if not conversationId$> <$obConfigID="BPEL"$> <$obInvokeProcess(obConfigID)$> <$endif$> 7. Login as sysadmin ( the user from step 6)Check in a document of Type Document trigger               condition in step 6) and verify ifthe BPM/BPEL process is instantiated. Trouble shooting Cross domain security – If the cross domain security is configured incorrectly you will see the following error: vax.xml.ws.WebServiceException: java.lang.SecurityException: [Security:090398]Invalid Subject: principals=[weblogic, Administrators]   at com.sun.xml.ws.client.dispatch.DispatchImpl.doInvoke(DispatchImpl.java:209) Enabling UCM System Audit to trace BPEL Integration related errors Navigateto Administration->System Audit Information and add the BPEL integrationcomponent under “Tracing Sections Information”. Update and click “View ServerOutput” to view the detailed logs. 3. Complex Types as BPEL/BPM process input. With the current release of Webcenter Content (11.1.1.6) UCM does not process the complex type as the process input and the “Update Payload” action will give and error. The work around is to use a simple type as input. Reference http://docs.oracle.com/cd/E21764_01/doc.1111/e16759/toc.htm

This blogs walks through the configurations required in Web Center Content and BPM to invoke a process deployed on the SOA server from thecontent server workflows. This is a common use case where a...

Design Patterns

Custom TaskList Portlet in Oracle BPM 11g

Introduction: Oracle BPM 11g suite provides the BPM Workspace for endusers to view and act upon tasks that are assigned to them. The various UserInterfaces available for end users are: The BPM Workspace Application TaskList Portlet in WebCenter Spaces Customers may need a task list portal as a part of theirenterprise application with the tasks displayed in a format that is mostappropriate to the business. A Custom Worklist Portlet can be built and consumedfrom other applications. This article describes solution that uses the Human TaskJava APIs to query the BPM engine, Oracle ADF to build the custom portlet andWebcenter spaces to consume the portlet. The benefit of this approach is that the business cancontinue to use the enterprise portal to complete the tasks assigned to them ina way that is most suited to the business. The following sections describe how to build a custom TaskList portlet that that can be consumed from Webcenter spaces. 1. Developing an ADF Project to display tasks,details, actions 2. BPM Authentication and Identity Propagation 3. Portletizing the ADF Application 4. Consuming the WSRP in Web Center 1. Developing an ADF Project to display tasks,details, actions   Create an ADF Application in Jdeveloper with a Java Class inthe View Controller project   to query the tasks from the BPM Engine. a. Connect to the BPM Engine   BPM Provides the Work List APIs to query and Act upon tasks.The Task services can be  accessed through SOAP connections. Map properties = new HashMap<CONNECTION_PROPERTY,String>(); properties.put(CONNECTION_PROPERTY.SOAP_END_POINT_ROOT, wsurl); // SOA server URL, http://[ServerName]:Port" properties.put(CONNECTION_PROPERTY.SECURITY_POLICY_URI, "oracle/wss10_saml_token_client_policy"); properties.put(CONNECTION_PROPERTY.MANAGEMENT_POLICY_URI, "oracle/log_policy"); wfSvcClient = WorkflowServiceClientFactory.getWorkflowServiceClient(WorkflowServiceClientFactory.SOAP_CLIENT, properties, null); b. Initialize the task attributes to be queried List queryColumns = new ArrayList(); queryColumns.add("TASKID"); queryColumns.add("TASKNUMBER"); queryColumns.add("TITLE"); queryColumns.add("OUTCOME"); queryColumns.add("STATE"); queryColumns.add("UPDATEDDATE"); queryColumns.add("UPDATEDBY"); queryColumns.add("CATEGORY"); queryColumns.add("HASSUBTASK"); c. Execute the query querySvc.queryTasks(ctx, queryColumns, optionalInfo, ITaskQueryService.AssignmentFilter.MY_AND_GROUP,null, null,null, 0);       d. Retrieve the task result set for (int i = 0; i < tasks.size(); i++) { Task task = (Task)tasks.get(i); int taskNumber =task.getSystemAttributes().getTaskNumber(); String title = task.getTitle(); String taskId =task.getSystemAttributes().getTaskId(); String outcome =task.getSystemAttributes().getOutcome(); String state =task.getSystemAttributes().getState(); } Right Click on the Java Class and create an ADF Datacontrol. Drag and drop the data control on the JSPX to create the task listtable. 2. BPM Authentication and Identity Propagation Identity propagation provides a mechanism to propagate theuser token (in this scenario we use the SAML token) when the user logs in tothe BPM web service. This method does not required usernames and passwords tobe sent as clear text in the code. The SAML token is created when the user logsin for the first time. The SAML token is passed to the BPM webservice to querytasks related to that user. The following properties can be set for identitypropagation: properties.put(CONNECTION_PROPERTY.SECURITY_POLICY_URI,"oracle/wss10_saml_token_client_policy"); properties.put(CONNECTION_PROPERTY.SOAP_IDENTITY_PROPAGATION, "saml"); 3. Portletizing the ADF Application Portletizing the ADF application creates an Oracle JSFPortlet bridge that exposes the application as a JSR 286 portlet that can beconsumed by other applications. a. Right click on the jspx in the ApplicationNavigator and click Create Portlet entry.     b. Deploy the Portlet to the WC_Portlet Server     c. Attaching a policy to the Portlet prodcucer end point Login to the Enterprise Manager Console, expandApplication Deployments. Right click on   the deployed application and select Webservices. Select WSRP_V2_Markup_Servicefrom the list of Web Services. Click Attach/Detach in the policies tab Select oracle/wss10_saml_token_service_policyand click Attach Click OK to save the changes 4. Consuming the WSRP in Web Center a. Registering the Portlet Login to the Web Center SpacesServer EM Console Expand Service WebCenter Spaces,right click webcenter and select Settings->Service Configuration Select Portlet producers -> Add Enter the following details, testand click OK b. Consuming the portlet Add the Portlet in the Webcenterspaces page

Introduction: Oracle BPM 11g suite provides the BPM Workspace for end users to view and act upon tasks that are assigned to them. The various User Interfaces available for end users are: The BPM...

101

BPM 101 Series: Collaborative Process Modeling using MDS, Composer and Jdev

MDS is the metadata repository used by many pieces of the Oracle Fusion Middleware product stack.  There are times when you can combine MDS repositories but for the most part these repositories exist to support their individual pieces of the stack.  In the context of BPM the MDS repository is used as a means to share project artifacts and attributes between the web based composer environmnet and jdeveloper.  Jdeveloper is geared towards the developer while Composer is geared towards process analysts and business users.  It should be stated that the statement of direction for Composer is to grow  the functionality and include much more in terms of functionality and satisfaction of use cases. That brings us to our need to share between the composer and jdeveloper environments.  a generic slide that has been referenced often is the ability to continuously develop and refine the process models using collabortion between business owners, process analysts, developers and other stakeholders. Using the Composer Space within Webcenter Spaces is one way to collaborate around process models and can include various stakeholders to the process.  The use case referenced here is the sharing of composer models between the web based composer application and jdeveloper.  From within Jdev you can create a connection to MDS and use that connection to push and pull versions of the process model that may get implemented in Jdev.  A simple use case could involve the first cut of a process model that now needs to have a simulation run on it from within Jdev.  A developer would need to create a connection to the MDS repository and pull down the process models and then create simulation artifacts and run simulation against that candidate process model.  The two main connection resources that need to be created in Jdev are the application server connection and the actual MDS database connection.  Once you wrap the MDS db connection with an mds resource configuration piece you can easily pull down existing projects and snapshots to the local Jdev environment.        mds db connection +     mds resource configuration +     application server configuraton = ------------------------------------------       mds_resource_pallette_connection Below are the steps to create an MDS connection: 1. Select to view the MDS Navigator by clicking on View > MDS Navigator. 2. Click on the 'Configure Connection' icon. 3.  Click on the add symbol to create a new MDS Connection  4. Specify a name for the new connection and click on the plus sign if you are not yet connected to your WLS application server instance. 5.  Specify a name for your app server connection. 6. Specify the username/password for the WLS server.  In a dev environment this should probably be an administrator on the WLS server. Click next. 7.  Enter your hostname, port and domain name.  Click next. 8. Test your connection. Click next after receiving 'success' for all 9 tests. 9. Click 'Finish' 10.  You are returned to the 'New BPM MDS Connection' panel.  Click the 'add' symbol in the 'SOA MDS' location. 11. A new panel opens.  Name your SOA mds connection and click on the 'add' symbol in the DB Connection section. 12. A new panel opens to create a database connection to your DB instance hosting the MDS schema.  Input connection information and click 'Test' to test the connection.  Once complete click 'Ok'. 13. The new connection should now show up on the 'Create SOA-MDS Connection' panel.  The obpm partition should also show up automatically in the 'Select MDS partition' section.  Test the connection by clicking the 'Test Connection' button. Click 'Ok'. 14. You should now see your create connection name, application server and soa MDS connection name showing in your original BPM MDS Connection panel.  Click the 'Test' button.  Upon success click 'Ok'. 15. Click 'Ok' on your original 'Configure Connection' panel.  16. Congratulations! You now have Composer projects that you can 'check out', 'export' or otherwise interact with. Our next BPM 101 series article will go into the use case scenarios for securing and sharing BPM Composer projects between Business Analysts and Developers.

MDS is the metadata repository used by many pieces of the Oracle Fusion Middleware product stack.  There are times when you can combine MDS repositories but for the most part these repositories exist...

ADF

Creating a Web Service Proxy in ADF to Consume a Web Service

Abstract There is more than one way to design your ADF application toconsume web services.  One example is touse the ADF wizards to create data controls to access the web service. Anotherexample is to use the ADF wizards to create a proxy to the web service you wantto consume. This article is an example of the proxy development process. Introduction Oracle has made it extremely easy to quickly develop a bodyof customizable code that can consume a web service. If there are complexities,they will be involved in the creation of the object that is transported as aSOAP message in the web service transmissions. Otherwise, the wizard gets youto a place very quickly where you can utilize the targeted web service. There are a large number of public web services you can useto practice creating ADF code to consume the web service.  Just query on the Internet for "publicweb services".  One site is www.service-repository.com. Theweb service I have selected for this example is Top Movies. Thisdevelopment example is completed using JDeveloper 11g Release 1 (11.1.1.4.0). Overview The following summarizes what is accomplished in thisarticle. Create the Application Start the Create Application Wizard Name your application Name your project Configure Java settings Create the Web Service Proxy Select the Create Web Service Proxy wizard Select the Client Style Select the WSDL Select the WSDL to Java packages mappings Define Port Endpoints Define the Asynchronous Methods Define Oracle Web Service Message Policies Define Message Handlers Review and Understand the Generated Code Review the Project Structure Review the Generated Code and Cross-References to the WSDL Understanding the binding Element Consuming the Web Service Create the driver class Review and understand the code  Using Environments and Migrations Identifying Four methods of migrating between environments Using generated class constructors for migrations Construction Create the Application Start the Create Application Wizard Open up JDeveloper. Click on the Application Menu > New.  Define the Application Dialog Select Generic Application from the Application Template list. Application Name:  TopMovie Directory: D:\JDev\jdev11114\TopMovie Click Next Define the Project Dialog Select Web Services from the Project Technologies list. Click on the move button to shuttle the service to the selected side. The wizard will add an additional step > Project JavaSettings. You will see that 2 technologies were added to the selectedwindow: Java and Web Services. Click Next Configure Java Settings Dialog Assign a Default Package:  webservices Click Finish Create the Web Service Proxy Start the ADF Wizard Right mouse click the Project > WebServices Click New New Gallery Dialog Box When the New Gallery dialog box appears perform thefollowing steps. Select Current Project Technologies tab Select Business Tier > Web Services in the categories list Select Web Service Proxy in the items list Click OK Create Web Service Proxy Welcome Dialog Box Click Next  Select Client Style Dialog Box Select JAX-WS Style (this should be the default) Click Next Select Web Service Description Dialog Box Enter the location of the WSDL file. This can be a local copy or you may have a URL address to enter which is also acceptable. By default, "Copy WSDL Into Project" is selected. Keep the default setting. Click Next Specify Default Mapping Options Dialog Box Enter a Package Name:  com.topmovie Enter a Root Package for Generated Types:  com.topmovie.types By default, "Unwrap Wrapped Parameters" is selected.  Keep the default. Click Next Port Endpoints Dialog Box This is an optional task.  Keep the defaults. Click Next Asynchronous Methods Dialog Box Accept the default selection "Generate asynchronous methods where specified by the JAX-WS binding" Click Next Policy Dialog Box Accept all the defaults in this dialog box Click Next Defined Handlers Dialog Box Accept all the defaults in this dialog box Click Next Finish Dialog Box Review and Click Finish Save your changes (Control-S) Review Application Structure Project View Numerousclass files and supporting files such as the WSDL file are generated. Below isa screenshot of the WebServices Project structure that is generated with theproxy web service wizard. Code and WSDL Cross-References Anexamination of the WSDL file will help understanding the resulting codegeneration via the wizard. Every time you use this wizard the code generation will be very similar to the structure reviewed below. By studying this structure you can very quickly know where to go to create code anytime you use this wizard. Below is a table of the structure elementscross-referenced to the WSDL location. Structure Name WSDL Location TopMovies.java wsdl:service name="TopMovies" You will always have one class file generated for your service with the name "serviceName.java" TopMoviesSoap.java wsdl: portType name="TopMoviesSoap" Also contains the methods used to invoke the web service TopMoviesSoap12Client.java wsdl: binding name="TopMoviesSoap12Client" A template that provides the beginning code to invoke the web service using SOAP 1.2 bindings TopMoviesSoapClient.java wsdl:binding name="TopMoviesSoapClient" A template that provides the beginning code to invoke the web service using SOAP 1.1 bindings (for backward compatibility) TopMoviesProxy a container that encapsulates all the class files and supporting files (such as the wsdl) in the defined structure Types Section WSDL Location ArrayOfString.java s:complexType name="ArrayOfString" GetMovieAtNumber.java s:complexType name="GetMovieAtNumber" GetMovieAtNumberResponse.java s:complexType name="GetMovieAtNumberResponse " GetTop10.java s:element name="GetTop10" GetTop10Response.java s:element name="GetTop10Response" ObjectFactory.java provides methods to create object instances of the above types package-info.java references the package of class files for the types (com.topmovie.types) Notes about the binding Element in the WSDL structure The binding element serves two purposes. 1.   It is a link between the abstract elements (<wsdl:types>,<wsdl:message>, <wsdl:operation>, <wsdl:portType>) and theconcrete elements (<wsdl:service>, <wsdl:port>,<wsdl:binding>) in the WSDL.  The attribute "type" is the name of the portType: <wsdl:binding name="TopMoviesSoap12" type="tns:TopMoviesSoap"> <wsdl:binding name="TopMoviesSoap"type="tns:TopMoviesSoap"> "tns:TopMoviesSoap" is the portType Notice that there are two bindings.  The binding with name"TopMoviesSoap12" is a SOAP 1.2 binding element. The binding withname "TopMoviesSoap" is a SOAP 1.1 binding. You can find additionalinformation about the two supported formats with a search on the Internet. ManyWSDL files provide both bindings for backward compatibility. There are threekey differences of SOAP 1.2 over SOAP 1.1: 1) A new namespace:http://schemas.xmlsoap.org/wsdl/soap12/ 2) The encodingStyle attribute is now a single URI,instead of a list of URIs 3) There is a new attribute: soapActionRequired,which is used to indicated that the server needs the SOAPAction value. 2.    The binding element provides a container forinformation such as the protocol and the operation of the Web service. The transport attribute is the protocol. In the binding element you can identify the operations that can be executed when consuming the web service and these become the methods used within the Java template code with "Client" in the class name (e.g. TopMoviesSoapClient.java). Consuming the Web Service Create a Driver The next step is to create our code that will execute thenewly created methods and consume the Top Movies web service. The job of accomplishing this is made easier by reviewingeither the TopMoviesSoapClient.java or TopMoviesSoap12Client.java class files.Each of these serve as a starting point to writing your own code to execute theoperations you want to target. Below is a segment of the TopMoviesSoapClient.java: public static void main(String [] args){ topMovies = new TopMovies(); TopMoviesSoap topMoviesSoap = topMovies.getTopMoviesSoap(); // Add your code to call the desired methods.} This can be used to begin our own coding efforts. Create a New Class File Right mouse click the project and click New on the menu New Gallery Dialog Box Select Current Project Technologies tab Select General > Java from the Categories list Select Java Class from the Items list Click OK Create Java Class Dialog Box Complete the form as follows: Name:  TopMovieWS Package:  webservices Extends:  java.lang.Object Select Main Method check box Click OK The defaults that should already be selected are: Access Modifiers> public, Other Modifiers > None, Constructors from Superclass andImplement Abstract Methods. Complete the new Class file to look like the following: package webservices;import com.topmovie.TopMovies;import com.topmovie.TopMoviesSoap;import com.topmovie.types.ArrayOfString;import java.io.UnsupportedEncodingException;import java.net.MalformedURLException;import java.net.URL;import java.net.URLDecoder;import java.util.Iterator;import java.util.List;import javax.xml.namespace.QName;import oracle.xquery.parser.Qname;public class TopMovieWS { private static TopMovies topMovies; public TopMovieWS() { super(); } public static void main(String[] args) { int movieRank = 1; // sample from TopMoviesSoapClient.java topMovies = new TopMovies(); QName serviceName = topMovies.getServiceName(); System.out.println("Service Name: " + serviceName + "\n"); URL wsdlDocumentLocation = topMovies.getWSDLDocumentLocation(); System.out.println("WSDL Location: " + wsdlDocumentLocation); URLDecoder decoder = new URLDecoder(); String decodedURL = null; try { decodedURL = decoder.decode(wsdlDocumentLocation.toString(), "UTF-8"); } catch (UnsupportedEncodingException e) { System.out.println("Error"); } System.out.println("WSDL Location without URL Escape codes: " + decodedURL); // consume the web service with SOAP 1.1 binding TopMoviesSoap topMoviesSoap = topMovies.getTopMoviesSoap(); movieRank = 2; String movieAtNumber = topMoviesSoap.getMovieAtNumber(movieRank); System.out.println("SOAP 1.1 binding - Movie at number " + movieRank + " is " + movieAtNumber + "\n"); // consume the web service with SOAP 1.2 binding TopMoviesSoap topMoviesSoap12Client = topMovies.getTopMoviesSoap12(); movieAtNumber = topMoviesSoap12Client.getMovieAtNumber(movieRank); System.out.println("SOAP 1.2 binding - Movie at number " + movieRank + " is " + movieAtNumber + "\n"); // also execute the Top 10 Movie operation TopMoviesSoap top10MoviesSoap = topMovies.getTopMoviesSoap(); ArrayOfString top10MoviesArrayOfString = top10MoviesSoap.getTop10(); List listOfTop10Movies = top10MoviesArrayOfString.getString(); Iterator iterator = listOfTop10Movies.iterator(); int iMovieCount = 0; while (iterator.hasNext()) { String movieDesc = (String)iterator.next(); iMovieCount++; System.out.println(iMovieCount + ". Top 10 Movie: " + movieDesc); } }} Notes About the Code The auto-complete feature in JDeveloper makes it very easyto inspect your possibilities as you begin typing your code. One of the very nice features is to use thecontrol-space key stroke to use the Declaration Insert operation on your code.They will do the necessary casting andshortcuts your work considerably. All you need to do is modify the variablenames to your own coding standards. A provided enough code to explore the two operations madeavailable and some of the other more interesting methods (e.g.getServiceName(), getWSDLDocumentLocation()). Sample of Output Below is a sample of the output produced by the code. Service Name: {http://www.kirupafx.com}TopMoviesWSDL Location: http://www.kirupafx.com/WebService/TopMovies.asmx/#%7Bhttp%3A%2F%2Fwww.kirupafx.com%7DTopMovies?wsdlWSDL Location without URL Escape codes: http://www.kirupafx.com/WebService/TopMovies.asmx/#{http://www.kirupafx.com}TopMovies?wsdlNote that the WSDL location is a combination of the WSDL URL plus the Service Name.SOAP 1.1 binding - Movie at number 2 is The Godfather: Part II (1974)SOAP 1.2 binding - Movie at number 2 is The Godfather: Part II (1974)1. Top 10 Movie: The Godfather (1972)2. Top 10 Movie: The Shawshank Redemption (1994)3. Top 10 Movie: The Godfather: Part II (1974)4. Top 10 Movie: The Lord of the Rings: The Return of the King (2003)5. Top 10 Movie: Casablanca6. Top 10 Movie: Schindler's List7. Top 10 Movie: Shichinin no samurai (1954)8. Top 10 Movie: Buono, il brutto, il cattivo, Il (1966)9. Top 10 Movie: Pulp Fiction (1994)10. Top 10 Movie: Star Wars: Episode V - The Empire Strikes Back (1980) Environments and Migrations As developers we will most likely be working in a settingthat has the traditional division of environments (e.g. Development, Testing,QA, PreProduction, Production). Whenthis is your setting you will most likely have a separate WSDL file for the webservice(s) to be consumed. If this is your case, then you must also prepareyour code to make migrations easier. The code generated by the wizard is very specifically tiedto the addresses provided in your WSDL file. Consequently, if you migrate yourcode from a development environment to a test environment, your code will becalling the development web service by default. This needs to be corrected forthe migration process. There are at least four ways that I know about to accomplishthis: Hard code your changes for each migration Make references to each environment's WSDL in the connections.xml file Use the BindingProvider Interface Use one of the additional constructors provided in the generated Java code where the class file name is the ServiceName.java (our example is TopMovies.java) For this discussion I will illustrate using one of theadditional constructors for the TopMovies.java class file. TopMovies Class Constructors and Migrations TopMovies() This constructor has no parameters. Below is the constructor generated from the wizard. With no parameters, the constructor will use the hard-coded URLthat was generated by the wizard from your WSDL file and assign it to "wsdlLocationURL". public TopMovies() { super(wsdlLocationURL, new QName("http://www.kirupafx.com", "TopMovies")); } TopMovies(URL wsdlLocation, QName serviceName) This constructor is expecting two parameters.  Below is the constructor generated from the wizard. public TopMovies(URL wsdlLocation, QName serviceName) { super(wsdlLocation, serviceName); } You must supply the wsdlLocation and the serviceName.  One way you can use this in multiple environments is to store your WSDLlocation for that corresponding environment in a file (topMovies.properties for example).You write your code to read the targeted properties file and retrieve thedesignated WSDL location. Below is my sample code with the new code (in yellow) needed to call the constructor with two parameters. I have hard coded the wsdlLocation but in a multi-environment setting you will use another means to supply the wsdlLocation based upon the current environment. package webservices;import com.topmovie.TopMovies;import com.topmovie.TopMoviesSoap;import com.topmovie.types.ArrayOfString;import java.io.UnsupportedEncodingException;import java.net.MalformedURLException;import java.net.URL;import java.net.URLDecoder;import java.util.Iterator;import java.util.List;import javax.xml.namespace.QName;import oracle.xquery.parser.Qname;public class TopMovieWS { private static TopMovies topMovies; public TopMovieWS() { super(); } public static void main(String[] args) { int movieRank = 1; URL topMoviesURL = null; try { topMoviesURL = new URL("http://www.kirupafx.com/WebService/TopMovies.asmx?wsdl"); } catch (MalformedURLException e) { System.out.println("An error occurred creating the URL: " + e.toString()); } QName qualifiedName = new QName("http://www.kirupafx.com", "TopMovies"); topMovies = new TopMovies(topMoviesURL, qualifiedName); QName serviceName = topMovies.getServiceName(); System.out.println("Service Name: " + serviceName + "\n"); URL wsdlDocumentLocation = topMovies.getWSDLDocumentLocation(); System.out.println("WSDL Location: " + wsdlDocumentLocation); URLDecoder decoder = new URLDecoder(); String decodedURL = null; try { decodedURL = decoder.decode(wsdlDocumentLocation.toString(), "UTF-8"); } catch (UnsupportedEncodingException e) { System.out.println("Error"); } System.out.println("WSDL Location without URL Escape codes: " + decodedURL); // consume the web service with SOAP 1.1 binding TopMoviesSoap topMoviesSoap = topMovies.getTopMoviesSoap(); movieRank = 2; String movieAtNumber = topMoviesSoap.getMovieAtNumber(movieRank); System.out.println("SOAP 1.1 binding - Movie at number " + movieRank + " is " + movieAtNumber + "\n"); // consume the web service with SOAP 1.2 binding TopMoviesSoap topMoviesSoap12Client = topMovies.getTopMoviesSoap12(); movieAtNumber = topMoviesSoap12Client.getMovieAtNumber(movieRank); System.out.println("SOAP 1.2 binding - Movie at number " + movieRank + " is " + movieAtNumber + "\n"); // also execute the Top 10 Movie operation TopMoviesSoap top10MoviesSoap = topMovies.getTopMoviesSoap(); ArrayOfString top10MoviesArrayOfString = top10MoviesSoap.getTop10(); List listOfTop10Movies = top10MoviesArrayOfString.getString(); Iterator iterator = listOfTop10Movies.iterator(); int iMovieCount = 0; while (iterator.hasNext()) { String movieDesc = (String)iterator.next(); iMovieCount++; System.out.println(iMovieCount + ". Top 10 Movie: " + movieDesc); } }} The qualified name logic used in the code above was found by referring to line 67in TopMovies.java (shown in yellow below). public TopMovies() { super(wsdlLocationURL,new QName("http://www.kirupafx.com", "TopMovies")); } The URL is simply theplace where the WSDL file is located. Ifyou add this code to your previous TopMovieWS.java you and run it you willnotice a slight difference in the display of the wsdlDocumentLocation: WSDL Location: http://www.kirupafx.com/WebService/TopMovies.asmx?wsdl WSDL Location without URL Escape codes: http://www.kirupafx.com/WebService/TopMovies.asmx?wsdl The display now reflects the URL assignment you made in yourcode. Summary Once you know how, ADF development to support consuming webservices becomes a very simple and straight forward task. The heavy lifting has already been done foryou. You only need to provide theparameter values needed to execute your targeted operations and when necessary,make adjustments to allow for code migration from one environment to another. Additional Resources Harvard Lecture by Prof. David J. Malan about Web Services, SOAP 1.2, and WSDL 1.1 W3C: From SOAP/1.1 to SOAP Version 1.2 in 9 points Oracle: Integrating Web Services Into a Fusion Web Application JDeveloper Tutorial - Developing an ADF Client Using a Web Service Data Control Oracle: Calling a Web Service from an Application Module I

Abstract There is more than one way to design your ADF application to consume web services.  One example is to use the ADF wizards to create data controls to access the web service. Anotherexample is...

Best Practices

Source Code Control (SVN) and Team Development with ALBPM and OBPM 10g

Summary Source code control is essential to managing the life-cycle of an application. Plus, it facilitates a predictable deployment practice. This document discusses how to use the SVN code repository to manage ALBPM and OBPM 10g projects. This document concludes with a suggested procedure for allowing development teams to submit their changes to a source code repository, which can then be deployed by system administrators to the BPM engines. Several BPM consultants have provided input to this document. And, it represents a compilation of their experiences.  BPM Studio Source Code Control Integration  Specific Source Code Control Systems Because the old ALBPM and OBPM 10g Studio's were build on the Eclipse foundation, integration with a source code control system that has Eclipse plug-ins is usually pretty straight-forward. What follows in this section are steps to integrate Studio with some Specific source code control systems.  CVS and SVN AqualogicBPM v6 comes with built-in integration with CVS. Support for SVN is built intoOBPM Studio 10g. To support SVN in v6, you must install the appropriate plug-ininto Eclipse. Two of the available plug-ins are Subversive and Subclipse. The followinglink provides a walk-though on how to install Subversive into ALBPM Studio: (http://www.function1.com/site/2008/01/integrating-albpm-60-with-subv.html). Rational Clear Case Appendix A contains a detailed description on how to integrate Rational Clear Case with ALBPM and OBPM 10g Studio. Please note, that the latest releases of Rational Clear Case are not compatible with the old version of Eclipse that Studio requires. Make sure your version works with the Studio version of Eclipse before trying to install the Eclipse plug-in. No Source Code Control Integration Possible? Can't seem to get your Source Code Control (SCC) system to integrate with BPM Studio? Well here is a manual way you can get your BPM projects into without using Eclipse integration. Generally,  all of the subdirectories and their contents ofa BPM project should be checked into the code repository with the exceptionof the “build” and “system” directories. But you may want to exclude some of the other directories and files listed below. /publication.xml -- This file keeps track of some objects published during local Studio testing. /component/Catalog/* -- Business objects in the catalog are good to keep in SCC. But introspected objects may not work out so well for reasons mentioned elsewhere in this document. /config/bam.xml and /config/engine.xml -- These files are updated when you run the Studio engine for testing. /config/organization/participant/* -- This folder contains all of the configured participant. These may change during testing. And, not everyone in the team may want the same participants. /config/externalResources/* -- Sometimes you may not want to have the External Resources in source control. /lib/* -- Depending upon the policy you are using, you may not want the jars in source code control. Problems with Document Merge There areknown problems with the ability of source code control software (particularly SVN) to accurately merge BPM documents. It is bestto avoid the scenarios where code merges occur. Usually, merges occur when twodevelopers are working on the same document. The first developer commits hischanges to the repository. Next, the other developer commits their changes. The source code control (SCC) softwarenotices that the versions are different and attempts to merge the twodocuments. Most of the time the SCC is not optimized for the XML rich content of theBPM documents, and things go awry. Here aresome helpful strategies to avoid this scenario. 1. Developerseither request edit permission, or lock the document in question beforeediting. Then, the developer releases the lock when editing is complete. 2. For SVN: change theMIME type in SVN of the OBPM document types to “octet/stream”. SVN will not tryto merge what it thinks are binary file types. 3. Reduce thelikelihood of developers needing to develop on the same document by decomposingyour project into smaller, more reusable pieces. a. Try not towrite long blocks of PBL code. Alternatively, put smaller pieces into BPMObject methods. Also, consider using Procedure implementations. b. Implementinteractive activities with Screenflows. c. Refactorlarge processes to call subprocesses. Divide the processes into reusableassets.  Problems with Re-introspecting Objects in the Component Catalog Frequently,web service definitions change. This causes the developers to re-introspect theweb service for OBPM Studio to recognize the changes. Unfortunately, the waythat OBPM Studio refactors the project’s file system when web services arere-introspected will seriously confuse the Source Code Control . Recovering from this confusion canbe very difficult. Follow theprocedures in Appendix B to avoidthese problems.  Problems with Existing Installations of Tortoise SVN The versionof SVN installed with Tortoise SVN will conflict with the version of SVNinstalled with the Eclipse plug-in. It is best that Tortoise SVN be removedfrom computers in which OBPM Studio development (with SVN integration) will beperformed.  Deploying BPM Projects from Source Code Control The ultimate goal of good source code control is not just to facilitate team development. Ultimately you want to have a scripted and reliable compile and deployment process that does not involve a lot of human interaction. This section will describe how this can be achieved with BPM Studio.  Development Process With Source Control Once the development team has integrated Source Code Control (SCC) with BPM Studio/Eclipse, they can proceed with the following procedure. Developers using OBPM Studio, with the SVN plug-in forEclipse, keep their source-code in sync with the SCC repository. After testing, and ready to deploy to the target BPM system, thedevelopers compile and double check to insure there are no errors. Note: I have other articles which cover unit testing of BPM processes on my personal web site: Unit testing ALBPM and OBPM: Unravelling PUnit, CUnit and PAPI JUnit Testing Automating ALBPM / OBPM 10g Interactive Forms in a JUnit Test Note: I have other articles which cover unit testing of BPM processes on my personal web site: Unit testing ALBPM and OBPM: Unravelling PUnit, CUnit and PAPI JUnit Testing Automating ALBPM / OBPM 10g Interactive Forms in a JUnit Test System Administrator Automated Deployment Process With Source Control Most of the customer engagements I have been on, the System Administrators were using the Process Administrator UI to deploy BPM projects. While this process works well, it does not eliminate the possibility for user error. Also, you can never be sure that the process of deploying a particular project was performed exactly the same way between environments. The Ant interface to the BPM Engine and Directory works really well. And, it solves these problems. Investing a little time in developing the scripts just right can make things much easier in the long run. Plus, as more projects get deployed, or they get more complex, ant scripts really help the System Administrators enforce architectural policies. The project is checked out of P&G’s SVN repositoryto a local Deployment folder. An Ant script is executed to deploy the project to theappropriate BPM engine. The BPM Ant API will deploy the project’s folderinstead of an BPM Studio exported file (*.exp). Note: You canfind the ANT API reference at the following URLs: ALBPM 6.0: Java Docs Publish Task OBPM 10g: Java Docs Publish Task  Appendix A: Rational ClearCase BPM Studio Integration This section will guide you step by step with how to install ClearCase integration with ALBPM or OBPM 10g Studio. Note, the latest version of ClearCase is not compatible with BPM Studio. 1. In BPM Studio, select the menu items: Help | Software Updates | Available Software | Add Site. 2. Type "http://jautodoc.sourceforge.net/update/" in the "Location" field and click "OK". 3. Click "Install…", "Next" and read and accept the license agreement. Select "No" when it asks you if you want to restart. 4. Select the menu item: Help | Software Updates… | Available Software | Add Site… tab. 5. Type "http://pmd.sourceforge.net/eclipse" in the "Location" field, and click "OK". 6. Check "PMD for eclipse 3" and click "Install…" Select "No" when it asks you if you want to restart. 7. Restart Eclipse: File | Restart. 8. Click: Help | Software Updates… | Available Software | Add Site… tab. 9. Type "http://www3.software.ibm.com/ibmdl/pub/software/rationalsdp/clearcase/ccrc/701/update/" in the "Location" field and click "Install...". 10. In the "Unsupported Install" dialogue box select "Launch". 11. In the "Install/Update" window, select "Search for new features to Install" and click "Next". 12. In the "Updates sites to visit" window, select "New Remote Site…" and give a Name. 13. The URL field needs to be "http://www3.software.ibm.com/ibmdl/pub/software/rationalsdp/clearcase/ccrc/701/update/.". Click "OK". 14. In the "Updates" window, select "Rational ClearCase Remote Client for Eclipse" and click "Next". 15. Select "Install All in Feature". 16. Select "Install All in Feature Verification." . 17. Restart Eclipse and open the ClearCase perspective. . Appendix B: Re-Introspecting a Web Service Under Source Code Control  Background When you re-introspect a resource into the Component Catalog, BPM Studio sometimes deletes files and folders, then recreates them. Source Code Control (SSC) systems keep track of differences of files. When the contents of a folder drastically change without the SSC knowing about it, bad things happen. There are two strategies that I have seen that work to alleviate this problem. 1. Keep the Component Catalog folders which get frequently changed out of SCC. Each team member has to manually keep track of changes to the components and re-introspect them. Then just prior to testing/deploy, introspect them with studio. This is a manual approach, but I have seen it work. There is usually a lot of time wasted getting the external resources and components introspected just right when things change. Another disadvantage is that interface code is not in source code control. 2. Have one person manage re-introspections. When changes to interfaces or objects, this team member will follow the procedure outlined in this section to make sure the changes get put into source code control. Then, the other team members can update their projects. This is a cumbersome process. But it isolates time wasted to a single team member. And, interface code will be saved to source control. Plus, it is easier to automate testing and deployment. The key concept is that the SCC needs to know when folders and files are getting deleted, so it doesn't try to change or merge documents. The procedure below shows how to do re-introspection of a Web Service. But this procedure can be used for other complex objects that are introspected. This procedure has been tested with ALBPM 6 with SVN. You will probably have to modify it to suit the SCC system you are using.  The Procedure 1.    Ensure that ALL of your project code is checked into Source Code Control (SCC).  You MUST completely remove the project in the course of these instructions and import it from SCC.  This means that any code that is NOT checked into the SCC will be LOST. 2.    Right click the Web Service in the “Project Navigator” pane of ALBPM Studio and select the “Recatalog Component”  menu item. 3.Copy the WSDL address field to the clipboard.  You’ll need this later. If necessary, paste it into a Notepad window. 4. Close ALBPM Studio. 5. In Windows Explorer, navigate to %ALBPM project home directory%]\componentCatalog\Custom\WebServices\" and select the web service that you need to re-introspect.  In the right-hand pane of Windows Explorer, select and delete all of the files in that directory with the exception of the “.svn” sub-directory. . 6. Re-open ALBPM Studio (note that the project will take a few minutes to recompile) 7. Commit the project from the top-most level in the “Project Navigator” pane. (This is where we tell the SCC that the files and folders have been deleted.) 8. Click on the “Select All” button and then the “OK” button. 9. Delete the Web Service you want to re-introspect in the “Project Navigator” pane of ALBPM Studio. 10. Commit the project from the top-most level in the “Project Navigator” pane. (See the screenshot for Step 7). 11. Click on the “Select All” button and then the “OK” button. 12. Right-click on the project name in the “Project Navigator” pane and select the “Remove from Workspace” menu item. 13. Close ALBPM Studio. 14. In Windows Explorer, delete project’s directory.       Yes, that's right. SSC systems like to store information in hidden files and folders. So does Studio/Eclipse for that matter. If you don't delete the project folder, you risk confusing the SSC into thinking that the re-introspected files and folders are the same ones. Then it will try to calculate differences and merge. In the end, it messes up the repository. 15. Open ALBPM Studio. 16. Select the menu item: File | Import…       Now we need to get the project from the SSC the way the SSC understands it, just like you would if you are just starting to work on the project. This gets us a nice clean version with no baggage from the deleted component catalog items. 17. Select the “Other / Checkout Projects” from SVN import source, then  click the “Next >” button. 18. Select the existing repository location and click the “Next  >” button. 19. Select the appropriate folder for the project and click the “Next >” button. 20. Click the “Next >” button. 21. Click the “Finish” button. (Allow code to download from SVN and for WorkSpace to recompile.) 22. Right click on the “Web Services” tree node in the “Project Navigator” and select “Catalog Component | Web Service” menu item.      Now we are introspecting the web service again. The SSC will think it is a new set of files and folders. And, it won't get confused. 23. Paste in the WSDL address that  was copied to the clipboard in Step 4 into the “WSDL Address” field. (See the screenshot in Step 4). 24. Commit the project from the top-most level in the “Project Navigator” pane. (See the screenshot for Step 8). 25. Click on the “Select All” button and then the “OK” button. 26. Run any available unit tests against all re-instrospected Web Services to insure if they are functioning correctly.  About the Author Floyd Walker has been helping companies implement BPM technologies for over six years. An expert in many different technologies, he has a passion to provide solutions and explore the new vistas of the software industry. Sometimes he posts interesting things on his blog http://www.floydwalker.com.  While he works as a consultant for Oracle Corporation, he wishes to remind you that all contents of his blog posts are his own opinions and do not reflect the views and policies of Oracle. I hope you have enjoyed reading this article.

Summary Source code control is essential to managing the life-cycle of an application. Plus, it facilitates a predictable deployment practice. This document discusses how to use the SVN code repository...