Monday, 10 October 2016

Install Oracle ICS On Premise

Introduction


Oracle Integration Cloud Service allows customers having a subscription to install the product in their On Premise site.
This is really useful in the following situations:
  • You need to create integrations between On Premise Applications;
  • You are developing a Custom Adapter using the Cloud Adapter SDK;
In the first scenario we can also use the Connectivity Agent to create a tunnel between the Cloud and our On Premise site and create the connection in the ICS Cloud instance configuring our agent in the Connection Configuration page. But if you only need to integrate two On Premise applications you can install ICS in our On Premise and create the integration locally. 
In the second scenario we need to register our Custom Adapter in ICS to test it and verify it is working as expected before publish it on the Cloud. 

System Requirements


Before installing on-premises Oracle Integration Cloud Service ensure that you satisfy the following prerequisites on your on-premises host:
  • Operating system: Oracle Enterprise Linux 6 UC4 or above
  • CPUs: 2
  • Physical memory: 8 GB
  • Hard disk space: 100 GB
  • Database:
    • Java Database (JavaDB). This is the default database.
    • Oracle Database (XE or Standard). If you select this database option during installation, you are prompted to provide specific Oracle Database details.

On Premise Host


To install ICS On Premise I used a host running Oracle Linux 7 matching the requirements above. In this host I created an oracle user having its Home folder in /home/oracle. Before starting the installation, I created the directory /home/oracle/ics to store the installer and all the ICS files.

Download ICS Execution Agent


To install Oracle ICS on premise we need to download the Execution Agent installer. This is a self-extracting Linux bash script.

The installer can only be downloaded from your Integration Cloud Service instance and can only be run on a Linux environment. In this post I used an ICS instance version 16.2.5.

To download the installer, follow the steps below:
  1. Log in to the instance of Oracle Integration Cloud Service to which you are subscribed.
  2. In the Integration Cloud Service toolbar, click Designer.
  3. On the Designer Portal, click Agents.
  4. The Agent Groups page is displayed.
  5. Click Download Agent Installer.
  6. Select Execution Agent. The execution agent is used for On Premise installations of Oracle Integration Cloud Service.
  1. Select Save File when prompted to save the ZIP file to a directory location on your on-premises host.
  2. Unzip the ZIP file in the folder /home/oracle/ics. The ics-executionagent-installer.bsx execution agent file is included in the ZIP file.
  1. Change the file permissions of the ics-executionagent-installer.bsx file to be executable.

    • chmod 755 ics-executionagent-installer.bsx

Install Oracle ICS


Execute the installer.

  • ./ics-executionagent-installer.bsx

This starts the installation. During the installation, you are prompted to specify authentication and configuration details. The table below shows the parameters I entered during the process

When Prompted With the Following...
Enter…
Enter your ICS subscription URL for authentication
https://<my-subscription-url>:7002/ics
Enter ICS subscription Username
<my ICS Username>
Enter ICS subscription Password
<my ICS Password>
Enter HTTPS Proxy Server Host Name
Enter
Enter HTTPS Proxy Server Port Number
Enter
What Do You Want to call this Execution Agent?
CSC-ICS-OnPremise
Press enter to accept the default path or enter a new install path
Enter
Enter the user name (cannot be root) to be used for install
oracle
Enter the group (groups <user> will list the groups of a user) of the user to be used for install
oracle
Press enter to accept the default value or enter a new port number
Enter
Press enter to accept the default value or enter a new port number
Enter
Enter the password for the default user weblogic
My secret password
Select the type of database to use (JavaDB or Oracle):

JavaDB

More information about these parameters can be found here. 
The installation process will take about 1 hour and 40 minutes. After the installation completed successful you will see the following:


I started the installer from the directory /home/oracle/ics and accepted the default installation location, this will create the following directories structure:
  • Oracle Base (OB): /home/oracle/ics/ICSOPInstall/ICSOP
  • Oracle Home (OH): OB/app/Oracle/Middleware/Oracle_Home
  • Domain Home (DH): OB/data/user_projects/domains
During the installation the installer also configured and started the Compact Domain available at:
  • Compact Domain (CD): DH/compact_domain
We can now access the ICS Console available at the address: http://<host-ip>:<port>/ics  



Verify the Agent Installation 


