Thursday, 25 December 2014

Oracle B2B 12c - HTTP Generic Channel with transport callout

First of all, season's greetings to everyone! 

Then, let me introduce this post saying that, already in the version 11g, a generic HTTP listening channel for message posting to B2B using the HTTP protocol was available. Any configured trading partner could use this generic channel to post messages to B2B.

A single common URL was available by default:
http://[host-name]:[host-port]/b2b/httpReceiver 

In this way, a single listening channel is able to serve multiple trading partners for every HTTP communications with B2B. 

When this channel is used, the process follows the default steps for message processing, namely:

  • Sender identification (i.e. using HTTP Header);
  • Document protocol/version/type identification ;
  • Agreement identification;
  • Message processing (parsing and validation);
  • Synchronous delivery to a back-end application.

The only differentiation factor is: since this channel is generic and not configurable or even available on the list of listening channels in B2B console, make it unavailable for channel callout configuration. 

This has now changed with the 12c version.

With the version 12c of B2B is now possible to define a generic HTTP transport callout and associate it with a specific transport level callout.

As of now, this is driven by an B2B configuration Fusion Middleware property that needs to be added on Oracle Enterprise Manager Fusion Middleware Control (EM) 

b2b.HTTPTransportCalloutName= [callout name] 
i.e. b2b.HTTPTransportCalloutName= InboundGeneralCallout

Note: Access the following Oracle documentation for full instruction on how to set EM B2B properties here

This is also isolated from the regular HTTP functionality since a new ulr is provided to be able to establish this new feature. 
There is now a separated URL to be used in case of setting a generic HTTP channel callout: 
http://[host-name]:[host-port]/b2b/calloutReceiver

With this, the callout will be triggered when the message is received in this URL and EM property is configured for a valid transport callout.

Wish you all a very prosperous 2015!

Friday, 19 December 2014

Oracle B2B 12c - Listening Channel activation and deactivation in bulk

With the version 12c of B2B the possibility to activate and deactivate all listening channels in one single command was introduced. Previously, it was necessary to provide the name of the listening channels to perform the action, what, in scenarios with a considerable number of listening channels, made the task ineffective.


Different scenarios can be pointed out where this functionality is extremely useful:
  • After importing a B2B configuration the channels are always in deactivated status. This command can be then executed in order to activate all the listening channels in bulk;
  • Deactivate all listening channels to stop momentously all message consumption for corrective or preventive reasons into B2B or back-end applications;
  • Switching the message consumption between two environments;


The feature is also provided in a command line based approach since is an extension to the already existing feature of enable/disable a particular listening channel. Therefore it is respecting the same prerequisites.

Prior to executing any B2B command line tool is necessary to set the following environment variables:

JAVA_HOME: Your Java home
ORACLE_HOME: Your oracle SOA home
ANT_HOME: Your ant home

For example:

export JAVA_HOME=/usr/java/jdk1.7.0_51
export ORACLE_HOME=/u01/fmw/soa/
export ANT_HOME=/u01/fmw/oracle_common/modules/org.apache.ant_1.9.2
export PATH=$PATH:$ANT_HOME/bin

After, the first command to execute is the one which create a jndi.properties file in the folder where the SOA ant build artefact are available. The jndi.properties file allows defining the connection details to execute any of the available B2B command tools.

cd $ORACLE_HOME\bin
ant -f ant-b2b-util.xml b2bcreate-prop

A jndi.properties files is created in the folder. Now is time to edit it in order to reflect the connection details.

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

All ready to run authenticated commands as the listening channel activation and deactivation command.

From the same directory where ant-b2b-util.xml exists execute:

ant -f ant-b2b-util.xml updatechannel -Dchannelname="*" -Dstate=active
ant -f ant-b2b-util.xml updatechannel -Dchannelname="*" -Dstate=inactive

By providing the channelname as “*” all the listening channels can be activated / deactivated.

Note: The operation is performed incrementally going throughout the listening channels and activating one by one. With a large number of listening channels it can take some time between the activation and the moment that all the channels start to consume messages. Be patient and check your logs and monitor B2B in order to check the message consumption is starting.

