BEA Logo BEA WLI Release 2.1

  BEA Home  |  Events  |  Solutions  |  Partners  |  Products  |  Services  |  Download  |  Developer Center  |  WebSUPPORT

 

   WLI Doc Home   |   B2B Topics   |   Implementing cXML   |   Previous Topic   |   Next Topic   |   Contents   |   Index   |   View as PDF

Using the cXML API

 

The following sections describe some of the key programming issues for the cXML API.

For more information about programming business operations, see Creating Workflows for B2B Integration.

 


cXML Methods

The following methods are available for cXML message manipulation.

Table 3-1 Public cXML Methods

Method

Package

Description

onMessage

com.bea.b2b.protocol.cxml.CXMLListener

Receives an incoming CXMLMessage

deregister

com.bea.b2b.protocol.cxml.CXMLManager

Deregisters the application with this CXMLManager. Uses a set of properties to select the registration.

getInstance

com.bea.b2b.protocol.cxml.CXMLManager

Gets an instance of the CXMLManager.

getSharedSecret

com.bea.b2b.protocol.cxml.CXMLManager

Gets the Shared Secret for this Trading Partner. Uses the Trading Partner name to find the Shared Secret.

register

com.bea.b2b.protocol.cxml.CXMLManager

Registers the application with this CXMLManager. Uses a set of properties to select the collaboration agreement for this Trading Partner.

Use for sending cXML messages.

getHttpStatusCode

com.bea.b2b.protocol.cxml.CXMLHttpStatusException

Returns the HTTP Status code from the exception.

getAsString

com.bea.b2b.protocol.cxml.messaging.CXMLDocument

Gets the cXML part as a String.

getDocument

com.bea.b2b.protocol.cxml.messaging.CXMLDocument

Gets the associated XML Document.

getFromCredentialDomains

com.bea.b2b.protocol.cxml.messaging.CXMLDocument

Gets the From Credential Domains from the document header.

getFromCredentialIdentities

com.bea.b2b.protocol.cxml.messaging.CXMLDocument

Gets the From Credential Identities from the document header.

getIdentifier

com.bea.b2b.protocol.cxml.messaging.CXMLDocument

Gets either the document identifier or the message identifier, as appropriate.

getNodeValue

com.bea.b2b.protocol.cxml.messaging.CXMLDocument

Gets the value of a document node using the specified XPath expression to locate the node. If multiple nodes match the XPath expression, then only the first node will be used.

getSenderCredentialDomain

com.bea.b2b.protocol.cxml.messaging.CXMLDocument

Gets the Sender Credential Domain from the document header.

getSenderCredentialIdentity

com.bea.b2b.protocol.cxml.messaging.CXMLDocument

Gets the Sender Credential Identity from the document header.

getSenderSharedSecret

com.bea.b2b.protocol.cxml.messaging.CXMLDocument

Gets the Sender Credential Shared Secret from the document header.

getSenderUserAgent

com.bea.b2b.protocol.cxml.messaging.CXMLDocument

Gets the Sender User Agent from the document header.

getTimeStamp

com.bea.b2b.protocol.cxml.messaging.CXMLDocument

Gets either the document timestamp or the message timestamp, as appropriate.

getToCredentialDomain

com.bea.b2b.protocol.cxml.messaging.CXMLDocument

Gets the To Credential Domain from the document header.

getToCredentialIdentity

com.bea.b2b.protocol.cxml.messaging.CXMLDocument

Gets the To Credential Identity from the document header.

getVersion

com.bea.b2b.protocol.cxml.messaging.CXMLDocument

Gets the document version.

setDocument

com.bea.b2b.protocol.cxml.messaging.CXMLDocument

Sets the associated XML document.

setNodeValue

com.bea.b2b.protocol.cxml.messaging.CXMLDocument

Sets the value of a document node using the specified XPath expression to locate the node.

reply

com.bea.b2b.protocol.cxml.messaging.CXMLMessage

Replies to the request message. This method is only valid when this object is used as a parameter to CXMLListener.onMessage(). The reply may be sent asynchronously after the method has been called.

getReplyDocument

com.bea.b2b.protocol.cxml.messaging.CXMLMessage

Gets the reply cXML document.

getRequestDocument

com.bea.b2b.protocol.cxml.messaging.CXMLMessage

