Powered By Blogger

Tuesday, June 25, 2013

Oracle JMS Sync/Async Request-Reply Pattern

 We can use the Oracle SOA 11g JMS Adapter to implement following interaction patterns
  • synchronous request reply interaction pattern
  • asynchronous request reply interaction pattern 

Synchronous request reply interaction pattern

This pattern allows the Oracle JMS Adapter sends a request to the request JMS queue and waits for a response from the reply JMS queue before further execution continues.
In turn, the adapter will set the JMSReplyTo header to the reply destination. This value is then used by a message consumer  to send the message to the reply destination which is then dequeued by the Oracle JMS Adapter and continue further processing.
Behind the scenes, the Oracle JMS Adapter uses a new interaction pattern called JmsRequestReplyInteractionSpec.
In above case JMS adapter framework automatically sets JMSReplyTo header on request message  to jms/ExceptionRespQueue and waits for the message on jms/ExceptionRespQueue. It is message consumer responsibility to read JMSReplyTo header and send message to the destination mentioned in the header

JMS adapter wizard showing Request/Reply operation modelling


Above wizard generates below JCA file

<adapter-config name="SyncRequest-Reply" adapter="JMS Adapter" wsdlLocation="SyncRequest_Reply.wsdl" xmlns="http://platform.integration.oracle/blocks/adapter/fw/metadata">
<connection-factory location="eis/wls/Queue" UIJmsProvider="WLSJMS" UiOperationMode="Synchronous" UIConnectionName="Dev2"/>
<endpoint-interaction portType="Request_Reply_ptt" operation="Request_Reply" UITransmissionPrimitive="Request-response">

<interaction-spec className="oracle.tip.adapter.jms.outbound.JmsRequestReplyInteractionSpec">
<property name="TimeToLive" value="0"/>
<property name="PayloadType" value="TextMessage"/>
<property name="DeliveryMode" value="Persistent"/>
<property name="ReplyDestinationName" value="jms/b2b/B2B_IN_QUEUE"/>
<property name="RequestDestinationName" value="jms/b2b/B2B_OUT_QUEUE"/>
</interaction-spec>
</endpoint-interaction>
</adapter-config>

Oracle recommendations for this pattern

  • Oracle suggests when using the Oracle JMS Adapter in a synchronous pattern ensure that you use a non-XA connection factory and set the connector factory isTransacted property to true in weblogic-ra.xml.
  • The connection factory must be weblogic.jms.ConnectionFactory or any other non-XA connection factory.
If we get into BPEL design we will be having invoke activity pointing to JMS adapter reference invoking Request_Reply operation and invoke activity is blocked from further execution untill it receives response from response queue

 Asynchronous request reply interaction pattern


We can use the Adapter configuration wizard to model a process that allows Oracle JMS Adapter to be used in an asynchronous request reply interaction pattern.

This pattern allows an Oracle JMS Adapter to send a message to a JMS destination.
When sending message it sets JMSReplyTo header on request message  to Reply destination JNDI name
Consumer reads the header on message and replies to that destination.
When a message is received on the reply queue, the Oracle JMS Adapter is able to route message to the correct composite or the component instance. The correlation is done based on the JMSMessageID of the request message, which becomes the JMSCorrelationID of the reply message, and the conversation ID of the underlying component.

JMS adapter wizard showing Async Request/Reply operation modelling






Above wizard generates below JCA file.Note that there are two interaction specs generated. One for producing and another for consuming message

<adapter-config name="Async-Request-Reply" adapter="JMS Adapter" wsdlLocation="Async_Request_Reply.wsdl" xmlns="http://platform.integration.oracle/blocks/adapter/fw/metadata">

<connection-factory location="eis/wls/Queue" UIJmsProvider="WLSJMS" UiOperationMode="Asynchronous" UIConnectionName="Dev2"/>

<endpoint-activation portType="Reply_ptt" operation="Reply" UITransmissionPrimitive="Request-response">
<activation-spec className="oracle.tip.adapter.jms.inbound.JmsConsumeActivationSpec">
<property name="PayloadType" value="TextMessage"/>
<property name="UseMessageListener" value="false"/>
<property name="DestinationName" value="jms/b2b/B2B_OUT_QUEUE"/>
</activation-spec>
</endpoint-activation>

<endpoint-interaction portType="Request_ptt" operation="Request" UITransmissionPrimitive="Request-response">
<interaction-spec className="oracle.tip.adapter.jms.outbound.JmsProduceInteractionSpec">
<property name="TimeToLive" value="0"/>
<property name="PayloadType" value="TextMessage"/>
<property name="DeliveryMode" value="Persistent"/>
<property name="DestinationName" value="jms/b2b/B2B_IN_QUEUE"/>
</interaction-spec>
</endpoint-interaction>
</adapter-config>

If we get into BPEL design  we will be having invoke activity pointing to JMS adapter reference invoking Request operation and we need to use receive activity pointing to same JMS adapter reference but waiting on Receive operation

Accessing Remote WLS Queues and Topics

In this post, let's throw some light on how Oracle SOA can access JMS destinations  deployed onto remote weblogic domain

