Oracle Directory Manager and Application Development

Peter O'Brien | Jul 8, 2008 16:00 -0600
Oracle Directory Manager is a Java-based tool for administering Oracle Internet Directory (LDAP). The Oracle Directory Manager is the main directory administration tool and it is installed with Oracle Internet Directory.

When developing applications there is often one or more central LDAP directories for developers to use. When working on a new application it is often necessary to reset entries, test scenarios, etc. However, it is unlikely that everyone's desktop will have the entire OID installation. On my desk alone there are 3 desktop machines, one laptop computer and non of them have the full Identity Management stack.

One easy way to have Oracle Directory Manager on every developer's machine, but not having to install anything else, is to take advantage of the fact that it is a Java application.

To achieve this, copy some jars (over 15 of them!) from the ORACLE_HOME/jlib and the ORACLE_HOME/ldap/oidadmin directories to a directory on your PC. Let's call it oidadmin. Keep the directory structures. The entire list of jars is below. The main class is oracle.ldap.admin.client.NavigatorFrame and there are a few parameters that need to be passed to it. The entire command line is too long to type, let alone remember, so put it all in a file called oidadmin.cmd (when on windows) in the same oidadmin directory.

oidadmin.cmd

java
-ms4m
-mx128m
-Dsun.java2d.noddraw=true
-Dsun.java2d.font.DisableAlgorithmicStyles=true
-classpath "./ldap/oidadmin/osdadmin.jar;
./jlib/netcfg.jar;
./jlib/help4.jar;
./jlib/help4-nls.jar;
./jlib/oracle_ice.jar;
./jlib/jewt4.jar;
./jlib/share.jar;
./jlib/ewt3.jar;
./jlib/ewt3-nls.jar;
./jlib/ewtcompat-3_3_15.jar;
./jlib/swingall-1_1_1.jar;
./jlib/dbui2.jar;
./jlib/dbui2-nls.jar;
./ldap/oidadmin/oidldap.jar;
./ldap/oidadmin/netutil.jar;
./jlib/oemlt-9_0_2.jar;
./jlib/ldapjclnt10.jar"
oracle.ldap.admin.client.NavigatorFrame
-AdminRoot:Start
-ldap
-AdminRoot:End
-LDAPRoot:Start
-meta
-ohhome
"."
-LDAPRoot:End


The above is formatted for readability and should be all on the one line. On windows I create shortcut on the desktop to the command file. The final touch is to use the OID Directory Manager icon for the shortcut. Any machine with Java can become a OID Directory Manager machine which I have found really useful for demonstrations and collaboration with developing new solutions.

Why people matter more in architecture than technology

Steve Jones | Jul 8, 2008 06:30 -0600
I've said before about Ivory towers v long term but I thought it was briefly worth bringing it up on the back of the Convenience v Correctness piece. Correctness is normally used to describe the technology side, solution X is more "correct" because it obeys more rules or exhibits better technology pieces. The goal in this mindset is to be as correct as possible, rather than being good enough for

Siebel Web Service Invocation Error

Peeyush Tugnawat | Jul 7, 2008 17:20 -0600

Issue: I was getting the error code: SBL-EAI-04313 while invoking a Sibel WS from BPEL.

Error Details:

“There is no active Web Service with operation named 'http://siebel.com/asi/:SiebelAccountInsert'.(SBL-EAI-04313”

<detail>
   <siebelf:siebdetail xmlns:siebelf="http://www.siebel.com/ws/fault" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
      <siebelf:logfilename xmlns:siebelf="http://www.siebel.com/ws/fault" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">EAIObjMgr_enu_0024_25165939.log</siebelf:logfilename>
      <siebelf:errorstack xmlns:siebelf="http://www.siebel.com/ws/fault" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
         <siebelf:error xmlns:siebelf="http://www.siebel.com/ws/fault" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
            <siebelf:errorcode xmlns:siebelf="http://www.siebel.com/ws/fault" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">SBL-EAI-04313</siebelf:errorcode>
            <siebelf:errorsymbol xmlns:siebelf="http://www.siebel.com/ws/fault" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">IDS_EAI_WS_OP_NOT_FOUND</siebelf:errorsymbol>
            <siebelf:errormsg xmlns:siebelf="http://www.siebel.com/ws/fault" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">There is no active Web Service with operation named 'http://siebel.com/asi/:SiebelAccountInsert'.(SBL-EAI-04313)</siebelf:errormsg>
         </siebelf:error>
      </siebelf:errorstack>
   </siebelf:siebdetail>
</detail>

 

This issue was resolved by making sure that the status of WS is ‘Active’ and clearing the cache.

Deployment too fast?

When doing configuration management on your SOA application to various environments; development, test, acceptance and production. You would use you on mechanism for deployment.


What I found out during some SOA projects, that your build system is too fast for the de Oracle SOA Suite server. When deploying a lot of BPEL processes and ESB services, you sometimes get strange errors. This is related that WSDL files cannot be found or strange errors when registering ESB services. The solution is very simple.

Introduce a wait time between each deployment. Choose this delay between 4 and 10 seconds.

After deployment, the system needs to take care that everything is in place. This will take some time. Therefore a new deployment directly after the previous one, could result in errors.

Marc

Convenience over Correctness - a deconstruction

Steve Jones | Jul 7, 2008 01:20 -0600
So I wrote a quick piece on Steve Vinoski's IEEE article and a criticism was levelled by an anonymous poster that I didn't dissect the article piece by piece... never one to not learn from such constructive criticism I thought I'd do just that.... So the paper starts of with a reasonable discussion of the origins of RPC. Noting indeed that its history dates back to the 1970s. This makes the

Catching Up

Greg Pavlik | Jul 4, 2008 10:30 -0600
Between work and holiday, I haven't been able to post much to the blog over the last 6 weeks. I am going to do a series of updates. Outside of work, I've been thinking a bit about the future of the web architecture, emerging markets and human social and religious history: post coming up related to all topics.

1) I was out of the country when Feedly was rolled out. I will talk about Feedly, why it is important and do a series of reviews on the technology.

2) I am hoping to publish details on a venture fund investing in Africa that I think will be quite interesting in the near future.

3) A longish entry on my recent holiday in Italy, including "the first Rome" is in the works.

Hope all that is of interest.

Tool and reality blindness

Steve Jones | Jul 4, 2008 10:30 -0600
There are ways of developing robust distributed applications that don’t require code-generation toolkits, piles of special code annotations, or brittle enterprisey frameworks. Is the view of Steve Vinoski. Its a general rant against RPC (its really really bad BTW) and in praise of the wonderful programming language renaissance we’re currently experiencing. Ummm I'm finding it really hard to

Removing additional whitespaces in your Elements and Attributes

ram.menon | Jul 2, 2008 12:01 -0600

In case your XML elements contain multiple whitespaces within the text, or leading and trailing the text, you could use normalize-space() function to remove the leading and trailing whitespaces, as well as to combine all adjacent intermediary whitespaces into one single whitespace.


For e.g


Input


&lt;input>   1sp 2sp  3sp   4sp     5sp     3sp   end&lt;/input>


XSLT


 &lt;ns1:result>
   &lt;xsl:value-of select="normalize-space(/input)"/>
&lt;/ns1:result>


Result


&lt;result>1sp 2sp 3sp 4sp 5sp 3sp end&lt;/result>

Customizing any BPEL Project Artifact using <customizeDocument>

Ramkumar Menon | Jul 2, 2008 12:01 -0600

Tokenization of artifacts in a BPEL Project


This note describes a simple ant task that I had come up with that provides an easy and flexible method to enable migration of Process artifacts while deploying to multiple target environments.


Problem Statement


Most often, the BPEL process projects that you develop contain XSDs and WSDLs that fall into one or more of the following categories.
a) The artifacts themselves are hosted on a dedicated server for the specific environment. [For instance, in the OHS htdocs within the development server] The artifacts are referred from the project using absolute URLs, containing the host, port, and other server specific information.
b) The artifacts include or import other artifacts that are hosted on a dedicated server for the specific environment.
c) The WSDL contains a JNDI location that changes for each environment.
d) The WSDL defines inline schemas that contain imported remote XSDs that again are hosted on the dedicated development server.
If your process exhibits one or more of the above characteristics, then more often that not, you will encounter the challenge of automating the migration of these artifacts at deployment time, especially when you have a medium to large number of projects, and/or if you have multiple target environments to deploy to.
There are multiple approaches that are in prevelance today to tackle this.
a) The laborious error-prone way of manually replacing the URLs/JNDI names for the new environments.
b) Usage of &lt;customize> and &lt;customizeWSDL> ant tasks.


But what will be really useful is a generic customization infrastructure that enables users to tokenize any arbitrary XML based artifact within the BPEL Project that includes, but is not limited to
a) The BPEL file
b) The WSDL file(s)
c) XSDs
d) XSLT
e) Toplink Mappings
The list goes on.


Overview


The above issues are addressed through a new customization ant task, namely customizeDocument. This task is very similar in usage and behaviour to the existing customization tasks shipped with the product.
The task allows token replacements of contents of any element or attribute that can be reached through an XPath expression. The only limitation of the task is within the tokenization of Processing Instructions within your XML based documents. For instance, the Jdeveloper generated XSL Map file contains a PI indicating the URLs of the source and target XSDs for the map. These URLs cannot be tokenized using this task, nor is this supported through any of the existing customization task.



Setup and Usage


To setup this task, perform the following steps.
a) Copy the customtasks.jar available at http://blogs.oracle.com/ramkumarMenon/gems/customtasks.jar into $ORACLE_HOME\integration\lib directory.
b) Open up ant-orabpel.xml in $ORACLE_HOME\bpel\utilities directory and paste the following piece of code into the file within the &lt;project> element.



&lt;path id="custom.tasks.class.path">
    &lt;pathelement location="&lt;absolute path to location of customtasks.jar>"/>
 &lt;/path>
 
  &lt;property name="custom.tasks.class.path" refid="custom.tasks.class.path"/>


&lt;taskdef name="customizeDocument" classname="com.collaxa.cube.ant.taskdefs.customize.document.CustomizeDocument">
    &lt;classpath>
      &lt;pathelement path="${custom.tasks.class.path}"/>
    &lt;/classpath>
&lt;/taskdef> 


The usage of this task is best illustrated through a simple running example.


You have a BPEL process project named ?CreatePurchaseOrder? that you have deployed to the ?test? environment. After you have performed all the necessary tests, you wish to promote this process to the production environment.
The project contains amongst others, the process WSDL named CreatePurchaseOrderService.wsdl that imports the local Process Schema named PurchaseOrder.xsd.


