Tuesday, September 30, 2008

Specify Time in onAlarm

What forced me into it?

This was in a onAlarm activity that I wanted to specify the duration.
This was to set an alarm and retry interval in BPEL.

I saw some documentation providing me incorrect info, and I did have a lot of BPEL instances go to invalid state once they hit the onAlarm.
Now I can not go wrong, I have this post to help me.

So what is the notation?

Well this is the notation as in 10.1.3.3 MLR 5
P1Y1M1DT1H1M1S

Explaination!

This is straight forward.

Duration is
1 Year
1 Month
1 Day

This is for the P1Y1M1D part of the expression

Duration is
1 Hour
1 Minute
1 Second

This is for the T1H1M1S part of the expression

Links I liked!


To be frank I did a few trial and errors in BPEL before I was sure that the doc was not correct.
And I could not Google this up in the first 2 pages I was looking at.
So here is the post that has it. Now I know where to look. I hope it helps others as well.

Whatz with the default Services TaskManager and TaskActionHandler

Why I wanted to write this?

When I first started to use BPEL console, I saw 2 service that were already deployed.
That did not make sense to me, and I wanted a clean environment.
I had not deployed anything. And here I see 2 services already deployed.
I wanted to undeploy those, but I decided to find out why.
Then I started to ask question to myself as to why these were there.


What is this TaskManager Service for?

TaskManager service is basically for managing the tasks.
Initiate Task
Update Task
Complete Task

Also does a few things like send callback for
Results for the task and
on expire of task

Basically operations on taks are performed through this service.

What is this TaskActionHandler for?

Task Action Handler as the name states handles actions.
Put items to user's worklist
Get response from the users
Maintain timer events

If you are wondering what timer events are, they are task expiration, task reminder and other such related timer based events.

Links that I liked!

The link you would like to read are
http://www.oracle.com/technology/products/ias/bpel/pdf/orabpel-Tutorial6-TaskManagerServiceTutorial.pdf

Monday, September 29, 2008

Undeploy BPEL with JAVA

What forced me into it?

Undeploying BPEL process from BPEL Console is a nightmare especially when you have many environments. And with each test cycle, the environment is refreshed and recreated.
It takes hell a lot of time and AS admin time to get this. (Well these admin guy are always short of time with their hand full of work)
Best option, automate the process. So I have small piece of code that I have pulled.

You will be surprised how short this is?

package bpelUndeployment;

import java.util.Properties;

import com.oracle.bpel.client.BPELProcessId;
import com.oracle.bpel.client.IBPELDomainHandle;
import com.oracle.bpel.client.Locator;
import com.oracle.bpel.client.ServerException;

/**
* @author Kalidass Mookkaiah
*/
public class UnDeployBPELProcess {
public static void main(String[] args) throws ServerException {

//Properties with BPEL server connection information
Properties props = new Properties();
props.put("orabpel.platform", "ias_10g");
props.put("java.naming.factory.initial", "com.evermind.server.rmi.RMIInitialContextFactory");
props.put("java.naming.provider.url", "opmn:ormi://hostname:6008:home/orabpel");
props.put("java.naming.security.principal", "oc4jadmin");
props.put("java.naming.security.credentials", "oc4jadmin");
props.put("dedicated.connection","true");

//Get a locator in default domain
Locator locator = new Locator("default","welcome1",props);


//Get a handle to the domain
IBPELDomainHandle iBPELDomainHandle = locator.lookupDomain();

//Undeploy this process from default domain
iBPELDomainHandle.undeployProcess(new BPELProcessId("default","MyUndeployedBPELProcess"));
}
}


Explanation!!!

If you do not know that the properties mean, see this post
http://oraclebpelindepth.blogspot.com/2008/08/bpel-context-properties-for-client-api.html

Well if you have read the above post then you know what the Properties are for.
In one word it is values to connect to the AS server.

Use the locator to get a handle to the domain.
Use this handle to perform undeployment.
Here I have used the BPELProcessId class to identify the domain and ProcessName.
The ProcessName should match exactly.

What about versioned BPEL process?

Help your self.
But what I can hint you with is this.
The Class BPELProcessId has overloaded constructor.
3 of them.
One takes domain and processID
Other takes domain, processID and revision Tag.
There is another one tooo with domain, processID, revision Tag and process GUID.

Happy hunting with the overloaded constructors.
And don't forget to run the code ;)

What Jars to include?

And if you are looking to find the jars to include to run this see the link
http://oraclebpelindepth.blogspot.com/2008/09/jars-for-bpel-java-api.html

JARs for BPEL Java API

What forced me into it?

