Main Page

Previous Section Next Section

JAXR and ebXML Registry

In practical terms, the JAXR information model is based on the ebXML information model. This makes sense from two perspectives: the ebXML v. 2.0 Registry Information Model (RIM) is functionally larger than the UDDI v. 2.0 information model, and developing such detailed models based on community consensus takes time.

As mentioned previously, all the previous discussion about using JAXR and UDDI remains unchanged with an ebXML registry, because of the API's abstraction. In this section, we will discuss how client applications can leverage some of JAXR's level 1 capability features.

Publishing Organizations in ebXML Registries

One of the significant differences between UDDI and ebXML registries is how client applications are authenticated. While UDDI requires only password-based authentication, the ebXML Registry Service allows for digital certificates to be used in the SOAP headers. The SOAP message in Listing 12.7 shows how the X.509 certificate is included using XML D-Sig specifications.

Listing 12.7: SOAP request to the registry with the X.509 certificate
Start example
<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
<soap-env:Header>
    <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
    <ds:SignedInfo>
    <ds:CanonicalizationMethod
              Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315">
        </ds:CanonicalizationMethod>
    <ds:SignatureMethod
              Algorithm="http://www.w3.org/2000/09/xmldsig#dsa-sha1">
           </ds:SignatureMethod>
    <ds:Reference URI="">
    <ds:Transforms>
    <ds:Transform
            Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature">
         </ds:Transform>
    <ds:Transform
         Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments">
           </ds:Transform>
    </ds:Transforms>
    <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1">
         </ds:DigestMethod>
    <ds:DigestValue>bT5BLPViSpaLoRE3fjnH0RpQ6Jw=</ds:DigestValue>
    </ds:Reference>
    </ds:SignedInfo>

    <ds:SignatureValue>YJZAHweU7komyE1p9yOiutWrwZR46/L2GByohkd/b16iVurDQ3ik1g==
            </ds:SignatureValue>
    <ds:KeyInfo>
    <ds:X509Data>
    <ds:X509Certificate>
    MIIC2DCCApYCBD2WJLAwCwYHKoZIzjgEAwUAMFIxDDAKBgNVBAYTA1VTQTEVMBMGA1UEChMMU
    cmNlIEZvcmdlMRAwDgYDVQQLEwdlYnhtbHJyMRkwFwYDVQQDExBSZWdpc3RyeU9wZXJhdG9yM
    DTAyMDkyODIxNTI0OFoXDTAyMTIyNzIxNTI0OFowUjEMMAoGA1UEBhMDVVNBMRUwEwYDVQQKE
    b3VyY2UgRm9yZ2UxEDAOBgNVBAsTB2VieG1scnIxGTAXBgNVBAMTEFJlZ2lzdHJ5T3BlcmF0b
    ggG3MIIBLAYHKoZIzjgEATCCAR8CgYEA/X9TgR11EilS30qcLuzk5/YRt1I870QAwx4/gLZRJ
    XUAiUftZPY1Y+r/F9bow9subVWzXgTuAHTRv8mZgt2uZUKWkn5/oBHsQIsJPu6nX/rfGG/g7V
    qKYVDwT7g/bTxR7DAjVUE1oWkTL2dfOuK2HXKu/yIgMZndFIAccCFQCXYFCPFSMLzLKSuYKi6
    8Fgc9QKBgQD34aCF1ps93su8q1w2uFe5eZSvu/o66oL5V0wLPQeCZ1FZV4661FlP5nEHEIGAt
    cSPoTCgWE7fPCTKMyKbhPBZ6i1R8jSjgo64eK7OmdZFuo38L+iE1YvH7YnoBJDvMpPG+qFGQi
    3+Fa5Z8GkotmXoB7VSVkAUw7/s9JKgOBhAACgYB19I45gtWIml4LIQXNNZS/u43ams5pjzjD9
    dr0voIUc/cWm/odiLnoNj4YNaRKncI8f5o9lQYX4y4QGusbVLVVUd7u4Xby50seu0nvAxh9//
    BHaQgHA/JTvatcmZwjXqqpZyBYrEYfXpHAFTY6fLJFKpp31Ai045gcXGIzALBgcqhkjOOAQDB
    LwAwLAIUYODY/SLIho4PAllVC4ZnCavE57cCFCtmGUi+oFftL8m29PdZqkW4XMKl
    </ds:X509Certificate>
    </ds:X509Data>
    <ds:KeyValue>
    <ds:DSAKeyValue>
    <ds:P>
    /X9TgR11EilS30qcLuzk5/YRt1I870QAwx4/gLZRJmlFXUAiUftZPY1Y+r/F9bow9subVWzXg
    HTRv8mZgt2uZUKWkn5/oBHsQIsJPu6nX/rfGG/g7V+fGqKYVDwT7g/bTxR7DAjVUE1oWkTL2d
    K2HXKu/yIgMZndFIAcc=
    </ds:P>
    <ds:Q>l2BQjxUjC8yykrmCouuEC/BYHPU=</ds:Q>
    <ds:G>
    9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCBgLRJFnEj6EwoF
    zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImog9/hWuWfB
    Zl6Ae1UlZAFMO/7PSSo=
    </ds:G>
    <ds:Y>
    dfSOOYLViJpeCyEFzTWUv7uN2prOaY84w/QlTHa9L6CFHP3Fpv6HYi56DY+GDWkSp3CPH+aPZ
    +MuEBrrG1S1VVHe7uF28udLHrtJ7wMYff/w9KgR2kIBwPyU72rXJmcI16qqWcgWKxGH16RwBU
    yyRSqad9QItOOYHFxiM=
    </ds:Y>
    </ds:DSAKeyValue>
    </ds:KeyValue>
    </ds:KeyInfo>
    </ds:Signature>