The WSDL also imports another WSDL named GeneralPOHeader.wsdl that is a shared WSDL amongst multiple BPEL Processes. This WSDL is hosted on the OHS on the ?test? environment. The CreatePurchaseOrderService.wsdl also imports an XSD named Addressing.xsd that is again hosted on the OHS on the test environment.
Moreover, each environment is associated with a specific support group ? that receives notification on faults and errors within processes deployed to that specific environment. The support team email is specified as a preference witihn the deployment descriptor of the BPEL process. [bpel.xml].


This is how a portion of CreatePurchaseOrderService.wsdl looks like.


&lt;?xml version = '1.0' encoding = 'UTF-8'?>
&lt;definitions name="PurchaseOrderService" targetNamespace="http://xmlns.oracle.com/PurchaseOrderService" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:client="http://xmlns.oracle.com/PurchaseOrderService" xmlns:plnk="http://schemas.xmlsoap.org/ws/2003/05/partner-link/">


        &lt;import namespace="http://xmlns.po.com/general" location="http://testsoa.server.com:7780/services/GeneralPOHeader.wsdl" />


        &lt;types>
  &lt;schema xmlns="http://www.w3.org/2001/XMLSchema">
   &lt;import namespace="http://xmlns.oracle.com/CreatePurchaseOrderService" schemaLocation="CreatePurchaseOrder.xsd"/>
   &lt;import namespace="http://xmlns.po.com/addressing" schemaLocation="http://testsoa.server.com:7780/schemas/Addressing.xsd"/>
  &lt;/schema>
 &lt;/types>


         . . . . .       
&lt;/definitions>


And the following is a snippet of bpel.xml.


&lt;?xml version = '1.0' encoding = 'UTF-8'?>
&lt;BPELSuitcase>
   &lt;BPELProcess id="CreatePurchaseOrderService" src="CreatePurchaseOrderService.bpel">
      &lt;partnerLinkBindings>
         &lt;partnerLinkBinding name="client">
            &lt;property name="wsdlLocation">CreatePurchaseOrderService.wsdl&lt;/property>
         &lt;/partnerLinkBinding>
      &lt;/partnerLinkBindings>
      &lt;preferences>
         &lt;property name="supportEmail" encryption="plaintext">test_support_group@clientcompany.com&lt;/property>
      &lt;/preferences>
   &lt;/BPELProcess>
&lt;/BPELSuitcase>


Note the lines highlighted in blue. The intent is to migrate these URLs and preferences to the values applicable for production. The corresponding values in the prod environment are
a) http://prodsoa.server.com:9876/services/GeneralPOHeader.wsdl
b) http://prodsoa.server.com:9876/schemas/Addressing.xsd
c) prod_support_group@clientcompany.com


Note: Steps 1 through 3 are only one of the different ways to manage multiple environments. You could have alternative mechanisms to manage multi-server deployments.


Step 1: Define multiple copies of ant-orabpel.properties, one for each environment - lets say as ant-orabpel_dev.properties, ant-orabpel_test.properties and ant-orabpel_prod.properties. Specify env specific parameters in each of these files.
Step 2: Define the following properties in the ant-orabpel_test.properties.
a) service_host=testsoa.server.com
b) service_ port = 7780
c) support_group_email=test_support_group@clientcompany.com
Define the following properties in the ant-orabpel_prod.properties.
a) service_ host=prodsoa.server.com
b) service_ port = 9876
c) support_group_email=prod_support_group@clientcompany.com
Step 3: Open the build.xml. Change the following line within it.
             &lt;property file="${bpel.home}/utilities/ant-orabpel.properties"/>
             So that it looks like this.
             &lt;property file="${bpel.home}/utilities/ant-orabpel_${deploy_env}.properties"/>
This enables us to pass in a command line argument named deploy_env to the build script and have it import the appropriate ant-orabpel.properties.
For e.g., When you invoke the build for the test environment by typing in ant ?Ddeploy_env=test, the build.xml automatically imports the ant-orabpel_test.properties.


Step 4: Open up the compile target block. We will now define the customizations on the process WSDL and the bpel.xml.


&lt;target name="compile">
        &lt;bpelc input="${process.dir}/bpel/bpel.xml" out="${process.dir}/output"
               rev="${rev}" home="${bpel.home}">
        &lt;/bpelc>
    &lt;/target>


Before the bpelc node, add the customizeDocument task.


&lt;target name=?compile?>
   &lt;customizeDocument inFile=?${process.dir}/bpel/CreatePurchaseOrderService.wsdl? outFile=?${process.dir}/bpel/CreatePurchaseOrderService.wsdl?>
&lt;/customizeDocument>
   . . . .
&lt;/target>
The above step indicates the intent to customize the CreatePurchaseOrderService.wsdl.
Next, we need to add the nested ?setTextContent? task that allows us to set the text of any attribute or element within the WSDL. Use the setTextContent task to specify the element or attribute to be updated, together with the value that it should be updated with.


&lt;target name=?compile?>
   &lt;customizeDocument inFile=?${process.dir}/bpel/CreatePurchaseOrderService.wsdl? outFile=?${process.dir}/bpel/CreatePurchaseOrderService.wsdl?>
   &lt;setTextContent select=?/wsdl:definitions/wsdl:import/@location? textContent=?http://${service_host}:${service_port}/services/GeneralPOHeader.wsdl?/>
