You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@juddi.apache.org by al...@apache.org on 2014/12/09 04:13:32 UTC

[11/28] juddi git commit: JUDDI-241 save/delete Node and clerk functioning

JUDDI-241 save/delete Node and clerk functioning


Project: http://git-wip-us.apache.org/repos/asf/juddi/repo
Commit: http://git-wip-us.apache.org/repos/asf/juddi/commit/7aa78f62
Tree: http://git-wip-us.apache.org/repos/asf/juddi/tree/7aa78f62
Diff: http://git-wip-us.apache.org/repos/asf/juddi/diff/7aa78f62

Branch: refs/heads/master
Commit: 7aa78f62cc66ff3484d105e293b361345a939b86
Parents: 455149a
Author: Alex <al...@apache.org>
Authored: Sat Nov 15 13:16:09 2014 -0500
Committer: Alex <al...@apache.org>
Committed: Sat Nov 15 13:16:09 2014 -0500

----------------------------------------------------------------------
 .../org/apache/juddi/api/impl/JUDDIApiImpl.java |   53 +-
 .../juddi/api/impl/UDDIReplicationImpl.java     | 1023 +++++++++---------
 .../api/impl/UDDISubscriptionListenerImpl.java  |    2 +-
 .../apache/juddi/mapping/MappingApiToModel.java |    2 +-
 .../apache/juddi/mapping/MappingModelToApi.java |   13 +-
 .../main/java/org/apache/juddi/model/Clerk.java |   18 +-
 .../main/java/org/apache/juddi/model/Node.java  |   12 +-
 .../juddi/validation/ValidatePublish.java       |   19 +-
 .../src/main/resources/messages.properties      |    5 +-
 .../juddi/api/impl/API_160_ReplicationTest.java |   77 +-
 .../uddi/repl_v3/ReplicationConfiguration.java  |    6 +
 11 files changed, 673 insertions(+), 557 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/juddi/blob/7aa78f62/juddi-core/src/main/java/org/apache/juddi/api/impl/JUDDIApiImpl.java
----------------------------------------------------------------------
diff --git a/juddi-core/src/main/java/org/apache/juddi/api/impl/JUDDIApiImpl.java b/juddi-core/src/main/java/org/apache/juddi/api/impl/JUDDIApiImpl.java
index a4ef416..1f7ca77 100644
--- a/juddi-core/src/main/java/org/apache/juddi/api/impl/JUDDIApiImpl.java
+++ b/juddi-core/src/main/java/org/apache/juddi/api/impl/JUDDIApiImpl.java
@@ -17,6 +17,7 @@
 package org.apache.juddi.api.impl;
 
 import java.io.StringWriter;
+import java.math.BigInteger;
 import java.rmi.RemoteException;
 import java.util.ArrayList;
 import java.util.Date;
@@ -558,7 +559,7 @@ public class JUDDIApiImpl extends AuthenticatedService implements JUDDIApiPortTy
 
                                 org.apache.juddi.api_v3.ClientSubscriptionInfo apiClientSubscriptionInfo = new org.apache.juddi.api_v3.ClientSubscriptionInfo();
 
-                                MappingModelToApi.mapClientSubscriptionInfo(modelClientSubscriptionInfo, apiClientSubscriptionInfo);
+                                MappingModelToApi.mapClientSubscriptionInfo(modelClientSubscriptionInfo, apiClientSubscriptionInfo,em);
 
                                 result.getClientSubscriptionInfo().add(apiClientSubscriptionInfo);
                         }
@@ -621,7 +622,7 @@ public class JUDDIApiImpl extends AuthenticatedService implements JUDDIApiPortTy
 
                                 org.apache.juddi.api_v3.ClientSubscriptionInfo apiClientSubscriptionInfo = new org.apache.juddi.api_v3.ClientSubscriptionInfo();
 
-                                MappingModelToApi.mapClientSubscriptionInfo(modelClientSubscriptionInfo, apiClientSubscriptionInfo);
+                                MappingModelToApi.mapClientSubscriptionInfo(modelClientSubscriptionInfo, apiClientSubscriptionInfo,em);
 
                                 result.getClientSubscriptionInfo().add(apiClientSubscriptionInfo);
                         }
@@ -655,6 +656,7 @@ public class JUDDIApiImpl extends AuthenticatedService implements JUDDIApiPortTy
          * @return ClerkDetail
          * @throws DispositionReportFaultMessage
          */
+        @Override
         public ClerkDetail saveClerk(SaveClerk body)
              throws DispositionReportFaultMessage {
                 long startTime = System.currentTimeMillis();
@@ -675,14 +677,16 @@ public class JUDDIApiImpl extends AuthenticatedService implements JUDDIApiPortTy
                                 org.apache.juddi.model.Clerk modelClerk = new org.apache.juddi.model.Clerk();
 
                                 MappingApiToModel.mapClerk(apiClerk, modelClerk);
-                                org.apache.juddi.model.Node node = em.find(org.apache.juddi.model.Node.class, apiClerk.getNode().getName());
-                                if (node==null)
+                                org.apache.juddi.model.Node node2 = em.find(org.apache.juddi.model.Node.class, apiClerk.getNode().getName());
+                                if (node2==null)
                                 {
                                         //it doesn't exist yet
-                                        node = new Node();
+                                        node2 = new Node();
+                                        MappingApiToModel.mapNode(apiClerk.getNode(), node2);
+                                        em.persist(node2);
                                 }
-                                MappingApiToModel.mapNode(apiClerk.getNode(), node);
-                                modelClerk.setNode(node);
+                                
+                                modelClerk.setNode(node2.getName());
                                 Object existingUddiEntity = em.find(modelClerk.getClass(), modelClerk.getClerkName());
                                 if (existingUddiEntity != null) {
                                         
@@ -690,7 +694,7 @@ public class JUDDIApiImpl extends AuthenticatedService implements JUDDIApiPortTy
                                 } else {
                                         em.persist(modelClerk);
                                 }
-
+                
                                 result.getClerk().add(apiClerk);
                         }
 
@@ -811,7 +815,7 @@ public class JUDDIApiImpl extends AuthenticatedService implements JUDDIApiPortTy
                                         throw new InvalidKeyPassedException(new ErrorMessage("errors.invalidkey.SubscripKeyNotFound", subscriptionKey));
                                 }
                                 org.apache.juddi.api_v3.ClientSubscriptionInfo apiClientSubscriptionInfo = new org.apache.juddi.api_v3.ClientSubscriptionInfo();
-                                MappingModelToApi.mapClientSubscriptionInfo(modelClientSubscriptionInfo, apiClientSubscriptionInfo);
+                                MappingModelToApi.mapClientSubscriptionInfo(modelClientSubscriptionInfo, apiClientSubscriptionInfo,em);
                                 clientSubscriptionInfoMap.put(apiClientSubscriptionInfo.getSubscriptionKey(), apiClientSubscriptionInfo);
                         }
 
@@ -947,7 +951,7 @@ public class JUDDIApiImpl extends AuthenticatedService implements JUDDIApiPortTy
                         List<org.apache.juddi.model.Clerk> resultList = qry.getResultList();
                         for (int i = 0; i < resultList.size(); i++) {
                                 Clerk api = new Clerk();
-                                MappingModelToApi.mapClerk(resultList.get(i), api);
+                                MappingModelToApi.mapClerk(resultList.get(i), api,em);
                                 ret.getClerk().add(api);
 
                         }
@@ -980,18 +984,25 @@ public class JUDDIApiImpl extends AuthenticatedService implements JUDDIApiPortTy
                 EntityTransaction tx = em.getTransaction();
                 try {
                         tx.begin();
-
+                        //TODO if the given node is in the replication config, prevent deletion
                         UddiEntityPublisher publisher = this.getEntityPublisher(em, req.getAuthInfo());
-                        new ValidatePublish(publisher).validateDeleteNode(em, req);
+                        new ValidatePublish(publisher).validateDeleteNode(em, req, getReplicationNodes(req.getAuthInfo()));
 
                         org.apache.juddi.model.Node existingUddiEntity = em.find(org.apache.juddi.model.Node.class, req.getNodeID());
-                        if (existingUddiEntity
-                             != null) {
-
-                                //TODO cascade delete all clerks tied to this node, confirm that it works
-                                em.remove(existingUddiEntity);
-                                found = true;
+                        if (existingUddiEntity != null) {
+
+                            
+                                //cascade delete all clerks tied to this node, confirm that it works
+                              
+                            Query createQuery = em.createQuery("delete from Clerk c where c.node = :nodename");
+                            createQuery.setParameter("nodename", req.getNodeID());
+                            createQuery.executeUpdate();
+                             
+                               em.remove(existingUddiEntity);
+                                found=true;
                         }
+                        else 
+                            throw new InvalidKeyPassedException(new ErrorMessage("errors.deleteNode.NotFound"));
 
                         tx.commit();
                         long procTime = System.currentTimeMillis() - startTime;
@@ -1012,7 +1023,7 @@ public class JUDDIApiImpl extends AuthenticatedService implements JUDDIApiPortTy
 
                 if (!found) {
 
-                        throw new InvalidKeyPassedException(new ErrorMessage("errors.deleteNode.NotFound"));
+                        throw new InvalidKeyPassedException(new ErrorMessage("errors.deleteNode.NotFound", req.getNodeID()));
                 }
         }
 
@@ -1306,7 +1317,7 @@ public class JUDDIApiImpl extends AuthenticatedService implements JUDDIApiPortTy
                         }
 
                         StringBuilder sql = new StringBuilder();