Thursday, 18 December 2014

Oracle B2B 12c - Document Callouts: The Concept

One of the coolest new features of that Oracle B2B 12c brings is the document callout.

Callouts had already an important role on previous releases of Oracle B2B and they allow for execution of custom Java code on different steps of a message process.

On previous versions we had already 2 types of callouts:

  • Transport or channel callouts: this type of callouts add the possibility to execute custom java code on the wire message, as soon as it is received on the channel on the inbound or before being sent for final delivery on the outbound
  • Agreement callouts: this type of callouts add the possibility to execute custom java code on the application message (the XML representation of the message) , just before being sent to the backend on the inbound or immediately after being received from the backend on the outbound.


With the new document callout B2B brings the possibility of executing custom java code to convert your raw format message into XML or vice-versa replacing the default xEngine as your parsing tool.
This is particularly useful for those complex messages that can not be defined using the document editor.

Note: For those of you still using Oracle B2B 11g this feature (and many others) is available by installation of patch SOA bundle Patch 19190139 11.1.1.7.5 

On a future post I will show you how to use this cool new feature!

Stay tunned!

Monday, 15 December 2014

Oracle B2B 12c – What’s New!

This post serves as the first of a series of posts dedicated to Oracle B2B.

What better way to start this series than to highlight the many new features have been added to Oracle B2B 12c which can change the landscape of the target usage for B2B.

Let's look at some of these new features:
  • Document Translation Callout Framework
    • Introduced Document Callout for custom document parsing (inbound), validation and construction (outbound)
  • Regular Expression Document Identification
  • Trading Partner Metadata API
    • Parameters, Identifiers and TP Agreements accessible via Java API and WS
  • SSL Support for SMTP
  • Trading Partner Identifier via Regular Expression
  • Batching of Custom Documents
  • xPath payload extraction from SOAP Body
  • xEngine (B2B Native Parser) API for EDIFACT
  • Bulk Listening Channel activation
  • Enriched exchange information on message metadata
    • Channel used
    • Agreement 
  • Priority on Document Identification
  • Message IN/OUT Collaboration by ID
  • Improved Provisioning Self Service 
    • Callouts
    • Identifiers
    • Parameters
    • Channel details
    • Incremental Update

Note: All of this features are available for the version 11g of SOA Suite by installation of patch SOA bundle Patch 19190139 11.1.1.7.5 

In 12.1.3 there's:
  • Support for streaming (effective process for large payloads)
  • MFT as an integration channel
  • Enhanced End2End monitoring and integration with Error Hospital
  • Local Policy Attachment for Web Services

In future posts we will go into more details on these and other B2B features.

Stay tunned!

Wednesday, 30 July 2014

Resolving localhost on clustered environment

After a clustered SOA Suite installation we were setting the deployment script to point to localhost when referencing another composites. Although, we were unable to resolve localhost connection in run time trowing the following exception every time that a composite tried to reference another composite:

oracle.fabric.common.FabricInvocationException
Tried all: '2' addresses, but could not connect over HTTP to server: 'localhost', port: '8101'

Turns out that the reason was related with the fact that the port 8101 was not listening on the localhost address. This was reveled executing the following command:

:~$ netstat -na | grep 8101

10.1.5.67.8101       172.28.251.83.53878  65840      0 129100      0 TIME_WAIT
10.1.5.67.8101       172.28.251.83.53880  65840      0 129100      0 TIME_WAIT

The list reveled that only one ip was related with port 8101 so by this we could conclude that localhost was not listening to this port.

Therefore, in order to solve it, we needed to change the IP address range that the servers are listening for incoming connections.
Going to weblogic console and checking the server configuration we could observe that the listen address was set with the machine IP, so in this way limiting the incoming connection to the ones referencing only this IP:



The solution was to remove the IP from the Listen Address field leaving this undefined so clients can reach this server using localhost string.