&lt;/customizeDocument>
   . . . .
&lt;/target>


The ?select? attribute on the customizeDocument indicates a qualified XPath expression that points to the node within the process WSDL that needs to be customized. In this example, it points to the location attribute of the WSDL import. The ?textContent? attribute will hold the text that will be set within the node. In this example, it points to the absolute URL of the imported WSDL. You can also specify the tokens in the URL ? The build script will automatically subsitute them with the actual values when it is executed. For instance, if the build were executed with the ?Ddeploy_env=test or prod, the appropriate values of service_host and service_port will be substituted from the ant-orabpel_test/prod.properties.


Next, we shall customize the XSD import within the WSDL. For this, add one more setTextContent task within the customizeDocument task. The semantics of this is identical to the earlier step.


&lt;target name=?compile?>
   &lt;customizeDocument inFile=?${process.dir}/bpel/CreatePurchaseOrderService.wsdl? outFile=?${process.dir}/bpel/CreatePurchaseOrderService.wsdl?>
   &lt;setTextContent select=?/wsdl:definitions/wsdl:import/@location? textContent=?http://${service_host}:${service_port}/services/GeneralPOHeader.wsdl?/>
   &lt;setTextContent select=?/wsdl:definitions/wsdl:types/xsd:schema/xsd:import/@schemaLocation? textContent=?http://${service_host}:${service_port}/schemas/Addressing.xsd?/>
&lt;/customizeDocument>


   . . . .
&lt;/target>