To get the BPEL Java API working the first thing to do is to have the java class be available for you to code.
And to get these classes into your work space, what else but include the libs.
Every time I do this I Google. I am either very bad at Google or there are not many people who write about this.
Now I want this as a reference for myself, and also for those who want the list.

What are the jars that I included? And why in that Order?

The first jar that I included was orabpel.jar
For what other reason that the fact that it has what I need.
And what I need to start is Locator.
To be more specific I need com.oracle.bpel.client.Locator class

Is this jar enough?

Well if you think this is enough then it is time for you to run and see for yourself.
Do not be surprised to get error that looks like this
Exception in thread "main" java.lang.NoClassDefFoundError: javax/ejb/EJBException

Make this error disappear?

How else but include the jar that has this class. And the jar is ejb.jar
I think now it is time to run this and see for your self.

Whatz the next error?

Well you have gussed it right. There is another error that comes up.
This time round it looks like this
Exception in thread "main" java.lang.NoClassDefFoundError: com/collaxa/common/util/NonSyncPrintWriter
at com.oracle.bpel.client.util.ExceptionUtils.handleServerException(ExceptionUtils.java:82)
at com.oracle.bpel.client.Locator.getFinder(Locator.java:962)
.......

Caused by: java.lang.NoClassDefFoundError: com/collaxa/common/util/NonSyncPrintWriter
at com.oracle.bpel.client.util.BeanRegistry.lookupFinderBean(BeanRegistry.java:351)
at com.oracle.bpel.client.Locator.getFinder(Locator.java:956)

...

Make this error disappear? And next error appears.

How else but include the jar that has this class. And the jar is orabpel-common.jar
You know what time this is. Yes run time. So letz see te next error.

The next error you might be seeing is

Exception in thread "main" java.lang.Exception: Failed to create "ejb/collaxa/system/FinderBean" bean; exception reported is: "javax.naming.NoInitialContextException: Cannot instantiate class: com.evermind.server.rmi.RMIInitialContextFactory [Root exception is java.lang.ClassNotFoundException: com.evermind.server.rmi.RMIInitialContextFactory]
....

Caused by: java.lang.ClassNotFoundException: com.evermind.server.rmi.RMIInitialContextFactory
...


Make this error disappear? And...

This time round I include the jar oc4j-internal.jar

The next error you might be seeing is
Exception in thread "main" java.lang.NoClassDefFoundError: oracle/ias/opmn/optic/OpticException
...
Caused by: java.lang.NoClassDefFoundError: oracle/ias/opmn/optic/OpticException
...


Make this error disappear? And...

This time round I include the jar optic.jar

The next error you might be seeing is nothing....

What was the code that I ran?

There might be other jars that need to be included based on what is that you want the Java do perfom.
But the java code that I ran is for undeploying BPEL process.
The code is in the post
http://oraclebpelindepth.blogspot.com/2008/09/undeploy-bpel-with-java.html

Thursday, September 25, 2008

FTP file name: Both Get fileName and dynamic Put filename

How did it make into my workspace?

What else but a requirement.
A file is dynamically created based on the web service message received.
The file that needs to be FTPed has a name, that is dynamic.
The file name is one of the fields in the message received.
Well this was about Put.

How the hell did Get file name come to my workspace?

Well it was not a requirement in my project. But was a help that I did for a friend.
This person wanted to read files from a server.
And drop this off to another server after some enrichment's to the content.
And wanted the Get and Put file names to match.

So this adds a new thing of getting the filename of the file that was read from FTP directory.

How does it work?

If you have created FTP Get and Puts you should see
ftpAdapterInboundHeader.wsdl and ftpAdapterOutboundHeader.wsdl file in your workspace.

These are the 2 key file to get this cracking.
Both of these have a element called fileName.

What to do with this element?

You have to either play with these elements to get the work done.
To play with these elements you first need to create a variable from the wsdl.

How to get the file name of the get file?

Just use the variable that you have created from the ftpAdapterInboundHeader.wsdl.
Read the fileName element. Yes it is that easy.

How to assign file name to put file?

Well nothing different from the above one.
But this time round you need not read but assign value to the fileName element.
The variable that you have created from the ftpAdapterOutboundHeader.wsdl, use that.

Assign the file name to the fileName element in this variable.
Thatz it. You have done it.

What Does it do in the background?

What you are trying to do here is either read or write to the FTP Adapter Header Message.

For Inbound messages the header has the fileName, FTP server and FTP port.
For Outbound message the header has the fileName.

You can play with these.
From Inbound message you can read the values.
For Outbound if you populate these values the Adapter will behave accordingly.

