Wednesday, June 15, 2011

How to dynamically change the end-point of adapter

In this sample exercise we will see how we can dynamically change the end point for adapter at run time.I will be depicting this feature by a simple composite process where in i will write a file in a particular folder and will change the folder location at run time.

My process will look something like this.



This is just a simple asynchronous bpel process where in i am mapping the input text to the content of file adapter and then writing it to a folder location.

first of all you can deploy and invoke this process to see if it is working fine and writing in the location specified during file adapter configuration.

Now go to em console and click on your process.
At bottom you will get Services and Reference tag.
You will find the service that you have created as can be seen.
Click on the adapter service that you have created.




Now go to properties tab of the adapter and you will get the physical directoty location that you have specified during your design time from jdeveloper.

You can change the value of physical directory over here to another location,Make sure the new location already exists and say apply.

No need to do any thing else,just test the composite process again from em console and this time the file will be written into the new location.



Though we have achieved the functionality of changing the file location at run time we still have not made it dynamic that is based on input or some other logic it should automatically goes to different folder location.We will see how we can achieve this now.

Now we will think of the approach that we can use to change the value dynamically.
Which mean we must have to refer to some table in order to map it to different directory structure.So we can use either business rules or DVm for the mapping.

But again we should have one field which should assing different values for output directory.

So first of all we will try to create a variable which can pass the value for output directory.

For this purpose i created a new variable as shown below.



Now we will see how we can use this variable to assign values.

I will drag and drop an assign activity and will pass on a location in my server where i want to write the file.Please make sure that it is within single inverted comma.

this value i will map to the variable which i have created now as can be seen.




now i need to map this value to the file Directory name.

You can know more about this proeprty from following doc

http://download.oracle.com/docs/cd/E12839_01/integration.1111/e10231/adptr_propertys.htm#CHDEDJEA

We have a property called jca.file.directory we will map our variable to this directory.

This takes precedence over the location that we have specified during the design time of adapter.

Just save this project and redeploy it to the server.




Now if you will test your service you will find that the file is now written to the new folder location that we have passed from Expression builder.

so we have got a variable also.Now it is very easy we can create our rule or dvm to assing dynamic values to this variable.We will now see how we can do that.

So now we just need to create one business rule and attach it to our composite.

I created a simple rule as shown below.







It is a simple rule which says if input in ankit send it to poll directory and when input is arpit send it to out directory.YOu can check my previous post on how to create business rules and attach it to your bpel in a composite

http://soa-bpel-esb.blogspot.com/2011/06/business-rules-ruleset-in-soa-suite.html


Now We need only one configuration we need to map the output of the rules to the variable which we have created to assign random outputDirectory so this i have done using an assign activity as you can see below.




That is it.Now deploy the process and depending upon the input it will write in different directory structure.Few common mistakes which you need to take care of if you have defined your input in rules as constant then in that case it will not work with input ankti or arpit rather you will have to use 'ankit' or 'arpit' as input.
failing to do so will give you following error.

Non Recoverable System Fault :
<bpelFault><faultType>0</faultType><operationErroredFault xmlns="http://xmlns.oracle.com/OracleRules1/OracleRules1_DecisionService_1"><part name="payload"><errorInfo xmlns="http://xmlns.oracle.com/OracleRules1/OracleRules1_DecisionService_1"><errorMessage>Fact not found in the rule engine working memory, rule session execution failed. The rule session 40567 failed because an instance of the fact com.oracle.xmlns.sample.dynamicfile.bpelprocessdynamic.ProcessResponse could not be found in the working memory of the rule session. This is most likely a rule modeling error. The decision service interaction expects the fact instance to exist in the working memory of the rule session. Check the rule actions in rule designer and make sure that a fact of the expected type is being asserted. If the error persists, contact Oracle Support Services. 40567</errorMessage></errorInfo></part></operationErroredFault></bpelFault>

So design you process carefully. :)

3 comments:

Anonymous said...

Hi,

CAn you expalin the same for DB and JMS?

Thanks
Satya

Mikku said...

I will try to create the same for DB and JMS

Mikku said...

Some pointers for your dynamically changing the data base.

You need to have same table structure in the two database which you want to connect.

It should have same user ,same table structure

Then again you can use property jca.db.XADataSourceName in your invoke activity to pass the value of data sources at run time.

You can have the business now to dynamically provide the data source based on input.

I checked this at my end ,the process is similar to one i have explained,Only thing is that you now need to use property jca.db.XADataSourceName to get the data source name.It works fine for me.Try with the same approach it should work.