Gets the request cXML document.

send

com.bea.b2b.protocol.cxml.messaging.CXMLMessage

Sends a request message. This method blocks until a reply is received. The reply can be accessed via getReplyDocument().

setCollaborationAgreement

com.bea.b2b.protocol.cxml.messaging.CXMLMessage

Sets the Collaboration Agreement ID for the collaboration agreement to which this message belongs. Uses a set of properties to select the Collaboration Agreement.

setReplyDocument

com.bea.b2b.protocol.cxml.messaging.CXMLMessage

Sets the reply cXML document.

setRequestDocument

com.bea.b2b.protocol.cxml.messaging.CXMLMessage

Sets the request cXML document.

getHttpStatusCode

com.bea.b2b.protocol.cxml.messaging.CXMLMessageToken

Gets the HTTP status code.


 

For more information about individual methods, see the BEA WebLogic Integration Javadoc.

Properties Used to Locate Collaboration Agreements

cXML uses a set of defined properties to locate unique collaboration agreements. When attempting to locate a specific collaboration agreement, you must supply values for all of the following properties:

 


cXML Message Structure

A cXML message is based on the message envelope. The message envelope includes the following data structures.

Figure 3-1 cXML Message Architecture


 

The message data structures are as follows:

The payload includes a number of messaging objects. Your application should be able to deal with all of them.

 


cXML DTDs

The DTDs you will need are available at the following locations:

Validation using these DTDs is not required when you send a cXML message. However, one assumption of the cXML messaging structure is that any message you send has been validated. Therefore it is a good idea to validate your messages routinely against the DTDs, at least while you are testing interoperability with a new trading partner. Once you are comfortable with your trading partner, you may optionally turn off message validation to enhance performance.

 


Dealing with Shared Secrets

The cXML API provides access to the value of the shared secret stored in the repository. The GetSharedSecret method allows you to retrieve the shared secret from the repository for comparison to the shared secret stored in incoming documents, or for use in outgoing cXML documents.

For incoming documents, your business operation code must perform verification of the shared secret of an incoming message by matching its value with the value specified in the configuration stored in the repository.

For outgoing documents your business operation code must insert the shared secret in the Credential node of each outgoing cXML document.

 


Processing Incoming Messages

To process an incoming message, you must first initialize it. The registration function associates a collaboration agreement with either a listener or a sending application. The token returned by the initialization process is used in the cXML message when the message is sent or received.

Initialization

To initialize an incoming message:

  1. Get a copy of the listener object.

  2. Define the return token.
    private static CXMLToken token;

  3. Retrieve an instance of the cXML Manager class com.bea.b2b.protocol.cxml.CXMLManager:
    private static CXMLManager cxmlm = CXMLManager.getInstance();

  4. Define a set of properties to register this application and listener. The properties are used to locate and map a unique collaboration agreement. For more information about the properties needed to map a unique collaboration agreement, see Properties Used to Locate Collaboration Agreements.
    prop.setProperty("BusinessProcess", businessProcess);
    prop.setProperty("BusinessProcessVersion", businessProcessVersion);
    prop.setProperty("DeliveryChannel", deliveryChannel);
    prop.setProperty("thisTradingPartner", myTradingPartnerName);
    prop.setProperty("otherTradingPartner", otherTradingPartnerName);
    prop.setProperty("toRole", toRole);
    prop.setProperty("Party", "duns4");

  5. Invoke the register method from the CXMLManager class:
    token = cxmlm.register(prop);

Processing the Message