The definition of the customization for the WSDL and XSD is almost complete. The missing step is the namespace URI mappings for the prefixes used within the select expressions. In this case, there are two prefixes that need to be mapped to a namespace URI.
a) The ?xsd? namespace prefix
b)  The ?wsdl? namespace prefix.
These prefixes are declared as properties within the same build file.
Declare two properties, one for each of the namespace URI, as below at the global level within the build.xml [i.e. as a child element of the &lt;project> element. The name of the properties should be  ?prefix.? Followed by the actual prefix. The value attribute contains the namespace URI for the prefix.


    &lt;property name="prefix.wsdl" value="http://schemas.xmlsoap.org/wsdl/"/>
    &lt;property name="prefix.xsd" value="http://www.w3.org/2001/XMLSchema"/>



Next, we specify the customization required for the bpel.xml.
Add another &lt;customizeDocument> task within the compile block. We need to add another one since we are customizing a different document.


&lt;project   ?..>
     . . . . .
     &lt;property name="prefix.wsdl" value="http://schemas.xmlsoap.org/wsdl/"/>
     &lt;property name="prefix.xsd" value="http://www.w3.org/2001/XMLSchema"/>


     &lt;target name=?compile?>
       &lt;customizeDocument inFile=?${process.dir}/bpel/CreatePurchaseOrderService.wsdl? outFile=?${process.dir}/bpel/CreatePurchaseOrderService.wsdl?>
      &lt;setTextContent select=?/wsdl:definitions/wsdl:import/@location? textContent=?http://${service_host}:${service_port}/services/GeneralPOHeader.wsdl?/>
     &lt;setTextContent select=?/wsdl:definitions/wsdl:types/xsd:schema/xsd:import/@schemaLocation? textContent=?http://${service_host}:${service_port}/schemas/Addressing.xsd?/>
&lt;/customizeDocument>


   &lt;customizeDocument inFile=?${process.dir}/bpel/bpel.xml? outFile=?${process.dir}/bpel/bpel.xml?>
     &lt;setTextContent select=?/BPELSuitcase/BPELProcess/preferences/property[@name=?supportEmail
?]? textContent=?${support_group_email}?/>
&lt;/customizeDocument>
   . . . .
&lt;/target>


Note that the select expression used for this customization does not need any namespace prefixes. This is attributed to the fact that bpel.xml by itself is an unqualified document.


This completes the customization features provided by this task.


Note that the customizeDocument task can be used to customize any bpel process project artifact, although not illustrated in this document.

Scanning text files using java.util.Scanner

ram.menon | Jul 2, 2008 12:01 -0600

I loved this tech-tip article from Sun.


http://java.sun.com/developer/JDCTechTips/2004/tt1201.html#1


 


 

Miscellaneous Ant tasks for Managing the BPEL Server

Ramkumar Menon | Jul 2, 2008 12:01 -0600

The serverAdmin ANT task

This news item describes a simple ant task that I had come up named serverAdmin that allows you to
  1. Selectively undeploy BPEL Processes
  2. Selectively purge BPEL process instances.
  3. Cancel and Recover Invocation Messages
  4. Cancel and Recover Callback Messages
  5. Get one or more domain configuration properties
  6. Set one or more domain configuration properties
  7. Fetch the latest domain log from the Server
  8. Create/delete a domain on the BPEL server

Setup and Usage

To setup this task, perform the following steps.
  1. Copy the admintasks.jar from http://blogs.oracle.com/ramkumarMenon/gems/admintasks.jar into $ORACLE_HOMEintegrationlib directory.
  2. Open up ant-orabpel.xml in $ORACLE_HOMEbpelutilities directory and paste the following piece of code into the file within the &lt;project> element.
&lt;path id="admin.tasks.class.path">
      &lt;pathelement location="${bpel.home}/../lib/admintasks.jar"/>
  &lt;/path>
  &lt;property name="admin.tasks.class.path" refid="admin.tasks.class.path"/>
  &lt;taskdef name="serverAdmin" classname="com.collaxa.cube.ant.taskdefs.ServerAdmin">
    &lt;classpath>
      &lt;pathelement path="${admin.tasks.class.path}"/>
    &lt;/classpath>
  &lt;/taskdef>
Illustrative Command Syntax
      &lt;serverAdmin  providerURL="opmn:ormi://&lt;hostName>:&lt;opmnRequestPort>:&lt;oc4jInstanceName>/orabpel" userName="oc4jadmin" password="&lt;pwdforoc4jadmin>">
       &lt;createDomain domainName="testDomain"/>
       &lt;deleteDomain domainName="testDomain"/>
       &lt;manageDomain domain="default">
              &lt;undeployProcesses select="BPELProcess.*"  type="all" revision="all"/>
              &lt;undeployProcesses select="TestXPath"  type="retired" revision="all"/>
             &lt;undeployProcesses select="Sample.*" type="all" revision="2.0"/>
             &lt;undeployProcesses select="SampleProcess" type="active" revision="1.0"/>
         &lt;!--example dateTime format "yyyy-MM-dd'T'HH:mm:ss Z"   "1994-11-05T08:15:30 -0800-->
         &lt;!--example date format "yyyy-MM-dd"   "1994-11-05"-->
          &lt;purgeInstances select="TestXPath" type="all" fromDateTime="2007-10-29T11:21:03 -0800" toDateTime="2007-10-31T13:21:03 -0800"/>
          &lt;purgeInstances select="TestJMS" type="closed.stale" fromDateTime="2007-10-29T11:21:03 -0800" toDateTime="2007-10-31T13:21:03 -0800"/>
             &lt;getProperties propertyNames="dspMinThreads,dspMaxThreads,syncMaxWaitTime"/>
              &lt;setProperty name="dspMinThreads" value="5"/>
              &lt;cancelInvocations select="PurchaseOrderProcess" revision="1.0" fromDateTime="2007-11-05T17:45:56 -0800" toDateTime="2007-11-05T17:45:58 -0800"/>
              &lt;recoverInvocations select="OrderCreationProcess" revision="1.0" fromDateTime="2007-11-05T17:21:10 -0800" toDateTime="2007-11-05T17:21:15 -0800"/>
              &lt;cancelCallbacks select="OrderCreationProcess" revision="2.0" fromDate="2007-11-05" toDate="2007-11-06"/>
              &lt;recoverCallbacks select="OrdeUpdateProcess" revision="2.0" fromDate="2007-11-05" toDate="2007-11-06"/>
              &lt;printLog outFile="D:\\temp\\latest_domain.log" lineCount="2000"/>
          &lt;purgeInstances select="all" type="closed.stale" fromDate="2007-10-29" toDate="2007-10-31"/>
          &lt;purgeInstances fromDate="2007-10-29" toDate="2007-10-31"/>
          &lt;purgeInstances select="SampleProcess" type="closed.completed"  toDateTime="2007-10-31"/>
          &lt;purgeInstances select="SampleProcess2" fromDateTime="2007-10-29T11:21:03 -0800"/>
          &lt;purgeInstances select="TestXPath" type="closed.stale" fromDate="2007-10-29" />
         &lt;purgeInstances/>
        &lt;/manageDomain>
      &lt;/serverAdmin>
   

Short Description

UnDeployProcesses subtask:-
The select argument for "undeployProcesses" subtask accepts both exact process names, as well as java regex expressions. For instance, the above example shows undeployment for all processes whose name starts with the string "BPELProcess". All arguments are mandatory.If you wish to specify "all" values for one or more arguments, specify them in the format &lt;argName>="all". For instance, you can specify type="all" or revision="all" or select="all" to indicate selection of all process states, all revisions or all processes.
PurgeInstances subtask :-
If fromDateTime/fromDate is omitted, it purges every matching instance upto and including the "toDateTime/toDate". Note that in case you specify a date as opposed to a dateTime, the time is defaulted to the beginning of the date. [i.e. 12 AM] If the "toDateTime/toDate" is omitted, it purges every matching instance till the present. If both are specified, the task purges all matching instances including and between the given timespan. If both are omitted, the task purges all matching instances irrespective of the time. The dateTime has to be specified in the format given in the above example. The "type" attribute, if omitted, is equivalent to "all". The other values are
  1. closed.aborted
  2. closed.cancelled
  3. closed.completed
  4. closed.faulted
  5. closed.stale
  6. closed.pendingCancel
  7. initiated
  8. open.running
  9. open.faulted
  10. open.suspended
Each serverAdmin task can be used to administer a different BPEL runtime. Within each serverAdmin, you can provide multiple &lt;manageDomain> tasks, one for each domain to purge and undeploy processes and instances in each domain.
Print Log Subtask
Prints the domain log
SetProperty subtask
Sets a domain property. e.g. dspMaxThreads
GetProperties subtask
Gets the property values for the given set of domain properties.[comma separated]
Recovery/Cancellation/Deletion of Invocation or callback subtasks
Recovers, deletes or cancels invocations/callback. Arguments to this task are the processName, revision, the from/to date or dateTimes in the given format as specified in the example. [yyyy-MM-dd'T'HH:mm:ss Z or yyyy-MM-dd]
Create Domain subtask
Creates a domain with the given name.
Delete Domain subtask
Deletes the domain with the given name. Notes: Ensure that BPEL_HOME and ORACLE_HOME are properly set. &lt;p/> Sample Build File
&lt;?xml version="1.0" encoding="iso-8859-1"?>
&lt;project name="ServerAdminBuild" default="deploy" basedir=".">
    &lt;!--=============================-->
    &lt;!-- Process deployment targets  -->
    &lt;!--=============================-->
    &lt;!-- Set bpel.home from developer prompt's environment variable BPEL_HOME -->
    &lt;condition property="bpel.home" value="${env.BPEL_HOME}">
        &lt;available file="${env.BPEL_HOME}/utilities/ant-orabpel.xml"/>
    &lt;/condition>
    &lt;!-- If bpel.home is not yet using env.BPEL_HOME, set it for JDev -->
    &lt;property name="bpel.home" value="${oracle.home}/integration/bpel"/>
    &lt;!-- First override from build.properties in process.dir, if available -->
    &lt;property file="${process.dir}/build.properties"/>
    &lt;!-- import custom ant tasks for the BPEL PM -->
    &lt;import file="${bpel.home}/utilities/ant-orabpel.xml"/>
    &lt;target name="adminTasks">
      &lt;serverAdmin  providerURL="opmn:ormi://server.host.com:6004:oc4j_soa/orabpel" userName="oc4jadmin" password="welcome1">
        &lt;manageDomain domain="default">
              &lt;undeployProcesses select="BPELProcess.*"  type="all" revision="all"/>
             &lt;getProperties propertyNames="dspMinThreads"/>
              &lt;setProperty name="dspMinThreads" value="5"/>
              &lt;cancelInvocations select="PurchaseOrderProcess" revision="1.0" fromDateTime="2007-11-05T17:45:56 -0800" toDateTime="2007-11-05T17:45:58 -0800"/>
              &lt;recoverlInvocations select="OrderCreationProcess" revision="1.0" fromDateTime="2007-11-05T17:21:10 -0800" toDateTime="2007-11-05T17:21:15 -0800"/>
              &lt;cancelCallbacks select="OrderCreationProcess" revision="2.0" fromDate="2007-11-05" toDate="2007-11-06"/>
              &lt;recoverCallbacks select="OrdeUpdateProcess" revision="2.0" fromDate="2007-11-05" toDate="2007-11-06"/>
              &lt;printLog outFile="D:\\temp\\latest_domain.log" lineCount="2000"/>
              &lt;undeployProcesses select="TestXPath"  type="retired" revision="all"/>
             &lt;undeployProcesses select="Sample.*" type="all" revision="2.0"/>
             &lt;undeployProcesses select="SampleProcess" type="active" revision="1.0"/>
         &lt;!--example dateTime format "yyyy-MM-dd'T'HH:mm:ss Z"   "1994-11-05T08:15:30 -0800-->
         &lt;!--example date format "yyyy-MM-dd"   "1994-11-05"-->
          &lt;purgeInstances select="TestXPath" type="all" fromDateTime="2007-10-29T11:21:03 -0800" toDateTime="2007-10-31T13:21:03 -0800"/>
          &lt;purgeInstances select="TestJMS" type="closed.stale" fromDateTime="2007-10-29T11:21:03 -0800" toDateTime="2007-10-31T13:21:03 -0800"/>
          &lt;purgeInstances select="all" type="closed.stale" fromDate="2007-10-29" toDate="2007-10-31"/>
          &lt;purgeInstances fromDate="2007-10-29" toDate="2007-10-31"/>
          &lt;purgeInstances select="SampleProcess" type="closed.completed"  toDateTime="2007-10-31"/>
          &lt;purgeInstances select="SampleProcess2" fromDateTime="2007-10-29T11:21:03 -0800"/>
          &lt;purgeInstances select="TestXPath" type="closed.stale" fromDate="2007-10-29" />
         &lt;purgeInstances/>
        &lt;/manageDomain>
      &lt;/serverAdmin>
    &lt;/target>
&lt;/project>

XML is Ten!

ram.menon | Jul 2, 2008 12:00 -0600

XML 10th anniversary

Stripping namespaces using XSLT

ram.menon | Jul 2, 2008 12:00 -0600

A common question often asked is "I have a namespace qualified XML document -
I need to remove all xmlns attributes from the same".



Here is an XSLT that you can use to strip all namespaces from your document.






  1. &lt;xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  
  2. exclude-result-prefixes="xsl">  
  3.   
  4.  &lt;xsl:template match="*">  
  5.     &lt;xsl:element name="{local-name()}">  
  6.       &lt;xsl:apply-templates select="@* | node()"/>  
  7.     &lt;/xsl:element>  
  8.   &lt;/xsl:template>  
  9.   &lt;xsl:template match="@* | text()">  
  10.     &lt;xsl:copy/>  
  11.   &lt;/xsl:template>  
  12. &lt;/xsl:stylesheet>
     

Reading only headers in an File/FTP Adapter and skipping the payload

ram.menon | Jul 2, 2008 12:00 -0600

At times, you might have a requirement where you only need to read the file headers[file name and directory] and ignore the payload while using an inbound file/ftp adapter.


For this purpose, you need to add UseHeaders="true" on the &lt;jca:operation> in the adapter wsdl.


This ensures that the payload is skipped while reading the file.


Then you can follow the usual steps to read the headers [through the inputHeaderVariable on the receive activity to retrieve the headers.


 

Recursively replacing a string in all files in a directory [Linux]

ram.menon | Jul 2, 2008 12:00 -0600

My colleague provided me an extremely useful script that will replace a source string with a target string in all files in the current directory and its subdirectories.

find . -type f | xargs perl -pi~ -e 's/oldtext/newtext/g;'

Replace "oldtext" with the source string, and "newtext" with the target string.


During the replacement, all original files are backed up with a  "~" suffix.

Dynamically updating bpel.xml properties within your BPEL Process

Ramkumar Menon | Jul 2, 2008 12:00 -0600

There are different properties that you could actually update in your process descriptor. They are a) The Configuration properties b) The preference properties c) The partnerlink properties. These properties are illustrated below.






  1. &lt;BPELSuitcase>  
  2.   &lt;BPELProcess id="UpdatePropertyProcess" src="UpdatePropertyProcess.bpel">  
  3.     &lt;partnerLinkBindings>  
  4.       &lt;partnerLinkBinding name="client">  
  5.         &lt;property name="wsdlLocation">  
  6.           UpdatePropertyProcess.wsdl   
  7.         &lt;/property>  
  8.         &lt;property name="partnerlinkProperty1">  
  9.           valueOfPartnerlinkProperty 1   
  10.         &lt;/property>  
  11.       &lt;/partnerLinkBinding>  
  12.     &lt;/partnerLinkBindings>  
  13.      &lt;preferences>  
  14.        &lt;property name="preferenceProperty1" encryption="plaintext">  
  15.          valueOfPreferenceProperty1   
  16.        &lt;/property>  
  17.      &lt;/preferences>  
  18.      &lt;configurations>  
  19.       &lt;property name="configProperty1" encryption="plaintext">  
  20.         valueOfConfigProperty1   
  21.       &lt;/property>  
  22.       &lt;/configurations>  
  23.    &lt;/BPELProcess>  
  24. &lt;/BPELSuitcase>  

