This project has retired. For details please refer to its Attic page.
<link rel="stylesheet" type="text/css" href="css/jbossorg.css"/><meta name="generator" content="DocBook XSL Stylesheets V1.76.1"/><link rel="home" href="index.html" title=""/><link rel="up" href="index.html" title=""/><link rel="prev" href="ch05.html" title=""/><link rel="next" href="ch07.html" title=""/><link rel="copyright" href="ln-d2e27.html" title=""/><meta xmlns:d="http://docbook.org/ns/docbook" xmlns:rf="java:org.jboss.highlight.XhtmlRendererFactory" http-equiv="Content-Type" content="text/html; charset=UTF-8"/></head><body><p xmlns:d="http://docbook.org/ns/docbook" id="title"><a href="http://www.jboss.org" class="site_href"><strong>JBoss.org</strong></a><a href="http://docs.jboss.org/" class="doc_href"><strong>Community Documentation</strong></a></p><ul xmlns:d="http://docbook.org/ns/docbook" class="docnav"><li class="previous"><a accesskey="p" href="ch05.html"><strong/></a></li><li class="next"><a accesskey="n" href="ch07.html"><strong/></a></li></ul><div class="chapter"><div class="titlepage"><div><div><h2 class="title"><a id="chapter-Replication"/></h2></div></div></div><div class="toc"><p><strong/></p><dl><dt><span class="section"><a href="ch06.html#_introduction">6.1. Introduction</a></span></dt><dt><span class="section"><a href="ch06.html#_uddiv3_replication_overview">6.2. UDDIv3 Replication Overview</a></span></dt><dd><dl><dt><span class="section"><a href="ch06.html#_uddiv3_replication_topology">6.2.1. UDDIv3 Replication Topology</a></span></dt><dt><span class="section"><a href="ch06.html#_conflict_handling">6.2.2. Conflict handling</a></span></dt></dl></dd><dt><span class="section"><a href="ch06.html#_configuring_your_juddi_node_for_replication">6.3. Configuring your jUDDI Node for replication</a></span></dt><dd><dl><dt><span class="section"><a href="ch06.html#_changing_the_node_id">6.3.1. Changing the Node ID</a></span></dt><dt><span class="section"><a href="ch06.html#_setting_up_client_cert_authentication">6.3.2. Setting up CLIENT-CERT authentication</a></span></dt><dt><span class="section"><a href="ch06.html#_setting_the_replication_configuration">6.3.3. Setting the Replication Configuration</a></span></dt><dt><span class="section"><a href="ch06.html#_performing_custody_transfer_between_nodes">6.3.4. Performing Custody Transfer between nodes</a></span></dt><dt><span class="section"><a href="ch06.html#_what_s_supported_and_what_s_not">6.3.5. What’s Supported and What’s Not</a></span></dt></dl></dd></dl></div> <div class="section"><div class="titlepage"><div><div><h2 class="title"><a id="_introduction"/></h2></div></div></div> <p>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).</p> </div> <div class="section"><div class="titlepage"><div><div><h2 class="title"><a id="_uddiv3_replication_overview"/></h2></div></div></div> <p>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.</p> <p>There’s one important note to remember. Each piece of data in UDDI is owned by a given node.</p> <div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="_uddiv3_replication_topology"/></h3></div></div></div> <p>The specification identifies two scenarios for replication topology.</p> <div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"> Non-directed Graph: All nodes can talk directly to each other and have direct communication with each other. </li><li class="listitem"> Directed Graph: Nodes can only talk to subset of the complete set of nodes. </li></ol></div> <p>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.</p> <p>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.</p> </div> <div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="_conflict_handling"/></h3></div></div></div> <p>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.</p> </div> </div> <div class="section"><div class="titlepage"><div><div><h2 class="title"><a id="_configuring_your_juddi_node_for_replication"/></h2></div></div></div> <p>Prerequisites:</p> <div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"> Each node must have a unique ID associated with it. </li><li class="listitem"> Each node must have the UDDI v3 Replication service (juddiv3replication.war) deployed and configured for CLIENT-CERT authentication using SSL/TLS. </li><li class="listitem"> Each node must have a configured JKS key store and trust store. </li></ol></div> <div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="_changing_the_node_id"/></h3></div></div></div> <p>Forgot to change the Node ID before starting jUDDI for the first time? No problem. Visit the jUDDI Administration console at <a class="ulink" href="http://localhost:8080/juddiv3/admin">http://localhost:8080/juddiv3/admin</a>, then go to the Admin page and select "Change Node Id" from the drop down menu.</p> </div> <div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="_setting_up_client_cert_authentication"/></h3></div></div></div> <p>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.</p> <div class="section"><div class="titlepage"><div><div><h4 class="title"><a id="_special_notes_on_key_stores_and_trust_stores"/></h4></div></div></div> <p>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</p> <p>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 <span class="emphasis"><em>juddiv3.xml</em></span>) 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.</p> <p>For Tomcat, all you need is a connector with "clientAuth=want". Here’s an example:</p> <pre class="screen"><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"/></pre> </div> <div class="section"><div class="titlepage"><div><div><h4 class="title"><a id="_mapping_certificates_to_roles"/></h4></div></div></div> <p>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 <span class="emphasis"><em>tomcat-users.xml</em></span> file.</p> <pre class="screen"><user username="CN=localhost, OU=jUDDI Test, O=Apache Software Foundation, L=Anytown, ST=MD, C=US" password="null" roles="replication"/></pre> <p>In this example, we’ve added our test certificate’s subject DN to the role of "replication".</p> <div xmlns:d="http://docbook.org/ns/docbook" xmlns:rf="java:org.jboss.highlight.XhtmlRendererFactory" class="tip" style="margin-left: 0.5in; margin-right: 0.5in;"><h2/> <p>If you run into issues getting things working, try adding the following to the startup parameters for tomcat: -Djavax.net.debug=all</p> </div> <div xmlns:d="http://docbook.org/ns/docbook" xmlns:rf="java:org.jboss.highlight.XhtmlRendererFactory" class="important" style="margin-left: 0.5in; margin-right: 0.5in;"><h2/> <p>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.</p> </div> <p>Since dealing with certificates can be confusing, consider the following configuration.</p> <div class="itemizedlist"><ul class="itemizedlist"><li class="listitem"> Node 1 sends updates to Node 2 </li><li class="listitem"> Node 2 sends updates to Node 1 </li></ul></div> <p>Then the certificates must be setup as follows (assuming that each node’s SSL cert is used for authentication to the other node(s))</p> <div class="itemizedlist"><ul class="itemizedlist"><li class="listitem"> Node 1’s public key must be trusted by Node 2 (in Node 2 app server’s trust store) </li><li class="listitem"> Node 2’s public key must be trusted by Node 1 (in Node 1 app server’s trust store) </li><li class="listitem"> Node 1 must have Node 2’s certificate’s Subject DN mapped to the <span class="emphasis"><em>replication</em></span> role </li><li class="listitem"> Node 2 must have Node 1’s certificate’s Subject DN mapped to the <span class="emphasis"><em>replication</em></span> role </li><li class="listitem"> Node 1’s public and private keys must be in a keystore on Node 1 (and the Java -D properties set) </li><li class="listitem"> Node 2’s public and private keys must be in a keystore on Node 2 (and the Java -D properties set) </li></ul></div> </div> </div> <div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="_setting_the_replication_configuration"/></h3></div></div></div> <p>To set the replication configuration, you’ll need to go to <a class="ulink" href="http://localhost:8080/juddiv3/admin">http://localhost:8080/juddiv3/admin</a> 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.</p> <p>Note: when saving the configuration, several of the fields (time stamp, serial number) will be overwritten by the server. This is normal.</p> <p>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.</p> <div class="section"><div class="titlepage"><div><div><h4 class="title"><a id="_replication_configuration"/></h4></div></div></div> <p>When using jUDDI’s Admin console to set the replication config, here’s a few things to keep in mind (using xpath notation).</p> <div class="itemizedlist"><ul class="itemizedlist"><li class="listitem"> replicationConfiguration/operator() - All nodes in the replication graph must be listed in the Operator section, including all directed graph nodes </li><li class="listitem"> 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. </li><li class="listitem"> replicationConfiguration/communicationGraph - Must be specified with all nodes listed as identified by the NodeID in replicationConfiguration/operator/operatorNodeID. </li><li class="listitem"> replicationConfiguration/communicationGraph/controlledMessage must be specified. jUDDI uses a <span class="emphasis"><em>*</em></span> to represent all messages. </li><li class="listitem"> replicationConfiguration/maximumTimeToSyncRegistry isn’t used and jUDDI will always set it to 1 </li><li class="listitem"> replicationConfiguration/maximumTimeToGetChanges - isn’t used and jUDDI will always set it to 1 </li><li class="listitem"> replicationConfiguration/serialNumber - jUDDI will always set this to the time stamp when the configuration was last changed (time since epoch) </li><li class="listitem"> 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. </li></ul></div> <p>Everytime the configuration changes, an audit log is required in jUDDI log file.</p> <p>Here’s an example default configuration</p> <pre class="screen"><?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></pre> <p>Here’s an example non-directed replicaton graph. In this example, all changes perform on all nodes get set to all the other nodes.</p> <pre class="screen"><?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></pre> <p>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.</p> <pre class="screen"><?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></pre> <p>One last point of interest, Edge’s can have a list of alternate message receivers and it is supported by jUDDI.</p> </div> </div> <div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="_performing_custody_transfer_between_nodes"/></h3></div></div></div> <p>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.</p> </div> <div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="_what_s_supported_and_what_s_not"/></h3></div></div></div> <p>Here’s a quick summary of what is and isn’t supported for jUDDI replication capabilities. Want more support? Open a ticket and contribute.</p> <p>Supported:</p> <div class="itemizedlist"><ul class="itemizedlist"><li class="listitem"> Directed graph replication with retransmit (primary and alternate message receivers) </li><li class="listitem"> Non-directed graphic replication (no edges defined) </li><li class="listitem"> All UDDI data is replicated (Business, Binding, Serivce, tModels and Publisher Assertions) </li><li class="listitem"> Custody transfer from Node to Node within the replication graph. </li></ul></div> <p>Functions not supported:</p> <div class="itemizedlist"><ul class="itemizedlist"><li class="listitem"> Conditional Data Updates </li><li class="listitem"> Configuration Settings: </li><li class="listitem"> maximumTimeToSyncRegistry </li><li class="listitem"> maximumTimeToGetChanges </li><li class="listitem"> OperatorStatus - Node Status (New, Normal, Resigned) </li><li class="listitem"> Controlled Messages (all messages are sent to all nodes) </li></ul></div> </div> </div> </div><ul xmlns:d="http://docbook.org/ns/docbook" class="docnav"><li class="previous"><a accesskey="p" href="ch05.html"><strong/></a></li><li class="up"><a accesskey="u" href="#"><strong/></a></li><li class="home"><a accesskey="h" href="index.html"><strong/></a></li><li class="next"><a accesskey="n" href="ch07.html"><strong/></a></li></ul></body></html>