Thursday, March 31, 2011

Define an error queue in SOA Suite

There is nothing called as Error queue as such in weblogic.It is basically a queue that we define to store the errored message.Consider a normal scenario where in you are polling a data from database and finally after doing some transformation writing in to a queue.Somehow the server is not able to queue it up to the target queue causing some exceptions.We can get rid of this by moving such errored message to another queue.


So essentially the concept is that we will create a error queue which is nothing but a simple queue and we will use it for handling the errored message.I am not coming up with a whole scenario ,just the basic idea which you can use to implement in your business logic.

First of all create a queue called as "Error Queue" within you JMS Module.






Use the existing subdeployment and target it to the JMS server you have created



Now we have the error queue we can use this queue to store the error message.

If you already have a queue(MessageQueue) which is handling the request we will
define the error queue for it.Click on your MessageQueue and go to

Configuration--> delivery Failure



Now check out the value i have defined here.

In the expiration policy i have defined it to redirect and the destination is

ErrorQueue,i.e expired message has to be redirected to the ErrorQueue that we
have defined.Further redirect limit is 5 and redelivery delay override is 1000

which means try to redeliver the same message 5 times at an interval of 1000ms.

So i believe you have now got an idea how to design an error and use it in your
scenario.

Wednesday, March 30, 2011

How to use Foreign Server to connect to Foreign Queue in soa suite 11g

It took me really a long time to make a working sample for this.I just couldn't recall all the steps which i have performed earlier but ya i have got several kind of errors while testing my process,The common logs that i got were

<bpelFault><faultType>0</faultType><bindingFault xmlns="http://schemas.oracle.com/bpel/extension"><part name="summary"><summary>Exception occured when binding was invoked. Exception occured during invocation of JCA binding: "JCA Binding execute of Reference operation 'Produce_Message' failed due to: ERRJMS_ERR_CR_QUEUE_PROD. ERRJMS_ERR_CR_QUEUE_PROD. Unable to create Queue producer due to JMSException. Please examine the log file to determine the problem. ". The invoked JCA adapter raised a resource exception. Please examine the above error message carefully to determine a resolution. </summary></part><part name="detail"><detail>[JMSExceptions:045101]The destination name passed to createTopic or createQueue "QueueA" is invalid. If the destination name does not contain a "/" character then it must be the name of a distributed destination that is available in the cluster to which the client is attached. If it does contain a "/" character then the string before the "/" must be the name of a JMSServer or a ".". The string after the "/" is the name of a the desired destination. If the "./" version of the string is used then any destination with the given name on the local WLS server will be returned.</detail></part><part name="code"><code>null</code></part></bindingFault></bpelFault>

<bpelFault><faultType>0</faultType><bindingFault xmlns="http://schemas.oracle.com/bpel/extension"><part name="summary"><summary>Exception occured when binding was invoked. Exception occured during invocation of JCA binding: "JCA Binding execute of Reference operation 'Produce_Message' failed due to: ERRJMS_ERR_CR_QUEUE_PROD. ERRJMS_ERR_CR_QUEUE_PROD. Unable to create Queue producer due to JMSException. Please examine the log file to determine the problem. ". The invoked JCA adapter raised a resource exception. Please examine the above error message carefully to determine a resolution. </summary></part><part name="detail"><detail>[JMSExceptions:045103]While trying to find a topic or a queue we could not find the specific JMSServer requested. The linked exception may contain more information about the reason for failure.</detail></part><part name="code"><code>null</code></part></bindingFault></bpelFault>