After the installation the execution agent should be listed in your ICS cloud instance. To verify that do the following: 
  1. Log in to the instance of Oracle Integration Cloud Service to which you are subscribed.
  2. In the Integration Cloud Service toolbar, click Designer.
  3. On the Designer Portal, click Agents.
  4. The Agent Groups page is displayed.


  1. In the Execution Agent Group click to expand the menu and select agents

Here you should see the agent just installed.

Solve the Proxy Issue


I don’t have any proxy so during the installation I pressed Enter to skip the proxy configuration. However, not configuring the proxy could generate the following error when accessing remote resources


The error is caused by an empty proxy Port. (See here for more details)
To solve this error, change the proxy settings by editing:

DH/compact_domain/bin/setICSDomainEnv.sh

This file contains the proxy settings:

#!/bin/sh
EXTRA_JAVA_PROPERTIES="${EXTRA_JAVA_PROPERTIES} -Dhttps.proxyHost= -Dhttps.proxyPort= -Dhttp.proxyHost= -Dhttp.proxyPort="
EXTRA_JAVA_PROPERTIES="${EXTRA_JAVA_PROPERTIES} -Dweblogic.security.SSL.minimumProtocolVersion=TLSv1.0"
EXTRA_JAVA_PROPERTIES="${EXTRA_JAVA_PROPERTIES} -DExecutionContext=ICS_ON_PREMISE"
export EXTRA_JAVA_PROPERTIES

Comment the line below:

#EXTRA_JAVA_PROPERTIES="${EXTRA_JAVA_PROPERTIES} -Dhttps.proxyHost= -Dhttps.proxyPort= -Dhttp.proxyHost= -Dhttp.proxyPort="

Restart the server.

The result of this is that ICS will not use a proxy server anymore


Documentation Links


Tuesday, 4 October 2016

Installing Oracle Event Processing 12.1.3

Introduction



Oracle Event Processing (OEP) consists of the Oracle Event Processing server, Oracle Event Processing Visualizer, Oracle Stream Explorer, a command-line administrative interface.
In this post I will show how to install Oracle Event Processing 12.1.3 and configure a domain using both Graphical and Silent modes.
To develop OEP applications we can use both Oracle Stream Explorer and the Oracle JDeveloper Integrated Development Environment (IDE).The easiest way to get the Oracle JDeveloper is to install a SOA Suite 12c Quick Start Distribution.  
Oracle Fusion Middleware 12.1.3 products require JDK7.0 Update 55 or later. Before starting the installation, make sure that you have a working Java Development Kit (JDK) environment.  To check your java version open a command prompt and type the following command: 

>java -version



Directories Structure


During the installation and domain configuration process, you must provide the locations for these directories: Oracle Home, Domain Home.
Create the base location (Oracle base) on your system /u01/app/oracle and from there, two separate branches config and product. The product directory will contain the product binary files and all of the Oracle home directories. The config directory will contain your domain data.


The following directories are used in examples throughout this post:
  • ORACLE_HOME: /u01/app/oracle/product/12.1.3/oep 
  • DOMAIN_HOME: /u01/app/oracle/config/12.1.3/oep/domains 
  • TMP: /temp
be sure to replace these directories with the actual directories on your system.

Obtain the Product Distribution


  1. Go to Oracle Software Delivery Cloud. 
  2. Search the Stream Explorer 
  3. Select the platform.


  1. This will download the following 2 files:
    • V74788-01_1of2.zip
      This archive contains the OEP installer jar file fmw_12.1.3.0.0_oep.jar
    • V74788-01_2of2.zip
      This archive file contains the Stream Explorer Patch
  1. Unzip both files in the TMP folder.

Installing Oracle Event Processing


We can use the Oracle Event Processing installer in the following modes: 
  • Graphical Mode
  • Silent Mode

Graphical Mode


  1. Open a Command Prompt as Administrator and navigate to the TMP folder

    > cd /temp

  2. Launch the installation program by invoking the following command:

    > java -jar fmw_12.1.3.0.0_oep.jar

  3. The installation wizard will launch and the installation welcome screen should appear
  1. Click Next.

  1. Click on Browse and navigate to the folder where the Oracle Event Processing home should be placed.
  2. Click Next.
  1. Choose Event Processing with Examples to install the event server with the example applications.
  2. Click Next.
  1. Click Next.

  1. Click Install to start the installation. This will take a few minutes and after that the following screen should appear.
  1. After the installation finishes, click Next and the following screen should show the summary of the installation.
  1. Click Finish.