Saving the changes, applying the modifications and restarting the server made available the composites on the servers to be invoked by clients using localhost in the reference.

Friday, 21 March 2014

Fault Handling Framework JAVA Custom Faults using fault policies properties

What I'm trying to achieve: Custom fault handling action on my fault policies that can publish a file to my file system before any handled fault is delivered to manual intervention on recovery EM area. This way will allow me to alert via platform management tool that an error occurred. Now, I want this flexible enough so I can change file content and location based on different targeted environments during my application promotion.

Implementation

  1. Create a generic JDeveloper project leaving the default options. 
  2. Add JAVA technology. Accept the creation of a new project and define the name.
  3. Define the default package where to create your java classes
  4. Add the necessary libraries
    • BPEL Runtime
    • SOA Runtime


Note: Right Click on project and choose Project Properties to access to Libraries and Classpath option.

Now:
  1. Create a new class (eg. Logging) inside the defined default package
  2. Copy/Paste the following code to the created class (Note: the package name should match the default package name that you defined)
package sample.faulthandling.custom.action;

import com.collaxa.cube.engine.fp.BPELFaultRecoveryContextImpl;

import java.io.BufferedWriter;
import java.io.File;

import java.io.FileWriter;

import java.util.ArrayList;
import java.util.Map;
import java.util.Properties;

import oracle.integration.platform.faultpolicy.IFaultRecoveryContext;
import oracle.integration.platform.faultpolicy.IFaultRecoveryJavaClass;


public class logging implements IFaultRecoveryJavaClass {
    public void handleRetrySuccess(IFaultRecoveryContext ctx) {
        System.out.println("This is for retry success");
        handleFault(ctx);
    }

    public String handleFault(IFaultRecoveryContext ctx) {
        System.out.println(" #### EXAMPLE ###### Action context:\n" +
                ctx.toString());

        // Get BPEL specific context here
        BPELFaultRecoveryContextImpl bpelCtx =
            (BPELFaultRecoveryContextImpl)ctx;

        // Writing an audit entry
        bpelCtx.addAuditTrailEntry(" ### SAMPLE Custom Fault Handling Example ### ");

        // Getting details
        System.out.println("Policy Id: " + ctx.getPolicyId());
        System.out.println("Composite Name: " + bpelCtx.getCompositeName());
            
        Map<String, ArrayList> props = ctx.getProperties();
        
        String logFileName = (String)((ArrayList)props.get("logFileName")).get(0);
        String logFileDir = (String)((ArrayList)props.get("logFileDir")).get(0);
        String message = (String)((ArrayList)props.get("message")).get(0);

        String content = message + " - Composite:" + bpelCtx.getCompositeName() + " InstanceID:" + bpelCtx.getCompositeInstanceId()
            + " Activity:" + bpelCtx.getActivityName() + " Fault:" + bpelCtx.getFault();

        File file = new File(logFileDir + logFileName);
        try {
            if (!file.exists()) {
                file.createNewFile();
            }

            FileWriter fw = new FileWriter(file.getAbsoluteFile());
            BufferedWriter bw = new BufferedWriter(fw);
            bw.write(content);
            bw.close();

        } catch (Exception e) {
            
        }
            return "MANUAL";

    }
}


1.      Create a new deployment profile to generate a JAR file (e.g. CustomFaultJavaAction.jar)

Note: Right Click on project and choose Project Properties to access to Deployment Profiles.

Now, deploy to a JAR file using the created deployment profile.

Deployment


1. Copy the deployed JAR file to the "oracle.soa.ext_11.1.1" directory
Note: You will find this SOA extension in [fmw_home]/Oracle_SOA1/soa/modules/oracle.soa.ext_11.1.1/

2. Update the environment variables running the appropriate domain setDomainEnv.sh
Note: [fmw_home]/user_projects/domains/[your_domain]/bin