<bpelFault><faultType>0</faultType><bindingFault xmlns="http://schemas.oracle.com/bpel/extension"><part name="summary"><summary>Exception occured when binding was invoked. Exception occured during invocation of JCA binding: "JCA Binding execute of Reference operation 'Produce_Message' failed due to: JCA Binding Component connection issue. JCA Binding Component is unable to create an outbound JCA (CCI) connection. AQSample:aqJMS [ Produce_Message_ptt::Produce_Message(body) ] : The JCA Binding Component was unable to establish an outbound JCA CCI connection due to the following issue: javax.resource.spi.IllegalStateException: [Connector:199176]Unable to execute allocateConnection(...) on ConnectionManager. A stale Connection Factory or Connection Handle may be used. The connection pool associated with it has already been destroyed. Try to re-lookup Connection Factory eis/wls/Queue from JNDI and get a new Connection Handle. Please make sure that the JCA connection factory and any dependent connection factories have been configured with a sufficient limit for max connections. Please also make sure that the physical connection to the backend EIS is available and the backend itself is accepting connections. ". The invoked JCA adapter raised a resource exception. Please examine the above error message carefully to determine a resolution. </summary></part><part name="detail"><detail>[Connector:199176]Unable to execute allocateConnection(...) on ConnectionManager. A stale Connection Factory or Connection Handle may be used. The connection pool associated with it has already been destroyed. Try to re-lookup Connection Factory eis/wls/Queue from JNDI and get a new Connection Handle.</detail></part><part name="code"><code>null</code></part></bindingFault></bpelFault>

Exception occured when binding was invoked. Exception occured during invocation of JCA binding: "JCA Binding execute of Reference operation 'Produce_Message' failed due to: JCA Binding Component connection issue. JCA Binding Component is unable to create an outbound JCA (CCI) connection. AQSample:aqJMS [ Produce_Message_ptt::Produce_Message(body) ] : The JCA Binding Component was unable to establish an outbound JCA CCI connection due to the following issue: BINDING.JCA-12141 ERRJMS_CONN_FAC_NOT_FOUND. ERRJMS_CONN_FAC_NOT_FOUND. Unable to instantiate connection factory. JMS adapter was unable to look up the connection factory jdbc/ConnectionFactoryDomainB neither through JNDI nor instantiate it as a Java class. Please examine the log file to determine the problem. Please make sure that the JCA connection factory and any dependent connection factories have been configured with a sufficient limit for max connections. Please also make sure that the physical connection to the backend EIS is available and the backend itself is accepting connections. ". The invoked JCA adapter raised a resource exception. Please examine the above error message carefully to determine a resolution.

The only reason to paste these error message is that i dont want you people to waste that much time which i have wasted so if you are doing a configuration for Foreign Server to connect to remote queue and getting any of the following exception ,what you need to do is just follow the steps as i have mentioned and inform me on any issues.

I am using two domain for this issue

Domain A running on port 7001

Domain B running on port 7777

I have not created any managed server ,My Admin server is working as a soa server.

Configuration that are required are

DomainA

JMS Server,JMS Module,SubDeployment,Connection Factory and Queue

DomainB

JMS Module,Foreign Server,Destinations and Conenction Factories

Further some secutiry settings are also required which we will see later.

Now we will start with our configuration.

1>Log in to domainA admin console

http://localhost:7001/console

Got to services-->Messaging-->JMS Servers and create a new JMS Server pointing it to admin server.




Now Create a JSM Module and also target it to admin server.




now go to the JMS module that you have created and create a sub deployment

This subdepoyment will target to the JMS Server that we have created.



Now create a connection factory and target it to the subdeployment.
Similary create a queue and also target it to the subdeployment as shown below



That is the only configuration needed to be done from DomainA so far
NOw log in to the admin console of DomainB

Create a JMS module


.
Now go inside the module and create a Foreign Server targetting to Admin server.



Now go to the configuration of Foreign Server

in the JNDI donnection url specify the url for domainA

t3://localhost:7001

JNDI Properties credential specify the password for the server.

IN the jndi properties specify

java.naming.security.principal=weblogic

as shown below



Now go to the connection factory tab and create a new conenction factory

Now here you have to take care

Your local JNDI name can be anything but your remote JNDI should be the JNDI

of conenction factory of domainA ,i.e. in the domainA we have created a connection
factory we have to specify the same url in the remote jndi name.

as shown below



Now again go the destination queue and create a Queue

Here also you need to take care that while giving the remote jndi name you have

to specify the jndi of the queue of domainA and local jndi can be anything.

So my configuration for Destination is as below.



Now just restart yourDomain B so that the queue and connection factory of DomainB can bind to the queue and connection factory of DomainA.

Now once you restarted you need to enable global trust between the two domain.

as pointed out in the following forum link

http://forums.oracle.com/forums/thread.jspa?threadID=2188645&tstart=0

So i followed document