Once you have initiated an incoming message as described in the previous section, Initialization, you can process it. To do so, your application must:

  1. Get the request cXML document from the received cXML message using the onMessage() callback method. This method passes the received cXML message from the WebLogic Integration run-time to your application code.

  2. Get the XML DOM document from the cXML document:
    // Get the cXML document
    CXMLDocument reqMsgDoc = cmsg.getRequestDocument();

    // Get the XML DOM doc
    Document reqXMLDoc = reqMsgDoc.getDocument();

  3. Process the request document based on the payload.

  4. Retrieve the shared secret from the incoming message. The shared secret for the trading partner is defined in the message, in: //cXML/Header/From/Credential.
    String otherSharedSecret = cxmlm.getSharedSecret(otherTradingPartnerName);

  5. Verify that the shared secret from the message matches the shared secret defined in the configuration for the trading partner. If the transaction is peer-to-peer, then the trading partner will be the buyer or supplier. If the transaction is occurring through the hub, then the trading partner will be the hub.
    debug("Stored Shared Secret for " + otherTradingPartnerName + ": " + otherSharedSecret);

    The following comparison failure options may occur.


     

  6. Create the reply XML DOM implementation document:
    DOMImplementationImpl domi = new DOMImplementationImpl();

    DocumentType dType =
    domi.createDocumentType("request", null, "cXML.dtd");

    org.w3c.dom.Document punchoutDoc = new DocumentImpl(dType);
    CxmlElementFactory cf = new CxmlElementFactory(punchoutDoc);

  7. Create the reply cXML document:
    Element request = punchoutDoc.createElement("Request");

  8. Create the header elements in the document:
    // header
    cf.createHeaderElement(
    // from
    cf.createFromElement(
    cf.createCredentialElement(
    "DUNS",
    myTradingPartnerName,
    null)),
    // to
    cf.createToElement(
    cf.createCredentialElement(
    "DUNS",
    otherTradingPartnerName,
    null)),
    // sender
    cf.createSenderElement(
    cf.createCredentialElement(
    "AribaNetworkUserId",
    "admin@acme.com",
    otherSharedSecret),
    "Ariba ORMS 5.1P4")),

  9. Set the XML document in the cXML document:
    CXMLDocument replyMsgDoc = new CXMLDocument();
    replyMsgDoc.setDocument(replyXMLDoc);

  10. Set the cXML document in the reply cXML message:
    cmsg.setReplyDocument(replyMsgDoc);

  11. Set the collaboration agreement in the cXML message:
    cmsg.setCollaborationAgreement(prop);

  12. Send the reply message to dispatch the outgoing cXML message from your application to the WebLogic Integration run-time:
    cmsg.reply();

 


Processing Outgoing Messages

You must initialize outgoing messages before you send them. To do so:

  1. Define the return token:
    private static CXMLToken token;

  2. Retrieve an instance of the cXML Manager class:
    com.bea.b2b.protocol.cxml.CXMLManager.
    private static CXMLManager cxmlm = CXMLManager.getInstance();

  3. Define a set of properties to register this application. The properties are used to locate and map a unique collaboration agreement. For more information about the properties needed to map a unique collaboration agreement, see Properties Used to Locate Collaboration Agreements.
    prop.setProperty("BusinessProcess", businessProcess);
    prop.setProperty("BusinessProcessVersion", businessProcessVersion);
    prop.setProperty("DeliveryChannel", deliveryChannel);
    prop.setProperty("thisTradingPartner", myTradingPartnerName);
    prop.setProperty("otherTradingPartner", otherTradingPartnerName);
    prop.setProperty("toRole", toRole);
    prop.setProperty("Party", "duns4");

  4. Invoke the register method:
    token = cxmlm.register(prop);

Sending the Message