To update these properties dynamically within the BPEL Process, you can use a Java embedding within the process, as shown below.






  1.   
  2. try {   
  3.   getLocator().lookupProcess ("UpdatePropertyProcess").   
  4.                  getDescriptor ().   
  5.                   getConfigurations().   
  6.                     setPropertyValue ("configProperty1",   
  7.                      "newValueOfConfigPropertyValue1");   
  8.   getLocator().lookupProcess ("UpdatePropertyProcess").   
  9.                   getDescriptor ().   
  10.                    getPreferences().   
  11.                     setPropertyValue ("preferenceProperty1",   
  12.                       "newValueOfPreferenceProperty1" );   
  13.   getLocator().lookupProcess ("UpdatePropertyProcess").   
  14.                   getDescriptor ().   
  15.                    getPartnerLinkBindings().   
  16.                      getPartnerLinkBinding ("client").   
  17.                        setPropertyValue ("partnerlinkProperty1",   
  18.                        "newValueOfPartnerlinkProperty 1");   
  19.  }   
  20.  catch(Throwable ex) {   
  21.  }   
  22.    

Click here to download the Sample BPEL Process project.

Obtaining the Execution Times of BPEL Processes over a period of time

Ramkumar Menon | Jul 2, 2008 12:00 -0600

Here is a simple BPEL Query that will get you the statistics of execution times of all BPEL Process instances over a period of time. The stats include the number of invocations, minimum, maximum and average time of execution.






  1. SELECT process_id,count(*) as num_invocations,   
  2.   max(((EXTRACT(HOUR FROM MODIFY_DATE) - extract(hour from creation_date)) *3600 +   
  3.       (EXTRACT(MINUTE FROM MODIFY_DATE) - extract(MINUTE from creation_date)) *60 +   
  4.       (EXTRACT(SECOND FROM MODIFY_DATE) - extract(SECOND from creation_date))) *1000)   
  5.   as Max_Time ,   
  6.   
  7.   min(((EXTRACT(HOUR FROM MODIFY_DATE) - extract(hour from creation_date)) *3600 +   
  8.      (EXTRACT(MINUTE FROM MODIFY_DATE) - extract(MINUTE from creation_date)) *60 +   
  9.      (EXTRACT(SECOND FROM MODIFY_DATE) - extract(SECOND from creation_date))) *1000)   
  10.   as Min_Time ,   
  11.   
  12.   avg(((EXTRACT(HOUR FROM MODIFY_DATE) - extract(hour from creation_date)) *3600 +   
  13.      (EXTRACT(MINUTE FROM MODIFY_DATE) - extract(MINUTE from creation_date)) *60 +   
  14.      (EXTRACT(SECOND FROM MODIFY_DATE) - extract(SECOND from creation_date))) *1000)   
  15.   as Avg_Time   
  16.   
  17.   FROM CUBE_INSTANCE   
  18.     WHERE  
  19.       state &lt;> 9   
  20.         and  
  21.       creation_date > '09-APR-08 09.00.00.000000000 AM'  
  22.         and  
  23.       creation_date &lt; '09-APR-08 01.00.00.000000000 PM'  
  24.   
  25.       group by process_id order by process_id asc  
