13 Managing Callouts

This chapter describes how to create and use Java callouts, which transform the formats of messages exchanged between the host and remote trading partners. You can use callouts to invoke an XSLT style sheet, and any Java program in general.

This chapter includes the following sections:

13.1 Introduction to Callouts

Callouts are used in environments in which a host trading partner application does not use the same message format as the remote trading partner.

For example, a remote trading partner sends a RosettaNet XML-formatted purchase order request to a host trading partner, as shown in Figure 13-1.

Figure 13-1 A Purchase Order Example: Using Callouts for Differently Formatted XML Messages

Description of Figure 13-1 follows
Description of "Figure 13-1 A Purchase Order Example: Using Callouts for Differently Formatted XML Messages"

In this example, the host application of the host trading partner is an Oracle E-Business Suite application that does not use RosettaNet XML-formatted messages. To enable communication between these two different formats, you create two callouts, as follows:

  • One callout, callout_inbound, for example, transforms the RosettaNet XML-formatted purchase order request into an Oracle E-Business Suite XML format understood by the Oracle E-Business Suite application. The Oracle E-Business Suite application, in turn, responds to the request message with a purchase order acceptance message in Oracle E-Business Suite XML format.

  • The other callout, callout_outbound, for example, transforms the Oracle E-Business Suite XML format back into a RosettaNet XML-formatted message for the remote trading partner.

These two callouts are then associated with the two agreements created for this exchange, as follows:

  • Include callout_outbound in the agreement for the outbound message, that is, the agreement for the initiating purchase order request.

  • Include callout_inbound in the agreement for the inbound message, that is, the agreement for the responding purchase order acceptance.

Because a document definition is a component of an agreement, a callout is associated with a specific document definition.

This purchase order example depicts a simple association of one callout to one agreement. In reality, however, the same callout can be included in many different agreements by changing the value of one or more callout parameters. See Figure 13-3 for where you add parameters and see Table 13-2 for a list of parameter attributes.

13.1.1 Transport Callouts

Another type of callout is the transport callout, which is associated with a channel. For the inbound message, B2B invokes the transport callout immediately after it receives a message from the transport. For the outbound message, B2B invokes the transport callout immediately before it sends a message to the transport. Transport callouts can be selected in the channel configuration, as shown in Figure 13-2, and can be used with any protocol.

You can use transport callouts to extract custom headers for inbound and outbound messages using the MLLP protocol. Example 13-1 shows how to set and get the CUSTOM_HEADER property in the callout.

For more information, see Using a Transport Callout to Extract Custom Headers.

Transport callouts are created like other callouts, from the Callout tab, as described in Creating a Callout. Although a transport callout is not added to an agreement, all transport callouts appear in the Callouts list on the Agreement tab; therefore, it is available for selection. To avoid confusion, when you create a transport callout, provide a name that indicates its type so that you do not select it from the Callouts list on the Agreement tab.

Example 13-1 Setting and Getting the CUSTOM_HEADER Property

import java.util.*;
import oracle.tip.b2b.callout.*;
import oracle.tip.b2b.callout.exception.*;

   public class SampleCallout implements Callout {
   public void execute(CalloutContext context,List input,List output)
               throws CalloutDomainException, CalloutSystemException {
     try {
      CalloutMessage cmIn = (CalloutMessage)input.get(0);
      String s =cmIn.getBodyAsString();

      //for getting the CUSTOM_HEADER
      Properties params =  (Properties)cmIn.getParameters();
      String customHeader = (String)params.get("CUSTOM_HEADER");

      //for setting the CUSTOM_HEADER
      CalloutMessage cmOut = new CalloutMessage(s);
      cmOut.setParameter("CUSTOM_HEADER", "your_value");
      output.add(cmOut);

      } catch (Exception e) {
      throw new CalloutDomainException(e);
      }
   }
}

13.1.2 Creating a Callout Library JAR File

If the callout JAR file provided with Oracle B2B is not sufficient for your needs, you can create your own callout JAR file outside of Oracle B2B, following the standards described in the Oracle Fusion Middleware B2B Callout Java API Reference. Use the Configuration tab of the Administration link to specify the directory location of this external JAR file. It is recommended that you create an external JAR file for your callouts; do not bundle your callouts with b2b.jar.

Note:

MySampleCallout is a restricted keyword and should not be used. It is already packaged into b2b.jar.

13.2 Creating a Callout

To create a callout, provide callout details—the implementation class name and library name—and callout parameters.

These are shown in Figure 13-3.

You can create multiple callouts with the same name if you assign them different implementation names. You cannot delete a callout that is included in an agreement.

Table 13-1 lists the callout details that you provide.

Table 13-1 Callout Details

Field Description

*Implementation Class