Oracle JMS Adapter can be used to access remote WLS JMS destinations. Remote destinations refer to queues/topics that are available in a WLS JMS server, which is part of a remote Oracle WebLogic Server domain.
To enable Oracle JMS Adapter to read/write from/to a remote queue that is present in a remote WLS JMS server, we must configure the following:


1.You must have a unique domain name and JMS server name in both the servers.
2.You must enable global trust between the two servers.

Refer to the following link for information about how to enable global trust between servers:

http://download.oracle.com/docs/cd/E13222_01/wls/docs100/ConsoleHelp/taskhelp/security/EnableGlobalTrustBetweenDomains.html
This configuration is appropriate when you connect to queues or topics present in WLS9.2 server.

There are two options supported that enable you to access remote destinations via the JMS adapter:

Direct Access

Direct access is defined via specification of the FactoryProperties property in the weblogic-ra.xml file, with access parameters indicating the remote domain.

FactoryProperties

java.naming.factory.initial=weblogic.jndi.WLInitialContextFactory;
java.naming.provider.url= t3://:;java.naming.security.principal= ;java.naming.security.credentials=

The disadvantage of this approach is security credentials will be displayed in plain text  

Foreign JMS server

Configure the foreign server to access the remote domain.
Please refer to Oracle documentation for this
http://docs.oracle.com/cd/E23943_01/apirefs.1111/e13952/taskhelp/jms_modules/foreign_servers/ConfigureForeignServers.html


Notes:

  1. For inbound use cases, both options are supported. For outbound use cases only, direct access is supported, but configuring the foreign server is not supported.
  2. The JMS Adapter enables you to interact with WebLogic Server JMS destination locations in a domain that are remote to the WebLogicServer domain where SOA is installed. 
There are two more options to move JMS messages between remote destinations.These options  are nothing to do with JCA JMS adapter but they are WLS administrative objects

  1. SAF(Store and Forward Agents)
  2. Bridges
SAF: SAF's let local producer reliably produce messages to remote destination irrespective of destination's availablity.
In SAF scenario, when producer produced the message and if remote destination is not reachable then messages are stored locally and forwared to remote destination later when that is available
 
Bridge:  This is similar to SAF but oracle recommendation is use it when we are connecting different messaging products(implemented by different vendors like Oracle and MS) or different implementations/versions of WLS messaging (like WLS 9.2 and WLS 10.3.x)

Wednesday, June 12, 2013

Oracle Database Adapter high availability/Scalability


Oracle Database Adapter can be configured for high availability in two models with in cluster environment
  1. Active-Active
  2. Active-Passive 
Active-Active setup.
In an active-active setup, distributed polling techniques can be used for inbound database adapters to ensure that the same data is not retrieved more than once.

One of the best practices for multiple Oracle database Adapter process instances deployed to multiple cluster nodes is to use the adapter configuration wizard to set the Distributed Polling check box in the Adapter

With an Oracle DB, this automatically creates SQL select appended with SELECT FOR UPDATE SKIP LOCKED. Concurrent poller threads from each node trying to select and lock the available rows will follow below orchestration,
If current row is locked, the next unlocked row is locked and fetched instead. If many threads all execute the same polling query at the same time, they should all relatively quickly obtain a disjoint subset of unprocessed rows.

With a non-Oracle database the SELECT FOR UPDATE safely ensures that the same row cannot be processed multiple times, however you should consider taking additional measurements like using a partition field or singleton property as a best practice

Active-Passive :
We use Singleton property in composite.xml for active-passive setup. This allows multi threaded inbound Oracle Database Adapter instance to follow a fan out pattern and invoke multiple composite instances across a cluster. The Oracle DB Adapter supports the high availability feature when there is a database failure,restart or crash . The DB adapter picks up again without any message loss.

This is essentially multi-threading on a single node with fan-out to multiple composite instances running on multiple nodes

Singleton (Active/Passive) is applicable only for inbound endpoint adapters
Set this property in the composite.xml within the element and set it to a value of true as shown in example.
This  property can be set for any JCA adapter

Example:
<service name="databasepoll" ui:wsdlLocation="databasepoll.wsdl">
<interface.wsdl interface="http://xmlns.oracle.com/...#wsdl.interface(Subscr_ptt)"/>
<binding.jca config="databasepoll_db.jca">
<property name="singleton">true</property>
</binding.jca>
</service>

Note:This property is not applicable to outbound adapters

How singleton works: If there are multiple activations of the same adapter endpoint for same composite service in an Oracle WebLogic cluster is identified, then only one activation is allowed to start the reading or publishing of messages.The JCA binding component instances choose one among the activations randomly as the primary activation responsibility and all other as Standby

If a primary activation at some point of time becomes unresponsive,unavailable or crashes then
remaining JCA binding component members of the Oracle WLS cluster immediately detect the deactivation, and reassign the primary activation responsibility to one of available endpoints

For scalability, think of setting below properties
Set MaxTransactionSize and increase concurrency by setting the adapter _db.JCA property NumberOfThreads.

Saturday, June 8, 2013

Exceeded maximum number of subscribers for queue