SELECT process_id,count(*) as num_invocations, max(((EXTRACT(HOUR FROM MODIFY_DATE) - extract(hour from creation_date)) *3600 + (EXTRACT(MINUTE FROM MODIFY_DATE) - extract(MINUTE from creation_date)) *60 + (EXTRACT(SECOND FROM MODIFY_DATE) - extract(SECOND from creation_date))) *1000) as Max_Time , min(((EXTRACT(HOUR FROM MODIFY_DATE) - extract(hour from creation_date)) *3600 + (EXTRACT(MINUTE FROM MODIFY_DATE) - extract(MINUTE from creation_date)) *60 + (EXTRACT(SECOND FROM MODIFY_DATE) - extract(SECOND from creation_date))) *1000) as Min_Time , avg(((EXTRACT(HOUR FROM MODIFY_DATE) - extract(hour from creation_date)) *3600 + (EXTRACT(MINUTE FROM MODIFY_DATE) - extract(MINUTE from creation_date)) *60 + (EXTRACT(SECOND FROM MODIFY_DATE) - extract(SECOND from creation_date))) *1000) as Avg_Time FROM CUBE_INSTANCE WHERE state &lt;> 9 and creation_date > '09-APR-08 09.00.00.000000000 AM' and creation_date &lt; '09-APR-08 01.00.00.000000000 PM' group by process_id order by process_id asc 