3. soa.ext build file uses If condition, default ANT installation available on SOA suite is not ready to use If conditions by default. It will be necessary to update both Ant Library and soa.ext build file to be able to incorporate this functionality. So you have to:
  • Download ant contrib jar file http://switch.dl.sourceforge.net/project/ant-contrib/ant-contrib/ant-contrib-1.0b2/ant-contrib-1.0b2-bin.zip
  • Unzip file and copy lib/ant-contrib.jar to your Ant lib folder
    Note: Ant is available on your SOA Suite installations. The location is: [fmw_home]/modules/org.apache.ant_1.7.1
  • It is necessary to reference now the Ant Contrib library from the build.xml file used to build the SOA ext. So edit the build.xml file contained on oracle.soa.ext_11.1.1 folder and add the element <taskdef resource="net/sf/antcontrib/antlib.xml"/> after the project element.

4. Run Ant on oracle.soa.ext_11.1.1 folder. Your build target should produce then the following output:

[oracle@soabpm-vm oracle.soa.ext_11.1.1]$ /oracle/fmwhome/modules/org.apache.ant_1.7.1/bin/ant
Buildfile: build.xml

create-manifest-jar:
     [echo] Creating oracle.soa.ext at /oracle/fmwhome/Oracle_SOA1/soa/modules/oracle.soa.ext_11.1.1/oracle.soa.ext.jar :/oracle/fmwhome/Oracle_SOA1/soa/modules/oracle.soa.ext_11.1.1/CustomFaultJavaAction.jar:/oracle/fmwhome/Oracle_SOA1/soa/modules/oracle.soa.ext_11.1.1/classes

BUILD SUCCESSFUL
Total time: 0 seconds

Note: Ant is available on your installations of SOA suite in:[fmw_home]/modules/org.apache.ant_1.7.1

5. Now it is time to restart your SOA server. :)

Fault Policy Configuration

1. The following example can be follow to be able to use the implemented custom fault action. Change your fault policy file to include the custom action following the next example:

<?xml version="1.0" encoding="UTF-8"?>
<faultPolicies xmlns="http://schemas.oracle.com/bpel/faultpolicy"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <faultPolicy version="0.0.1" id="FusionMidFaults"
               xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
               xmlns:xs="http://www.w3.org/2001/XMLSchema"
               xmlns="http://schemas.oracle.com/bpel/faultpolicy"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <Conditions>
      <faultName>
        <condition>
          <action ref="ora-retry"/>
        </condition>
      </faultName>
    </Conditions>
    <Actions>
      <Action id="ora-retry">
        <retry>
          <retryCount>3</retryCount>
          <retryInterval>2</retryInterval>
          <exponentialBackoff/>
          <retryFailureAction ref="my-custom-java"/>
        </retry>
      </Action>
      <Action id="my-custom-java">
        <!-- this is user provided class-->
        <javaAction className="sample.faulthandling.custom.action.logging"
                    defaultAction="default-human-intervention"
                    propertySet="prop-for-my-monitoring">
          <returnValue value="MANUAL" ref="default-human-intervention"/>
          <returnValue value="ABORT" ref="default-terminate"/>
          <returnValue value="RETHROW" ref="default-rethrow-fault"/>
        </javaAction>
      </Action>
      <!-- Generics -->
      <Action id="default-terminate">
        <abort/>
      </Action>
      <Action id="default-replay-scope">
        <replayScope/>
      </Action>
      <Action id="default-rethrow-fault">
        <rethrowFault/>
      </Action>
      <Action id="default-human-intervention">
        <humanIntervention/>
      </Action>
    </Actions>
    <Properties>
      <propertySet name="prop-for-my-monitoring">
        <property name="logFileName">my-soa-faults.log</property>
        <property name="logFileDir">/home/oracle/logs/</property>
        <property name="message">### SAMPLE Custom Fault Handling Example ###</property>
      </propertySet>
    </Properties>
  </faultPolicy>
</faultPolicies>

2. Deploy the policies file (composite or MDS) and test.

Conclusions

This will allow you to manage your properties per fault-policy referencing fault policies files that are available on MDS of the targeted server, managing this way the properties that will influence your fault handling custom actions depending on the environment of your application life cycle.