</soap-env:Header>
<soap-env:Body>
    <SubmitObjectsRequest
            xmlns="urn:oasis:names:tc:ebxml-regrep:registry:xsd:2.1">
    <LeafRegistryObjectList>
       <RegistryPackage id="urn:uuid:bfef9997-508d-4131-a826-edebc7a47836" objectType=
                                                                    "RegistryPackage">
    <Name>
            <LocalizedString charset="UTF-8" lang="en-us"
            value="Flute Bank Agreements">
             </LocalizedString>
    </Name>
    <Description>
          <LocalizedString charset="UTF-8" lang="en-us" value="">
     </LocalizedString>
    </Description>
    </RegistryPackage>
    </LeafRegistryObjectList>
    </SubmitObjectsRequest>
</soap-env:Body>
</soap-env:Envelope>
End example

Let us look at how a client can publish Organization information in the ebXML registry using JAXR. Listing 12.8 shows how the JAXR provider for ebXML (available under open source) can be used. The example is identical to Listing 12.1, which published the information to a UDDI registry. The only difference is the manner in which the connection is passed the user's credentials for authentication. Instead of a username and password, the user sends the X.509 certificate.

Listing 12.8: Using the open source JAXR provider to include the X.509 certificate
Start example
import java.security.*;
import java.security.cert.X509Certificate;
// other imports

public class ebXMLPublishOrg {

public static void main (String args[]){
// keystore location and alias

// Start JAXR provider imsplementation specific code
    String alias = "mykey";
    String location="c:/temp/rr/jaxr/keystore.jks";
    String storepass="ebxmlrr";
    String keypass="password";
HashSet creds = new HashSet();
// get the keystore
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(new FileInputStream(location), storepass.toCharArray());
X509Certificate cert =(X509Certificate)keyStore.getCertificate(alias);
PrivateKey privateKey=
(PrivateKey)keyStore.getKey(alias,keypass.toCharArray());
   X500PrivateCredential credential=
                             new X500PrivateCredential(cert,privateKey,alias);
// End  JAXR provider implementation specific code
    creds.add(credential);
// Create the connection factory, which can be set by the system property
//-Djavax.xml.registry.ConnectionFactoryClass=
//                   com.sun.xml.registry.ebxml.ConnectionFactoryImpl
 ConnectionFactory factory = ConnectionFactory.newInstance();
 Connection connection = connFactory.createConnection();
 connection.setCredentials(creds);
// create organization and other objects with BusinessLifeCyleManager and
// use the BusinessLifeCyleManager.saveOrganizations(orgs) method
      }
}