Enter the class file name without .class.

Note: Oracle B2B includes a predefined class file named XSLTCalloutImpl that you can use for XML-to-XML transformations.

*Library Name

Enter the JAR file name that has the callout implementation classes.

Note: If you specify one or more of your own callout JAR files, you must specify the directory location. Use the Configuration tab from the Administration link. The directory location for the default b2b.jar file included with Oracle B2B does not need to be specified.

The callout library must be manually migrated from one environment to another. The B2B export/import feature does not migrate the callout library JAR.

For information about specifying the callout directory for your own callout JAR files, see Setting Configuration Parameters.

Description

Enter a description.

Timeout (seconds)

Enter the time limit in which to process the callout.

Callout parameters are similar in cafterpt to global variables to which you can assign local values that are applicable only to a specific callout use. Or, you can create a callout parameter and assign it a default value that is applicable to all callout uses. Changes to callout parameters for an existing callout affect all agreements that use that callout.

Table 13-2 lists the optional callout parameter attributes.

Table 13-2 Callout Parameter Attributes

Field Description

Name

Enter a parameter name.

Type

Select from Integer, Float, String, Boolean, or Date types. The format for the Date type is MM/DD/YYYY.

Note: Changing a type can invalidate the parameter default value.

Value

Enter a value. If Encrypted is set to True, then this value is encrypted.

Mandatory

Select True or False.

Encrypted

Select True or False.

Description

Enter an optional description.

After you create a callout, it is available to include in an agreement. For more information, see Including a Callout in an Agreement. If you change a callout after it is deployed with an agreement, a server restart is required.

To create a callout:

  1. Click Administration, and then Callout.
  2. In the Callout section, click Add.
  3. Enter a name for the callout.

    (You may want to indicate if you are creating a transport callout in the name.)

  4. Enter callout details, as described in Table 13-1.
  5. (Optional) Click Add in the Parameters section.
  6. Enter a parameter name and attributes, as described in Table 13-2.
  7. Click Save.

You can edit the details, parameters, or parameter values at any time, but not the callout name.

13.3 Securing Messages with PGP

Oracle B2B and Healthcare support message level security using PGP (Pretty Good Privacy). PGP combines features of both symmetric and public key cryptography. PGP creates a session key which is a onetime only, randomly-generated key for the text. The session key encrypts the plain text, and then the session key is then encrypted to the recipient’s public key. Decryption works in reverse.

You can use this functionality as a transport callout only in B2B and Healthcare, using the PGP callout jar provided. You must have the capability to create PGP keys.

Usage Scenario

Inbound: Oracle B2B/Healthcare receives Encrypted PGP messages from an external trading partner. As part of the message processing, the encrypted PGP message will be decrypted using the enterprise’s Private key. In case the PGP encrypted message contains the digital signature, the digital signature will be verified using the sender’s public key. Also, in case the PGP encrypted message contains the message digest, then as part of decryption, data integrity will be verified.

Outbound: Oracle B2B/Healthcare sends encrypted PGP messages to an external trading partner. As part of the processing, the message will be encrypted using PGP APIs using the external trading partner’s public key. During encryption, enterprise has the option to add the digital signature for message origin authentication and message digest for integrity check. For message signature, the Enterprise’s private key will be used.

Callout Parameters

The PGP callout needs the following callout parameters while configuring the callout:

  • publicKeyLocation

  • secretKeyLocation

  • password

  • direction

  • encryptionType

encryptionType is used to specify the type of algorithm used for encryption. The table below lists the supported types and the integer values that must be provided to the callout. For example, to use the AES_256 algorithm, the callout parameter value for encryptionType would be 9.

EncryptionType Integer value

TRIPLE_DES

2

CAST5

3

BLOWFISH

4

DES

6

AES_128

7

AES_192

8

AES_256

9

TWOFISH

10

Figure 13-4 PGP Callout Parameters

Description of Figure 13-4 follows
Description of "Figure 13-4 PGP Callout Parameters"

13.4 Including a Callout in an Agreement

After you create a callout, it is available to include in an agreement

This is shown in Figure 13-5.

Figure 13-5 Specifying a Callout in an Agreement

Description of Figure 13-5 follows
Description of "Figure 13-5 Specifying a Callout in an Agreement"

To include a callout in an agreement:

  1. Click Partners.

  2. Click an agreement name.

  3. Select a callout.

  4. Click Save.

To update the value of a callout parameter for a specific agreement:

  1. Click Partners.
  2. Click an agreement name.
  3. Select a callout.
  4. Click Callout Details.
  5. Enter a value for the parameter name, as shown in Figure 13-6.

    Figure 13-6 Entering Callout Details

    Description of Figure 13-6 follows
    Description of "Figure 13-6 Entering Callout Details"
  6. Click OK.