http://download.oracle.com/docs/cd/E13222_01/wls/docs100/ConsoleHelp/taskhelp/security/EnableGlobalTrustBetweenDomains.html

and enabled golbal trust in both my domains

Go to the admin page of each server and click on the domain

Now click on security link -->general page and select

cross domain security enabled

Further go to advanced settings and provide the credentials for the weblogic server.Save the changes.



Now go to you deployment -->JMD adapter and create a new outbound connection pool

Provide the local jndi that you have specified in connection factories of domainB in the connectionFactoryLocation and redeploy your JSM Adapter.



So now you are done with the configuration from Server side.

Now you just need to create a simple process to put the data in the foreign queue.

My process will look like this where in i am just taking an input data and inserting it in to the foreign queue.


Now while creating the JMS adapter wizard you will find the Foreign queue in the drop down list as shown below you have to select the same and proceed.

Here you ahve to take care of two things

First select the right queue and in the jndi name provide the jndi name of the connection pool that you have created for connecting to the queue.



Now test your bpel process and you will find that the data is getting stored in your remote domain.

However this is not a perfect JMS patter as the message can be lost if the remote server is switched off.For testing purpose i shutdown the remote server to see if the server picks up the data once the server restart but it doesn't.i got following error in that case when my remote server was shutdown and i tried to inserted data from foreign server.


<bpelFault><faultType>0</faultType><remoteFault xmlns="http://schemas.oracle.com/bpel/extension"><part name="summary"><summary>Exception occured when binding was invoked. Exception occured during invocation of JCA binding: "JCA Binding execute of Reference operation 'Produce_Message' failed due to: JCA Binding Component connection issue. JCA Binding Component is unable to create an outbound JCA (CCI) connection. AQSample:aqJMS [ Produce_Message_ptt::Produce_Message(body) ] : The JCA Binding Component was unable to establish an outbound JCA CCI connection due to the following issue: BINDING.JCA-12141 ERRJMS_CONN_FAC_NOT_FOUND. ERRJMS_CONN_FAC_NOT_FOUND. Unable to instantiate connection factory. JMS adapter was unable to look up the connection factory jdbc/ConnectionFactoryDomainB neither through JNDI nor instantiate it as a Java class. Please examine the log file to determine the problem. Please make sure that the JCA connection factory and any dependent connection factories have been configured with a sufficient limit for max connections. Please also make sure that the physical connection to the backend EIS is available and the backend itself is accepting connections. ". The invoked JCA adapter raised a resource exception. Please examine the above error message carefully to determine a resolution. </summary></part><part name="detail"><detail>Destination unreachable; nested exception is: java.net.ConnectException: Connection refused: connect; No available router to destination</detail></part><part name="code"><code>null</code></part></remoteFault></bpelFault>

So this process has some demerit that the messages are not saved so that when the remote system gets active again the data can be delivered.We can create our own error queue to store those messages which are not delivered.

However i believe this give us a new point to understand the use of Store and Forward concept in weblogic which we will see in the following post.

http://soa-bpel-esb.blogspot.com/2011/04/store-and-forwardsaf-in-soa-suite-11g.html

Thursday, March 24, 2011

How to use AQ JMS in SOA Suite 11g

I am using the following docs to set up this test case.

Document1

Document2

As per the first document i have created a queue table ,a queue and have started it using following commands

connect / as sysdba;
Grant connect, resource TO jmsuser IDENTIFIED BY jmsuserpwd;
Grant aq_user_role TO jmsuser;
Grant execute ON sys.dbms_aqadm TO jmsuser;
Grant execute ON sys.dbms_aq TO jmsuser;
Grant execute ON sys.dbms_aqin TO jmsuser;
Grant execute ON sys.dbms_aqjms TO jmsuser;



Create queue table

exec DBMS_AQADM.CREATE_QUEUE_TABLE(Queue_table =>'arpit',Queue_payload_type =>'sys.aq$_jms_text_message',multiple_consumers =>false);

create queue

EXEC DBMS_AQADM.CREATE_QUEUE(queue_name =>'ankit',queue_table =>'arpit');

exec DBMS_AQADM.START_QUEUE('ankit');

Now following steps

1>Create a data source to connect to the queue created

log in to Admin console