Monday, September 22, 2008

The requested URL /integration/services/deploy/deployHttpClientProcess.jsp was not found on this server

How the hell did I get it?

I tried deploying BPEL process from automated deployment script that I have got.
This script uses ANT process to do the job.
What I see is the below error.


--------------------- Error Message Start ------------------------
BUILD FAILED

/nas/orasoft/orbit/oracle/soasuite_pc_deploy_v1.2/bpel_deploy/build.xml:223: The following error occurred while executing this line:
/nas/orasoft/orbit/oracle/soasuite_pc_deploy_v1.2/bpel_deploy/src/ErrorLogging/build.xml:79: A problem occured while connecting to server "orbit" using port "7777":
<HTML><HEAD>
<TITLE>404 Not Found</TITLE>
</HEAD><BODY>

Not Found
The requested URL /integration/services/deploy/deployHttpClientProcess.jsp was not found on this server.
<HR>
<ADDRESS>Oracle-Application-Server-10g/10.1.3.1.0 Oracle-HTTP-Server Server at orbit Port 7777</ADDRESS>
</BODY></HTML>
--------------------- Error Message End ------------------------


Where did I find the solution?

Well first I read a few posts in oracle forum.
The post that helped me solve or at least pointed towards a solution was
http://kr.forums.oracle.com/forums/thread.jspa?threadID=631670

Healthy Green hw_service!!

My hw_services was working and was green in colour.
Well that meant that it was healthy.
But later I found it was not configured for deployment (read to find where I found the jsp)

Next I wanted to find the directory. /integration/services/deploy/deployHttpClientProcess.jsp
I could not. So I started a search to find it! And yes I did find it. Not as a directory but as a configuration in Active Servlets/JSPs.

Where did I find /integration/services/deploy/deployHttpClientProcess.jsp?

I tried to find this in the hw_services from EM (enterprise manager). And yes I did.
Thanks to the post there.

These are the steps that I followed.
Go to EM.
From the home page click the + sign of OC4J instance used.
Click hw_services to open up the properties.
Click the deploy Web Module.
You will find "deployHttpClientProcess.jsp" under the Active Servlets/JSPs.


That is where I found this guy registered.

What happened to deployment from JDEV?

The deployment from JDev went with out any issues.
This issues was with ANT deployment only.

What I found and how I solved it?

Before I tried to solve the issue. I wanted to find this. And I did as above.

My DEV ENV was working so I wanted to see that before I did any thing else.
I found this configuration present in my DEV environment.
I found this missing in my SYS TEST ENV and that had this above error.

What I found was "deployHttpClientProcess.jsp" was not not present in the Active Servlets/JSPs list at all. It was blank in DEV.

The very next thing I did was to stop and start hw_services.
And when I did the deployment went smoothly.
And the "deployHttpClientProcess.jsp" came back to the Active Servlets/JSPs.

Sunday, September 21, 2008

Arrays in BPEL

Why it made itself into my Project?

What else but FlowN. That was the culprit.
FlowN will use index to create separate flows for each of the parallel flows using the index variable.
And the index was used to read data from where else but array.

How to create a array?

Actually it is not as complex as I originally though it to be.
Array in XML can be any element that can store multiple repetition of some data.

For example if A represents sequence of element B then A can be used as array for B.

What is that I am going to show you below?

In short this is what I am attempting to show you.

1. Add elements into the array using BPEL append. 
Most of the cases people already have a array from the source system.
Use this when you want to build your ow array i the fly.

2. Build the XPath 
If you have decided to use array then build a dynamic XPath.
Store that in a temporary variable.
And use that XPath temporary variable while reading elements from the array.
If you ask me what type of variable, I prefer String type.

2. Read data from array 
Just as plain as use the temporary XPath variable and read data from the array element.
Just like saying A[X] i ay other lang. Here A is the array and X is the temporary XPath.
Movig in rounds to read like A[1], A[2] etc.

How to add value into the array?

What else but use append. I you have not seen this, it looks like a + in the assign activity. Just see an assign.

Behind the scenes the bpel code looks like:

<assign name="Assign_CDM_Contents_Append">
<bpelx:append>
<bpelx:from variable="Variable_Add_Array_Element"
query="/ns1:ABC"/>
<bpelx:to variable="Variable_Array"
part="payload"
query="/ns1:ArrayList"/>
</bpelx:append>
</assign>


Here Variable_Array is the variable to hold the array of Variable_Add_Array_Element
I am trying to add elements into the Array (Variable_Array).
I am doing this by appending the elements to be end of it.