By that the Oracle Event Processing server software has been installed. In order to use it, we have to create an Oracle Event Processing domain.
Note: An Oracle Event Processing installation does not include Oracle Fusion Middleware Infrastructure, so only Standalone-server domains may be created for Oracle Event Processing. A standalone-server domain can later be incorporated into a Multiserver domain, if needed.

Silent Mode


Create the following files in the /temp folder: 
  • install.file
  • oraInst.loc (Linux only)

install.file


Copy and paste the following content in the install.file:

[ENGINE]

#DO NOT CHANGE THIS.
Response File Version=1.0.0.0.0

[GENERIC]

#Set this to true if you wish to skip software updates
DECLINE_AUTO_UPDATES=true

#The oracle home location. This can be an existing Oracle Home or a new Oracle Home
ORACLE_HOME=C:\\u01\\app\\oracle\\product\\12.1.3\\oep

#Set this variable value to the Installation Type selected. e.g. Event Processing, Event Processing With Examples.
INSTALL_TYPE=Event Processing With Examples


Set the ORACLE_HOME parameter accordingly to your directories structure.

oraInst.loc


Copy and Paste the following content in the oraInst.loc:


inventory_loc=/u01/oracle/.inventory
inst_group=oracle


Set inventory_loc (inventory location) and inst_group (installation group) parameters accordingly to your Linux environment.

Run the installer


  1. Open a Command Prompt as Administrator and navigate to the TMP folder

    > cd /temp

  2. Launch the installation program by invoking the following command:

    • Windows

      > java -jar fmw_12.1.3.0.0_oep.jar -silent -responseFile C:\\temp\\install.file

    • Linux

      > java -jar fmw_12.1.3.0.0_oep.jar -silent -responseFile /temp/install.file -invPtrLoc /temp/oraInst.loc

Note: you must use the absolute path for install.file and oraInst.loc.

Configuring an Oracle Event Processing Domain


An Oracle Event Processing standalone-server domain contains a single Oracle Event Processing server. We can create a new domain using the Graphical Mode or in Silent Mode.

Graphical Mode


The Configuration Wizard is an administration tool that enables you to create a new domain or update an existing domain.
By default, the Configuration Wizard creates a standalone-server domain, which can be the starting point for a multi-server domain.
  1. Open the Terminal and navigate to the folder ORACLE_HOME/oep/common/bin 

  2. Launch the Configuration Wizard in graphical mode by invoking the following command:

    • Windows

      > config.cmd

    • Linux

      > ./config.sh

  3. The Configuration Wizard welcome screen should appear.
  1. Click Next.
  1. Choose Create a new OEP domain and click Next.
  1. In the Configure Administrator username and Password screen enter oepadmin into the User name field and welcome1 into the User password and Confirm user password field.
  2. Click Next.
  1. On the Configure Server screen, enter oep_server into the Server name field and 9002 into the Server listen port field.
  2. Click Next.
  1. On the Configure Domain Identity Keystore screen enter welcome1 into the Keystore password field and Confirm keystore password field.
  2. Click Next.
  1. On the Configuration Options screen, accept the defaults and click Next.
  1. On the Create OEP Domain screen, enter oep_domain into the Domain name field and accept the default for the Domain location field.
  2. Click Create to start the domain creation process. The progress is shown on the Creating Domain screen.
  1. Click Done to exit the Configuration Wizard.

Silent Mode


Silent mode is a non-interactive way to create or update a domain and requires an XML properties file for selecting configuration options. 

Create the XML Properties file

  1. Create an XML empty file in the TMP folder. (You can name the file anything you want as long as it has a .xml extension. For this post, the file name is silent.xml). 

  2. Copy the contents of the following sample XML file into the silent.xml file.

    <?xml version="1.0" encoding="UTF-8"?>
    <bea-installer xmlns="http://www.bea.com/plateng/wlevs/config/silent">
      <input-fields>
        <data-value name="CONFIGURATION_OPTION" value="createDomain" />
        <data-value name="USERNAME" value="oepadmin" />
        <data-value name="PASSWORD" value="welcome1" />
        <data-value name="SERVER_NAME" value="oep_server" />
        <data-value name="DOMAIN_NAME" value="oep_domain" />
        <data-value name="DOMAIN_LOCATION" value="/home/oracle/config/12.2.1/oep/domains" />
        <data-value name="NETIO_PORT" value="9002" />
        <data-value name="KEYSTORE_PASSWORD" value="welcome1" /> 
      </input-fields>
    </bea-installer>

  3. In the silent.xml file, edit the values to reflect your configuration.

  4. Save the file