Go to data sources as indicated and create a new data source.
give it some qunique name such as jdbc/SampleAQJMSDataSource




Provide details for the database you want to connect

Verify the user name and password that you have just created



target it to the soa server



now go to admin console

Services-->Messaging -->JMS module and create a JMS module

Now as per document create a Foreign server in the JMS module

In the foreign server you need to take care of two things

1>JNDI Initial Context Factory: is essentially set to "oracle.jms.AQjmsInitialContextFactory"

2>In the JNDI properties you have to set the jndi for your data source
which should appear like this

datasource=jdbc/SampleAQJMSDataSource

Here jdbc/SampleAQJMSDataSource is the name of the data source i have used in my case to connect to the queues that i have created.

If you will check the document it corresponds to following configuration

<foreign-server>
<initial-context-factory>oracle.jms.AQjmsInitialContextFactory</initial-context-factory>
<jndi-property>
<key>datasource</key>
<value>jdbc/aqjmsds</value>
</jndi-property>
</foreign-server>







Now click on connection factory tab and provide the following details

In the local JNDI -jms/myCF

In Remote JNDI Name:XAQueueConnectionFactory

This is as per the document



Now Further click on Destination tab and create local and remote jndi

The use case and how these works internally has been explained in the document.

Here i am talking only about a working scenario.

So as per document provide some unique local JNDI which server will use to connect to the destination.I have specified it as jms/myQueue

Further in the Remote JNDI name provide the value as Queues/ankit

Here ankit is the name of my queue,you have to replace this with the name of your queue.

Once done save these changes.



Now once you will save the changes it will ask you to restart the server.
Restart the server to make the changes take effect



Now there is one more settings that we need to do which the document doesn't talk about.We need to create an outbound connection pool for JMS adapter to be used in jdeveloper.

So i went to Deployment-->JMS Adapter-->configuration and Outbound connection pool and created an outbound connection pool

eis/SureshQueue as shown in the list



Now once the outbound connection pool is created go to the connection and go to properties tab

In the properteis tab in connection factory location

provide the connection factory that you have created for your foreign server.

The conenctionfactory will be the local JNDI for the connection factory as shown below ==jms/myCF



Save the changes and update your JMS adapter deployment.



Now we will create a simple bpel process to test the functionality of the process.

Just create a simple asynchronous BPEL process



Now drag and drop a JMS adapter in the external reference swinlane and start doing the configuration



select oracle adavanced queuing as option




select produce message beacue we are using it for outbound operation.



search for the queues


NOw pay attenstion in the following configuration

as you can see the Destination name is taking the value which we have specified for local jndi in our destination for foreign server

Further i am using eis/SureshQueue for JMS connection



Use your schema or use opaque schema as per your business need to complete the process.Once process is complete drag a wire from bpel process to the adapter you have created so in all you composite should look like this



Further go to your bpel process and drag a drop an invoke activity and assign activity to copy input variable to the input of invoke activity so your bpel process should look something like this after completion



Now deploy the process and check this

Once you will invoke the process you might get an error like this



Specifically you will get the following error message