In SOA 11.1.1.6, when  someone sees error like "java.sql.SQLException: ORA-24067: exceeded maximum number of subscribers for queue APPS.SAMPLE_QUEUE"


" in soa log then I suggest to follow below steps
This generally occurs in the clustered environment, but standalone should work fine.

Cause: An attempt was made to add new subscribers to the specified, but the number of subscribers for this queue has exceeded the maximum number (1024) of subscribers allowed per queue.

Why does some one create this many number of subscribers?
Answer is obviously nobody wants to do it intentionally but this might happen without developer even knowing. Let's say if you have below plsql code to create subscribers and you deploy code multiple times then each deployment create one subscriber.Please check for this kind of code sections

dbms_aqadm.add_subscriber(queue_name => 'SAMPLE_QUEUE'
,subscriber => TempSubscriber );   Solution: If this issue occurs then you have to delete the AQ table and AQ in your Schema and recreate them

I have also seen another issue if PL/SQL code creates subscriber like above and BPEL 11g service also deployed with durable subscriber set in jms JCA file

Error I see in above case is

BINDING.JCA-12134
ERRJMS_ERR_CR_TOPIC_CONS.
ERRJMS_ERR_CR_TOPIC_CONS.
Unable to create Topic consumer due to JMSException.
Caused by: oracle.jms.AQjmsException: JMS-230: Illegal operation on durable subscription with active TopicSubscriber

Tuesday, June 4, 2013

Oracle Service Bus Inbound Custom Authentication

In addition to supporting standard authentication mechanisms using security policies and HTPP basic authentication, OSB also supports custom authentication mechanism for inbound requests

Authentication can be implemented at two levels
  • Transport level
  • Message level
Transport level:

Transport level authentication mechanism resorts to sending authentication information in protocol headers and authentication providers validate the header
  • Custom token in an HTTP header
Message level:
Message level authentication mechanism uses either actual business XML payload or SOAP header  to store the authentication data.Oracle Service Bus accepts and attempts to authenticate a username and password passed in a SOAP header/XML payload
  •  For SOAP protocol based proxy services
                  1.Custom token in a SOAP header
                  2.Username/Password in a SOAP header
  • For non-SOAP protocol based proxy services
                 1.Custom token in the payload of any XML-based proxy services
                 2.Username/Password in the payload of any XML-based proxy services

Let's talk about what is custom authentication token

Custom Authentication Token:

An authentication token is some kind of data, represented as XML or a string, that identifies an entity, such as an X509 client certificate. Typically, authentication tokens are designed to be used within specific security protocols.
A custom authentication token is an identity assertion token in a user-defined location in the request.  An identity assertion token is allowed in an HTTP header, in a SOAP header (for SOAP-based services), or in the payload of some non-SOAP proxy service. The Oracle Service Bus domain must include an Identity Assertion provider that supports the token type.Assertion provider that maps the client's credential to an Oracle Service Bus user. Oracle Service Bus uses this resulting username to establish a security context for the client


Oracle Service Bus uses the authenticated user to establish a security context for the caller. The security context established by authenticating a custom token or username and password can be used as the basis for outbound credential mapping and access control.
In this post I am going to talk about message level authentication(Username/Password in a SOAP header) 

In this mechanism client passes username/password information in SOAP header.Remember that this information can be passed in any identifiable XML elements and need not be named as UserName and PassWord 

Assume that we have designed a service to accept below request and let's see how we design proxy service to accept and process the authentication header

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns1="http://www.oracle.com">
<soapenv:Header>
<AuthenticationHeader>
<UserName>
<user123>  
</UserName>
<PassWord>
<pasword123>
</PassWord>
</AuthenticationHeader>
</soapenv:Header>
<soapenv:Body>
</soapenv:Body>
</soapenv:Envelope>    Proxy service configuration to accept  
  1. Create a WSDL based proxy service
  2. Go to  Security tab
  3. Go to Custom Authentication section and select 'Custom User Name and Password' as Authentication Type
  4. In User Name XPath, enter in same line  declare namespace ns1="http://www.oracle.com";./ns1:AuthenticationHeader/ns1:UserName/text()
  5. In User Password XPath,enter in same line  declare namespace ns1="http://www.oracle.com";./ns1:AuthenticationHeader/ns1:PassWord/text()
  6. Leave Context Properties  empty

user123 has to be configured in appropriate authentication provider of WLS
Test the proxy service by passing above sample request then OSB will authenticate the user and establish security context
Also try testing by passing wrong user name/password in the SOAP header then you will see authentication failure errors

HttpOutboundMessageContext.RetrieveHttpResponseWork.run: java.lang.ArrayIndexOutOfBoundsException

When anyone see below error in OSB logs then need to think about applying a patch

[WliSbTransports:381304]Exception in HttpOutboundMessageContext.RetrieveHttpResponseWork.run: java.lang.ArrayIndexOutOfBoundsException
at weblogic.utils.io.ChunkedInputStream.read   Seems this error happens when ssl is configured and there is no clarity/explanation from Oracle on why this error is thrown.
One of the possible explanations is, after encrypting using ssl cipher suite payload is becoming too large.


Please check metalink with bug# 14747231 and apply the patch. This patch resolved the issue