13.5 Implementing a Callout

These examples illustrate the code for implementing a callout.

Example 13-2 shows how an incoming XML document is transformed to another XML document. The directory structure is oracle.tip.callout. In this example, note that setting the output CalloutMessage in the output list is required (output.add(cmOut)).

Example 13-2 Code Example of an XML-to-XML Transformation

import java.io.*;
import java.net.*;
import java.util.*;
import oracle.xml.parser.v2.*;
import oracle.tip.b2b.callout.Callout;
import oracle.tip.b2b.callout.CalloutMessage;
import oracle.tip.b2b.callout.CalloutContext;
import oracle.tip.b2b.callout.exception.*;
 
/**
 * This sample callout transforms the incoming XML document
 * to another XML document. It also shows how to generate
 * Functional Ack and Error message.
 */
public class XSLTCalloutImpl implements Callout {  
   public void execute(CalloutContext context,
                       List input,
                       List output)
          throws CalloutDomainException, CalloutSystemException {
     try {
 
      // (1) Retrieve the callout properties from CalloutContext
      String xsltFile     = context.getStringProperty("xsltFile");
 
      // (2) Get the input callout message
      CalloutMessage cmIn = (CalloutMessage)input.get(0);
 
      // (3) Process the message
      // instantiate a stylesheet
      URL xslURL = new URL("file://" + xsltFile);     
      XSLProcessor processor = new XSLProcessor();
      XSLStylesheet xsl = processor.newXSLStylesheet(xslURL);
 
      // parser input XML content
      DOMParser parser = new DOMParser();
      parser.setPreserveWhitespace(true);  
      parser.parse(new StringReader(cmIn.getBodyAsString()));
      XMLDocument xml = parser.getDocument();
      processor.showWarnings(true);
      processor.setErrorStream(System.err);
 
      // Transform the document
      StringWriter strWriter = new  StringWriter();
      processor.processXSL(xsl, xml, new PrintWriter(strWriter));
 
      // (4) Create a output callout message
      // create a callout output message
      CalloutMessage cmOut =
          new CalloutMessage(strWriter.getBuffer().toString());
      strWriter.close();
 
// create Functional Ack callout message
// this is an optional step
CalloutMessage fa = new CalloutMessage(/*set FA payload here*/);
fa.setParameter("functional_ack", "true");
//setting your own doctype and revision
//set the doc type name and revision as defined in b2b ui
fa.setParameter("doctype_name", "fa");
fa.setParameter("doctype_revision", "1.0");
 
// create Error callout message
// this is an optional step
CalloutMessage err = new CalloutMessage(/* set the payload that causes 
this error */);
err.setParameter("error_message", "true");
err.setParameter("error_desc", "set the error desc");

      output.add(cmOut);
      output.add(fa);
      output.add(err);

      //(5) Throw an exception, if any
    } catch (Exception e) {
      throw new CalloutDomainException(e);
    }
  }
}

Example 13-3 shows how to create a synchronous callback callout for use with Transport Synch Callback. See Using Transport Sync Callback for more information.

Example 13-3 Code Example of a Sync Callback Callout

import java.io.FileInputStream;
import java.util.List;
import java.util.Properties;
import oracle.tip.b2b.callout.Callout;
import oracle.tip.b2b.callout.CalloutContext;
import oracle.tip.b2b.callout.CalloutMessage;
import oracle.tip.b2b.callout.exception.CalloutDomainException;
import oracle.tip.b2b.callout.exception.CalloutSystemException;
import oracle.tip.b2b.domain.B2BParameters;
import oracle.tip.b2b.system.B2BRuntimeException;
import oracle.tip.b2b.system.ErrorKeys;
 
public class SyncSampleCallout implements Callout {
 
  public void execute(CalloutContext calloutContext, List input, List output)
        throws CalloutDomainException, CalloutSystemException {
            try
             {
               CalloutMessage message = new CalloutMessage();
               Properties properties = new Properties();
                        
               properties.put("FROM_PARTY", "MarketInc");
               properties.put(B2BParameters.TO_PARTY, "OracleServices");
               properties.put(B2BParameters.DOCTYPE_NAME, "271");
               properties.put(B2BParameters.DOCTYPE_REVISION, "4010X092A1");
                        
               message.setParameters(properties);
                        
                  FileInputStream inStream = new FileInputStream("/tmp/271.dat");

                  byte[] content = new byte[inStream.available()];
                        
                  inStream.read(content);
 
                  inStream.close();
 
                  message.setBody(content);
                        
                  output.add(message);
         }
           catch(Exception e) {
           new B2BRuntimeException(ErrorKeys.B2B_RUNTIME_ERROR, e);
                }
        }
}