-                        sql.append("select c from ReplicationConfiguration c order by c.SerialNumber desc");
+                        sql.append("select c from ReplicationConfiguration c order by c.serialNumber desc");
                         sql.toString();
                         Query qry = em.createQuery(sql.toString());
                         qry.setMaxResults(1);
@@ -1329,6 +1340,8 @@ public class JUDDIApiImpl extends AuthenticatedService implements JUDDIApiPortTy
                         em.close();
                 }
 
+                r.setMaximumTimeToGetChanges(BigInteger.ONE);
+                r.setMaximumTimeToSyncRegistry(BigInteger.ONE);
                 return r;
         }
 

http://git-wip-us.apache.org/repos/asf/juddi/blob/7aa78f62/juddi-core/src/main/java/org/apache/juddi/api/impl/UDDIReplicationImpl.java
----------------------------------------------------------------------
diff --git a/juddi-core/src/main/java/org/apache/juddi/api/impl/UDDIReplicationImpl.java b/juddi-core/src/main/java/org/apache/juddi/api/impl/UDDIReplicationImpl.java
index e2fe3fd..15ed7a8 100644
--- a/juddi-core/src/main/java/org/apache/juddi/api/impl/UDDIReplicationImpl.java
+++ b/juddi-core/src/main/java/org/apache/juddi/api/impl/UDDIReplicationImpl.java
@@ -78,562 +78,559 @@ import org.uddi.v3_service.UDDIReplicationPortType;
  * @author <a href="mailto:alexoree@apache.org">Alex O'Ree<a/>
  */
 public class UDDIReplicationImpl extends AuthenticatedService implements UDDIReplicationPortType {
-
-        private UDDIServiceCounter serviceCounter;
-
-        private static PullTimerTask timer = null;
-        private long startBuffer = 20000l;//AppConfig.getConfiguration().getLong(Property.JUDDI_NOTIFICATION_START_BUFFER, 20000l); // 20s startup delay default 
-        private long interval = 300000l;// AppConfig.getConfiguration().getLong(Property.JUDDI_NOTIFICATION_INTERVAL, 300000l); //5 min default
-
-        private static UDDIPublicationImpl pub = null;
-
-        public UDDIReplicationImpl() {
-                super();
-                if (pub == null) {
-                        pub = new UDDIPublicationImpl();
-                }
-                serviceCounter = ServiceCounterLifecycleResource.getServiceCounter(UDDIReplicationImpl.class);
-                Init();
-                try {
-                        startBuffer = AppConfig.getConfiguration().getLong(Property.JUDDI_NOTIFICATION_START_BUFFER, 20000l); // 20s startup delay default 
-                        interval = AppConfig.getConfiguration().getLong(Property.JUDDI_NOTIFICATION_INTERVAL, 300000l); //5 min default
-                } catch (ConfigurationException ex) {
-                        logger.fatal(ex);
-                }
-
+    
+    private UDDIServiceCounter serviceCounter;
+    
+    private static PullTimerTask timer = null;
+    private long startBuffer = 20000l;//AppConfig.getConfiguration().getLong(Property.JUDDI_NOTIFICATION_START_BUFFER, 20000l); // 20s startup delay default 
+    private long interval = 300000l;// AppConfig.getConfiguration().getLong(Property.JUDDI_NOTIFICATION_INTERVAL, 300000l); //5 min default
+
+    private static UDDIPublicationImpl pub = null;
+    
+    public UDDIReplicationImpl() {
+        super();
+        if (pub == null) {
+            pub = new UDDIPublicationImpl();
         }
-
-        private synchronized void Init() {
-                if (queue == null) {
-                        queue = new ConcurrentLinkedDeque<NotifyChangeRecordsAvailable>();
-                }
-                timer = new PullTimerTask();
-
+        serviceCounter = ServiceCounterLifecycleResource.getServiceCounter(UDDIReplicationImpl.class);
+        Init();
+        try {
+            startBuffer = AppConfig.getConfiguration().getLong(Property.JUDDI_NOTIFICATION_START_BUFFER, 20000l); // 20s startup delay default 
+            interval = AppConfig.getConfiguration().getLong(Property.JUDDI_NOTIFICATION_INTERVAL, 300000l); //5 min default
+        } catch (ConfigurationException ex) {
+            logger.fatal(ex);
         }
-
-        private boolean Excluded(HighWaterMarkVectorType changesAlreadySeen, ChangeRecord r) {
-                if (changesAlreadySeen != null) {
-                        for (int i = 0; i < changesAlreadySeen.getHighWaterMark().size(); i++) {
-                                if (changesAlreadySeen.getHighWaterMark().get(i).getNodeID().equals(r.getChangeID().getNodeID())
-                                     && changesAlreadySeen.getHighWaterMark().get(i).getOriginatingUSN().equals(r.getChangeID().getOriginatingUSN())) {
-                                        return true;
-                                }
-                        }
-                }
-                return false;
+        
+    }
+    
+    private synchronized void Init() {
+        if (queue == null) {
+            queue = new ConcurrentLinkedDeque<NotifyChangeRecordsAvailable>();
         }
-
-        private class PullTimerTask extends TimerTask {
-
-                private Timer timer = null;
-
-                public PullTimerTask() {
-                        super();
-                        timer = new Timer(true);
-                        timer.scheduleAtFixedRate(this, startBuffer, interval);
+        timer = new PullTimerTask();
+        
+    }
+    
+    private boolean Excluded(HighWaterMarkVectorType changesAlreadySeen, ChangeRecord r) {
+        if (changesAlreadySeen != null) {
+            for (int i = 0; i < changesAlreadySeen.getHighWaterMark().size(); i++) {
+                if (changesAlreadySeen.getHighWaterMark().get(i).getNodeID().equals(r.getChangeID().getNodeID())
+                        && changesAlreadySeen.getHighWaterMark().get(i).getOriginatingUSN().equals(r.getChangeID().getOriginatingUSN())) {
+                    return true;
                 }
-
-                @Override
-                public void run() {
-
-                        //ok someone told me there's a change available
-                        while (!queue.isEmpty()) {
-                                NotifyChangeRecordsAvailable poll = queue.poll();
-                                if (poll != null) {
-                                        UDDIReplicationPortType replicationClient = getReplicationClient(poll.getNotifyingNode());
-                                        try {
-                                                //ok now get all the changes
-                                                List<ChangeRecord> records
-                                                     = replicationClient.getChangeRecords(node,
-                                                          null, null, poll.getChangesAvailable());
-                                                //ok now we need to persist the change records
-                                                for (int i = 0; i < records.size(); i++) {
-                                                        PersistChangeRecord(records.get(i));
-                                                }
-                                        } catch (Exception ex) {
-                                                logger.equals(ex);
-                                        }
-                                }
+            }
+        }
+        return false;
+    }
+    
+    private class PullTimerTask extends TimerTask {
+        
+        private Timer timer = null;
+        
+        public PullTimerTask() {
+            super();
+            timer = new Timer(true);
+            timer.scheduleAtFixedRate(this, startBuffer, interval);
+        }
+        
+        @Override
+        public void run() {
+
+            //ok someone told me there's a change available
+            while (!queue.isEmpty()) {
+                NotifyChangeRecordsAvailable poll = queue.poll();
+                if (poll != null) {
+                    UDDIReplicationPortType replicationClient = getReplicationClient(poll.getNotifyingNode());
+                    try {
+                        //ok now get all the changes
+                        List<ChangeRecord> records
+                                = replicationClient.getChangeRecords(node,
+                                        null, null, poll.getChangesAvailable());
+                        //ok now we need to persist the change records
+                        for (int i = 0; i < records.size(); i++) {
+                            PersistChangeRecord(records.get(i));
                         }
+                    } catch (Exception ex) {
+                        logger.equals(ex);
+                    }
                 }
+            }
+        }
+        
+        @Override
+        public boolean cancel() {
+            timer.cancel();
+            return super.cancel();
+        }
 
-                @Override
-                public boolean cancel() {
-                        timer.cancel();
-                        return super.cancel();
-                }
-
-                /**
-                 * someone told me there's a change available, we retrieved it
-                 * and are processing the changes locally
-                 *
-                 * @param rec
-                 */
-                private void PersistChangeRecord(ChangeRecord rec) {
-                        if (rec == null) {
-                                return;
-                        }
-                        EntityManager em = PersistenceManager.getEntityManager();
-                        EntityTransaction tx = em.getTransaction();
+        /**
+         * someone told me there's a change available, we retrieved it and are
+         * processing the changes locally
+         *
+         * @param rec
+         */
+        private void PersistChangeRecord(ChangeRecord rec) {
+            if (rec == null) {
+                return;
+            }
+            EntityManager em = PersistenceManager.getEntityManager();
+            EntityTransaction tx = em.getTransaction();
+            /**
+             * In nodes that support pre-bundled replication responses, the
+             * recipient of the get_changeRecords message MAY return more change
+             * records than requested by the caller. In this scenario, the
+             * caller MUST also be prepared to deal with such redundant changes
+             * where a USN is less than the USN specified in the
+             * changesAlreadySeen highWaterMarkVector.
+             */
+            try {
+                tx.begin();
+                //the change record rec must also be persisted!!
+                em.persist(MappingApiToModel.mapChangeRecord(rec));
+                //<editor-fold defaultstate="collapsed" desc="delete a record">
+
+                if (rec.getChangeRecordDelete() != null) {
+                    if (rec.getChangeRecordDelete() != null && rec.getChangeRecordDelete().getBindingKey() != null && !"".equalsIgnoreCase(rec.getChangeRecordDelete().getBindingKey())) {
+                        //delete a binding template
+                        pub.deleteBinding(rec.getChangeRecordDelete().getBindingKey(), em);
+                    }
+                    if (rec.getChangeRecordDelete() != null && rec.getChangeRecordDelete().getBusinessKey() != null && !"".equalsIgnoreCase(rec.getChangeRecordDelete().getBusinessKey())) {
+                        //delete a business 
+                        pub.deleteBusiness(rec.getChangeRecordDelete().getBusinessKey(), em);
+                    }
+                    if (rec.getChangeRecordDelete() != null && rec.getChangeRecordDelete().getServiceKey() != null && !"".equalsIgnoreCase(rec.getChangeRecordDelete().getServiceKey())) {
+                        //delete a service 
+                        pub.deleteService(rec.getChangeRecordDelete().getServiceKey(), em);
+                    }
+                    if (rec.getChangeRecordDelete() != null && rec.getChangeRecordDelete().getTModelKey() != null && !"".equalsIgnoreCase(rec.getChangeRecordDelete().getTModelKey())) {
+                        //delete a tmodel 
                         /**
-                         * In nodes that support pre-bundled replication
-                         * responses, the recipient of the get_changeRecords
-                         * message MAY return more change records than requested
-                         * by the caller. In this scenario, the caller MUST also
-                         * be prepared to deal with such redundant changes where
-                         * a USN is less than the USN specified in the
-                         * changesAlreadySeen highWaterMarkVector.
+                         * The changeRecordDelete for a tModel does not
+                         * correspond to any API described in this specification
+                         * and should only appear in the replication stream as
+                         * the result of an administrative function to
+                         * permanently remove a tModel.
                          */
-                        try {
-                                tx.begin();
-                                //the change record rec must also be persisted!!
-                                em.persist(MappingApiToModel.mapChangeRecord(rec));
-                                //<editor-fold defaultstate="collapsed" desc="delete a record">
-
-                                if (rec.getChangeRecordDelete() != null) {
-                                        if (rec.getChangeRecordDelete() != null && rec.getChangeRecordDelete().getBindingKey() != null && !"".equalsIgnoreCase(rec.getChangeRecordDelete().getBindingKey())) {
-                                                //delete a binding template
-                                                pub.deleteBinding(rec.getChangeRecordDelete().getBindingKey(), em);
-                                        }
-                                        if (rec.getChangeRecordDelete() != null && rec.getChangeRecordDelete().getBusinessKey() != null && !"".equalsIgnoreCase(rec.getChangeRecordDelete().getBusinessKey())) {
-                                                //delete a business 
-                                                pub.deleteBusiness(rec.getChangeRecordDelete().getBusinessKey(), em);
-                                        }
-                                        if (rec.getChangeRecordDelete() != null && rec.getChangeRecordDelete().getServiceKey() != null && !"".equalsIgnoreCase(rec.getChangeRecordDelete().getServiceKey())) {
-                                                //delete a service 
-                                                pub.deleteService(rec.getChangeRecordDelete().getServiceKey(), em);
-                                        }
-                                        if (rec.getChangeRecordDelete() != null && rec.getChangeRecordDelete().getTModelKey() != null && !"".equalsIgnoreCase(rec.getChangeRecordDelete().getTModelKey())) {
-                                                //delete a tmodel 
-                                                /**
-                                                 * The changeRecordDelete for a
-                                                 * tModel does not correspond to
-                                                 * any API described in this
-                                                 * specification and should only
-                                                 * appear in the replication
-                                                 * stream as the result of an
-                                                 * administrative function to
-                                                 * permanently remove a tModel.
-                                                 */
-                                                pub.deleteTModel(rec.getChangeRecordDelete().getTModelKey(), em);
-                                        }
-                                }
-                                if (rec.getChangeRecordDeleteAssertion() != null && rec.getChangeRecordDeleteAssertion().getPublisherAssertion() != null) {
-                                        //delete a pa template                            
-                                        pub.deletePublisherAssertion(rec.getChangeRecordDeleteAssertion().getPublisherAssertion(), em);
-                                }
+                        pub.deleteTModel(rec.getChangeRecordDelete().getTModelKey(), em);
+                    }
+                }
+                if (rec.getChangeRecordDeleteAssertion() != null && rec.getChangeRecordDeleteAssertion().getPublisherAssertion() != null) {
+                    //delete a pa template                            
+                    pub.deletePublisherAssertion(rec.getChangeRecordDeleteAssertion().getPublisherAssertion(), em);
+                }
 
 //</editor-fold>
-                                //<editor-fold defaultstate="collapsed" desc="New Data">
-                                if (rec.getChangeRecordNewData() != null) {
-
-                                        if (rec.getChangeRecordNewData().getOperationalInfo().getNodeID() == null) {
-                                                throw new Exception("Inbound replication data is missiong node id!");
-                                        }
-
-                                        //The operationalInfo element MUST contain the operational information associated with the indicated new data.
-                                        if (rec.getChangeRecordNewData().getOperationalInfo() == null) {
-                                                logger.warn("Inbound replication data does not have the required OperationalInfo element and is NOT spec compliant. Data will be ignored");
-                                        } else {
-                                                if (rec.getChangeRecordNewData().getBindingTemplate() != null) {
+                //<editor-fold defaultstate="collapsed" desc="New Data">
+                if (rec.getChangeRecordNewData() != null) {
+                    
+                    if (rec.getChangeRecordNewData().getOperationalInfo().getNodeID() == null) {
+                        throw new Exception("Inbound replication data is missiong node id!");
+                    }
+
+                    //The operationalInfo element MUST contain the operational information associated with the indicated new data.
+                    if (rec.getChangeRecordNewData().getOperationalInfo() == null) {
+                        logger.warn("Inbound replication data does not have the required OperationalInfo element and is NOT spec compliant. Data will be ignored");
+                    } else {
+                        if (rec.getChangeRecordNewData().getBindingTemplate() != null) {
                                                         //fetch the binding template if it exists already
-                                                        //if it exists, 
-                                                        //      confirm the owning node, it shouldn't be the local node id, if it is, throw
-                                                        //      the owning node should be the same as it was before
-
-                                                        BusinessService model = em.find(org.apache.juddi.model.BusinessService.class, rec.getChangeRecordNewData().getBindingTemplate().getServiceKey());
-                                                        if (model == null) {
-                                                                logger.error("Replication error, attempting to insert a binding where the service doesn't exist yet");
-                                                        } else {
-                                                                ValidateNodeIdMatches(model.getNodeId(), rec.getChangeRecordNewData().getOperationalInfo());
-
-                                                                org.apache.juddi.model.BindingTemplate modelT = new org.apache.juddi.model.BindingTemplate();
-                                                                MappingApiToModel.mapBindingTemplate(rec.getChangeRecordNewData().getBindingTemplate(), modelT, model);
-                                                                MappingApiToModel.mapOperationalInfo(model, rec.getChangeRecordNewData().getOperationalInfo());
-                                                                em.persist(model);
-                                                        }
-
-                                                } else if (rec.getChangeRecordNewData().getBusinessEntity() != null) {
-
-                                                        BusinessEntity model = em.find(org.apache.juddi.model.BusinessEntity.class, rec.getChangeRecordNewData().getBusinessEntity().getBusinessKey());
-                                                        if (model == null) {
-                                                                model = new BusinessEntity();
-                                                        } else {
-                                                                ValidateNodeIdMatches(model.getNodeId(), rec.getChangeRecordNewData().getOperationalInfo());
-                                                        }
-                                                        MappingApiToModel.mapBusinessEntity(rec.getChangeRecordNewData().getBusinessEntity(), model);
-                                                        MappingApiToModel.mapOperationalInfo(model, rec.getChangeRecordNewData().getOperationalInfo());
-
-                                                        em.persist(model);
-
-                                                }
-                                                if (rec.getChangeRecordNewData().getBusinessService() != null) {
-                                                        BusinessEntity find = em.find(org.apache.juddi.model.BusinessEntity.class, rec.getChangeRecordNewData().getBusinessService().getBusinessKey());
-                                                        if (find == null) {
-                                                                logger.error("Replication error, attempting to insert a service where the business doesn't exist yet");
-                                                        } else {
-                                                                org.apache.juddi.model.BusinessService model = new org.apache.juddi.model.BusinessService();
-                                                                MappingApiToModel.mapBusinessService(rec.getChangeRecordNewData().getBusinessService(), model, find);
-                                                                MappingApiToModel.mapOperationalInfo(model, rec.getChangeRecordNewData().getOperationalInfo());
-
-                                                                em.persist(model);
-                                                        }
-
-                                                } else if (rec.getChangeRecordNewData().getTModel() != null) {
-                                                        Tmodel model = new Tmodel();
-                                                        MappingApiToModel.mapTModel(rec.getChangeRecordNewData().getTModel(), model);
-
-                                                        MappingApiToModel.mapOperationalInfo(model, rec.getChangeRecordNewData().getOperationalInfo());
-
-                                                        em.persist(model);
-                                                }
-
-                                        }
-
-                                }
+                            //if it exists, 
+                            //      confirm the owning node, it shouldn't be the local node id, if it is, throw
+                            //      the owning node should be the same as it was before
+
+                            BusinessService model = em.find(org.apache.juddi.model.BusinessService.class, rec.getChangeRecordNewData().getBindingTemplate().getServiceKey());
+                            if (model == null) {
+                                logger.error("Replication error, attempting to insert a binding where the service doesn't exist yet");
+                            } else {
+                                ValidateNodeIdMatches(model.getNodeId(), rec.getChangeRecordNewData().getOperationalInfo());
+                                
+                                org.apache.juddi.model.BindingTemplate modelT = new org.apache.juddi.model.BindingTemplate();
+                                MappingApiToModel.mapBindingTemplate(rec.getChangeRecordNewData().getBindingTemplate(), modelT, model);
+                                MappingApiToModel.mapOperationalInfo(model, rec.getChangeRecordNewData().getOperationalInfo());
+                                em.persist(model);
+                            }
+                            
+                        } else if (rec.getChangeRecordNewData().getBusinessEntity() != null) {
+                            
+                            BusinessEntity model = em.find(org.apache.juddi.model.BusinessEntity.class, rec.getChangeRecordNewData().getBusinessEntity().getBusinessKey());
+                            if (model == null) {
+                                model = new BusinessEntity();
+                            } else {
+                                ValidateNodeIdMatches(model.getNodeId(), rec.getChangeRecordNewData().getOperationalInfo());
+                            }
+                            MappingApiToModel.mapBusinessEntity(rec.getChangeRecordNewData().getBusinessEntity(), model);
+                            MappingApiToModel.mapOperationalInfo(model, rec.getChangeRecordNewData().getOperationalInfo());
+                            
+                            em.persist(model);
+                            
+                        }
+                        if (rec.getChangeRecordNewData().getBusinessService() != null) {
+                            BusinessEntity find = em.find(org.apache.juddi.model.BusinessEntity.class, rec.getChangeRecordNewData().getBusinessService().getBusinessKey());
+                            if (find == null) {
+                                logger.error("Replication error, attempting to insert a service where the business doesn't exist yet");
+                            } else {
+                                org.apache.juddi.model.BusinessService model = new org.apache.juddi.model.BusinessService();
+                                MappingApiToModel.mapBusinessService(rec.getChangeRecordNewData().getBusinessService(), model, find);
+                                MappingApiToModel.mapOperationalInfo(model, rec.getChangeRecordNewData().getOperationalInfo());
+                                
+                                em.persist(model);
+                            }
+                            
+                        } else if (rec.getChangeRecordNewData().getTModel() != null) {
+                            Tmodel model = new Tmodel();
+                            MappingApiToModel.mapTModel(rec.getChangeRecordNewData().getTModel(), model);
+                            
+                            MappingApiToModel.mapOperationalInfo(model, rec.getChangeRecordNewData().getOperationalInfo());
+                            
+                            em.persist(model);
+                        }
+                        
+                    }
+                    
+                }
 //</editor-fold>
 
                                 // changeRecordNull no action needed
-                                // changeRecordHide tmodel only
-                                //<editor-fold defaultstate="collapsed" desc="hide tmodel">
-                                if (rec.getChangeRecordHide() != null) {
-                                        /*
-                                         A changeRecordHide element corresponds to the behavior of hiding a tModel described in the delete_tModel in the Publish API section of this Specification.  A tModel listed in a changeRecordHide should be marked as hidden, so that it is not returned in response to a find_tModel API call.
+                // changeRecordHide tmodel only
+                //<editor-fold defaultstate="collapsed" desc="hide tmodel">
+                if (rec.getChangeRecordHide() != null) {
+                    /*
+                     A changeRecordHide element corresponds to the behavior of hiding a tModel described in the delete_tModel in the Publish API section of this Specification.  A tModel listed in a changeRecordHide should be marked as hidden, so that it is not returned in response to a find_tModel API call.
                                         
-                                         The changeRecordHide MUST contain a modified timestamp to allow multi-node registries to calculate consistent modifiedIncludingChildren timestamps as described in Section 3.8 operationalInfo Structure.
-                                         */
-                                        String key = rec.getChangeRecordHide().getTModelKey();
-                                        org.apache.juddi.model.Tmodel existing = em.find(org.apache.juddi.model.Tmodel.class, key);
-                                        if (existing == null) {
-                                                logger.error("Unexpected delete/hide tmodel message received for non existing key " + key);
-                                        } else {
-                                                existing.setDeleted(true);
-                                                existing.setModified(rec.getChangeRecordHide().getModified().toGregorianCalendar().getTime());
-                                                existing.setModifiedIncludingChildren(rec.getChangeRecordHide().getModified().toGregorianCalendar().getTime());
-                                                em.persist(existing);
-                                        }
-                                }
+                     The changeRecordHide MUST contain a modified timestamp to allow multi-node registries to calculate consistent modifiedIncludingChildren timestamps as described in Section 3.8 operationalInfo Structure.
+                     */
+                    String key = rec.getChangeRecordHide().getTModelKey();
+                    org.apache.juddi.model.Tmodel existing = em.find(org.apache.juddi.model.Tmodel.class, key);
+                    if (existing == null) {
+                        logger.error("Unexpected delete/hide tmodel message received for non existing key " + key);
+                    } else {
+                        existing.setDeleted(true);
+                        existing.setModified(rec.getChangeRecordHide().getModified().toGregorianCalendar().getTime());
+                        existing.setModifiedIncludingChildren(rec.getChangeRecordHide().getModified().toGregorianCalendar().getTime());
+                        em.persist(existing);
+                    }
+                }
 //</editor-fold>
 
-                                //<editor-fold defaultstate="collapsed" desc="changeRecordPublisherAssertion">
-                                if (rec.getChangeRecordPublisherAssertion() != null) {
+                //<editor-fold defaultstate="collapsed" desc="changeRecordPublisherAssertion">
+                if (rec.getChangeRecordPublisherAssertion() != null) {
 //TODO implement
-                                }
+                }
 //</editor-fold>
 
-                                tx.commit();
-
-                        } catch (Exception drfm) {
-                                logger.warn(drfm);
-                        } finally {
-                                if (tx.isActive()) {
-                                        tx.rollback();
-                                }
-                                em.close();
-                        }
+                tx.commit();
+                
+            } catch (Exception drfm) {
+                logger.warn(drfm);
+            } finally {
+                if (tx.isActive()) {
+                    tx.rollback();
                 }
-
+                em.close();
+            }
         }
-
-        private static void ValidateNodeIdMatches(String nodeId, OperationalInfo operationalInfo) throws Exception {
-                if (nodeId == null || operationalInfo == null) {
-                        throw new Exception("either the local node ID is null or the inbound replication data's node id is null");
-                }
-                if (!nodeId.equals(operationalInfo.getNodeID())) {
-                        throw new Exception("node id mismatch!");
-                }
+        
+    }
+    
+    private static void ValidateNodeIdMatches(String nodeId, OperationalInfo operationalInfo) throws Exception {
+        if (nodeId == null || operationalInfo == null) {
+            throw new Exception("either the local node ID is null or the inbound replication data's node id is null");
         }
-
-        private synchronized UDDIReplicationPortType getReplicationClient(String node) {
-                if (cache.containsKey(node)) {
-                        return cache.get(node);
-                }
-                UDDIService svc = new UDDIService();
-                UDDIReplicationPortType replicationClient = svc.getUDDIReplicationPort();
-                EntityManager em = PersistenceManager.getEntityManager();
-                EntityTransaction tx = em.getTransaction();
-                try {
-                        Node find = em.find(org.apache.juddi.model.Node.class, node);
-                        ((BindingProvider) replicationClient).getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, find.getReplicationUrl());
-                        cache.put(node, replicationClient);
-                        return replicationClient;
-                } catch (Exception ex) {
-                        logger.fatal("Node not found!" + node, ex);
-                } finally {
-                        if (tx.isActive()) {
-                                tx.rollback();
-                        }
-                        em.close();
-                }
-                em.close();
-                return null;
-
+        if (!nodeId.equals(operationalInfo.getNodeID())) {
+            throw new Exception("node id mismatch!");
+        }
+    }
+    
+    private synchronized UDDIReplicationPortType getReplicationClient(String node) {
+        if (cache.containsKey(node)) {
+            return cache.get(node);
         }
-        private Map<String, UDDIReplicationPortType> cache = new HashMap<String, UDDIReplicationPortType>();
+        UDDIService svc = new UDDIService();
+        UDDIReplicationPortType replicationClient = svc.getUDDIReplicationPort();
+        EntityManager em = PersistenceManager.getEntityManager();
+        EntityTransaction tx = em.getTransaction();
+        try {
+            Node find = em.find(org.apache.juddi.model.Node.class, node);
+            ((BindingProvider) replicationClient).getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, find.getReplicationUrl());
+            cache.put(node, replicationClient);
+            return replicationClient;
+        } catch (Exception ex) {
+            logger.fatal("Node not found!" + node, ex);
+        } finally {
+            if (tx.isActive()) {
+                tx.rollback();
+            }
+            em.close();
+        }
+        em.close();
+        return null;
+        
+    }
+    private Map<String, UDDIReplicationPortType> cache = new HashMap<String, UDDIReplicationPortType>();
+
+    /**
+     * @since 3.3
+     * @param body
+     * @return
+     * @throws DispositionReportFaultMessage
+     */
+    public String doPing(DoPing body) throws DispositionReportFaultMessage {
+        long startTime = System.currentTimeMillis();
+        long procTime = System.currentTimeMillis() - startTime;
+        serviceCounter.update(ReplicationQuery.DO_PING, QueryStatus.SUCCESS, procTime);
+        
+        return node;
+        
+    }
+    
+    @Override
+    public List<ChangeRecord> getChangeRecords(String requestingNode,
+            HighWaterMarkVectorType changesAlreadySeen,
+            BigInteger responseLimitCount,
+            HighWaterMarkVectorType responseLimitVector)
+            throws DispositionReportFaultMessage {
+        long startTime = System.currentTimeMillis();
+        
+        new ValidateReplication(null).validateGetChangeRecords(requestingNode, changesAlreadySeen, responseLimitCount, responseLimitVector, FetchEdges(), ctx);
+
+        //TODO should we validate that "requestingNode" is in the replication config?
+        List<ChangeRecord> ret = new ArrayList<ChangeRecord>();
+        EntityManager em = PersistenceManager.getEntityManager();
+        EntityTransaction tx = em.getTransaction();
 
         /**
-         * @since 3.3
-         * @param body
-         * @return
-         * @throws DispositionReportFaultMessage
+         * More specifically, the recipient determines the particular change
+         * records that are returned by comparing the originating USNs in the
+         * caller’s high water mark vector with the originating USNs of each of
+         * the changes the recipient has seen from others or generated by
+         * itself. The recipient SHOULD only return change records that have
+         * originating USNs that are greater than those listed in the
+         * changesAlreadySeen highWaterMarkVector and less than the limit
+         * required by either the responseLimitCount or the responseLimitVector.
+         *
+         *
+         * Part of the message is a high water mark vector that contains for
+         * each node of the registry the originating USN of the most recent
+         * change record that has been successfully processed by the invocating
+         * node
          */
-        public String doPing(DoPing body) throws DispositionReportFaultMessage {
-                long startTime = System.currentTimeMillis();
-                long procTime = System.currentTimeMillis() - startTime;
-                serviceCounter.update(ReplicationQuery.DO_PING, QueryStatus.SUCCESS, procTime);
-
-                return node;
-
+        int maxrecords = 100;
+        if (responseLimitCount != null) {
+            maxrecords = responseLimitCount.intValue();
         }
-
-        @Override
-        public List<ChangeRecord> getChangeRecords(String requestingNode,
-             HighWaterMarkVectorType changesAlreadySeen,
-             BigInteger responseLimitCount,
-             HighWaterMarkVectorType responseLimitVector)
-             throws DispositionReportFaultMessage {
-                long startTime = System.currentTimeMillis();
-
-                new ValidateReplication(null).validateGetChangeRecords(requestingNode, changesAlreadySeen, responseLimitCount, responseLimitVector, FetchEdges(), ctx);
-
-                //TODO should we validate that "requestingNode" is in the replication config?
-                List<ChangeRecord> ret = new ArrayList<ChangeRecord>();
-                EntityManager em = PersistenceManager.getEntityManager();
-                EntityTransaction tx = em.getTransaction();
-
-                /**
-                 * More specifically, the recipient determines the particular
-                 * change records that are returned by comparing the originating
-                 * USNs in the caller’s high water mark vector with the
-                 * originating USNs of each of the changes the recipient has
-                 * seen from others or generated by itself. The recipient SHOULD
-                 * only return change records that have originating USNs that
-                 * are greater than those listed in the changesAlreadySeen
-                 * highWaterMarkVector and less than the limit required by
-                 * either the responseLimitCount or the responseLimitVector.
-                 *
-                 *
-                 * Part of the message is a high water mark vector that contains
-                 * for each node of the registry the originating USN of the most
-                 * recent change record that has been successfully processed by
-                 * the invocating node
-                 */
-                int maxrecords = 100;
-                if (responseLimitCount != null) {
-                        maxrecords = responseLimitCount.intValue();
-                }
-                try {
-                        tx.begin();
-                        Long firstrecord = 1L;
-                        Long lastrecord = null;
-
-                        if (changesAlreadySeen != null) {
+        try {
+            tx.begin();
+            Long firstrecord = 1L;
+            Long lastrecord = null;
+            
+            if (changesAlreadySeen != null) {
                                 //this is basically a lower limit (i.e. the newest record that was processed by the requestor
-                                //therefore we want the oldest record stored locally to return to the requestor for processing
-                                for (int i = 0; i < changesAlreadySeen.getHighWaterMark().size(); i++) {
-                                        if (responseLimitVector.getHighWaterMark().get(i).getNodeID().equals(node)) {
-                                                firstrecord = changesAlreadySeen.getHighWaterMark().get(i).getOriginatingUSN() + 1;
-                                        }
-                                }
-                        }
-                        if (responseLimitVector != null) {
+                //therefore we want the oldest record stored locally to return to the requestor for processing
+                for (int i = 0; i < changesAlreadySeen.getHighWaterMark().size(); i++) {
+                    if (responseLimitVector.getHighWaterMark().get(i).getNodeID().equals(node)) {
+                        firstrecord = changesAlreadySeen.getHighWaterMark().get(i).getOriginatingUSN() + 1;
+                    }
+                }
+            }
+            if (responseLimitVector != null) {
                                 //using responseLimitVector, indicating for each node in the graph the first change originating there that he does not wish to be returned.
-                                //upper limit basically
-                                for (int i = 0; i < responseLimitVector.getHighWaterMark().size(); i++) {
-                                        if (responseLimitVector.getHighWaterMark().get(i).getNodeID().equals(node)) {
-                                                lastrecord = responseLimitVector.getHighWaterMark().get(i).getOriginatingUSN();
-                                        }
-                                }
-                        }
-
-                        Query createQuery = null;
-                        if (lastrecord != null) {
-                                createQuery = em.createQuery("select e from ChangeRecord e where (e.id > :inbound and e.nodeID = :node and e.id < :lastrecord) OR (e.originatingUSN > :inbound and e.nodeID != :node and e.originatingUSN < :lastrecord) order by e.id ASC");
-                                createQuery.setParameter("lastrecord", lastrecord);
-                        } else {
-                                createQuery = em.createQuery("select e from ChangeRecord e where (e.id > :inbound and e.nodeID = :node) OR (e.originatingUSN > :inbound and e.nodeID != :node) order by e.id ASC");
-                        }
-                        createQuery.setMaxResults(maxrecords);
-                        createQuery.setParameter("inbound", firstrecord);
-                        createQuery.setParameter("node", node);
-
-                        List<org.apache.juddi.model.ChangeRecord> records = (List<org.apache.juddi.model.ChangeRecord>) (org.apache.juddi.model.ChangeRecord) createQuery.getResultList();
-                        for (int i = 0; i < records.size(); i++) {
-                                ChangeRecord r = MappingModelToApi.mapChangeRecord(records.get(i));
-                                if (!Excluded(changesAlreadySeen, r)) {
-                                        ret.add(r);
-                                }
-
-                        }
-
-                        tx.rollback();
-                        long procTime = System.currentTimeMillis() - startTime;
-                        serviceCounter.update(ReplicationQuery.GET_CHANGERECORDS,
-                             QueryStatus.SUCCESS, procTime);
-
-                } catch (Exception ex) {
-                        logger.fatal("Error, this node is: " + node, ex);
-                        throw new FatalErrorException(new ErrorMessage("E_fatalError", ex.getMessage()));
-
-                } finally {
-                        if (tx.isActive()) {
-                                tx.rollback();
-                        }
-                        em.close();
+                //upper limit basically
+                for (int i = 0; i < responseLimitVector.getHighWaterMark().size(); i++) {
+                    if (responseLimitVector.getHighWaterMark().get(i).getNodeID().equals(node)) {
+                        lastrecord = responseLimitVector.getHighWaterMark().get(i).getOriginatingUSN();
+                    }
+                }
+            }
+            
+            Query createQuery = null;
+            if (lastrecord != null) {
+                createQuery = em.createQuery("select e from ChangeRecord e where (e.id > :inbound and e.nodeID = :node and e.id < :lastrecord) OR (e.originatingUSN > :inbound and e.nodeID != :node and e.originatingUSN < :lastrecord) order by e.id ASC");
+                createQuery.setParameter("lastrecord", lastrecord);
+            } else {
+                createQuery = em.createQuery("select e from ChangeRecord e where (e.id > :inbound and e.nodeID = :node) OR (e.originatingUSN > :inbound and e.nodeID != :node) order by e.id ASC");
+            }
+            createQuery.setMaxResults(maxrecords);
+            createQuery.setParameter("inbound", firstrecord);
+            createQuery.setParameter("node", node);
+            
+            List<org.apache.juddi.model.ChangeRecord> records = (List<org.apache.juddi.model.ChangeRecord>) (org.apache.juddi.model.ChangeRecord) createQuery.getResultList();
+            for (int i = 0; i < records.size(); i++) {
+                ChangeRecord r = MappingModelToApi.mapChangeRecord(records.get(i));
+                if (!Excluded(changesAlreadySeen, r)) {
+                    ret.add(r);
                 }
-                return ret;
+                
+            }
+            
+            tx.rollback();
+            long procTime = System.currentTimeMillis() - startTime;
+            serviceCounter.update(ReplicationQuery.GET_CHANGERECORDS,
+                    QueryStatus.SUCCESS, procTime);
+            
+        } catch (Exception ex) {
+            logger.fatal("Error, this node is: " + node, ex);
+            throw new FatalErrorException(new ErrorMessage("E_fatalError", ex.getMessage()));
+            
+        } finally {
+            if (tx.isActive()) {
+                tx.rollback();
+            }
+            em.close();
         }
-
-        /**
-         * This UDDI API message provides a means to obtain a list of
-         * highWaterMark element containing the highest known USN for all nodes
-         * in the replication graph. If there is no graph, we just return the
-         * local bits
-         *
-         * @return
-         * @throws DispositionReportFaultMessage
-         */
-        @Override
-        public List<ChangeRecordIDType> getHighWaterMarks()
-             throws DispositionReportFaultMessage {
-                long startTime = System.currentTimeMillis();
-
-                List<ChangeRecordIDType> ret = new ArrayList<ChangeRecordIDType>();
-
-                //fetch from database the highest known watermark
-                ReplicationConfiguration FetchEdges = FetchEdges();
-
-                EntityManager em = PersistenceManager.getEntityManager();
-                EntityTransaction tx = em.getTransaction();
-                try {
-                        tx.begin();
-                        if (FetchEdges != null) {
-                                Iterator<String> it = FetchEdges.getCommunicationGraph().getNode().iterator();
-                                while (it.hasNext()) {
-                                        String nextNode = it.next();
-                                        if (!nextNode.equals(node)) {
-
-                                                Long id = (Long) em.createQuery("select e.originatingUSN from ChangeRecord e where e.nodeID = :node order by e.originatingUSN desc").setParameter("node", nextNode).setMaxResults(1).getSingleResult();
-                                                if (id == null) {
-                                                        id = 0L;
-                                                        //per the spec
-                                                }
-                                                ChangeRecordIDType x = new ChangeRecordIDType(nextNode, id);
-                                                ret.add(x);
-                                        }
-                                }
+        return ret;
+    }
+
+    /**
+     * This UDDI API message provides a means to obtain a list of highWaterMark
+     * element containing the highest known USN for all nodes in the replication
+     * graph. If there is no graph, we just return the local bits
+     *
+     * @return
+     * @throws DispositionReportFaultMessage
+     */
+    @Override
+    public List<ChangeRecordIDType> getHighWaterMarks()
+            throws DispositionReportFaultMessage {
+        long startTime = System.currentTimeMillis();
+        
+        List<ChangeRecordIDType> ret = new ArrayList<ChangeRecordIDType>();
+
+        //fetch from database the highest known watermark
+        ReplicationConfiguration FetchEdges = FetchEdges();
+        
+        EntityManager em = PersistenceManager.getEntityManager();
+        EntityTransaction tx = em.getTransaction();
+        try {
+            tx.begin();
+            if (FetchEdges != null) {
+                Iterator<String> it = FetchEdges.getCommunicationGraph().getNode().iterator();
+                while (it.hasNext()) {
+                    String nextNode = it.next();
+                    if (!nextNode.equals(node)) {
+                        
+                        Long id = 0L;
+                        try {
+                            id = (Long) em.createQuery("select e.originatingUSN from ChangeRecord e where e.nodeID = :node order by e.originatingUSN desc").setParameter("node", nextNode).setMaxResults(1).getSingleResult();
+                        } catch (Exception ex) {
+                            logger.debug(ex);
                         }
-                        //dont forget this node
-                        Long id = (Long) em.createQuery("select (e.id) from ChangeRecord e where e.nodeID = :node  order by e.id desc").setParameter("node", node).setMaxResults(1).getSingleResult();
                         if (id == null) {
-                                id = 0L;
+                            id = 0L;
+                            //per the spec
                         }
-                        ChangeRecordIDType x = new ChangeRecordIDType();
-                        x.setNodeID(node);
-                        x.setOriginatingUSN(id);
+                        ChangeRecordIDType x = new ChangeRecordIDType(nextNode, id);
+                        
                         ret.add(x);
-
-                        tx.rollback();
-                        long procTime = System.currentTimeMillis() - startTime;
-                        serviceCounter.update(ReplicationQuery.GET_HIGHWATERMARKS, QueryStatus.SUCCESS, procTime);
-
-                } catch (Exception drfm) {
-                        throw new FatalErrorException(new ErrorMessage("E_fatalError", drfm.getMessage()));
-
-                } finally {
-                        if (tx.isActive()) {
-                                tx.rollback();
-                        }
-                        em.close();
+                        
+                    }
                 }
-
-                return ret;
+            }
+            //dont forget this node
+            Long id = (Long) em.createQuery("select (e.id) from ChangeRecord e where e.nodeID = :node  order by e.id desc").setParameter("node", node).setMaxResults(1).getSingleResult();
+            if (id == null) {
+                id = 0L;
+            }
+            ChangeRecordIDType x = new ChangeRecordIDType();
+            x.setNodeID(node);
+            x.setOriginatingUSN(id);
+            ret.add(x);
+            
+            tx.rollback();
+            long procTime = System.currentTimeMillis() - startTime;
+            serviceCounter.update(ReplicationQuery.GET_HIGHWATERMARKS, QueryStatus.SUCCESS, procTime);
+            
+        } catch (Exception drfm) {
+            throw new FatalErrorException(new ErrorMessage("E_fatalError", drfm.getMessage()));
+            
+        } finally {
+            if (tx.isActive()) {
+                tx.rollback();
+            }
+            em.close();
         }
-
-        /**
-         * this means that another node has a change and we need to pick up the
-         * change and apply it to our local database.
-         *
-         * @param body
-         * @throws DispositionReportFaultMessage
-         */
-        @Override
-        public void notifyChangeRecordsAvailable(NotifyChangeRecordsAvailable body)
-             throws DispositionReportFaultMessage {
-                long startTime = System.currentTimeMillis();
-                long procTime = System.currentTimeMillis() - startTime;
-                serviceCounter.update(ReplicationQuery.NOTIFY_CHANGERECORDSAVAILABLE,
-                     QueryStatus.SUCCESS, procTime);
+        
+        
+        
+        return ret;
+    }
+
+    /**
+     * this means that another node has a change and we need to pick up the
+     * change and apply it to our local database.
+     *
+     * @param body
+     * @throws DispositionReportFaultMessage
+     */
+    @Override
+    public void notifyChangeRecordsAvailable(NotifyChangeRecordsAvailable body)
+            throws DispositionReportFaultMessage {
+        long startTime = System.currentTimeMillis();
+        long procTime = System.currentTimeMillis() - startTime;
+        serviceCounter.update(ReplicationQuery.NOTIFY_CHANGERECORDSAVAILABLE,
+                QueryStatus.SUCCESS, procTime);
                 //some other node just told us there's new records available, call
-                //getChangeRecords from the remote node asynch
-
-                new ValidateReplication(null).validateNotifyChangeRecordsAvailable(body, ctx);
-
-                queue.add(body);
+        //getChangeRecords from the remote node asynch
+
+        new ValidateReplication(null).validateNotifyChangeRecordsAvailable(body, ctx);
+        
+        queue.add(body);
+
+        //ValidateReplication.unsupportedAPICall();
+    }
+    private static Queue<NotifyChangeRecordsAvailable> queue = null;
+
+    /**
+     * transfers custody of an entity from node1/user1 to node2/user2
+     *
+     * @param body
+     * @throws DispositionReportFaultMessage
+     */
+    @Override
+    public void transferCustody(TransferCustody body)
+            throws DispositionReportFaultMessage {
+        long startTime = System.currentTimeMillis();
 
-                //ValidateReplication.unsupportedAPICall();
-        }
-        private static Queue<NotifyChangeRecordsAvailable> queue = null;
+                //*this node is transfering data to another node
+        //body.getTransferOperationalInfo().
+        ValidateReplication.unsupportedAPICall();
+        
+        EntityManager em = PersistenceManager.getEntityManager();
+        //EntityTransaction tx = em.getTransaction();
 
         /**
-         * transfers custody of an entity from node1/user1 to node2/user2
+         * The custodial node must verify that it has granted permission to
+         * transfer the entities identified and that this permission is still
+         * valid. This operation is comprised of two steps:
+         *
+         * 1. Verification that the transferToken was issued by it, that it has
+         * not expired, that it represents the authority to transfer no more and
+         * no less than those entities identified by the businessKey and
+         * tModelKey elements and that all these entities are still valid and
+         * not yet transferred. The transferToken is invalidated if any of these
+         * conditions are not met.
+         *
+         * 2. If the conditions above are met, the custodial node will prevent
+         * any further changes to the entities identified by the businessKey and
+         * tModelKey elements identified. The entity will remain in this state
+         * until the replication stream indicates it has been successfully
+         * processed via the replication stream. Upon successful verification of
+         * the custody transfer request by the custodial node, an empty message
+         * is returned by it indicating the success of the request and
+         * acknowledging the custody transfer. Following the issue of the empty
+         * message, the custodial node will submit into the replication stream a
+         * changeRecordNewData providing in the operationalInfo, the nodeID
+         * accepting custody of the datum and the authorizedName of the
+         * publisher accepting ownership. The acknowledgmentRequested attribute
+         * of this change record MUST be set to "true".
          *
-         * @param body
-         * @throws DispositionReportFaultMessage
+         * TODO enqueue Replication message
+         *
+         * Finally, the custodial node invalidates the transferToken in order to
+         * prevent additional calls of the transfer_entities API.
          */
-        @Override
-        public void transferCustody(TransferCustody body)
-             throws DispositionReportFaultMessage {
-                long startTime = System.currentTimeMillis();
-
-                //*this node is transfering data to another node
-                //body.getTransferOperationalInfo().
-                ValidateReplication.unsupportedAPICall();
-
-                EntityManager em = PersistenceManager.getEntityManager();
-                //EntityTransaction tx = em.getTransaction();
-
-                /**
-                 * The custodial node must verify that it has granted permission
-                 * to transfer the entities identified and that this permission
-                 * is still valid. This operation is comprised of two steps: 
-                 * 
-                 * 1.
-                 * Verification that the transferToken was issued by it, that it
-                 * has not expired, that it represents the authority to transfer
-                 * no more and no less than those entities identified by the
-                 * businessKey and tModelKey elements and that all these
-                 * entities are still valid and not yet transferred. The
-                 * transferToken is invalidated if any of these conditions are
-                 * not met. 
-                 * 
-                 * 2. If the conditions above are met, the custodial
-                 * node will prevent any further changes to the entities
-                 * identified by the businessKey and tModelKey elements
-                 * identified. The entity will remain in this state until the
-                 * replication stream indicates it has been successfully
-                 * processed via the replication stream. Upon successful
-                 * verification of the custody transfer request by the custodial
-                 * node, an empty message is returned by it indicating the
-                 * success of the request and acknowledging the custody
-                 * transfer. Following the issue of the empty message, the
-                 * custodial node will submit into the replication stream a
-                 * changeRecordNewData providing in the operationalInfo, the
-                 * nodeID accepting custody of the datum and the authorizedName
-                 * of the publisher accepting ownership. The
-                 * acknowledgmentRequested attribute of this change record MUST
-                 * be set to "true".
-                 *
-                 * TODO enqueue Replication message 
-                 * 
-                 * Finally, the custodial node
-                 * invalidates the transferToken in order to prevent additional
-                 * calls of the transfer_entities API.
-                 */
-                DiscardTransferToken dtt = new DiscardTransferToken();
-                dtt.setKeyBag(body.getKeyBag());
-                dtt.setTransferToken(body.getTransferToken());
-                new UDDICustodyTransferImpl().discardTransferToken(dtt);
-        }
-
+        DiscardTransferToken dtt = new DiscardTransferToken();
+        dtt.setKeyBag(body.getKeyBag());
+        dtt.setTransferToken(body.getTransferToken());
+        new UDDICustodyTransferImpl().discardTransferToken(dtt);
+    }
+    
 }

http://git-wip-us.apache.org/repos/asf/juddi/blob/7aa78f62/juddi-core/src/main/java/org/apache/juddi/api/impl/UDDISubscriptionListenerImpl.java
----------------------------------------------------------------------
diff --git a/juddi-core/src/main/java/org/apache/juddi/api/impl/UDDISubscriptionListenerImpl.java b/juddi-core/src/main/java/org/apache/juddi/api/impl/UDDISubscriptionListenerImpl.java
index d1a1f3f..a6239b1 100644
--- a/juddi-core/src/main/java/org/apache/juddi/api/impl/UDDISubscriptionListenerImpl.java
+++ b/juddi-core/src/main/java/org/apache/juddi/api/impl/UDDISubscriptionListenerImpl.java
@@ -88,7 +88,7 @@ public class UDDISubscriptionListenerImpl extends AuthenticatedService implement
 					throw new InvalidKeyPassedException(new ErrorMessage("errors.invalidkey.SubscripKeyNotFound", subscriptionKey));
 				}
 				apiClientSubscriptionInfo = new org.apache.juddi.api_v3.ClientSubscriptionInfo();
-				MappingModelToApi.mapClientSubscriptionInfo(modelClientSubscriptionInfo, apiClientSubscriptionInfo);
+				MappingModelToApi.mapClientSubscriptionInfo(modelClientSubscriptionInfo, apiClientSubscriptionInfo,em);
 		
 				tx.commit();
 			} finally {

http://git-wip-us.apache.org/repos/asf/juddi/blob/7aa78f62/juddi-core/src/main/java/org/apache/juddi/mapping/MappingApiToModel.java
----------------------------------------------------------------------
diff --git a/juddi-core/src/main/java/org/apache/juddi/mapping/MappingApiToModel.java b/juddi-core/src/main/java/org/apache/juddi/mapping/MappingApiToModel.java
index 7297311..65739a4 100644
--- a/juddi-core/src/main/java/org/apache/juddi/mapping/MappingApiToModel.java
+++ b/juddi-core/src/main/java/org/apache/juddi/mapping/MappingApiToModel.java
@@ -1071,7 +1071,7 @@ public class MappingApiToModel {
                         if (apiClerk.getNode() != null) {
                                 org.apache.juddi.model.Node modelNode = new org.apache.juddi.model.Node();
                                 mapNode(apiClerk.getNode(), modelNode);
-                                modelClerk.setNode(modelNode);
+                                modelClerk.setNode(modelNode.getName());
                         }
                 }
         }

http://git-wip-us.apache.org/repos/asf/juddi/blob/7aa78f62/juddi-core/src/main/java/org/apache/juddi/mapping/MappingModelToApi.java
----------------------------------------------------------------------
diff --git a/juddi-core/src/main/java/org/apache/juddi/mapping/MappingModelToApi.java b/juddi-core/src/main/java/org/apache/juddi/mapping/MappingModelToApi.java
index 8a4f1c1..0b5d9a3 100644
--- a/juddi-core/src/main/java/org/apache/juddi/mapping/MappingModelToApi.java
+++ b/juddi-core/src/main/java/org/apache/juddi/mapping/MappingModelToApi.java
@@ -30,6 +30,7 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.logging.Level;
 import java.util.logging.Logger;
+import javax.persistence.EntityManager;
 import javax.xml.bind.JAXB;
 import javax.xml.bind.JAXBElement;
 
@@ -1111,7 +1112,7 @@ public class MappingModelToApi {
         }
 
         public static void mapClientSubscriptionInfo(org.apache.juddi.model.ClientSubscriptionInfo modelClientSubscriptionInfo,
-             org.apache.juddi.api_v3.ClientSubscriptionInfo apiClientSubscriptionInfo)
+             org.apache.juddi.api_v3.ClientSubscriptionInfo apiClientSubscriptionInfo, EntityManager em)
              throws DispositionReportFaultMessage {
 
                 apiClientSubscriptionInfo.setSubscriptionKey(modelClientSubscriptionInfo.getSubscriptionKey());
@@ -1125,18 +1126,18 @@ public class MappingModelToApi {
 
                 if (modelClientSubscriptionInfo.getFromClerk() != null) {
                         org.apache.juddi.api_v3.Clerk apiFromClerk = new org.apache.juddi.api_v3.Clerk();
-                        mapClerk(modelClientSubscriptionInfo.getFromClerk(), apiFromClerk);
+                        mapClerk(modelClientSubscriptionInfo.getFromClerk(), apiFromClerk,em);
                         apiClientSubscriptionInfo.setFromClerk(apiFromClerk);
                 }
                 if (modelClientSubscriptionInfo.getToClerk() != null) {
                         org.apache.juddi.api_v3.Clerk apiToClerk = new org.apache.juddi.api_v3.Clerk();
-                        mapClerk(modelClientSubscriptionInfo.getToClerk(), apiToClerk);
+                        mapClerk(modelClientSubscriptionInfo.getToClerk(), apiToClerk,em);
                         apiClientSubscriptionInfo.setToClerk(apiToClerk);
                 }
         }
 
         public static void mapClerk(org.apache.juddi.model.Clerk modelClerk,
-             org.apache.juddi.api_v3.Clerk apiClerk)
+             org.apache.juddi.api_v3.Clerk apiClerk,EntityManager em)
              throws DispositionReportFaultMessage {
 
                 apiClerk.setName(modelClerk.getClerkName());
@@ -1144,7 +1145,9 @@ public class MappingModelToApi {
                 apiClerk.setPublisher(modelClerk.getPublisherId());
                 if (modelClerk.getNode() != null) {
                         org.apache.juddi.api_v3.Node apiNode = new org.apache.juddi.api_v3.Node();
-                        mapNode(modelClerk.getNode(), apiNode);
+                        mapNode(
+                                em.find(org.apache.juddi.model.Node.class, modelClerk.getNode()) 
+                               , apiNode);
                         apiClerk.setNode(apiNode);
                 }
         }

http://git-wip-us.apache.org/repos/asf/juddi/blob/7aa78f62/juddi-core/src/main/java/org/apache/juddi/model/Clerk.java
----------------------------------------------------------------------
diff --git a/juddi-core/src/main/java/org/apache/juddi/model/Clerk.java b/juddi-core/src/main/java/org/apache/juddi/model/Clerk.java
index fe0ca52..3ed1368 100644
--- a/juddi-core/src/main/java/org/apache/juddi/model/Clerk.java
+++ b/juddi-core/src/main/java/org/apache/juddi/model/Clerk.java
@@ -20,7 +20,10 @@ import javax.persistence.Column;
 import javax.persistence.Entity;
 import javax.persistence.FetchType;
 import javax.persistence.Id;
+import javax.persistence.JoinColumn;
 import javax.persistence.ManyToOne;
+import javax.persistence.OneToMany;
+import javax.persistence.OneToOne;
 import javax.persistence.Table;
 import javax.persistence.Transient;
 
@@ -38,14 +41,19 @@ public class Clerk implements java.io.Serializable {
 	private String clerkName;
 	@Column(name="publisher_id", nullable = false, length=255)
 	private String publisherId;
-	@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
-	private Node node;
+        //@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
+	//@OneToOne(cascade = CascadeType.PERSIST , fetch = FetchType.EAGER)
+        //@JoinColumn(name = "nodeid", nullable = false)
+	//@ManyToOne(fetch = FetchType.LAZY,  targetEntity = Node.class , cascade =  {CascadeType.PERSIST,  CascadeType.DETACH, CascadeType.MERGE, CascadeType.REFRESH })
+        
+        @Column (name="nodeid")
+        private String node;
 	@Column(name="cred", length=255)
 	private String cred;
 	
 	public Clerk() {}
 
-	public Clerk(String clerkName, String cred, Node node, String publisherId) {
+	public Clerk(String clerkName, String cred, String node, String publisherId) {
 		super();
 		this.clerkName = clerkName;
 		this.cred = cred;
@@ -69,11 +77,11 @@ public class Clerk implements java.io.Serializable {
 		this.publisherId = publisherId;
 	}
 
-	public Node getNode() {
+	public String getNode() {
 		return node;
 	}
 
-	public void setNode(Node node) {
+	public void setNode(String node) {
 		this.node = node;
 	}
 

http://git-wip-us.apache.org/repos/asf/juddi/blob/7aa78f62/juddi-core/src/main/java/org/apache/juddi/model/Node.java
----------------------------------------------------------------------
diff --git a/juddi-core/src/main/java/org/apache/juddi/model/Node.java b/juddi-core/src/main/java/org/apache/juddi/model/Node.java
index a085536..53fbe12 100644
--- a/juddi-core/src/main/java/org/apache/juddi/model/Node.java
+++ b/juddi-core/src/main/java/org/apache/juddi/model/Node.java
@@ -15,9 +15,17 @@ package org.apache.juddi.model;
  * limitations under the License.
  */
 
+import java.util.List;
+import java.util.Set;
+import javax.persistence.CascadeType;
 import javax.persistence.Column;
 import javax.persistence.Entity;
+import javax.persistence.FetchType;
 import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.OneToMany;
+import javax.persistence.OneToOne;
 import javax.persistence.Table;
 import javax.persistence.Transient;
 
@@ -61,7 +69,7 @@ public class Node implements java.io.Serializable {
 	private String factoryURLPkgs;
 	@Column(name="factory_naming_provider", nullable = true, length=255)
 	private String factoryNamingProvider;
-
+        
 	public Node() {}
 
 	public Node(String custodyTransferUrl, String inquiryUrl,
@@ -189,5 +197,7 @@ public class Node implements java.io.Serializable {
 	public void setFactoryNamingProvider(String factoryNamingProvider) {
 		this.factoryNamingProvider = factoryNamingProvider;
 	}
+        
+        
 
 }

http://git-wip-us.apache.org/repos/asf/juddi/blob/7aa78f62/juddi-core/src/main/java/org/apache/juddi/validation/ValidatePublish.java
----------------------------------------------------------------------
diff --git a/juddi-core/src/main/java/org/apache/juddi/validation/ValidatePublish.java b/juddi-core/src/main/java/org/apache/juddi/validation/ValidatePublish.java
index ca560f1..9d02d9c 100644
--- a/juddi-core/src/main/java/org/apache/juddi/validation/ValidatePublish.java
+++ b/juddi-core/src/main/java/org/apache/juddi/validation/ValidatePublish.java
@@ -90,6 +90,7 @@ import org.uddi.api_v3.SaveBusiness;
 import org.uddi.api_v3.SaveService;
 import org.uddi.api_v3.SaveTModel;
 import org.uddi.api_v3.TModel;
+import org.uddi.repl_v3.ReplicationConfiguration;
 import org.uddi.sub_v3.Subscription;
 import org.uddi.v3_service.DispositionReportFaultMessage;
 
@@ -2365,7 +2366,7 @@ public class ValidatePublish extends ValidateUDDIApi {
                 return TokenResolver.replaceTokens(url, p);
         }
 
-        public void validateDeleteNode(EntityManager em, DeleteNode nodeID) throws DispositionReportFaultMessage {
+        public void validateDeleteNode(EntityManager em, DeleteNode nodeID, ReplicationConfiguration cfg) throws DispositionReportFaultMessage {
                 if (nodeID == null) {
                         throw new InvalidKeyPassedException(new ErrorMessage("errors.deleteClerk.NoInput"));
                 }
@@ -2375,6 +2376,22 @@ public class ValidatePublish extends ValidateUDDIApi {
                 if (nodeID.getNodeID() == null || nodeID.getNodeID().trim().equalsIgnoreCase("")) {
                         throw new InvalidKeyPassedException(new ErrorMessage("errors.deleteNode.NoInput"));
                 }
+                //get the latest replication config
+                if (cfg!=null){
+                    if (cfg.getCommunicationGraph()!=null){
+                        for (String node : cfg.getCommunicationGraph().getNode()) {
+                            if (node.equals(nodeID.getNodeID()))
+                                throw new InvalidKeyPassedException(new ErrorMessage("errors.deleteNode.InReplicationConfig", nodeID.getNodeID()));
+                        }
+                        for (int i=0; i <cfg.getCommunicationGraph().getEdge().size(); i++){
+                            if (nodeID.getNodeID().equals(cfg.getCommunicationGraph().getEdge().get(i).getMessageReceiver()))
+                                throw new InvalidKeyPassedException(new ErrorMessage("errors.deleteNode.InReplicationConfig", nodeID.getNodeID()));
+                            if (nodeID.getNodeID().equals(cfg.getCommunicationGraph().getEdge().get(i).getMessageSender()))
+                                throw new InvalidKeyPassedException(new ErrorMessage("errors.deleteNode.InReplicationConfig", nodeID.getNodeID()));
+                            
+                        }
+                    }
+                }
 
         }
 

http://git-wip-us.apache.org/repos/asf/juddi/blob/7aa78f62/juddi-core/src/main/resources/messages.properties
----------------------------------------------------------------------
diff --git a/juddi-core/src/main/resources/messages.properties b/juddi-core/src/main/resources/messages.properties
index 18f7cfc..9665589 100644
--- a/juddi-core/src/main/resources/messages.properties
+++ b/juddi-core/src/main/resources/messages.properties
@@ -107,7 +107,7 @@ errors.saveclientsubscriptionKey.NoInput=The SubscriptionKey must be provided
 errors.saveClerk.NoInput=At least one Clerk must be provided
 errors.saveNodes.NoInput=At least one Node must be provided
 errors.deleteNode.NoInput=A node id must be specified
-errors.deleteNode.NotFound=The specified node if could not be found.
+errors.deleteNode.NotFound=The specified node could not be found.
 errors.deleteClerk.NoInput=A clerk id must be specified
 errors.deleteClerk.NotFound=The specified clerk if could not be found.
 errors.savetmodel.NoInput=At least one tModel must be provided
@@ -292,4 +292,5 @@ errors.replication.negativeLimit=The specified response limit is either 0 or a n
 errors.replication.limitVectorNull=The high water mark vector limit specified OriginatingUSN is null or invalid
 errors.replication.limitVectorNoNode=No node name was specified
 errors.replication.configNodeNotFound=No specified node name is not currently registered as a node. Use the jUDDI Service API to register it. Node id: 
-errors.replication.configNull=No replication config was present in the message
\ No newline at end of file
+errors.replication.configNull=No replication config was present in the message
+errors.deleteNode.InReplicationConfig=The node to be deleted is currently referenced in the replication configuration. You must revise the configuration before deleting the node, 
\ No newline at end of file


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@juddi.apache.org
For additional commands, e-mail: commits-help@juddi.apache.org