Whatz with XPath?

There are 2 options to read data from XML arrays.
One is to use another XPath variable to build the dynamic XPath query.
Second option is to not use a new variable but dynamically insert the XPath in the bpws:getVariableData()

I prefer the first option as it gives a little clarity over the second option.

Why Dynamically build XPath?

Well what ever the case be you need to build XPath dynamically.
But why? Just to use the changing index into the Array.

How to Read data?

If you have a running index over either a flowN or a while loop that does this for you, either way you need the index to access the array.

Now the way to read is through dynamic XPath. That need to be built.
Here I have used option 1.

The below code shows how to use assign to build the dynamic XPath.

<assign name="Assign_XPath_For_Array">
<copy>
<from expression="concat('/ns1:ArrayList/ns2:ArrayElem[',bpws:getVariableData('Variable_Index_Counter'),']') "/>
<to variable="Variable_Xpath"/>
</copy>
</assing>


Note have used [index] to represent index element here in the array.
Here Variable_Xpath acts as a temporary string variable that holds the intermediate Xpath as string.

Now use this XPath string Variable while reading array index elements.
This would look like
<assign name="Assign_Read_Array">
<copy>
<from expression="bpws:getVariableData('Variable_Array','payload',bpws:getVariableData('Variable_Xpath'))"/>
<to variable="Variable_Read_Array_Element"
query="/ns1: ABC"/>
</copy>
</assign>


How to do with out another variable?

Just do not use the new variable. Build your XPath dynamically right in the bpws:getVariableData() 3rd parameter.

Tuesday, September 16, 2008

How to perform manual copy of bpel code for faster development!! With out issues

What forced it?

Well as part of the BPEL development I had used a set of Enterprise Integration Patterns that each particular type of BPEL scope code should follow.

When each of those BPEL processes are created, they follow the same Pattern, a lot of code looked similar. But are not the same.

That where the catch was!!
SIMILAR but not the SAME!!!

What I wanted to do?

Well what I originally planned to do was to copy some of the code from one of the already built BPEL scope onto the new one I was building.
And I would be seamlessly able to reuse the stuff.

What that meant from code perspective was, I would like a scope from another BPEL code into my current BPEL code.
Well originally I though it was a brilliant idea. And finally it did turn up that way.
But it was damn hard till I figured out the trick. Not a trick actually but divide and conquer.

What are the problems I faced?

The first time I did that. I saw ERROR. Actually a brilliant one.
"XML parsing failed"

Nothing else. How the hell is that supposed to help me?

How did I make it work?

Well that is when I put my experimenting hand into the BPEL xml code.

The first thing you need to worry about are the non-declared variables that have come over as part of the copy process.
Resolution : declare them.

The second thing would be the name space that are new or namespaces that already exist.
Resolution : Either create the new namespace or when appropriate use the old namespace.

The third and the best helping hand is. Comment out groups of code. Leave a logical complete unit and compile. Follow the above steps. Fix apparent errors are they come.
Then go on to the next logical unit and repeat till finally you have completed the full Scope.

Just be aware of the Catch, if you have them. I hope you will as part of the scope. Copy them as well.

Why I like this better than drag and drop?

Some people advice not to do that but I prefer this better than the GUI to build.
If you ask me why? I would say this is damn faster to build.
And that is what brings me back into the BPEL xml code.

And the second reason is the way JDeveloper behaves.
Some times it does weired thing. Does not save thing that I have changed.
Some times goes back to the old code after I save.
It catches you by surprise some times as you are damn sure that you made the change that does not exist.

What is it with templates?

Some people recommend templates but they give complete BPEL template.
Not scopes to copy. But templates are good options if the BPEL processes are damn alike.

Create Empty Tag in Tranformations

What forced me into it?

The message received from a web service had less data than what the XML (cannonical Data model needed) had. Down the line there were conditions that check the value of a element in the XML. These could be empty or some XYZ value.

Now the transformation had to map these value onto the XML, but if I did not map them the XML will miss the elements.

What I wanted to see?

What I wanted to see was, I should be able to perform the transformation from the Input Variable to the Output Variable.

Those elements that were required should not be lost.
These elements should be as empty tags in the Output Variable.

What did I get?

The transformation lost those elemements that I did not map.
That left me with only a few elements in the Output Variable.
Less than the required elements.

How I fixed this?

First of all I could not change the XML definition as the XMl is shared my a host of systems.
And it would be a massive effort to get this done.

Now a simple work around for this would be to assign a blank to the element in the transformation.