Use the Silent mode and Generate Log


  1. Open a Command Prompt and navigate to the folder ORACLE_HOME/oep/common/bin:

  2. Run the config command to start the wizard in silent mode and generate a log file to catch failures due to incorrect XML property entries:

    • Windows

      >config.cmd -mode=silent -silent_xml=/temp/silent.xml - log=/temp/create_domain.log

    • Linux

      >./config.sh -mode=silent -silent_xml=/temp/silent.xml -log=/temp/create_domain.log
Note: you must use the absolute path for silent.xml and create_domain.log.

Install Stream Explorer



Oracle Stream Explorer (SX) is distributed as an OPatch. We already downloaded and extracted this patch in the /temp folder. This patch needs to be installed on top of Oracle Event Processing 12.1.3 installation. OPatch can be found in your Fusion Middleware's product's ORACLE_HOME/OPatch. OPatch uses the ORACLE_HOME environment variable to identify the Oracle home you are planning to patch.
To install the SX follow the steps below:
  1. Open a terminal windows and navigate to the patch folder TMP/20225179

    > cd /temp/20225179

  2. Set ORACLE_HOME environment variable:

    • Windows

      >set ORACLE_HOME=/u01/app/oracle/product/12.1.3/oep

    • Linux

      >export ORACLE_HOME=/u01/app/oracle/product/12.1.3/oep

  3. Run the OPatch apply command

    • Windows

      >%ORACLE_HOME%/OPatch/opatch apply

    • Linux

      >$ORACLE_HOME/OPatch/opatch apply


 By that Oracle Stream Explorer software has been installed.

Starting OEP server


To start the OEP server do the following:
  1. Open the terminal and navigate to DOMAIN_HOME/oep_domain/oep_server

  2. Run the startwlevs.cmd script

    • Windows

      >startwlevs.cmd

    • Linux

      >./startwlevs.sh

The server is now up and running.

Oracle Event Processing Visualizer is available at  http://host-ip:9002/wlevs.


Oracle Stream Explorer is available at  http://host-ip:9002/sx.


Stop OEP server


To stop the OEP server do the following:
  1. Open the terminal and navigate to DOMAIN_HOME/oep_domain/oep_server

  2. Run the stopwlevs script

    • Windows 

      >stopwlevs.cmd
    • Linux 

      >./stopwlevs.sh

The server is now stopped.

Documentation 


Oracle Event Processing Get Started
Administering Oracle Event Processing
Getting Started with Oracle Stream Explorer

Friday, 15 April 2016

Oracle Event Processing JMS Adapters: Custom Conversion using JAXB and EclipseLink Moxy

In this article, we will look at the very common interaction between Oracle Event Processing and JMS. JMS is a commonly used channel for decoupled exchange of messages or events. An OEP Application can both consume messages from a JMS destination, through a JMS inbound Adapter, and publish findings to a JMS destination with a JMS outbound Adapter. The Oracle Event Processing JMS adapters support any JMS service provider that provides a Java client that is compliant with Java EE. In this demonstration we will use WebLogic as JMS provider.
The inbound adapter converts incoming JMS map messages to an Event.


The outbound JMS adapter converts events into a JMS map message and sends the JMS message to a JMS destination.


When the JMS message type is not a Map message, we can still use JMS adapters, but we need to convert the incoming type to the desired event type and vice versa in our code.
Our objective in this article is demonstrate how customize the inbound and outbound conversion, using Java Architecture for XML Binding (JAXB) and EclipseLink Moxy, when the JMS message is text message in XML format.
Oracle Event Processing provides a simplified interface for JAXB mapping capabilities in adapters and event beans to marshall and unmarshall event data between XML and Java objects. The JAXB interface supports the JAXB 2.2 specification and EclipseLink Moxy provider extensions.
EclipseLink Moxy provides extensions that enable you to map between an existing XML schema and a predefined set of Java classes without modifying the XML schema or the Java classes without providing annotations. We provide the mapping information in an external metadata file using a XPath syntax. 
For this demonstration we will create an OEP Application that will consume messages published in a JMS queue called “OrderError” using a JMS inbound Adapter and publish them to another queue “OrderErrorOut” using a JMS outbound adapter.