In this query, you need to replace the sample date and time values with the values that you wish to use and report. Here is another query that gives the execution times of all BPEL instances over the given time period.






  1.   
  2. select bpel_process_name as process_id,   
  3.        instance_key as cikey,   
  4.        trunc(creation_date),   
  5.        eval_time as exec_time   
  6. from bpel_process_instances   
  7. where state &lt;> 9 and  
  8.       creation_date > '11-APR-08 09.00.00.000000000 AM' and  
  9.       creation_date &lt; '11-APR-08 05.00.00.420000000 PM'  
  10. order by process_id asc, exec_time desc  
  11.     
select bpel_process_name as process_id, instance_key as cikey, trunc(creation_date), eval_time as exec_time from bpel_process_instances where state &lt;> 9 and creation_date > '11-APR-08 09.00.00.000000000 AM' and creation_date &lt; '11-APR-08 05.00.00.420000000 PM' order by process_id asc, exec_time desc 

In this query, you need to replace the sample date and time values with the values that you wish to use and report. Note that the above query shall give you the execution times for a particular day. Take a look at the comments on this blog entry to see a modified example that uses the "day" as well to obtain stats that span across multiple days.

Reusing code snippets in JDeveloper

Ramkumar Menon | Jul 2, 2008 12:00 -0600

Here is one simple but useful thing that I've been too lazy to make use of, and had overlooked.


JDeveloper's component palette has a page named "Code Snippets". You could actually add frequently re-used code snippets and save them into the "code snippets" section.



Once you click on "Add component", you can give the snippet a name, for e.g. "Assign WS-Addressing Headers" and copy the snippet from your source code  to the given text area.


You can now re-use the code snippet by dragging and dropping the component from the code snippet palette onto the source view of any file that you open in JDeveloper.


Similarly, you can also add your own Pages to the Component palette, to capture Snippets for diferent cateogies of code [for instnace, BPEL,XML, XSD, XSLT etc].



Now you can specify the Page Name and specify the type  - "snippet", "java" etc.


 


 



 


Now you can add new code snippets to the new Palette Page that you created.


 

Viewing Audits for Stale instances

Ramkumar Menon | Jul 2, 2008 12:00 -0600

Wondering what to do if you wished to view the audit trail for stale instances?


Well, you could make use of the View Raw XML feature in the BPEL Console.


 


 

Interesting XSLT Recipe - Computing line totals

Ramkumar Menon | Jul 2, 2008 12:00 -0600

You might have run into a requirement where you need to compute the total value of all items in a purchase order. Consider the PO XML shown below.





  1.   
  2. &lt;?xml version="1.0" encoding="UTF-8" ?>  
  3. &lt;po xmlns="http://www.example.org">  
  4.    &lt;Items>  
  5.       &lt;item>  
  6.          &lt;price>1&lt;/price>  
  7.          &lt;qty>2&lt;/qty>  
  8.       &lt;/item>  
  9.       &lt;item>  
  10.          &lt;price>3&lt;/price>  
  11.          &lt;qty>4&lt;/qty>  
  12.       &lt;/item>  
  13.       &lt;item>  
  14.          &lt;price>5&lt;/price>  
  15.          &lt;qty>6&lt;/qty>  
  16.       &lt;/item>  
  17.    &lt;/Items>  
  18. &lt;/po>  
You might want to compute the total value of all items in the purchase Order. For computing this, you would need to multiply the price and qty for each item, and add them up. In XSLT 1.0, I guess the way to do this would be to recursively invoke a template that computes the sum total. In XSLT 2.0, this can be done in a very elegant single expression.




  1.   
  2.   &lt;xsl:variable name="itemVar" select="/tns:po/tns:Items/tns:item"/>                
  3.   &lt;xsl:template match="/">  
  4.     &lt;tns:poSummary>  
  5.       &lt;tns:totalValue>&lt;xsl:value-of select="sum(for $i in $itemVar return ($i/tns:price * $i/tns:qty))"/>&lt;/tns:totalValue>  
  6.     &lt;/tns:poSummary>  
  7.   &lt;/xsl:template>  
  8. &lt;/xsl:stylesheet>