Thursday, May 19, 2011

Weblogic 11g - MDB accessing secure JMS Queue

Now that we have a secure queue (from the prevous post), let's leverage that from an MDB.

The MDB will simply consume the messages - the only logic our onMessage() requires is -

public void onMessage(Message message) {

try{


if (message instanceof TextMessage) {
TextMessage txtMsg = (TextMessage) message;
System.out.println("**** Message: " + txtMsg.getText());
}
}

catch(Exception e){
e.printStackTrace();
}


Step 1. - Create a new project in JDeveloper

Step 2. - Create a new MDB in the project
-- File --> New --> EJB --> Message Driven Bean --> 2.1




Step 3 - Set up security
-- run-as identity is specified in the ejb-jar.xml
-- security-role is specified in the ejb-jar.xml

-- Map run-as identity to principal-name in weblogic-ejb-jar.xml

Step 3.1 - ejb-jar.xml



-- These properties can be set via the properties palette (Right mouse click on the bean and select Properties)

Step 3.2. weblogic-ejb-jar.xml



-- These properties can also be set via the palette



Step 4. Deploy

Step 5. Test



-- Check WLS log for the output message



-- Change principal-name in weblogic-ejb-jar.xml to weblogic

-- Re-test

Wednesday, May 18, 2011

Weblogic 11g - securing JMS artifacts

Scenario -

I need to secure a JMS Queue.
Only the members of the JMSUSERGROUP (e.g.JMSUSER) -
should be able to access it.







Create JMS Server/JMS Module/Connection Factory/ Queue



Add Security Role/Policy -





Test with JMS Client
---------------------------------------------------------

public class JMSClient {
public static void main(String [] args) throws JMSException,
NamingException {
final Context ic = getInitialContext();
System.out.println("*** CONTEXT =");
final QueueConnectionFactory qcf = (QueueConnectionFactory)ic.lookup("jms/MyCF2");
// Lookup should specify the queue name that is mentioned as "mappedName" in MessageDriven Bean.


final Queue destQueue = (Queue)ic.lookup("jms/MyQueue3");

final QueueConnection connection = qcf.createQueueConnection("JMSUSER", "welcome1");
try {
final QueueSession session = connection.createQueueSession(false, 0);

final QueueSender sender = session.createSender(destQueue);
final TextMessage msg = session.createTextMessage("Hello from Galway - fans of FCN");
sender.send(msg);


} catch (Exception ex) {
ex.printStackTrace();
} finally {
connection.close();
ic.close();
}
}

---------------------------------------------------------

Test with JMSUSER -->




Test with weblogic -->

Tuesday, May 17, 2011

Basic JMS Clustering with Weblogic 11g - standalone Queue/Service Migration

In this scenario we need to make a standalone Queue highly available.

The Queue will be targeted to JMSServer2 running on MgdServer2.
If MgdServer2 goes down then the JMSServer will be migrated to MgdServer1.


Here I strongly suggest you consult the weblogic docs to understand fully
the concepts. Here is a short extract from the aforementioned -
------------------------------------------------------------------------
In a WebLogic Server cluster, most subsystem services are hosted homogeneously on all server instances in the cluster, enabling transparent failover from one server to another. In contrast, pinned services, such as JMS-related services, the JTA Transaction Recovery Service, and user-defined singleton services are hosted on individual server instances within a cluster—for these services, the WebLogic Server migration framework supports failure recovery with service migration, as opposed to failover.

Service-level migration in WebLogic Server is the process of moving the pinned services from one server instance to a different available server instance within the cluster. Service migration is controlled by logical migratable target, which serves as a grouping of services that is hosted on only one physical server in a cluster. You can select a migratable target in place of a server or cluster when targeting certain pinned services. High availability is achieved by migrating a migratable target from one clustered server to another when a problem occurs on the original server. You can also manually migrate a migratable target for scheduled maintenance or you can configure the migratable target for automatic migration.



------------------------------------------------------------------------
Leading on from the previous post...

Create a second JMS Server - JMSServer2 and target to MgdServer2(Migratable)



Step 1 - Create a new JMS module /Connection Factory and Queue



Subdeployment targeted as follows -



Create the connection Factory and target as follows -





Create the Queue, target to JMSServer2





Test -

------------------------------------------

public static void main(String [] args) throws JMSException,
NamingException {
final Context ic = getInitialContext();
System.out.println("*** CONTEXT =");
final QueueConnectionFactory qcf = (QueueConnectionFactory)ic.lookup("jms/MyCF2");
// Lookup should specify the queue name that is mentioned as "mappedName" in MessageDriven Bean.
final Queue destQueue = (Queue)ic.lookup("jms/MyQueue2");
ic.close();
final QueueConnection connection = qcf.createQueueConnection();
try {
final QueueSession session = connection.createQueueSession(false, 0);
final QueueSender sender = session.createSender(destQueue);
final TextMessage msg = session.createTextMessage("Hello from Dublin - fans of FCN");
sender.send(msg);
-------------------------------------------

View message in the WLS console



We can also enable logging on the Queue





Re-test and view logs



Now stop MgdServer2 and re-test



View logs under MgdServer1

Basic JMS Clustering with Weblogic 11g - Uniform distributed destination

JMS is an integral part of many SOA/Integration projects.
Like any other resource, we want scalability and reliability for our JMS artifacts.

So here is a simple example based on the following simple WLS cluster I've set up





Example 1: Using a UDD(Uniform distributed destination)

Thanks to my colleague Santosh for his support here.

UDDs make sense for both reliability and scalability. Essentially the UDD Queue
will be deployed to my cluster and thus available on both of my managed servers.

Step 1 -Create a JMS Server (JMSServer1)
-- FileStore= JMSFileStore1
-- Target= MgdServer1(Migratable)





Step 2 - Create a JMS System Module for the ConnectionFactory & UDD Queue (JMSModuleCluster)







Step 4 - Test with a JMS Client

--------------------------------------------------
package jmsclient;

import java.util.Hashtable;

import javax.jms.JMSException;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueSender;
import javax.jms.QueueSession;
import javax.jms.TextMessage;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

public class JMSClient {
public static void main(String [] args) throws JMSException,
NamingException {
final Context ic = getInitialContext();
System.out.println("*** CONTEXT =");
final QueueConnectionFactory qcf = (QueueConnectionFactory)ic.lookup("jms/MyCF");
// Lookup should specify the queue name that is mentioned as "mappedName" in MessageDriven Bean.
final Queue destQueue = (Queue)ic.lookup("jms/MyDistQueue");
ic.close();
final QueueConnection connection = qcf.createQueueConnection();
try {
final QueueSession session = connection.createQueueSession(false, 0);
final QueueSender sender = session.createSender(destQueue);
final TextMessage msg = session.createTextMessage("Hello from Lichtenau - fans of FCN");
sender.send(msg);
} catch (Exception ex) {
ex.printStackTrace();
} finally {
connection.close();
}
}

private static Context getInitialContext() throws NamingException {
Hashtable env = new Hashtable();
// Add InitialContext property assignments here.
env.put( Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory" );
// Note that by default WebLogic server is not created with security, so credentials are not needed.
// TODO: Verify the server address and port number
env.put(Context.PROVIDER_URL, "t3://localhost:7003,localhost:7004");
env.put(Context.SECURITY_PRINCIPAL, "weblogic");
env.put(Context.SECURITY_CREDENTIALS, "welcome1");
return new InitialContext( env );
}
}

------------------------------------------------------------

You can stop any of the 2 managed servers and re-test.
The Queue is alway available.

Tuesday, May 10, 2011

SOA Suite 11.1.1.5.0 now available

software
http://www.oracle.com/technetwork/middleware/soasuite/downloads/index.html

docs
http://www.oracle.com/technetwork/middleware/soasuite/documentation/index.html#111150

Monday, May 9, 2011

EDN via PL/SQL

Scenario:

Raise an event on an insert to a DB table. Event is then consumed by a SOA composite.
In this case, this is a viable alternative to using a DB adapter(polling) as our table, in this scenario, only gets a couple of inserts per day.

XSD used



Create a sample ORDERS table in SCOTT's schema



Create a SOA app/project in JDev

Create an Event Definition in the project



Import the XSD



Here is the edl file



Create a PLSQL stored procedure that will call the following –



Our parameters, taken in part from the edl above, are as follows –
NAMESPACE – http://www.example.org
LOCAL_NAME - anything you like e.g. Our Event Name - NewOrder
PAYLOAD – This is our order





PRIORITY – DEFAULT is 5 so we don’t need to enter this.
However there is some “wrapper” overhead.



eb:business-event xmlns:eb=http://oracle.com/fabric/businessEvent
This is the default, so no need to change.

xmlns:ob="http://schemas.oracle.com/events/edl/NewOrder">
Set to the namespace from our edl.

eb:name ob:NewOrder
This is set to the EventName e.g. NewOrder

eb:content
Contains the actual payload i.e. our Order

Test the PLSQL
There should be an entry in the dev_soainfra.EDN_EVENT_QUEUE_TABLE



Now back to the SOA app...

Create a Mediator that subscribes to the event



Then create a File Adapter(Write) using the same xsd



Deploy and test
- You can execute the procedure directly in JDev
- View the result in em



View the output file



Now we need to include the PLSQL code in the POST-INSERT trigger logic.
Create a POST-Insert trigger on the nc_orders table



Insert a row