The current challenge in e-business development is to cross the boundaries of traditional enterprise and seamlessly integrate businesses into an interoperable set of loosely coupled components. This is the basic concept of collaborative commerce, in which across-the-enterprise communication through open standards plays a key role. In other words, this is the era of interoperability, which is fast becoming as important as the more traditional and well recognized requirements of portability and scalability in e-business solutions. ebXML ("electronic business XML") is a set of specifications to define a modular yet complete framework for collaborative commerce. The ebXML set of specifications is a combined effort of two organizations OASIS (Organization for the Advancement of Structured Information Standards; see http://www.oasis-open.org/) and UN/CEFACT (United Nations Centre for Trade Facilitation and Electronic Business; see http://www.unece.org/cefact/). ebXML defines XML-based grammars to facilitate interoperability. The following are the main features that the ebXML specification suite offers:
A complete discussion of the entire ebXML architecture is beyond the scope of this section. We will keep our focus on the third point (the ebXML registry services). The ebXML Registry ServicesThe ebXML registry services are meant to manage publishing, indexing, and the categorization of information. It serves as a storage facility for business information and associated metamodels. The main aim of this effort is the same as that of all search engines such as Yahoo! the information should be available to those searching for it. For this purpose, the ebXML registry services include a set of data structures that collectively form the ebXML Registry Information Model (ebRIM). We will first discuss the information model of the ebXML registry services, and then move on to the programmatic interface necessary to access the services. The ebXML Registry Information ModelThis section describes the information model for the ebXML registry services. The information model explains the data structures and data types of objects contained in an ebXML registry. The official documentation for ebRIM defines interfaces instead of classes to describe the information model. The use of interfaces reminds us that the ebRIM documentation is an abstract definition, and does not imply any specific implementation. Therefore, the interfaces included in ebRIM are not the actual interfaces that will be used to interact with the objects in an ebXML data repository. We will discuss the XML-based interfaces that expose the functionality of the ebXML registry services separately in a later section. Another important thing to remember is that the interfaces in ebRIM only govern the metadata structures describing the content residing in an ebXML data repository. The ebRIM interfaces do not say anything about the actual content submitted to the data repository. The actual content is normally in the form of XML files, DTDs, schema documents, and so on. The ebXML registry service users might control the structure of the actual content, instead of the registry service itself. A content item (an XML file, for example) that a registry service user submits to the registry service is called a repository item. A metadata structure that describes a repository item is referred to as a registry entry. Therefore, repository items and registry entries are related to each other, but are not the same. The ebXML registry information model is all about defining structures for the registry entry objects. Note Note that this section only aims to present the basic concepts of the ebXML information model to support the next section, in which we describe the programmatic interfaces for accessing the ebXML registry services. It is not possible to cover the entire information model in this section, so the interfaces and data structures presented here are not exhaustive. The RegistryObject InterfaceThe RegistryObject interface forms the base interface in the information model. Most of the registry entries extend the RegistryObject interface. It contains set and get methods for four important parameters: name, id, description, and accessControlPolicy. The first three parameters are related to the identity of the object instantiating this interface. All three parameters map to XML attributes with the same names while accessing a registry service. The fourth parameter defines a security model in terms of access control (who is allowed to do what with this object). All registry entry interfaces that require an identity (ID, name, and description) and security model (access control policy) will extend from the RegistryObject interface. The most important interface that extends the RegistryObject interface is the RegistryEntry interface. The RegistryEntry Interface and Its Sub-InterfacesRegistryEntry is the base interface for all the metadata interfaces that describe the content submitted to the ebXML registry. One of the important attributes in this interface is the status attribute. The getStatus method in the RegistryEntry interface tells the status of any RegistryEntry object. The status attribute depicts the lifecycle of a repository item. A repository item can have one of the four predefined status values: Submitted, Approved, Deprecated, and Withdrawn. When a repository item is first submitted by a submitting organization, the value of its status attribute is Submitted. The submitting organization can approve a previously submitted RegistryEntry instance, so that its status will change to Approved. Similarly, RegistryEntry instances can be Deprecated and Withdrawn by the submitting organizations. Another important attribute in the RegistryEntry interface is the stability attribute. A submitting organization needs to indicate the stability of content being submitted. The stability attribute can have one of three possible predefined values: Dynamic (meaning it's not stable and can change arbitrarily), DynamicCompatible (meaning it's not stable, but will change in a backward-compatible manner) and static (meaning it's stable). The RegistryEntry interface is directly extended by two interfaces the ExtrinsicObject interface and the IntrinsicObject interface. The ExtrinsicObject interface describes the repository items whose type is not intrinsically known to the ebXML registry service. The exact type of an ExtrinsicObject is normally determined through additional means, such as MIME types and so on. The ExtrinsicObject interface is not extended further to produce other interfaces, and therefore different ExtrinsicObject instances only differ from each other in their data types. The following is how an ExtrinsicObject will look like in XML format: <ExtrinsicObject id = "CarRentalProfile" contentURI = "A resolvable URI to a Car Rental Profile." objectType = "CPP" name = "CarRentalCPP" description = "Profile to rent a car on-line." /> The name, id, and description attributes are inherited from the RegistryObject interface. The objectType attribute is inherited from the RegistryEntry interface (we'll explain what this means shortly). The contentURI attribute contains a URI that points to the actual content catalogues by this ExtrinsicObject. The IntrinsicObject interface describes the content submitted to the ebXML data repository whose type is intrinsically known to the registry service. This interface is further extended by these interfaces: Package, ExternalIdentifier, ExternalLink, Organization, Association, ClassificationNode, and Classification. Therefore, the RegistryEntry interface is directly and indirectly extended to produce many other interfaces. To identify the interface or data type of a particular RegistryEntry instance, the RegistryEntry interface has an attribute named objectType. The objectType attribute tells the type of interface of a particular RegistryEntry instance. The objectType attribute can have one of several predefined values. Each value corresponds to a data type (in the case of an ExtrinsicObject instance) or an interface (in the case of an IntrinsicObject instance). The predefined values for ExtrinsicObject data types are as follows:
The predefined values for IntrinsicObject interfaces are as follows:
Programmatic Interfaces for the ebXML Registry ServicesWe'll first see how to submit (or publish) information on an ebXML registry service. The discussion on searching or browsing through the registry will be next. Publishing to an ebXML RegistryThe ebXML registry services manage information as objects through an interface named ObjectManager. Whenever an ebXML client wants to submit some information to ebRS, it will invoke the submitObjects methods of the ObjectManager interface. The submitObjects method takes a parameter named SubmitObjectsRequest, which specifies all objects that need to be published. For example, look at the following XML structure: <SubmitObjectsRequest> <RegistryEntryList> <Package id = "TourismPackage" name = "Package #1" description = "Everything related to tours."/> <ExtrinsicObject id = "CarRentalProfile" contentURI = "A resolvable URI to a Car Rental Profile." objectType = "CPP" name = "CarRentalCPP" description = "Profile to rent a car on-line." /> <Association id = "TourismPackage CarRentalProfile" associationType = "Packages" sourceObject = "TourismPackage" targetObject = "CarRentalProfile" /> <ObjectRef id = "urn:uuid:a2345678-1234-1234"/> <Association id = "TourismPackage - HotelBookingProfile" associationType = "Packages" sourceObject = "TourismPackage" targetObject = "urn:uuid:a2345678-1234-1234"/> </RegistryEntryList> </SubmitObjectsRequest> We'll now look into the details of SubmitObjectsRequest. The SubmitObjectsRequest shown here has only one child element: RegistryEntryList, which is a list of entries that we want to publish on the ebXML registry services. Our entries are very simple. There is a Package element, an ExtrinsicObject instance, two Association instances, and another object referred to by an ObjectRef element. An ObjectRef element simply refers to another registry entry through its id attribute. The registry entry being referred to should be available at the ebXML registry. First, look at the two Association elements. Each Association element has a sourceObject attribute. Both sourceObject attributes have the same value (TourismPackage). This means that the source object of the two associations is the same. Compare this source object with the id attribute of the Package element. They are the same. Therefore, the source object of the two associations is the Package element in the SubmitObjectsRequest. Now look at the targetObject attributes of the two Association elements. The two target objects are different from each other. One of the two matches with the id attribute of the ExtrinsicObject instance, whereas the other matches with the id attribute of the ObjectRef element. Therefore, the target objects of the associations are the ExtrinsicObject and the ObjectRef elements. This is how we can package or group different objects. The sourceObject attribute of an Association element refers to a Package element, and the targetObject attribute of the association refers to the object that needs to be packaged. You can include any number of objects in the same package. Moreover, you can create any number of packages in the same SubmitObjectsRequest. Removing Objects from an ebXML RegistryWe will now explain how to delete metadata objects from an ebXML registry service. The following XML message accomplishes this: <RemoveObjectsRequest deletionScope = "Delete All" <ObjectRefList> <ObjectRef id = "urn:uuid:b2345678-1234-1234"/> </ObjectRefList> </RemoveObjectsRequest> The RemoveObjectsRequest contains an ObjectRefList that is actually a list of ObjectRef elements (we have shown only one). This request will remove all objects referred to by the ObjectRef elements in the ObjectRefList. Note that you will need to remove all references to a RegistryEntry before removing the entry itself. For example, if you want to remove the CarRentalProfile ExtrinsicObject that we previously published while explaining the SubmitObjectsRequest method, you will first have to remove all association instances whose targetObject is referring to the CarRentalProfile ExtrinsicObject. The deletionScope attribute of RemoveObjectsRequest shown in the preceding code controls the scope of deletion. The deleteAll value of this attribute will delete both the repository item and the registry entry associated with it. If you want to delete only the registry entry and not the repository item, you will specify DeleteRepositoryItemOnly as the value of the deletionScope attribute. Publishing ClassificationsThe following SubmitObjectsRequest call will publish the classificationNode and Classification elements that we presented during the discussion on ClassificationNode and Classification elements (refer to the section "The ebXML Registry Information Model"): <SubmitObjectsRequest> <RegistryEntryList> <ExtrinsicObject id = "CarRentalProfile" contentURI = "A resolvable URI to a Car Rental Profile." objectType = "CPP" name = "CarRentalCPP" description = "Profile to rent a car on-line." /> <ClassificationNode id = "Industry" name = "Industrial Classification Scheme" description = "The Industrial Classification example."/> <ClassificationNode id = "AutomotiveIndustryNode" name = "Automotive industry" description = "Automotive industry node under the industrial classification." parent = "Industry"/> <ClassificationNode id = "MotorVehicleAssemblyNode" name = "Motor Vehicle Assembly" description = "The Motor Vehicle Assembly node under the AutomotiveIndustryNode" parent = "AutomotiveIndustryNode"/> <Classification id = "sampleClassification" description = "Classifies the CarRentalProfile extrinsic object by Industry/ AutomotiveIndustryNode/MotorVehicleAssemblyNode" classifiedObject = "CarRentalProfile" classificationNode = "MotorVehicleAssemblyNode" /> </RegistryEntryList> </SubmitObjectsRequest> Searching and Browsing Through the ebXML RegistryebXML offers an Object Query Management service that exposes an ObjectQueryManager interface. The ObjectQueryManager interface is responsible for performing all browsing and search operations. An ebXML registry user who wants to browse through or search for information on an ebXML data repository will use the ObjectQueryManager interface. Such users are called ObjectQueryManagerClients. You have already seen that there are several types of registry entries: Classification and association instances, intrinsic and extrinsic objects, and business organizations are all registry entries. The XML syntax of ebXML search queries aims at testing the relationships between different types of registry entries to find the required information. Let's consider a few search requirements to elaborate upon this point. We will start with the most primitive and slowly move to the advanced searches. Search Scenario 1: We want to search for companies offering specific products and services on an ebXML registry, but we don't know the keywords to search for. So, we'll want to browse through the classification tree in the ebXML registry. If there is more than one classification of trees available, we'll want to learn about all of them. This basic search requirement is fulfilled in two steps using the ObjectQueryManager interface: Discovering all available classification trees and browsing through the classification trees. GetRootClassificationNodesRequest will return the root nodes of all classification trees. A root node in the classification tree is like the root element of an XML file it has no parent, so that's the point where the classification tree starts. All other classification nodes are descendants of the root classification nodes. There can be any number of root classification nodes in an ebXML registry. For example, there will be separate classification root nodes (and therefore separate classification trees) for industrial and geographical classifications. GetRootClassificationNodesRequest has the following XML syntax: <GetRootClassificationNodesRequest namePattern = "*"/> The namePattern attribute uses a wildcard pattern specified by SQL. We have specified the asterisk mark as the name pattern, which means we are interested in all root classification nodes. The following is a typical registry response of GetRootClassificationNodesRequest: <RegistryResponse status = "success"> <GetRootClassificationNodesResponse> <ClassificationNode name = "Name of this classification node." description = "Some descriptive text for this classification node"/> <ClassificationNode name = "Name of this classification node." description = "Some descriptive text for this classification node"/> <ClassificationNode name = "Name of this classification node." description = "Some descriptive text for this classification node"/> </GetRootClassificationNodesResponse> </RegistryResponse> Notice that the RegistryResponse element has a status attribute that says "success". If there was an error during request processing, this attribute would have said "failure". The registry response will contain one ClassificationNode element for each classification tree present in the registry. We have shown three nodes in the registry response, each of which has an id attribute. The id attribute uniquely identifies a ClassificationNode. Each ClassificationNode also contains a description attribute. Upon receipt, the ObjectQueryManagerClient will parse the registry response and decide which ClassificationNodes are of interest. When it has chosen the ClassificationNodes that it wants to peruse further, it can go ahead with the next step and browse the classification trees. The browsing consists of opening a classification tree to the required number of levels. This is like browsing through a list of folders using Windows Explorer. You can click on a folder to view another level of child folders. In this way, you can open the tree of folders to the deepest level. Let's see how we can follow the same technique to browse through and open a classification tree to our desired level. The following code shows a GetClassificationTreeRequest, which takes two parameters, parent and depth: <GetClassificationTreeRequest parent = "parent that needs to be drilled down" depth = "1"/> The parent parameter identifies the ClassificationNode that needs to be drilled down. The depth attribute specifies the number of levels that we want to drill down. A depth value of 1 will return only the immediate children of the classification node specified by the parent attribute. A zero or negative depth value will return the entire subtree of the parent classification node. The following is a typical response of GetClassificationTreeRequest: <RegistryResponse status = "success"> <GetClassificationTreeResponse> <ClassificationNode name = "Name of this classification node." description = "Some descriptive text for this classification node" parent = "parent of this classification node"/> <ClassificationNode name = "Name of this classification node." description = "Some descriptive text for this classification node" parent = "parent of this classification node"/> <! Other classification nodes. > </GetClassificationTreeResponse> </RegistryResponse> An ObjectQueryManagerClient might use a number of GetClassificationTreeRequest calls to arrive at the required classification node(s). Search Scenario 2: Search for all companies that offer a certain product and are located in a certain region. We will now see a search scenario in which an ebXML registry service client will use the classification nodes previously obtained to search for other types of registry entries. This scenario requires finding organizations that have been classified with certain geographical and product classifications. The GetClassifiedObjectsRequest element can specify this query in XML syntax. Look at the following XML code: <GetClassifiedObjectsRequest> <ObjectRefList> <ObjectRef /> <ObjectRef /> <ObjectRefList> </GetClassifiedObjectsRequest> The GetClassifiedObjectsRequest element contains a single ObjectRefList element. The ObjectRefList element contains a list of references to classification nodes. Each classification node is referenced through an ObjectRef element. The GetClassifiedObjectsRequest will bring all registry entries that have been classified by all the classification nodes being referenced by the ObjectRef elements. The first ObjectRef element might point to the product classification, and the other might refer to the geographical classification of our interest. How do we know the values of id attributes of classification nodes? The previously discussed GetRootClassificationNodesRequest and GetClassificationTreeRequest methods used one after the other will fetch the id attributes of classification nodes to be passed to the GetClassifiedObjectsRequest. A response to GetClassifiedObjectsRequest is supposed to contain registry entries that have been classified with all the classification nodes specified in the request. This means that there is a logical AND between individual classification nodes included in the ObjectRefList element. It's possible that some of the classification nodes we specify in the ObjectRefList structure have further child nodes. As an example, consider the Product classification tree shown in Figure 13.5. Figure 13.5. A sample product classification tree.Figure 13.5 shows a root classification node Product that has a child classification node Engineering Services. The Engineering Services node has three child nodes: Mechanical Engineering, Electrical Engineering, and Software Engineering. The Mechanical Engineering node has further children: Process Plant Fabrication and Power Generation Set Repairs. Let's suppose, we included a reference to the Mechanical Engineering classification node in the ObjectRefList. This means that the response to our GetClassifiedObjectsRequest will contain any registry entry that has been classified with the Mechanical Engineering node or with the Process Plant Fabrication node, or with the Power Generation Set Repairs node. So, there is a logical OR between the entries of a subtree of a classification node included in the ObjectRefList. Combining the logical AND with the logical OR rules is simple. Suppose there were two classification nodes in the GetClassifiedObjectsRequest: Asia under the geographical classification parent and Mechanical Engineering under the product classification parent node. In this case, the registry entries fulfilling both of the following conditions will be returned:
The GetClassifiedObjectsRequest given previously will return the following XML structure: <RegistryResponse status = "success"> <GetClassifiedObjectsResponse> <RegistryEntryList> <Organization primaryContact = "id of a User object that acts as a primary contact for the organization."> <PostalAddress street = "Street" city = "City" country = "Country" postalCode = ""postal code"/> <TelephoneNumber number = "5834567" areaCode = "42" contryCode = "92"/> <FaxNumber number = "5834568" areaCode = "42" contryCode = "92"/> </Organization> <ExtrinsicObject id = "some CPP document" contentURI = "CPP1" objectType = "CPP" name = "Name of this profile" description = "Textual description of this profile."/> <! Other registry entries. > </RegistryEntryList> </GetClassifiedObjectsResponse> </RegistryResponse> The GetClassifiedObjectsResponse structure shown here contains two registry entries: an Organization structure and an ExtrinsicObject instance. Search Scenario 3: We want to search for all hotels that have classified themselves under tourism-related services and are located in Lahore. We know the UNSPSC code of tourism-related services, and will look for all organizations that have the keyword hotel in their name, and have classified them under both the following conditions:
We have so far considered how to browse and drill down the classification trees in an ebXML registry service. We have also considered the case in which classification nodes are used to search all registry entries classified against specific classification nodes. We will now consider another search scenario, in which none of the previously discussed search techniques are useful. This search scenario requires finding the registry entries that fulfil the following criteria:
The GetClassifiedObjectsRequest that we discussed previously can take care of only the first criterion (classified under the specified product and geographical classifications). The latter two search criteria need the support of filtering the results. The ebXML registry service provides a comprehensive mechanism of filter queries to search according to filtering requirements. Probably the most frequently used filter query is RegistryEntryQuery. Have a look at the following code that demonstrates the use of RegistryEntryQuery: <RegistryEntryQuery> <RegistryEntryFilter> <Clause> <CompoundClause connectivityPredicate = "And"> <Clause> <SimpleClause leftArgument = "objectType"> <StringClause stringcomparepredicate = "equal"> Organization </StringClause> </SimpleClause> </Clause> <Clause> <SimpleClause leftArgument = "status"> <StringClause stringcomparepredicate = "equal"> Approved </StringClause> </SimpleClause> </Clause> </CompoundClause> </Clause> </RegistryEntryFilter> <HasClassificationBranch> <ClassificationNodeFilter> <Clause> <SimpleClause leftArgument = "id"> <StringClause stringcomparepredicate = "startswith"> urn:un:spsc:XXXX </StringClause> </SimpleClause> </Clause> </ClassificationNodeFilter> <ClassificationNodeFilter> <Clause> <SimpleClause leftArgument = "id"> <StringClause stringcomparepredicate = "startswith"> urn:un:spsc:YYYY </StringClause> </SimpleClause> </Clause> </ClassificationNodeFilter> </HasClassificationBranch> <SubmittingOrganizationBranch> <OrganizationFilter> <Clause> <SimpleClause leftArgument = "name"> <StringClause stringcomparepredicate = "contains"> hotel </StringClause> </SimpleClause> </Clause> </OrganizationFilter> </SubmittingOrganizationBranch> </RegistryEntryQuery> This RegistryEntryQuery structure contains three child elements: RegistryEntryFilter, HasClassificationBranch, and SubmittingOrganizationBranch. These three elements represent three filters that will be applied one by one to the search results. The search filter query process starts with all the registry entry objects in the ebXML registry. The first filter to be applied is the RegistryEntryFilter, which has two requirements:
There is a logical AND operation between the two requirements; therefore the search results will contain only the registry entries that fulfill both requirements. The two filtering requirements of the RegistryEntryFilter are accomplished through the Clause child element. ebXML has defined an XML-based grammar to specify filtering queries. The Clause element belongs to this grammar. For clarity, look at the Clause structure separately, which we have extracted from the main structure: <Clause> <CompoundClause connectivityPredicate = "And"> <Clause> <SimpleClause leftArgument = "objectType"> <StringClause stringcomparepredicate = "equal"> Organization </StringClause> </SimpleClause> </Clause> <Clause> <SimpleClause leftArgument = "status"> <StringClause stringcomparepredicate = "equal"> Approved </StringClause> </SimpleClause> </Clause> </CompoundClause> </Clause> The main Clause structure shown here has a child element named CompoundClause. You will need a CompoundClause only when you have more than one logical condition to specify (recall that we have two conditions to specify). The CompoundClause element has an attribute named connectivityPredicate that specifies the logical operator between the logical conditions inside the CompoundClause (we have specified AND). There are two Clause elements inside the CompoundClause element. Each Clause element will specify one logical condition. The first Clause element specifies the first condition: "objectType of the registry entry should be Organization (objectType EQUALS "Organization")." This is a string comparison operation that requires a combination of SimpleClause and StringClause elements. There are other types of comparison operations also available, such as Boolean comparison (using BooleanClause), integer comparison (using IntClause), and so on, but for this example, we need only the string comparison function. Every string comparison operation requires specifying three things:
You can follow the other clause in a similar way. The second filter (HasClassificationBranch) operates on the set of registry entries that have passed the first filter (RegistryEntryFilter). The HasClassificationBranch element will filter out all those entries that do not have any classification. The remaining set of entries will be passed on to the two ClassificationNodeFilter elements one by one. The first ClassificationNodeFilter element is for the UNSPSC product classification for tourism, and the second is for the geographical classification node. Similarly, the third filter (SubmittingOrganizationBranch) will act on the set of remaining nodes that have passed all the filters encountered thus far. This last filter will block all registry entries that do not have keyword hotel in their name. We have presented only a few search scenarios in this section to convey the basic concept. It is not feasible to cover all logical cases in this section. Many other search and query features are comprehensively covered in the ebRS document that is part of the official ebXML documentation. |