Now if you are think what is that supposed to mean, here is what I mean.
In the transformation right click the element that you dod not want to loose as that is not mapped.
Choose "setText" option in there.
Give a space in the "Text" field that you see there.

Congrats you have done this. Was simple aint it.

What does it look like back there?

Well inthe transaformation it will look like this

<xsl:text disable-output-escaping="no"> </xsl:text>

If you want to try?

If you have noted this, the xsl will have a space between the tags.
Delete that. And see what you get.
I have seen no difference on my instance.

Monday, September 15, 2008

Change my Partnerlink Property Dynamically

What forced me into it?

This was in production. And there were 2 releases planned into production.
This was a property that was defined in bpel.xml file in the partnerLinkBinding.
As part of the second release the property had to be changed.

How did I do it?

Well I used java embedding to get this done.

Created a java embedding to change the property value in the partnerLinkBinding

Sample bpel.xml file
<?xml version = '1.0' encoding = 'UTF-8'?>
<bpelsuitcase>
<bpelprocess id="UpdateThis" src="UpdateThis.bpel">
<partnerlinkbindings>
<partnerlinkbinding name="client">
<property name="wsdlLocation">UpdateThis.wsdl</property>
<property name="myPartnerlinkProperty">myValueOfPartnerlinkProperty</property>
</partnerlinkbinding>
</partnerlinkbindings>
<configurations>
<property name="configProperty" encryption="plaintext">myBPMSystemAdmin</property>
</configurations>
</bpelprocess>
</bpelsuitcase>


Sample java embedding code to change these

try {
getLocator().lookupProcess ("UpdateThis").getDescriptor ().
getConfigurations().

setPropertyValue ("configProperty",
"BPMSystemAdmin");
getLocator().lookupProcess ("UpdateThis").getDescriptor ().

getPartnerLinkBindings().
getPartnerLinkBinding ("client").
setPropertyValue ("myPartnerlinkProperty",
"myChangedValueOfPartnerlinkProperty");
}
catch(Throwable ex) { .... }


Whatz the issue with restarting AS?

The first time I saw this it looked stupid. I changed the property from using another dummy bpel process. Used that happily till I restarted the AS.
And when I did the values in the partnerlink went back to those present earlier.

What I tried but failed?

And then I realized that the AS will reload all the BPEL process from the SUITCASE_BIN
The changed functionality with 10.1.3.X

A option that I tried but failed was to change the DESCRIPTOR column value in the PROCESS_DESCRIPTOR table.

But that did not help with restart. It always went back to the values that were present as part of the original deployment.
If you are thinking where can I find these tables, they are in the ORABPEL schema.

Friday, September 12, 2008

Database Adapters JNDI name in JDev and Application server

Why I used it?

Well in all 3 of big projects that I worked in, Db adapters was required. I had no choice but use it.

Why JNDI?

Well JNDI itself provides one level of indirection from the physical database connection. 
Decouples the actual database connection code from the application logic. 
If you are thinking cut the theory and tell me the real thing, how to do this in BPEL, that's exactly what I am about to do.

Where is this done for DBAdapter?

If you had a look at DB Adapter, JNDI is a configuration that comes up while following the wizard for DBAdapter. Now where the hell did I set up JNDI connections and how will AS (application server [for those who might not guess AS is this]) figure this out.

Well actually you need to do this in 2 places. One in DBAdapter and another in AS.

Why I need this in AS?

Well how can AS figure out which database and other connection details. 
What else but you need to do this in application server as well!
If you are asking what all I need to setup in AS just read on!!

What is the order to do this?

Both of these are independent and can be done in any order. (By both I mean JDev setup and AS setup)
Just be sure that both of these are done before you execute any code in BPEL else your opmn logs will show thing that you never like to see, ERRORS.

How to relate them? Whatz this use the same name thing?

Both the JDev and AS JNDI names should be the same or else AS will not be able to relate these together.

What's the AS setup?

There are 3 basic things that need to be setup in AS before AS JNDI can be used.
Number 1 the physical connection pool with all the service details.
Number 2 the Data source that points to the connection pool.
Number 3 setup the JNDI name as in JDev and pointing to the Data Source.

What do I setup in JDev?

In the connections in JDev create a connection to the database that was created in AS connection pool. Else you will not be able to explore the stuff in the Database.

What is with this mcf thing?

If you setup connection in JDev there is some thing that comes on board but not directly visible.
What else but the mcf properties.
Does not harm anything but if the JNDI are missing in AS starts using this to connect.
So for production it is best that these mcf details are removed.
If you don't know that where it is located just create a project with JNDI see it for your self.
It will be present in the Database Adapter generated files. Do you want clues!! I guess not.