The published message will be in the XML format and will follow the OrderError.xsd schema showed below:


<?xml version="1.0" encoding="windows-1252" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.example.org"
targetNamespace="http://www.example.org" elementFormDefault="qualified">                    

<xsd:element name="orderError">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="orderId" type="xsd:ID"/>
        <xsd:element name="customerId" type="xsd:ID"/>
        <xsd:element name="errorCode" type="xsd:string"/>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
</xsd:schema>

We will customize the message conversion using a converter bean. In OEP applications the adapter or event bean that requires JAXB functionality obtains the functionality by injection of a bean that implements the com.oracle.cep.mappers.api.Mapper interface.

Create JMS Queues in WebLogic
Access the WebLogic console and create the JMS queues and the connection factory.

  
Import Packages
To make a package available to our application at runtime for OEP, we need to add it to the application's MANIFEST.MF file to the Import Package section (since the OEP server is OSGi-based). For our demonstration we need to import the following packages:
  • com.bea.wlevs.adapters.jms.api
  • javax.jms
  • com.oracle.cep.mappers.api
  • com.oracle.cep.mappers.jaxb
The MANIFEST.MF file will look as in the picture below:

                                                                                           
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: OrderJMS.JAXBConversionDemo
Bundle-SymbolicName: OrderJMS.JAXBConversionDemo
Bundle-Version: 1.0.0
Bundle-Localization: bundle
Bundle-Vendor: %project.vendor
Bundle-ClassPath: .
Import-Package: com.bea.wlevs.configuration;version="12.1.3",
 com.bea.wlevs.ede.api;version="12.1.3",
 com.bea.wlevs.ede.impl;version="12.1.3",
 com.bea.wlevs.ede.spi;version="12.1.3",
 com.bea.wlevs.ede;version="12.1.3",
 com.bea.wlevs.management.spi;version="12.1.3",
 com.bea.wlevs.spring.support;version="12.1.3",
 com.bea.wlevs.spring;version="12.1.3",
 com.bea.wlevs.util;version="12.1.3",
 com.bea.wlevs.adapters.jms.api;version="12.1.3", 
 javax.jms;version="1.1.4",
 com.oracle.cep.mappers.api;version="12.1.3",
 com.oracle.cep.mappers.jaxb;version="12.1.3",
 org.apache.commons.logging;version="1.1.1",
 org.springframework.beans.factory.config;version="3.1.1",
 org.springframework.beans.factory;version="3.1.1",
 org.springframework.beans;version="3.1.1",
 org.springframework.core.annotation;version="3.1.1",
 org.springframework.osgi.context;version="1.2.0",
 org.springframework.osgi.extensions.annotation;version="1.2.0",
 org.springframework.osgi.service;version="1.2.0",
 org.springframework.util;version="3.1.1"


We also need to add them to the application classpath in jdeveloper.


Event Type
Create the “OrderErrorEvent” JavaBean to map the XML message. The Class will have an attribute for each XML element we need to map. Below is the java code: 

                                                                                           
package com.csc.oep.ordererror;

public class OrderErrorEvent {
   
    private String customerId;
    private String errorCode;
    private String orderId;
   
    public OrderErrorEvent() {
        super();
    }

    public void setCustomerId(String customerId) {
        this.customerId = customerId;
    }

    public String getCustomerId() {
        return customerId;
    }

    public void setErrorCode(String errorCode) {
        this.errorCode = errorCode;
    }

    public String getErrorCode() {
        return errorCode;
    }

    public void setOrderId(String orderId) {
        this.orderId = orderId;
    }

    public String getOrderId() {
        return orderId;
    }
}


To use this bean as an Event Type we need to add it in our Event Repository. Open the EPN-Diagram and click on Event Type tab. To add a new Event Type click on the plus greed icon, enter the event type name as “OrderErrorEvent”, select the “Properties defined in a Java Bean”, click the glass icon and select the Java Bean just created.

  
This operation will add the Event Type to the Event Repository in the assembly file as showed below:

…                                                                                          
<wlevs:event-type-repository >
   <wlevs:event-type type-name="OrderErrorEvent">
     <wlevs:class >com.csc.oep.ordererror.OrderErrorEvent</wlevs:class>
   </wlevs:event-type>