To send a message, your application must perform the following actions:

  1. Create a cXML message:
    DOMImplementationImpl domi = new DOMImplementationImpl();

    DocumentType dType =
    domi.createDocumentType("request", null, "cXML.dtd");

    org.w3c.dom.Document punchoutDoc = new DocumentImpl(dType);
    CxmlElementFactory cf = new CxmlElementFactory(punchoutDoc);

  2. Create the XML DOM request document:
    Element request = punchoutDoc.createElement("request");
    Element trans = punchoutDoc.createElement("PunchoutSetupRequest");
    request.appendchild(trans);

  3. Create the header elements in the request document:
    punchoutDoc.appendChild(
    cf.createCxmlElement(
    // header
    cf.createHeaderElement(
    // from
    cf.createFromElement(
    cf.createCredentialElement(
    "DUNS",
    myTradingPartnerName,
    null)),
    // to
    cf.createToElement(
    cf.createCredentialElement(
    "DUNS",
    otherTradingPartnerName,
    null)),
    // sender
    cf.createSenderElement(
    cf.createCredentialElement(
    "AribaNetworkUserId",
    "admin@acme.com",
    otherSharedSecret),
    "Ariba ORMS 5.1P4")),

  4. Retrieve the receiving trading partner's shared secret from the appropriate trading partner profile. For peer-to-peer messages, this will be the actual receiving trading partner's shared secret. For messages routed through a hub, this will be the hub's shared secret.

    The value of the receiving trading partner's shared secret (defined in //cXML/Header/To/Credential) is updated to the sender's shared secret element (defined in //cXML/Header/Sender/Credential):

    String otherSharedSecret = cxmlm.getSharedSecret(otherTradingPartnerName);
    debug("Stored Shared Secret for " + otherTradingPartnerName + ": " + otherSharedSecret);

  5. Create the cXML document:
    CXMLDocument reqMsgDoc = new CXMLDocument();

  6. Set the cXML document in the cXML message:
    reqMsgDoc.setDocument(reqXMLDoc);
    cmsg.setRequestDocument(reqMsgDoc);

  7. Set the collaboration agreement in the cXML message:
    cmsg.setCollaborationAgreement(prop);

  8. Send the message:
    CXMLMessageToken sendToken = (CXMLMessageToken) cmsg.send();

  9. Get the reply document:
    CXMLDocument replyMsgDoc = cmsg.getReplyDocument();

  10. Extract the XML document:
    org.w3c.dom.Document replyXMLDoc = replyMsgDoc.getDocument();

  11. Verify the response.

Code Samples

This section shows examples of code used by buyers and suppliers to process messages. These examples are provided solely to illustrate the operation of the cXML classes; they are not intended for execution. The examples below are configured for peer-to-peer operation.

For more information about cXML classes, see BEA WebLogic Integration Javadoc.

Sample Buyer

Listing 3-1 Sample Buyer Code Example

/*
* Copyright (c) 2001 BEA
* All rights reserved
/
package examples.ibcxmlverifier;

import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

import org.w3c.dom.*;
import org.apache.html.dom.*;
import org.apache.xml.serialize.*;
import org.apache.xerces.dom.*;

import com.bea.b2b.protocol.cxml.messaging.*;
import com.bea.b2b.protocol.cxml.*;

import com.bea.eci.logging.*;

/**
* This example provides a simple test that will verify message flow of cXML
* peer-to-peer sending and receiving a cXML document.
* The two peers (Partner1 and Partner2) are running on a single WLS.
* Partner1 sends a PunchoutRequest to Partner2. Partner2 generates a
* PunchoutSetupResponse and returns it to Partner1. Shared Secrets are verified
* at both ends.
*/
public class Partner1Servlet extends HttpServlet
{
static final boolean DEBUG = true;

private final static String businessProcess = "PunchoutSetup";
private final static String businessProcessVersion = "1.1.009";
private final static String deliveryChannel = "CXMLPartnerVerifier1";
private final static String myTradingPartnerName = "CXMLPartnerVerifier1";
private final static String otherTradingPartnerName = "CXMLPartnerVerifier2";
private final static String toRole = "Supplier";
private final static String expectedURL = "http://xyz/abc?from=" + myTradingPartnerName;
private DocSerializer ds;

// Create the token for this application
private static CXMLToken token;

// Get the manager instance
private static CXMLManager cxmlm = CXMLManager.getInstance();

private static Properties prop = new Properties();

public void init(ServletConfig sc) {
try {
debug("Initializing servlet for Partner1");

// Set the properties for finding the Collaboration Agreement
prop.setProperty("BusinessProcess", businessProcess);
prop.setProperty("BusinessProcessVersion", businessProcessVersion);
prop.setProperty("DeliveryChannel", deliveryChannel);
prop.setProperty("thisTradingPartner", myTradingPartnerName);
prop.setProperty("otherTradingPartner", otherTradingPartnerName);
prop.setProperty("toRole", toRole);
prop.setProperty("Party", "duns4");

// Register the buyer with the manager using properties
token = cxmlm.register(prop);

} catch (Exception e) {
debug("CXMLPartnerVerifier1 init exception: " + e);
e.printStackTrace();
}
}

private org.w3c.dom.Document getBusinessDocument() {
DOMImplementationImpl domi = new DOMImplementationImpl();

DocumentType dType =
domi.createDocumentType("request", null, "cXML.dtd");

org.w3c.dom.Document punchoutDoc = new DocumentImpl(dType);
CxmlElementFactory cf = new CxmlElementFactory(punchoutDoc);

try {
String otherSharedSecret = cxmlm.getSharedSecret(otherTradingPartnerName);
debug("Stored Shared Secret for " + otherTradingPartnerName + ": " + otherSharedSecret);

// Header
Element request = punchoutDoc.createElement("Request");
Element trans = punchoutDoc.createElement("PunchoutSetupRequest");
request.appendChild(trans);

punchoutDoc.appendChild(
cf.createCxmlElement(
// payload
"1233444-200@ariba.acme.com",

// header
cf.createHeaderElement(
// from
cf.createFromElement(
cf.createCredentialElement(
"DUNS",
myTradingPartnerName,
null)),
// to
cf.createToElement(
cf.createCredentialElement(
"DUNS",
otherTradingPartnerName,<

Sample Supplier

Listing 3-2 Sample Supplier Code Example

/*
* Copyright (c) 20001 BEA
* All rights reserved
*/
package examples.ibcxmlverifier;

import java.io.*;
import java.util.*;

import javax.servlet.*;
import javax.servlet.http.*;

import org.w3c.dom.*;
import org.apache.html.dom.*;
import org.apache.xml.serialize.*;
import org.apache.xerces.dom.*;

import com.bea.b2b.protocol.messaging.*;
import com.bea.b2b.protocol.cxml.messaging.*;
import com.bea.b2b.protocol.cxml.CXMLListener;
import com.bea.b2b.protocol.cxml.*;

import com.bea.eci.logging.*;

/**
* This example provides a simple test that will verify message flow of cXML
* peer-to-peer sending and receiving a cXML document.
* The two peers (Partner1 and Partner2) are running on a single WLS.
* Partner1 sends a PunchoutRequest to Partner2. Partner2 generates a
* PunchoutSetupResponse and returns it to Partner1. Shared Secrets are verified
* at both ends.
*/
public class Partner2Servlet extends HttpServlet {

static final boolean DEBUG = true;

private final static String businessProcess = "PunchoutSetup";
private final static String businessProcessVersion = "1.1.009";
private final static String deliveryChannel = "CXMLPartnerVerifier2";
private final static String myTradingPartnerName = "CXMLPartnerVerifier2";
private final static String otherTradingPartnerName = "CXMLPartnerVerifier1";
private final static String toRole = "Buyer";

// Create the token for this application
private static CXMLToken token;

// Get the manager instance
private static CXMLManager cxmlm = CXMLManager.getInstance();

private static Properties prop = new Properties();

public void init(ServletConfig sc) {
try {
debug("Initializing servlet for Partner2");

// Set the properties for finding the Collaboration Agreement
prop.setProperty("BusinessProcess", businessProcess);
prop.setProperty("BusinessProcessVersion", businessProcessVersion);
prop.setProperty("DeliveryChannel", deliveryChannel);
prop.setProperty("thisTradingPartner", myTradingPartnerName);
prop.setProperty("otherTradingPartner", otherTradingPartnerName);
prop.setProperty("toRole", toRole);
prop.setProperty("Party", "duns5");

// Register the supplier listener with the manager using properties
token = cxmlm.register(new Partner2MessageListener(), prop);

debug("Partner2 waiting for message...");
} catch (Exception e) {
debug("CXMLPartnerVerifier2 init exception: " + e);
e.printStackTrace();
}
}

/**
* This routine starts the peer
*/
public void service(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException{
debug("Starting Partner2");
}

/**
* A simple routine that writes to the wls log
*/
private static void debug(String msg){
if (DEBUG)
UserLog.log("***Partner2Servlet: " + msg);
}

public class Partner2MessageListener
implements CXMLListener
{
public void onMessage(CXMLMessage cmsg) {
XPathHelper xp = new XPathHelper();

try {
debug("Partner2 received message");
// QualityOfService qos = cmsg.getQoS();

CXMLDocument reqMsgDoc = cmsg.getRequestDocument();
if (reqMsgDoc == null){
throw new Exception("Did not get a request payload");
}
Document reqXMLDoc = reqMsgDoc.getDocument();
if (reqXMLDoc == null){
throw new Exception("Did not get a request document");
}
String from = reqMsgDoc.getNodeValue(
"//cXML/Header/From/Credential/Identity" );
if

 

back to top previous page next page