JBoss.orgCommunity Documentation

Chapter 6. Replication Services

Table of Contents

6.1. Introduction
6.2. UDDIv3 Replication Overview
6.2.1. UDDIv3 Replication Topology
6.2.2. Conflict handling
6.3. Configuring your jUDDI Node for replication
6.3.1. Changing the Node ID
6.3.2. Setting up CLIENT-CERT authentication
6.3.3. Setting the Replication Configuration
6.3.4. Performing Custody Transfer between nodes
6.3.5. What’s Supported and What’s Not

The UDDIv3 specification introduced a Replication API that outlines a mechansim for maintaing data ownership and data synchronization across more than one UDDI node. The replication specification has a number of facets that to the casual reader, can see overwhelmingly complex. jUDDI v3 provides support for the majority of the UDDIv3 replication API. This article will attempt to describe the in’s and out’s of the specification, what jUDDI supports and doesn’t, finally, how to use it with your jUDDI instance(s).

The UDDIv3 replication API defines a number of web service methods that are used to manage and replicate UDDI data. Each node is responsible for maintaining a record of all changes made both locally and at all remote nodes. Everytime a Business, Service, Binding, tModel, or Publisher Assertion changes, all nodes are notified of the change. Once receiving the notification of the change, all nodes are then responsible to obtain the change set, apply it locally, and then retransmit (if needed and based on topology). The topology is configured via the Replication Configuration. With jUDDI, this is configured using the adminstration console.

There’s one important note to remember. Each piece of data in UDDI is owned by a given node.

Prerequisites:

  1. Each node must have a unique ID associated with it.
  2. Each node must have the UDDI v3 Replication service (juddiv3replication.war) deployed and configured for CLIENT-CERT authentication using SSL/TLS.
  3. Each node must have a configured JKS key store and trust store.

Since a registry can be corrupted via the replication endpoint, it is important to provide adequate security. The UDDI spec recommends using mutual certificate authentication. This is somtimes returned to as "CLIENT-CERT", certificate based authentication, or two-way SSL. All of these terms really refer to the same thing. jUDDI comes prebundled with Apache Tomcat that is configured for mutal certificate authentication out of the box (with self signed certificates). To setup CLIENT-CERT authentication, please see the documentation for your web application server.

For each certificate that is used by a jUDDI node to authenticate to another, you’ll have to map the Subject DN of the certificate to a user with the role "replication". In our example, we’ll use tomcat’s tomcat-users.xml file.

<user username="CN=localhost, OU=jUDDI Test, O=Apache Software Foundation, L=Anytown, ST=MD, C=US" password="null" roles="replication"/>

In this example, we’ve added our test certificate’s subject DN to the role of "replication".

Tip

If you run into issues getting things working, try adding the following to the startup parameters for tomcat: -Djavax.net.debug=all

Important

Besides mapping the certificates to the replication role, either the certificate itself or the issuer of the certificate must be in the trust store used by the application server.

Since dealing with certificates can be confusing, consider the following configuration.

  • Node 1 sends updates to Node 2
  • Node 2 sends updates to Node 1

Then the certificates must be setup as follows (assuming that each node’s SSL cert is used for authentication to the other node(s))

  • Node 1’s public key must be trusted by Node 2 (in Node 2 app server’s trust store)
  • Node 2’s public key must be trusted by Node 1 (in Node 1 app server’s trust store)
  • Node 1 must have Node 2’s certificate’s Subject DN mapped to the replication role
  • Node 2 must have Node 1’s certificate’s Subject DN mapped to the replication role
  • Node 1’s public and private keys must be in a keystore on Node 1 (and the Java -D properties set)
  • Node 2’s public and private keys must be in a keystore on Node 2 (and the Java -D properties set)

To set the replication configuration, you’ll need to go to http://localhost:8080/juddiv3/admin then click on "Admin" in the top navigation bar and login. Once logged in, select "set_ReplicationNodes" from the drop down menu. The text entry field is actually resizable, so you’ll probably want to make it bigger. This text box should be pre-populated with an example replication configuration. Edit the replication as needed, then click the "Go!" button to save it.