</wlevs:event-type-repository>
…

Mapper
OEP uses JAXB to handle XML payloads, so in order to understand what an event type looks like in the XML format; We want to use an EclipseLink Moxy external metadata file to specify the mapping details, so create a new xml file, call it “orderErrorEventMetadata.xml” and put the follow content in it:

                                                                                           
<?xml version="1.0"?>
<xml-bindings xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm" 
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xmlns:xs="http://www.w3.org/2001/XMLSchema"
              xml-accessor-type="PROPERTY"
              package-name="com.csc.oep.ordererror.OrderErrorEvent">
   
       <xml-schema element-form-default="QUALIFIED"
                   namespace="http://www.example.org" >
          <xml-ns prefix="ns0" namespace-uri="http://www.example.org" />
       </xml-schema>
       <java-types>
          <java-type name="com.csc.oep.ordererror.OrderErrorEvent">
            <xml-root-element name="orderError"/>
              <java-attributes>
                <xml-element java-attribute="customerId" />
                <xml-element java-attribute="errorCode" />
                <xml-element java-attribute="orderId" />
             </java-attributes>
          </java-type>
       </java-types>
</xml-bindings>


The file above must be created in the wlevs/mappers/jaxb directory as showed below:


To start using the XML mapper, we need to configure in the assembly file a bean factory for the following class: com.oracle.cep.mappers.jaxb.JAXBMapperFactory.
Listing below show the XML mapper defined in the assembly file:


….                                                                                         
<bean id="xmlMapper" class="com.oracle.cep.mappers.jaxb.JAXBMapperFactory"  
       factory-method="create">
       <property name="eventTypeName" value="OrderErrorEvent" />
       <property name="metadata" value="orderErrorEventMetadata.xml" />
   </bean>
….

Converter Bean
The inbound and outbound converter bean implement methods in the following two inbound and outbound interfaces
  • Inbound: com.bea.wlevs.adapters.jms.api.InboundMessageConverter. You have to implement its convert method. The return value is a List of events to be passed downstream.
public List convert(Message message)
     throws MessageConverterException, JMSException;
  • Outbound: com.bea.wlevs.adapters.jms.api.OutboundMessageConverter interface. We have to implement its convert method. The return value is a List of JMS messages.
public List<Message> convert(Session session, Object event)
     throws MessageConverterException, JMSException;

Below is the code of our converter bean :

                                                                                           
package com.csc.oep.ordererror;

import com.bea.wlevs.adapters.jms.api.InboundMessageConverter;
import com.bea.wlevs.adapters.jms.api.MessageConverterException;
import com.bea.wlevs.adapters.jms.api.OutboundMessageConverter;
import com.oracle.cep.mappers.api.Mapper;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;


public class JmsJaxbMessageConverter implements InboundMessageConverter,   
                                                OutboundMessageConverter {
   
    private OrderErrorEvent result;
    private Mapper xmlMapper;
   
    public JmsJaxbMessageConverter() {
        super();
    }

    @Override
    public List convert(Message message) throws MessageConverterException{
       
      List<OrderErrorEvent> eventsList = new ArrayList<>();
       
      if(message instanceof TextMessage ){
           
          TextMessage textMessage = (TextMessage) message;
           
          try {
              StringReader reader = new StringReader(textMessage.getText());
              result = (OrderErrorEvent) xmlMapper
                                            .createUnmarshaller()
                                            .unmarshal(new StreamSource(reader));
                eventsList.add(result);
                System.out.println("JMS Message Converted to OrderErrorEvent");
            } catch (Exception e) {  
                System.out.println(e.getMessage());  
            }    
           
        } else {        
             System.out.println("NO TEXT MESSAGE");   
        }
      
        return eventsList;
    }

    @Override
    public List<Message> convert(Session, Object object)
                    throws MessageConverterException, JMSException {
       
        String strResult= null;
       
        try {
            OrderErrorEvent errorEvent = (OrderErrorEvent)object;      
            StringWriter writer = new StringWriter();
            StreamResult result = new StreamResult(writer);
            xmlMapper.createMarshaller().marshal(errorEvent, result);
            strResult = writer.toString();
           
            System.out.println("OrderErrorEvent Converted to JMS Message");
           
        } catch (Exception e) {
       
            e.printStackTrace();
       
        };
      
        TextMessage m = session.createTextMessage();
        m.setText(strResult);
        List<Message> result = new ArrayList<Message>();
        result.add(m);
        return result;
    }

    public void setXmlMapper(Mapper xmlMapper) {
        this.xmlMapper = xmlMapper;
    }

    public Mapper getXmlMapper() {
        return xmlMapper;
    }

}