Error Message: {http://schemas.oracle.com/bpel/extension}bindingFault
Fault ID default/AQJMS!1.0*soa_3f7f4fbd-e72e-4fdd-9820-16e30daab15c/BPELProcess1/80011-BpInv0-BpSeq0.3-3
Fault Time Mar 25, 2011 1:03:34 PM
Non Recoverable System Fault :
<bpelFault><faultType>0</faultType><bindingFault xmlns="http://schemas.oracle.com/bpel/extension"><part name="summary"><summary>Exception occured when binding was invoked. Exception occured during invocation of JCA binding: "JCA Binding execute of Reference operation 'Produce_Message' failed due to: [Connector:199175]This ManagedConnection is managed by container for its transactional behavior and has been enlisted to JTA transaction by container; application/adapter must not call the local transaction begin/commit/rollback API. Reject event LOCAL_TRANSACTION_STARTED from adapter.". The invoked JCA adapter raised a resource exception. Please examine the above error message carefully to determine a resolution. </summary></part><part name="detail"><detail>[Connector:199175]This ManagedConnection is managed by container for its transactional behavior and has been enlisted to JTA transaction by container; application/adapter must not call the local transaction begin/commit/rollback API. Reject event LOCAL_TRANSACTION_STARTED from adapter.</detail></part><part name="code"><code>null</code></part></bindingFault></bpelFault>




Error Message:
Fault ID reference:40011
Fault Time Mar 25, 2011 1:03:34 PM
Non Recoverable System Fault :
Exception occured when binding was invoked. Exception occured during invocation of JCA binding: "JCA Binding execute of Reference operation 'Produce_Message' failed due to: [Connector:199175]This ManagedConnection is managed by container for its transactional behavior and has been enlisted to JTA transaction by container; application/adapter must not call the local transaction begin/commit/rollback API. Reject event LOCAL_TRANSACTION_STARTED from adapter.". The invoked JCA adapter raised a resource exception. Please examine the above error message carefully to determine a resolution.


It took me a long time to resolve this issue.

By default when you are configuring the process from jdeveloper

a default outbound connection pool is used that is

eis/aqjms/Queue

YOu have to use only this one.

So Just go to your admin console

Go to Deployment-->JMS Adapter

Configuration_>Outbound connection pool and click on eis/aqjms/Queue

Go to properties tab and in the connection factory location specify the local jndi of the connection factory that you have created,which in our case is jms/myCF

Now update your JMS Adapter and change the jndi name in your Jdeveloper also.

Redeploy the process and test it again.

This time it should work fine.


now you can log in to database with the user and password and do a query on the table to know if the process completed successfully or not.In my case i have called it twice so i am getting a count of 2.

Tuesday, March 22, 2011

NonBlockingInvoke and the concept of parallelism in SOA Suite 11.1.1.4

nonBlockingInvoke

By default, Oracle BPEL Process Manager executes in a single thread, executing the branches sequentially instead of in parallel. When this property is set to True, the process manager creates a new thread to perform each branch's invoke activity in parallel. This property is applicable to both durable and transient processes.

Consider setting this property to True if you have invoke activities in multiple flow or flow n branches. This is especially effective if the parallel invoke activities are two-way, but some benefits can be realized for parallel one-way invokes as well.

Values:

This property has the following values:

*

True: Oracle BPEL Server spawns a new thread to execute the invocation.
*

False (default): Oracle BPEL Server executes the invoke activity in the single process thread.


In this exercise we will try to find out practically what does it mean.


I have created a simple BPEL process with a flow activity with two sequence.

In both the sequence i am using an assign activity and a invoke activity.

In one of the sequence i am using wait activity which has a dealy of 5 second.

Both the sequence are invoking a single asynchronous bpel proess so in all my

process looks something like this.


As per Oracle documentation

Now as per the documentation the two branches should execute sequentially because non blocking invoke is set to false by default.So i executed this process with some random input and i got the following time duration sheet for the process.





I couldn't notice the behavior that is expected ,if as per documentation



the sequence should be processed in a sequence but here as you can see in the flow timing both the flow has started at almost similar time then there is a once second dealy on calling the next invoke that is the only thing which i can see in the flow which points me that it first waited for first sequence to complete.However we will go ahead and set the nonblockinginvoke to true and see the result how does it behave




I redeployed the process and i didn't get much difference the only difference is a second delay which i believe is due to property that we have set.






Here as you can see the two assign are at same time so this might have caused because now we have allowed parallel processing and both the sequence are working concurrently.Here we have seen scenario where in there was a change of 1 second but we can use this scenario in many case where in even a delay of second will be crucial.May be i will come up with some better example to illustarte this,The whole idea was to give you an idea on this property.

Few things that we need to take care is that we should use this property when we are making a call to asynchronous service,we can use it for synchronous process also but that is not a good design process as synch process are supposed to complete in fraction of seconds,so it won't make much sense if you have two sequence with call to synchronous process.Bottom line its all about how you desing your process.

Monday, March 21, 2011

How to make a Durable process a Transient one

First of all we need to understand what is a durable process and what is a transient process.A transient process is one that do not contain any dehydration points such as receive, wait, onMessage and onAlarm activities.In opposite way a durable process is one which has dehydration point.Dehydration point are called as the rollback point in a process that is if a system is executing a process and in middle the server just crashes the process will be rolledback to the last dehydration point passed in the process.That is the reason why this process is called durable.

select count(*) from cube_instance;




We will achieve this by creating a simple asynchronous bpel process which by default will dehydrate the instance in the database.Then we will use some bpel performacne properties to change this default bahaviour

We will be essentially using two properties

completionPersistPolicy and inMemoryOptimization

As per Oracle documentation

inMemoryOptimization
inMemoryOptimization

This property indicates to Oracle BPEL Server that this process is a transient process and dehydration of the instance is not required. When set to True, the completionPersistPolicy is used to determine persistence behavior. This property can only be set to True for transient processes or processes that do not contain any dehydration points such as receive, wait, onMessage and onAlarm activities. The inMemoryOptimization property is set at the BPEL component level. When set to False, dehydration is disabled which can improve performance in some use cases.

Values:

This property has the following values:

*

False (default): instances are persisted completely and recorded in the dehydration store database.
*

True: The completionPersist policy is used to determine persistence behavior.

13.3.1.2 completionPersistPolicy

This property configures how the instance data is saved. It can only be set at the BPEL component level. The completionPersistPolicy property can only be used when inMemoryOptimization is set to be True (transient processes). Note that this parameter may affect database growth and throughput (due to reduced I/O).
Value Description
On (default) The completed instance is saved normally
Deferred The completed instance is saved, but with a different thread and in another transaction.
Faulted Only the faulted instances are saved.
Off No instances of this process are saved.

For more information these properties check the following link


Now we will create a simple asynchoronous process which will assing the input variable to the out put variable and deploy it in a server.Once you deploy the process go to em console and create a instance of this process.

before testing the service.

Open up a command console and log in to sql

Log in with dev_soainfra user and corresponding passoword.

ONce you log in to the schema issue a statement

select count(*) from cube_instance;

this will fetch you some result.

Now run the instance from em console and again issue the same command in sql

you will find an increase in the number of count in cube_instance table because
the data is dehydrate into data base.

IF you don't want this behaviour and want that the instance should not be

dehydrated to data base.you need to use these properties.

SO open you project in jdeveloper.

Open your composite.xml and go to source view.

Look for the "component.name" filed once you find the field

Just mention the two properties in the configuration ,in my case it looks like

this

<component name="BPELInstance" version="1.1">
<implementation.bpel src="BPELInstance.bpel"/>
<property name="configuration.inMemoryOptimization">true</property>
<property name="configuration.completionPersistPolicy">off</property>
</component>

Now save the changes and redeploy the process.Now again create an instance and you

will not find an increase in the number of cube_instance.This property is often

used to achieve improved performance.

Sunday, March 20, 2011

How to use SubVersion with Jdeveloper 11.1.1.4

Subversion is required for developers.
If a firm is developing a business application.
There will be different developer working on it and may be on different time zone.
So in order to isolate the work of different developer we use subversion,it will
essentially create different version of the same project keeping the original version of the application remain untouched.The most important use of subversion is that user will be able to connect to the subversion server through http.However it can be done through file and ftp also but http is one of the most important ways to access the subversion server.This will become more clear to you once you will go through this post.The first thing required in this case is the subversion server.Since i am using Windows i will use the most popular VirtualSVN Server.You can download the same from following location.

NOw once you download the software install it in your local machine.

These screeshots will guide you of the steps for the same.

















Select repository right click on it and create a repository.







Similarly click on user and create a user also





Now you are good to go for creating a connection with subversion.
If you want to create it in jdeveloper 10g there is an excellent document you can get here

Open you jdeveloper

Go to VersioningVersioning Application as shown below






It will ask for repository url which you can get from the svn console
But right click on the repository and choose copy url to clipboard
Provide the username and password that you have created and test the access





If you get any certificate information accept it permanently,if you choose in temporarily you will have to accept it everytime you log to your jdeveloper.












Choose the directory whose files you want to create a subversion.







Now you can do change your project ,update it and finally commit as shown

Once you are done with the project you can check out with your comments so that the new user

Who will log in to the same svn server will come to know the changes you have done.

New user might be using different version of jdeveloper and different machine he can use his credentials

to connect to the svn server.



This is just a concept there can be more complex issue on how a user will connect to existing process which i am leaving for readers to do R & D but this is the basic concept for Subversion which developers can use in your project