Note: when saving the configuration, several of the fields (time stamp, serial number) will be overwritten by the server. This is normal.

Additional notes: jUDDI doesn’t currently support maximumTimeToSyncRegistry, maximumTimeToGetChanges, and controlledMessage. Due to the way the specification was written, these fields are mandatory (they must be in the Replication Configuration XML), but jUDDI wont’t respect them.

When using jUDDI’s Admin console to set the replication config, here’s a few things to keep in mind (using xpath notation).

  • replicationConfiguration/operator() - All nodes in the replication graph must be listed in the Operator section, including all directed graph nodes
  • replicationConfiguration/registryContact - Must have at least one contact. If one is specified for the node’s root business, then jUDDI will include that with the default config.
  • replicationConfiguration/communicationGraph - Must be specified with all nodes listed as identified by the NodeID in replicationConfiguration/operator/operatorNodeID.
  • replicationConfiguration/communicationGraph/controlledMessage must be specified. jUDDI uses a * to represent all messages.
  • replicationConfiguration/maximumTimeToSyncRegistry isn’t used and jUDDI will always set it to 1
  • replicationConfiguration/maximumTimeToGetChanges - isn’t used and jUDDI will always set it to 1
  • replicationConfiguration/serialNumber - jUDDI will always set this to the time stamp when the configuration was last changed (time since epoch)
  • replicationConfiguration/timeOfConfigurationUpdate - jUDDI will always set this to the time stamp when the configuraiton was last changed in a human readable form. The UDDI specification doesn’t state what format it should be in, so we used ISO 8601 as the format.

Everytime the configuration changes, an audit log is required in jUDDI log file.

Here’s an example default configuration

<?xml version="1.0" encoding="UTF-8"?><replicationConfiguration xmlns="urn:uddi-org:repl_v3" xmlns:ns2="urn:uddi-org:api_v3" xmlns:ns3="http://www.w3.org/2000/09/xmldsig#">
    <serialNumber>1424114880586</serialNumber>
    <timeOfConfigurationUpdate>201502161428-0500</timeOfConfigurationUpdate>
    <registryContact>
        <ns2:contact>
            <ns2:personName>unknown</ns2:personName>
        </ns2:contact>
    </registryContact>
    <operator>
        <operatorNodeID>uddi:juddi.apache.org:node1</operatorNodeID>
        <operatorStatus>normal</operatorStatus>
        <ns2:contact/>
        <soapReplicationURL>http://localhost:8080/juddiv3/services/replication</soapReplicationURL>
    </operator>
    <communicationGraph>
        <node>uddi:juddi.apache.org:node1</node>
        <controlledMessage>*</controlledMessage>
    </communicationGraph>
    <maximumTimeToSyncRegistry>1</maximumTimeToSyncRegistry>
    <maximumTimeToGetChanges>1</maximumTimeToGetChanges>
</replicationConfiguration>

Here’s an example non-directed replicaton graph. In this example, all changes perform on all nodes get set to all the other nodes.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<replicationConfiguration xmlns="urn:uddi-org:repl_v3" xmlns:ns2="urn:uddi-org:api_v3" xmlns:ns3="http://www.w3.org/2000/09/xmldsig#">
    <serialNumber>0</serialNumber>
    <timeOfConfigurationUpdate></timeOfConfigurationUpdate>
    <registryContact>
        <ns2:contact>
            <ns2:personName>unknown</ns2:personName>
        </ns2:contact>
    </registryContact>
    <operator>
        <operatorNodeID>uddi:juddi.apache.org:node1</operatorNodeID>
        <operatorStatus>normal</operatorStatus>
        <ns2:contact useType="admin">
            <ns2:personName xml:lang="en">bob</ns2:personName>
        </ns2:contact>
        <soapReplicationURL>https://localhost:8443/juddiv3replication/services/replication</soapReplicationURL>
    </operator>
    <operator>
        <operatorNodeID>uddi:another.juddi.apache.org:node2</operatorNodeID>
        <operatorStatus>normal</operatorStatus>
        <ns2:contact useType="admin">
            <ns2:personName xml:lang="en">mary</ns2:personName>
        </ns2:contact>
        <soapReplicationURL>https://localhost:9443/juddiv3replication/services/replication</soapReplicationURL>
    </operator>
    <communicationGraph>
        <node>uddi:juddi.apache.org:node1</node>
        <node>uddi:another.juddi.apache.org:node2</node>
        <controlledMessage>*</controlledMessage>
    </communicationGraph>
    <maximumTimeToSyncRegistry>1</maximumTimeToSyncRegistry>
    <maximumTimeToGetChanges>1</maximumTimeToGetChanges>