As you can see from the code above the converter bean will use the xml Mapper to perform marshall and unmarshall operations, so we need to inject the mapper into the bean. Below is the converter bean configured in the assembly file:

…                                                                      
<bean id="jmsJaxbMessageConverter"
         class="com.csc.oep.ordererror.JmsJaxbMessageConverter">
        <property name="xmlMapper" ref="xmlMapper"/>
    </bean>
…

Event Processing Network
The diagram below show the EPN created for our demonstration.

The JMS Adapters are configured using the adapter.xml file showed below:

                                                                                           
<?xml version="1.0" encoding="windows-1252" ?>
<wlevs:config xmlns:wlevs="http://www.bea.com/ns/wlevs/config/application">

 <jms-adapter>
    <name>jms-inbound-adapter</name>
    <jndi-provider-url>t3://${host}:7001</jndi-provider-url>
    <jndi-factory>weblogic.jndi.WLInitialContextFactory</jndi-factory>
    <connection-jndi-name>jms/OrderErrorCF</connection-jndi-name>
    <destination-jndi-name>jms/OrderErrorQueue</destination-jndi-name>
    <session-transacted>false</session-transacted>
  </jms-adapter>
 
 <jms-adapter>
    <name>jms-outbound-adapter</name>
    <jndi-provider-url>t3:// ${host}:7001</jndi-provider-url>
    <jndi-factory>weblogic.jndi.WLInitialContextFactory</jndi-factory>
    <connection-jndi-name>jms/OrderErrorCF</connection-jndi-name>
    <destination-jndi-name>jms/OrderErrorOutQueue</destination-jndi-name>
    <session-transacted>false</session-transacted>
  </jms-adapter>

</wlevs:config>


The CQL processor is configured in the processor.xml file.

                                                                                           
<?xml version="1.0" encoding="UTF-8"?>
<wlevs:config xmlns:wlevs="http://www.bea.com/ns/wlevs/config/application">

  <processor>
    <name>OrderErrorProcessor</name>
    <rules>
      <query id="AllErrorQuery"><![CDATA[
         select * from OrderErrorInputChannel
    ]]></query>
    </rules>
  </processor>

</wlevs:config>


The query will pass any event from the input channel to the output channel. To complete our configuration, we need to instruct OEP to use the converter bean to convert messages processed by the JMS adapters. We do this specifying the instance property “converterBean” in the assembly file for both the inbound and outbound JMS adapters.

…                                                                                          
  <wlevs:adapter id="jms-inbound-adapter" provider="jms-inbound">
      <wlevs:instance-property name="converterBean" ref="jmsJaxbMessageConverter"/>
      <wlevs:listener ref="OrderErrorInputChannel"/>
    </wlevs:adapter>

    <wlevs:adapter id="jms-outbound-adapter" provider="jms-outbound">
        <wlevs:instance-property name="converterBean" ref="jmsJaxbMessageConverter"/>
    </wlevs:adapter>
…

Test the Application
Deploy the application into your OEP server. To test the application, we need to:
  1. produce a JMS message in the OrderErrorQueue; 
  2. verify that the converter bean converts it to an OrderErrorEvent object.    
  3. verify that the ErrorEventObject is converted back to the XML message;
  4. verify that the OrderErrorOut queue receive the XML message.
Below is an example message to use for our test:

                                                                                           
<?xml version="1.0" encoding="UTF-8" ?>
   <ns0:orderError xmlns:ns0="http://www.example.org">
   <ns0:orderId>ID-1</ns0:orderId>
   <ns0:customerId>ID-2</ns0:customerId>
   <ns0:errorCode>ASD234</ns0:errorCode>
</ns0:orderError>


Use the WebLogic console to produce a new JMS message in The OrderError queue and copy the message above as body.
The converter bean will print a message to the server console after any conversion. We can verify from the server console that the message is been converted to the OrderErrorEvent object and then again back to XML.


Now, using again the WebLogic console, we can verify that the message is been received from the OrderErrorOut queue.


A copy of the source code is available here