End example

Publishing Content to ebXML Registry

One of the advantages of using an ebXML registry is that it can store arbitrary content, such as business process descriptions (BPML documents), and business agreements, such as the CPP and CPA agreements used in ebXML messaging systems. This is different from storing WSDL in UDDI, in the sense that the actual business document is stored in the repository, which the registry service exposes. For example, the code in Listing 12.3 publishes a URL only to the WSDL document, whereas in an ebXML registry, the actual WSDL document may be published to the registry. In this sense, the ebXML registry plays a sort of content management role.

In JAXR, the ExtrinsicObject is used to model the metadata representing such content. Let us look at some code extracts that show how this can be used. Flute Bank can choose to store its CPP/CPA with OfficeMin as the following code shows.

// Create a connection and authenticate with the registry
// Obtain the BusinessLifeCyleManager instance from the connection
// Now get the XML file
URL url = getClass().getResource("/agreements/officemin.xml");
DataHandler handler = new DataHandler(url);
// Create an ExtrinsicObject
ExtrinsicObject obj = lifecyclemgr.createExtrinsicObject(handler);
obj.setRepositoryItem(handler);
// Save the arbitrary content
Collection data = new ArrayList();
data.add(obj);
BulkResponse response = lifecyclemgr.saveObjects(data);
if(response.getStatus()==BulkResponse.STATUS_SUCCESS){
    System.out.println("CPP successfully saved");
     System.out.println("ID is :+obj.getKey().getId()");
        }

Note that in the above example, the resource can be any arbitrary content, such as graphic files, XML schemas, or Word documents.

In practical terms, content will be grouped into RegistryPackage objects that can be associated with any RegistryObject. RegistryPackages are a powerful level 1 feature. Any registry object can have multiple RegistryPackages associated with it and can also be associated with multiple packages. Therefore, business documents such as privacy policies, grouped under a package named "Policies" and associated with an Organization, can be retrieved as shown below:

// Locate the Organization
   BulkResponse response =  querymgr.findOrganizations(findqualifier,
                                      searchpattern, null, null, null,
// Iterate and get to the individual Organization
    Organization org =  (Organization) orgiterator.next();
     Collection packages =org.getRegistryPackages();
// Iterate and get to the package we are interested in
   if(package.getName().getValue().equals("Policies"){
        Collection extobjects=package.getRegistryObjects();
//  Iterate and get individual ExtrinsicObject elements
          ExtrinsicObject obj=eoiter.next();
// get underlying content
          DataHandler handler= obj.getRepositoryItem();

Documents such as the CPP and CPA, which relate to the Service, can also be queried and stored in a similar manner under the associated Service object (which is also an instance of a RegistryObject).

As a general programming note, while interacting with the ebXML registry, client applications will rely more on the generic methods defined in the LifeCycleManager rather than the subclass BusinessLifeCycleManager to create and save objects. Similarly, they will rely more on the declarative queries and the DeclarativeQueryManager looked at earlier to find data in the registry, as opposed to the BusinessQueryManager looked at for UDDI.

A Complete ebXML Example

Let us look at a complete example of publishing information to an ebXML registry, using the open source JAXR provider and ebXML registry implementation. We have slightly modified the UDDI example from Listing 12.1, for two reasons: the ebXML registry has tighter validation rules than UDDI (e.g., a contact person for an Organization is required), and we wanted to show the use of some level 1 capabilities.

Listing 12.9 publishes Flute Bank's information, its BillPay service information, some associated documents (we will use Flute's BPSS and CPA XML documents used in Chapter 7), and creates a package object in the registry and an association. For the sake of brevity, we have not included the SOAP messages exchanged between the client and the registry. Upon successful execution, the results can be viewed using the graphical registry browser, as Figure 12.19 shows.

Listing 12.9: Publishing with the JAXR provider
Start example
import javax.xml.registry.infomodel.*;
import javax.xml.registry.*;
import java.util.*;
import java.net.URL;
import javax.activation.*;
import java.security.*;
import java.io.FileInputStream;
import java.security.cert.X509Certificate;
import javax.security.auth.x500.X500PrivateCredential;

public class ebXMLPublishOrg{
  private static final String QUERY_URL= "http://localhost:9090/ebxmlrr/registry";
  private static final String PUBLISH_URL="http://localhost:9090/ebxmlrr/registry";
  public static void main(String[] args) throws Exception {
// Set the properties for the ConnectionFactory
Properties environment = new Properties();
environment.setProperty("javax.xml.registry.queryManagerURL", QUERY_URL);
environment.setProperty("javax.xml.registry.lifeCycleManagerURL", PUBLISH_URL);

// Instantiate the factory and create a connection from it
    ConnectionFactory connfactory = ConnectionFactory.newInstance();
    connfactory.setProperties(environment);
    Connection conn = connfactory.createConnection();
// Authenticate the username and password with the registry

/////////////// Start JAXR provider implementation-specific code
    String alias = "mykey";
    String location="c:/temp/rr/jaxr/keystore.jks";
    String storepass="ebxmlrr";
    String keypass="password";
    HashSet creds = new HashSet();
// get the keystore
  KeyStore keyStore = KeyStore.getInstance("JKS");
    keyStore.load(new FileInputStream(location), storepass.toCharArray());

  X509Certificate cert =(X509Certificate)keyStore.getCertificate(alias);
  PrivateKey privateKey =
                     (PrivateKey)keyStore.getKey(alias,keypass.toCharArray());
  X500PrivateCredential credential=
                           new X500PrivateCredential(cert,privateKey,alias);
    creds.add(credential);
//////////////  END JAXR provider implementation-specific code
    conn.setCredentials(creds);

// Obtain a reference to the RegistryService, the BusinessLifeCycleManager, and
// the BusinessQueryManager
RegistryService registryservice = conn.getRegistryService();
BusinessLifeCycleManager lifecyclemgr =
                             registryservice.getBusinessLifeCycleManager();
BusinessQueryManager querymgr = registryservice.getBusinessQueryManager();

// Create a user object
User contact = lifecyclemgr.createUser();
PersonName name = lifecyclemgr.createPersonName("John Malkovich");
contact.setPersonName(name);
InternationalString contactdescription = lifecyclemgr.createInternationalString
                                ("The primary contact person for Flute Web services");
contact.setDescription(contactdescription);

// Create and set the user's telephone number
TelephoneNumber telnum = lifecyclemgr.createTelephoneNumber();
telnum.setNumber("1-800-FLUTE-US");
Collection phonenumbers = new ArrayList();
phonenumbers.add(telnum);
contact.setTelephoneNumbers(phonenumbers);

// Create and set the user's email address
EmailAddress email =  lifecyclemgr.createEmailAddress(
                                                "ebxml-admin@flutebank.com");
Collection emaillist = new ArrayList();
emaillist.add(email);
contact.setEmailAddresses(emaillist);

PostalAddress addr = lifecyclemgr.createPostalAddress("64"," Bit
                       Street"," Windsor"," CT"," USA","03060"," Office Address");
ArrayList addresses = new ArrayList();
addresses.add(addr);
contact.setPostalAddresses(addresses);
// Create an organization object
Organization company =   lifecyclemgr.createOrganization("Flute Bank");
InternationalString description = lifecyclemgr.createInternationalString
                       "A fictitious bank used for examples in the book Java Web
Services Architecture, published by Morgan Kaufman, ISBN 1-55860-900-8. The authors
can be reached at webservicesbook@yahoogroups.com OR
www.javawebservicesarchitecture.com. ");
company.setDescription(description);

// Set the user as the primary contact for the organization. User's address and
// company address are same
company.setPrimaryContact(contact);
company.setPostalAddress(addr);
company.setTelephoneNumbers(phonenumbers);

ExternalLink website = lifecyclemgr.createExternalLink("http://www.flutebank.com",
"Flute Bank Inc");
website.setValidateURI(false);
company.addExternalLink(website);

// We now have the objects representing our information model
// To publish it, we must classify it. We decide to use the
//  NAICS scheme
ClassificationScheme scheme =
              querymgr.findClassificationSchemeByName(null," ntis-gov:naics");

// Create the classification using the above scheme and pass the relevant
// category code and description

Classification classification =
(Classification)lifecyclemgr.createClassification(scheme,"Finance and Insurance", "52");
Collection classificationlist = new ArrayList();
classificationlist.add(classification);
company.addClassifications(classificationlist);

// Create the concrete service (this maps to the businessService)
Service service = lifecyclemgr.createService("Billpayservice");
company.addService(service);
InternationalString servicedescription =
                                     lifecyclemgr.createInternationalString("A Web
                               service allowing account holders to pay bills online");
service.setDescription(servicedescription);

ExternalLink link1 = lifecyclemgr.createExternalLink
 ("http://127.0.0.1:8080/billpayservice/billpayservice.wsdl", "Service WSDL");
link1.setValidateURI(false);
service.addExternalLink(link1);

// Create the service bindings for the Web service
ServiceBinding binding = lifecyclemgr.createServiceBinding();
binding.setValidateURI(false);
InternationalString bindingdescription =
    lifecyclemgr.createInternationalString("HTTP bindings for the Billpayservice Web
                                                                            service");
binding.setDescription(bindingdescription);
// replace with the actual URL where the service is deployed
binding.setAccessURI("http://127.0.0.1:8080/billpayservice/jaxrpc/BillPay");
service.addServiceBinding(binding);

DataHandler upload1 = new DataHandler(new FileDataSource("C:/rr/jaxr/build/test/
classes/bpss.xml"));
DataHandler upload2 = new DataHandler(new FileDataSource("C:/rr/jaxr/build/test/
classes/cpa.xml"));

// Create an ExtrinsicObject
ExtrinsicObject obj1 = lifecyclemgr.createExtrinsicObject(upload1);
ExtrinsicObject obj2 = lifecyclemgr.createExtrinsicObject(upload2);

RegistryPackage docs =lifecyclemgr.createRegistryPackage("BusinessDocuments");
docs.addRegistryObject(obj1);
docs.addRegistryObject(obj2);

Concept assType = querymgr.findConceptByPath("/AssociationType/packages");
Association ass = lifecyclemgr.createAssociation(docs, assType);
company.addAssociation(ass);
// make the final call to the registry and get a response
// This could have been used instead
//BulkResponse response = lifecyclemgr.saveOrganizations(organizationlist);
// We show the more general method below

ArrayList objs = new ArrayList();
objs.add(company);
objs.add(service);
objs.add(binding);
objs.add(contact);
objs.add(docs);
objs.add(website);

BulkResponse response = lifecyclemgr.saveObjects(objs);
if (response.getStatus()==JAXRResponse.STATUS_SUCCESS)
        System.out.println("The request was processed successfully");
// Finally, close the connection
conn.close();
    }
}
End example
Click To expand
Figure 12.19: ebXML registry browser

Mapping of ebXML Registry Information Model to JAXR

No mapping is required from the JAXR model to the ebXML Registry Information Model, because they are identical (e.g., Organization interface in JAXR maps to an Organization object in RIM, etc.) Also, JAXR supports all features and functionality defined by OASIS for the ebXML registry.


Previous Section Next Section


JavaScript Editor Java Tutorials Free JavaScript Editor