</replicationConfiguration>

In this example, we have a directed graph where Node 1 sends to Node2, Node 2 to Node 3, and Node 3 to Node 1. Note the addition of the replicationConfiguration/communicationGraph/edge() that defines this interaction pattern. Again all nodes defined in edges must also be defined both in the communicationGraph and as operator() XML elements.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<replicationConfiguration xmlns="urn:uddi-org:repl_v3" xmlns:ns2="urn:uddi-org:api_v3" xmlns:ns3="http://www.w3.org/2000/09/xmldsig#">
    <serialNumber>0</serialNumber>
    <timeOfConfigurationUpdate></timeOfConfigurationUpdate>
    <registryContact>
        <ns2:contact>
            <ns2:personName>unknown</ns2:personName>
        </ns2:contact>
    </registryContact>
    <operator>
        <operatorNodeID>uddi:juddi.apache.org:node1</operatorNodeID>
        <operatorStatus>normal</operatorStatus>
        <ns2:contact useType="admin">
            <ns2:personName xml:lang="en">bob</ns2:personName>
        </ns2:contact>
        <soapReplicationURL>https://localhost:8443/juddiv3replication/services/replication</soapReplicationURL>
    </operator>
    <operator>
        <operatorNodeID>uddi:another.juddi.apache.org:node2</operatorNodeID>
        <operatorStatus>normal</operatorStatus>
        <ns2:contact useType="admin">
            <ns2:personName xml:lang="en">mary</ns2:personName>
        </ns2:contact>
        <soapReplicationURL>https://localhost:9443/juddiv3replication/services/replication</soapReplicationURL>
    </operator>
    <operator>
        <operatorNodeID>uddi:yet.another.juddi.apache.org:node3</operatorNodeID>
        <operatorStatus>normal</operatorStatus>
        <ns2:contact useType="admin">
            <ns2:personName xml:lang="en">mary</ns2:personName>
        </ns2:contact>
        <soapReplicationURL>https://localhost:10443/juddiv3replication/services/replication</soapReplicationURL>
    </operator>
    <communicationGraph>
        <node>uddi:another.juddi.apache.org:node2</node>
        <node>uddi:juddi.apache.org:node1</node>
        <node>uddi:yet.another.juddi.apache.org:node3</node>
        <edge>
            <messageSender>uddi:juddi.apache.org:node1</messageSender>
            <messageReceiver>uddi:another.juddi.apache.org:node2</messageReceiver>
        </edge>
        <edge>
            <messageSender>uddi:another.juddi.apache.org:node2</messageSender>
            <messageReceiver>uddi:yet.another.juddi.apache.org:node3</messageReceiver>
        </edge>
        <edge>
            <messageSender>uddi:yet.another.juddi.apache.org:node3</messageSender>
            <messageReceiver>uddi:juddi.apache.org:node1</messageReceiver>
        </edge>
    </communicationGraph>
    <maximumTimeToSyncRegistry>1</maximumTimeToSyncRegistry>
    <maximumTimeToGetChanges>1</maximumTimeToGetChanges>
</replicationConfiguration>

One last point of interest, Edge’s can have a list of alternate message receivers and it is supported by jUDDI.