JBoss.orgCommunity Documentation
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.
The specification identifies two scenarios for replication topology.
The Non-directed graph is easier to implement and to understand. During the "notify" phase of replication, the node where the change originates, simply tell’s everyone it knows about it.
In a directed graph, the node where the change originates only notifies the nodes designated nodes. This typically forms some kind of ring in which one node notifies the next and so on until the original change ends up at the origin.
The specification defines a mechanism that is similar to a two step commit (for those familiar with database terminology). Esscentially, when a given change (typically a new record) is created, it then notifies all other nodes to put a block on the new record’s keys and waits for all nodes to respond with an "OK" to commit message. This prevents the same record from being created in multiple locations. These types of messages are refered to in the specification as NewDataConditional. As of the time of this writting jUDDI doesn’t support it. When a record is created at the same at two different nodes within the same replication graph, jUDDI will simply reject the change and prevent the modifications or the transfer from happening. Records that fail to apply for one reason or another are stored in the database and can be accessed via the admin console via "Admin" and selected "getFailedReplicationChangeRecords" from the drop down menu.
Prerequisites:
Forgot to change the Node ID before starting jUDDI for the first time? No problem. Visit the jUDDI Administration console at http://localhost:8080/juddiv3/admin, then go to the Admin page and select "Change Node Id" from the drop down menu.
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.
jUDDI’s use of key stores and trust stores for replication purposes using the standard system properties - -Djavax.net.ssl.keyStore - -Djavax.net.ssl.keyPassword - -Djavax.net.ssl.trustStore - -Djavax.net.ssl.trustStorePassword
These are used for transport layer security (node to node). On a side node, jUDDI (server) can also use the trust store to verify signed entities (configured though juddiv3.xml) and finally, the application server itself needs access to the key store and trust store for providing a certificate for SSL/TLS communication with clients for validating users (or another jUDDI replication node) that provide a client certificate.
For Tomcat, all you need is a connector with "clientAuth=want". Here’s an example:
<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true" maxThreads="150" scheme="https" secure="true" clientAuth="want" sslProtocol="TLS" truststoreFile="truststore.jks" truststorePass="password" keystoreFile="conf/keystore.jks" keystorePass="password"/>
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".
If you run into issues getting things working, try adding the following to the startup parameters for tomcat: -Djavax.net.debug=all
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.
Then the certificates must be setup as follows (assuming that each node’s SSL cert is used for authentication to the other node(s))
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).
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.
Custody transfer (from a user’s perspective) happens exacty the same way as it would to transfer between two users on the same node. The only change is that the Replication API plays a signficant role in this process and is thus a requirement.
Here’s a quick summary of what is and isn’t supported for jUDDI replication capabilities. Want more support? Open a ticket and contribute.
Supported:
Functions not supported: