|
|
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.
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:
http://xml.cxml.org/schemas/cXML/version/cXML.dtd
Here, version is the full cXML version number (such as 1.1, 1.2, and so on).
http://xml.cxml.org/schemas/cXML/version/Fulfill.dtd
Here, version is the full cXML version number (such as 1.1, 1.2, and so on).
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:
private static CXMLManager cxmlm = CXMLManager.getInstance();
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");
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:
// Get the cXML document
CXMLDocument reqMsgDoc = cmsg.getRequestDocument();
// Get the XML DOM doc
Document reqXMLDoc = reqMsgDoc.getDocument();
String otherSharedSecret = cxmlm.getSharedSecret(otherTradingPartnerName);
debug("Stored Shared Secret for " + otherTradingPartnerName + ": " + otherSharedSecret);
The following comparison failure options may occur.
Table 3-2 Verification Failure Options
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);
Element request = punchoutDoc.createElement("Request");
// 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")),
CXMLDocument replyMsgDoc = new CXMLDocument();
replyMsgDoc.setDocument(replyXMLDoc);
cmsg.setReplyDocument(replyMsgDoc);
cmsg.setCollaborationAgreement(prop);
cmsg.reply();
Processing Outgoing Messages
You must initialize outgoing messages before you send them. To do so:
private static CXMLToken token;
private static CXMLManager cxmlm = CXMLManager.getInstance();
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");
token = cxmlm.register(prop);
Sending the Message
To send a message, your application must perform the following actions:
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);
Element request = punchoutDoc.createElement("request");
Element trans = punchoutDoc.createElement("PunchoutSetupRequest");
request.appendchild(trans);
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")),
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);
CXMLDocument reqMsgDoc = new CXMLDocument();
reqMsgDoc.setDocument(reqXMLDoc);
cmsg.setRequestDocument(reqMsgDoc);
cmsg.setCollaborationAgreement(prop);
CXMLMessageToken sendToken = (CXMLMessageToken) cmsg.send();
CXMLDocument replyMsgDoc = cmsg.getReplyDocument();
org.w3c.dom.Document replyXMLDoc = replyMsgDoc.getDocument();
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
Copyright © 2001 BEA Systems, Inc. All rights reserved.
Required browser: Netscape 4.0 or higher, or Microsoft Internet Explorer 4.0 or higher.