Repository: juddi
Updated Branches:
  refs/heads/master 4a7e282e9 -> d0bbde646


JUDDI-272 we can now transfer ownership between nodes that are in the 
replication configuration graph. This required some minor refactoring in the 
custody transfer impl. Minor corrections to performance reporting by juddi api 
service. All other changes are formatting.


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

Branch: refs/heads/master
Commit: d0bbde64623a5b87a804b2da19965bcf6bc1d224
Parents: 4a7e282
Author: Alex <[email protected]>
Authored: Fri Jan 2 10:02:27 2015 -0500
Committer: Alex <[email protected]>
Committed: Fri Jan 2 10:02:27 2015 -0500

----------------------------------------------------------------------
 .../org/apache/juddi/api/impl/JUDDIApiImpl.java |   4 +-
 .../juddi/api/impl/UDDICustodyTransferImpl.java | 183 +++++++----
 .../juddi/api/impl/UDDIPublicationImpl.java     |   4 +-
 .../juddi/api/impl/UDDIReplicationImpl.java     | 187 ++++++-----
 .../apache/juddi/mapping/MappingApiToModel.java |  71 ++--
 .../validation/ValidateCustodyTransfer.java     | 322 ++++++++++---------
 .../juddi/validation/ValidateReplication.java   |  16 +-
 .../src/main/resources/messages.properties      |   1 +
 8 files changed, 455 insertions(+), 333 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/juddi/blob/d0bbde64/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 67bc1aa..95dddbe 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
@@ -1162,11 +1162,11 @@ public class JUDDIApiImpl extends AuthenticatedService 
implements JUDDIApiPortTy
 
                         tx.commit();
                         long procTime = System.currentTimeMillis() - startTime;
-                        serviceCounter.update(JUDDIQuery.ADMIN_SAVE_SUB,
+                        serviceCounter.update(JUDDIQuery.ADMIN_DELETE_SUB,
                                 QueryStatus.SUCCESS, procTime);
                 } catch (DispositionReportFaultMessage drfm) {
                         long procTime = System.currentTimeMillis() - startTime;
-                        serviceCounter.update(JUDDIQuery.ADMIN_SAVE_SUB,
+                        serviceCounter.update(JUDDIQuery.ADMIN_DELETE_SUB,
                                 QueryStatus.FAILED, procTime);
                         throw drfm;
                 } finally {

http://git-wip-us.apache.org/repos/asf/juddi/blob/d0bbde64/juddi-core/src/main/java/org/apache/juddi/api/impl/UDDICustodyTransferImpl.java
----------------------------------------------------------------------
diff --git 
a/juddi-core/src/main/java/org/apache/juddi/api/impl/UDDICustodyTransferImpl.java
 
b/juddi-core/src/main/java/org/apache/juddi/api/impl/UDDICustodyTransferImpl.java
index 2c5d295..8a3d862 100644
--- 
a/juddi-core/src/main/java/org/apache/juddi/api/impl/UDDICustodyTransferImpl.java
+++ 
b/juddi-core/src/main/java/org/apache/juddi/api/impl/UDDICustodyTransferImpl.java
@@ -59,6 +59,7 @@ import org.apache.juddi.replication.ReplicationNotifier;
 import org.apache.juddi.v3.client.UDDIService;
 import org.apache.juddi.v3.error.ErrorMessage;
 import org.apache.juddi.v3.error.FatalErrorException;
+import org.apache.juddi.v3.error.TransferNotAllowedException;
 import org.apache.juddi.validation.ValidateCustodyTransfer;
 import org.uddi.api_v3.OperationalInfo;
 import org.uddi.custody_v3.DiscardTransferToken;
@@ -72,6 +73,7 @@ import org.uddi.repl_v3.TransferCustody;
 import org.uddi.v3_service.DispositionReportFaultMessage;
 import org.uddi.v3_service.UDDICustodyTransferPortType;
 import org.uddi.v3_service.UDDIReplicationPortType;
+import sun.util.BuddhistCalendar;
 
 /**
  * This implements the UDDI v3 Custody Transfer API web service
@@ -238,7 +240,7 @@ public class UDDICustodyTransferImpl extends 
AuthenticatedService implements UDD
 
                 EntityManager em = PersistenceManager.getEntityManager();
                 EntityTransaction tx = em.getTransaction();
-                 List<ChangeRecord> changes = new ArrayList<ChangeRecord>();
+                List<ChangeRecord> changes = new ArrayList<ChangeRecord>();
                 try {
                         tx.begin();
 
@@ -248,7 +250,7 @@ public class UDDICustodyTransferImpl extends 
AuthenticatedService implements UDD
 
                         //if the destination transfer is to a different node, 
                         if (!verifier.validateTransferEntities(em, body)) {
-                                //i don't own these entities, so tell the ower 
to transfer to me.
+                                //i don't own these entities, so tell the 
owner to transfer to me.
 
                                 //look up the replication config endpoint for 
that node and trigger the transfer, then return
                                 //ok this is a node to node transfer, first up 
a replication client to the destination node
@@ -258,11 +260,20 @@ public class UDDICustodyTransferImpl extends 
AuthenticatedService implements UDD
                                         List<String> keyList = keyBag.getKey();
                                         for (String key : keyList) {
                                                 UddiEntity uddiEntity = 
em.find(UddiEntity.class, key);
-                                                if (sourceNode != null
-                                                        && 
!uddiEntity.getNodeId().equals(sourceNode)) {
-                                                        throw new 
Exception("All entities to be transfer must be transfered to the same source 
and destination node");
+                                                
+                                                if (uddiEntity!=null) {
+                                                        sourceNode = 
uddiEntity.getNodeId();
+                                                        break;  //we only need 
one source node
                                                 }
-                                                sourceNode = 
uddiEntity.getNodeId();
+                                                else
+                                                {
+                                                        logger.warn("couldn't 
find a record for key " + key);
+                                                }
+                                        }
+                                        if (sourceNode==null){
+                                                logger.warn("unable to process 
transfer, could not locate the source node, perhaps it hasn't been replicated 
to this node yet?")
+                                                        ;
+                                                throw new Exception("unable to 
process transfer, could not locate the source node for any of the specific 
keys, perhaps it hasn't been replicated to this node yet?");
                                         }
 
                                         UDDIReplicationPortType 
replicationClient = getReplicationClient(sourceNode);
@@ -276,76 +287,35 @@ public class UDDICustodyTransferImpl extends 
AuthenticatedService implements UDD
                                         
transferCustody.getTransferOperationalInfo().setAuthorizedName(publisher.getAuthorizedName());
                                         
transferCustody.getTransferOperationalInfo().setNodeID(node);
 
+                                        //and trigger the transfer
+                                        logger.info("AUDIT, transfering " + 
transferCustody.getKeyBag().getKey().size() + " entities to " + 
publisher.getAuthorizedName() + " at node " + node + " from source " + 
sourceNode);
                                         
replicationClient.transferCustody(transferCustody);
+                                } catch (DispositionReportFaultMessage df) {
+                                        logger.error("Unable to transfer 
entities from " + sourceNode + " to node " + node + " to user " + 
publisher.getAuthorizedName(), df);
+                                        throw new 
TransferNotAllowedException(new ErrorMessage("E_transferBlocked", 
df.getMessage()));
                                 } catch (Exception ex) {
-                                        logger.error("Unable to transfer 
entities to node " + sourceNode + ".", ex);
+                                        logger.error("Unable to transfer 
entities from " + sourceNode + " to node " + node + " to user " + 
publisher.getAuthorizedName(), ex);
+                                        throw new 
TransferNotAllowedException(new ErrorMessage("E_transferBlocked", 
ex.getMessage()));
                                 }
-                                //and trigger the transfer
-                        } else {
-
-                                // Once validated, the ownership transfer is 
as simple as switching the publisher
-                                KeyBag keyBag = body.getKeyBag();
-                                List<String> keyList = keyBag.getKey();
-                                //used for the change journal
-                               
-                                for (String key : keyList) {
-                                        UddiEntity uddiEntity = 
em.find(UddiEntity.class, key);
-                                        
uddiEntity.setAuthorizedName(publisher.getAuthorizedName());
-                                        Date now = new Date();
-                                        uddiEntity.setModified(now);
-                                        
uddiEntity.setModifiedIncludingChildren(now);
-                                        
-                                        if (uddiEntity instanceof 
BusinessEntity) {
-                                                BusinessEntity be = 
(BusinessEntity) uddiEntity;
-
-                                                List<BusinessService> bsList = 
be.getBusinessServices();
-                                                for (BusinessService bs : 
bsList) {
-                                                        
bs.setAuthorizedName(publisher.getAuthorizedName());
-                                                        bs.setModified(now);
-                                                        
bs.setModifiedIncludingChildren(now);
-
-                                                        List<BindingTemplate> 
btList = bs.getBindingTemplates();
-                                                        for (BindingTemplate 
bt : btList) {
-                                                                
bt.setAuthorizedName(publisher.getAuthorizedName());
-                                                                
bt.setModified(now);
-                                                                
bt.setModifiedIncludingChildren(now);
-                                                       
-                                                        }
-                                                }
-                                        }
-                                        ChangeRecord cr = new ChangeRecord();
-                                        cr.setChangeRecordNewData(new 
ChangeRecordNewData());
-                                        if (uddiEntity instanceof 
BusinessEntity) {
-                                                
cr.getChangeRecordNewData().setBusinessEntity(new 
org.uddi.api_v3.BusinessEntity());
-                                                
MappingModelToApi.mapBusinessEntity((BusinessEntity) uddiEntity, 
cr.getChangeRecordNewData().getBusinessEntity());
-                                        }
-                                        if (uddiEntity instanceof Tmodel) {
-                                                
cr.getChangeRecordNewData().setTModel(new org.uddi.api_v3.TModel());
-                                                
MappingModelToApi.mapTModel((Tmodel) uddiEntity, 
cr.getChangeRecordNewData().getTModel());
-                                        }
-                                        changes.add(cr);
-                                        em.persist(uddiEntity);
 
-                                }
+                        } else {
+                                changes.addAll(executeTransfer(body, em, 
publisher.getAuthorizedName(), node));
+                                //all of the items to be transfer are owned 
locally by *this node.
 
-                                // After transfer is finished, the token can 
be removed
-                                org.uddi.custody_v3.TransferToken 
apiTransferToken = body.getTransferToken();
-                                String transferTokenId = new 
String(apiTransferToken.getOpaqueToken());
-                                org.apache.juddi.model.TransferToken 
modelTransferToken = em.find(org.apache.juddi.model.TransferToken.class, 
transferTokenId);
-                                em.remove(modelTransferToken);
                         }
                         tx.commit();
                         //we need to do something for replication purposes here
                         //enqueue notifications and storage of the changed 
records
-                        for (ChangeRecord c: changes)
-                                 try {
-                                         c.setChangeID(new 
ChangeRecordIDType());
-                                         c.getChangeID().setNodeID(node);
-                                         
c.getChangeID().setOriginatingUSN(null);
-                                         
ReplicationNotifier.Enqueue(MappingApiToModel.mapChangeRecord(c));
+                        for (ChangeRecord c : changes) {
+                                try {
+                                        c.setChangeID(new 
ChangeRecordIDType());
+                                        c.getChangeID().setNodeID(node);
+                                        
c.getChangeID().setOriginatingUSN(null);
+                                        
ReplicationNotifier.Enqueue(MappingApiToModel.mapChangeRecord(c));
                                 } catch (UnsupportedEncodingException ex) {
-                                        
Logger.getLogger(UDDICustodyTransferImpl.class.getName()).log(Level.SEVERE, 
null, ex);
+                                        logger.error("", ex);
                                 }
+                        }
                         long procTime = System.currentTimeMillis() - startTime;
                         
serviceCounter.update(CustodyTransferQuery.TRANSFER_ENTITIES,
                                 QueryStatus.SUCCESS, procTime);
@@ -395,4 +365,87 @@ public class UDDICustodyTransferImpl extends 
AuthenticatedService implements UDD
                 return null;
 
         }
+
+        /**
+         * used to factor out the actual execution of custody transfer, used by
+         * both this service and the replication service.
+         *
+         * @since 3.3
+         * @param body
+         * @param em
+         * @param transferToPublisher
+         * @param transferToNode
+         * @return
+         * @throws DispositionReportFaultMessage
+         */
+        protected List<ChangeRecord> executeTransfer(TransferEntities body, 
EntityManager em, String transferToPublisher, String transferToNode) throws 
DispositionReportFaultMessage {
+                // Once validated, the ownership transfer is as simple as 
switching the publisher
+                List<ChangeRecord> changes = new ArrayList<ChangeRecord>();;
+                KeyBag keyBag = body.getKeyBag();
+                List<String> keyList = keyBag.getKey();
+                //used for the change journal
+
+                for (String key : keyList) {
+                        UddiEntity uddiEntity = em.find(UddiEntity.class, key);
+                        uddiEntity.setAuthorizedName(transferToPublisher);
+                        uddiEntity.setNodeId(transferToNode);
+                        Date now = new Date();
+                        uddiEntity.setModified(now);
+                        uddiEntity.setModifiedIncludingChildren(now);
+
+                        if (uddiEntity instanceof BusinessEntity) {
+                                BusinessEntity be = (BusinessEntity) 
uddiEntity;
+
+                                List<BusinessService> bsList = 
be.getBusinessServices();
+                                for (BusinessService bs : bsList) {
+                                        
bs.setAuthorizedName(transferToPublisher);
+                                        bs.setNodeId(transferToNode);
+                                        bs.setModified(now);
+                                        bs.setModifiedIncludingChildren(now);
+
+                                        List<BindingTemplate> btList = 
bs.getBindingTemplates();
+                                        for (BindingTemplate bt : btList) {
+                                                
bt.setAuthorizedName(transferToPublisher);
+                                                bt.setNodeId(transferToNode);
+                                                bt.setModified(now);
+                                                
bt.setModifiedIncludingChildren(now);
+
+                                        }
+                                }
+                        }
+                        ChangeRecord cr = new ChangeRecord();
+                        cr.setChangeRecordNewData(new ChangeRecordNewData());
+                        cr.getChangeRecordNewData().setOperationalInfo(new 
OperationalInfo());
+                        
cr.getChangeRecordNewData().getOperationalInfo().setAuthorizedName(transferToPublisher);
+                        
cr.getChangeRecordNewData().getOperationalInfo().setEntityKey(uddiEntity.getEntityKey());
+                        
cr.getChangeRecordNewData().getOperationalInfo().setNodeID(transferToNode);
+                        GregorianCalendar gcal = new GregorianCalendar();
+                        gcal.setTime(uddiEntity.getCreated());
+                        
cr.getChangeRecordNewData().getOperationalInfo().setCreated(df.newXMLGregorianCalendar(gcal));
+                        gcal = new GregorianCalendar();
+                        gcal.setTime(now);
+                        
cr.getChangeRecordNewData().getOperationalInfo().setModified(df.newXMLGregorianCalendar(gcal));
+                        
cr.getChangeRecordNewData().getOperationalInfo().setModifiedIncludingChildren(df.newXMLGregorianCalendar(gcal));
+                        
cr.getChangeRecordNewData().getOperationalInfo().setEntityKey(uddiEntity.getEntityKey());
+
+                        if (uddiEntity instanceof BusinessEntity) {
+                                
cr.getChangeRecordNewData().setBusinessEntity(new 
org.uddi.api_v3.BusinessEntity());
+                                
MappingModelToApi.mapBusinessEntity((BusinessEntity) uddiEntity, 
cr.getChangeRecordNewData().getBusinessEntity());
+                        }
+                        if (uddiEntity instanceof Tmodel) {
+                                cr.getChangeRecordNewData().setTModel(new 
org.uddi.api_v3.TModel());
+                                MappingModelToApi.mapTModel((Tmodel) 
uddiEntity, cr.getChangeRecordNewData().getTModel());
+                        }
+                        changes.add(cr);
+                        em.persist(uddiEntity);
+
+                }
+
+                // After transfer is finished, the token can be removed
+                org.uddi.custody_v3.TransferToken apiTransferToken = 
body.getTransferToken();
+                String transferTokenId = new 
String(apiTransferToken.getOpaqueToken());
+                org.apache.juddi.model.TransferToken modelTransferToken = 
em.find(org.apache.juddi.model.TransferToken.class, transferTokenId);
+                em.remove(modelTransferToken);
+                return changes;
+        }
 }

http://git-wip-us.apache.org/repos/asf/juddi/blob/d0bbde64/juddi-core/src/main/java/org/apache/juddi/api/impl/UDDIPublicationImpl.java
----------------------------------------------------------------------
diff --git 
a/juddi-core/src/main/java/org/apache/juddi/api/impl/UDDIPublicationImpl.java 
b/juddi-core/src/main/java/org/apache/juddi/api/impl/UDDIPublicationImpl.java
index b683aee..10ba3c4 100644
--- 
a/juddi-core/src/main/java/org/apache/juddi/api/impl/UDDIPublicationImpl.java
+++ 
b/juddi-core/src/main/java/org/apache/juddi/api/impl/UDDIPublicationImpl.java
@@ -1039,10 +1039,10 @@ public class UDDIPublicationImpl extends 
AuthenticatedService implements UDDIPub
                                 
businessParent.setModifiedIncludingChildren(now);
                                 em.persist(businessParent);
                         } else {
-                                logger.warn("Parent business is null for saved 
binding template!");
+                                logger.debug("Parent business is null for 
saved binding template!");
                         }
                 } else {
-                        logger.warn("Parent service is null for saved binding 
template!");
+                        logger.debug("Parent service is null for saved binding 
template!");
                 }
                 // }
 

http://git-wip-us.apache.org/repos/asf/juddi/blob/d0bbde64/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 af3a46b..cba57fc 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
@@ -16,6 +16,7 @@
  */
 package org.apache.juddi.api.impl;
 
+import java.io.UnsupportedEncodingException;
 import java.math.BigInteger;
 import java.rmi.RemoteException;
 import java.util.ArrayList;
@@ -40,6 +41,7 @@ import javax.xml.bind.annotation.XmlSeeAlso;
 import javax.xml.ws.BindingProvider;
 import org.apache.commons.configuration.ConfigurationException;
 import static org.apache.juddi.api.impl.AuthenticatedService.logger;
+import static org.apache.juddi.api.impl.AuthenticatedService.node;
 import org.apache.juddi.api.util.QueryStatus;
 import org.apache.juddi.api.util.ReplicationQuery;
 import org.apache.juddi.config.AppConfig;
@@ -64,9 +66,11 @@ import org.apache.juddi.validation.ValidateCustodyTransfer;
 import org.apache.juddi.validation.ValidateReplication;
 import org.uddi.api_v3.OperationalInfo;
 import org.uddi.custody_v3.DiscardTransferToken;
+import org.uddi.custody_v3.TransferEntities;
 import org.uddi.repl_v3.ChangeRecord;
 import org.uddi.repl_v3.ChangeRecordAcknowledgement;
 import org.uddi.repl_v3.ChangeRecordIDType;
+import org.uddi.repl_v3.ChangeRecordNewData;
 import org.uddi.repl_v3.ChangeRecords;
 import org.uddi.repl_v3.DoPing;
 import org.uddi.repl_v3.GetChangeRecords;
@@ -635,7 +639,8 @@ public class UDDIReplicationImpl extends 
AuthenticatedService implements UDDIRep
                 }
                 //only time this is allowed is custody transfer
                 if (!modelNodeId.equals(newDataOperationalInfo.getNodeID())) {
-                        throw new Exception("node id mismatch!");
+                        //throw new Exception("node id mismatch!");
+                        logger.info("AUDIT, custory transfer from node, " + 
modelNodeId + " to " + newDataOperationalInfo.getNodeID() + "/" + 
newDataOperationalInfo.getAuthorizedName());
                 }
 
                 //if i already have a record and "own it" and the remote node 
has a record with the same key, reject the update
@@ -790,7 +795,7 @@ public class UDDIReplicationImpl extends 
AuthenticatedService implements UDDIRep
                                 }
                         }
 
-                        logger.info("Query db for replication changes, lower 
index is " + (firstrecord - 1) + " last index " + lastrecord + " record limit " 
+ maxrecords);
+                        logger.debug("Query db for replication changes, lower 
index is " + (firstrecord - 1) + " last index " + lastrecord + " record limit " 
+ maxrecords);
                         Query createQuery = null;
                         if (lastrecord != null) {
                                 createQuery = em.createQuery("select e from 
ChangeRecord e where "
@@ -809,7 +814,7 @@ public class UDDIReplicationImpl extends 
AuthenticatedService implements UDDIRep
                         createQuery.setParameter("node", node);
 
                         List<org.apache.juddi.model.ChangeRecord> records = 
(List<org.apache.juddi.model.ChangeRecord>) createQuery.getResultList();
-                        logger.info(records.size() + " CR records returned 
from query");
+                        logger.debug(records.size() + " CR records returned 
from query");
                         for (int i = 0; i < records.size(); i++) {
                                 ChangeRecord r = 
MappingModelToApi.mapChangeRecord(records.get(i));
                                 //if (!Excluded(changesAlreadySeen, r)) {
@@ -946,14 +951,15 @@ public class UDDIReplicationImpl extends 
AuthenticatedService implements UDDIRep
 
         /**
          * transfers custody of an entity from node1/user1 to node2/user2
-         * 
+         *
          * assume this node is node 2.
-         * 
+         *
          * user1 on node1 requests a transfer token. node 1 issues the token.
-         * 
-         * user1 now has a transfer token for their stuff
-         * user now takes the token to node 2 and calls transferEntities
-         *<img 
src="http://www.uddi.org/pubs/uddi-v3.0.2-20041019_files/image086.gif";> 
+         *
+         * user1 now has a transfer token for their stuff user now takes the
+         * token to node 2 and calls transferEntities
+         * <img 
src="http://www.uddi.org/pubs/uddi-v3.0.2-20041019_files/image086.gif";>
+         *
          * @param body
          * @throws DispositionReportFaultMessage
          */
@@ -961,79 +967,106 @@ public class UDDIReplicationImpl extends 
AuthenticatedService implements UDDIRep
         public void transferCustody(TransferCustody body)
                 throws DispositionReportFaultMessage {
                 long startTime = System.currentTimeMillis();
-
+                EntityManager em = PersistenceManager.getEntityManager();
+                EntityTransaction tx = em.getTransaction();
+                logger.info("Inbound transfer request (via replication api, 
node to node");
+                try {
+                        tx.begin();
                 //*this node is transfering data to another node
-                //ValidateReplication.unsupportedAPICall();
+                        //ValidateReplication.unsupportedAPICall();
+                        //a remote node just told me to give up control of 
some of my entities
 
-                //a remote node just told me to give up control of some of my 
entities
-                EntityManager em = PersistenceManager.getEntityManager();
                 //EntityTransaction tx = em.getTransaction();
-                //confirm i have a replication config
-                boolean ok =false;
-                ReplicationConfiguration FetchEdges = 
ReplicationNotifier.FetchEdges();
-                for (int i=0; i<FetchEdges.getOperator().size(); i++){
-                        //confirm that the destination node is in the 
replication config
-                        if 
(FetchEdges.getOperator().get(i).getOperatorNodeID().equals(body.getTransferOperationalInfo().getNodeID()))
-                        {
-                                ok = true;
-                                break;
+                        //confirm i have a replication config
+                        boolean ok = false;
+                        ReplicationConfiguration FetchEdges = 
ReplicationNotifier.FetchEdges();
+                        if (FetchEdges != null) {
+                                for (int i = 0; i < 
FetchEdges.getOperator().size(); i++) {
+                                        //confirm that the destination node is 
in the replication config
+                                        if 
(FetchEdges.getOperator().get(i).getOperatorNodeID().equals(body.getTransferOperationalInfo().getNodeID()))
 {
+                                                ok = true;
+                                                break;
+                                        }
+                                }
                         }
+                        if (!ok) {
+                                throw new TransferNotAllowedException(new 
ErrorMessage("E_transferNotAllowedUnknownNode"));
+                        }
+
+                        new ValidateReplication(null).validateTransfer(em, 
body);
+                       
+                        TransferEntities te = new TransferEntities();
+                        te.setKeyBag(body.getKeyBag());
+                        te.setTransferToken(body.getTransferToken());
+                        te.setAuthInfo(null);
+                        //make the change
+                        //enqueue in replication notifier
+                        //discard the token
+                        logger.info("request validated, processing transfer");
+                        List<ChangeRecord> executeTransfer = new 
UDDICustodyTransferImpl().executeTransfer(te, em, 
body.getTransferOperationalInfo().getAuthorizedName(), 
body.getTransferOperationalInfo().getNodeID());
+                        
+                        for (ChangeRecord c : executeTransfer) {
+                                try {
+                                        c.setChangeID(new 
ChangeRecordIDType());
+                                        c.getChangeID().setNodeID(node);
+                                        
c.getChangeID().setOriginatingUSN(null);
+                                        
ReplicationNotifier.Enqueue(MappingApiToModel.mapChangeRecord(c));
+                                } catch (UnsupportedEncodingException ex) {
+                                       logger.error("", ex);
+                                }
+                        }
+                        /**
+                         * 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".
+                         *
+                         * 
+                         *
+                         * Finally, the custodial node invalidates the
+                         * transferToken in order to prevent additional calls 
of
+                         * the transfer_entities API.
+                         */
+                        tx.commit();
+                        long procTime = System.currentTimeMillis() - startTime;
+                        
serviceCounter.update(ReplicationQuery.TRANSFER_CUSTODY,
+                                QueryStatus.SUCCESS, procTime);
+                } catch (DispositionReportFaultMessage d) {
+                        logger.error("Unable to process node to node custody 
transfer ", d);
+                        throw d;
+                } finally {
+                        if (em != null && em.isOpen()) {
+                                em.close();
+                        }
+                        if (tx.isActive())
+                                tx.rollback();
                 }
-                if (!ok){
-                        throw new TransferNotAllowedException(new 
ErrorMessage("E_transferNotAllowedUnknownNode"));
-                }
-                
-                
-                
-                new ValidateReplication(null).validateTransfer(em,body);
-                
-                
-                //make the change
-                //enqueue in replication notifier
-                //discard the token
-                
-                /**
-                 * 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);
-                long procTime = System.currentTimeMillis() - startTime;
-                serviceCounter.update(ReplicationQuery.TRANSFER_CUSTODY,
-                        QueryStatus.SUCCESS, procTime);
         }
 
 }

http://git-wip-us.apache.org/repos/asf/juddi/blob/d0bbde64/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 63af296..334fadd 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
@@ -1383,27 +1383,31 @@ public class MappingApiToModel {
                 org.apache.juddi.model.ChangeRecord r = new 
org.apache.juddi.model.ChangeRecord();
                 r.setId(rec.getChangeID().getOriginatingUSN());
                 r.setOriginatingUSN(rec.getChangeID().getOriginatingUSN());
-                if (rec.getChangeRecordNewData()!=null)
-                
r.setRecordType(org.apache.juddi.model.ChangeRecord.RecordType.ChangeRecordNewData);
-                else if (rec.getChangeRecordAcknowledgement()!=null)
+                if (rec.getChangeRecordNewData() != null) {
+                        
r.setRecordType(org.apache.juddi.model.ChangeRecord.RecordType.ChangeRecordNewData);
+                } else if (rec.getChangeRecordAcknowledgement() != null) {
                         
r.setRecordType(org.apache.juddi.model.ChangeRecord.RecordType.ChangeRecordAcknowledgement);
-                else if (rec.getChangeRecordConditionFailed()!=null)
+                } else if (rec.getChangeRecordConditionFailed() != null) {
                         
r.setRecordType(org.apache.juddi.model.ChangeRecord.RecordType.ChangeRecordConditionFailed);
-                else if (rec.getChangeRecordCorrection()!=null)
+                } else if (rec.getChangeRecordCorrection() != null) {
                         
r.setRecordType(org.apache.juddi.model.ChangeRecord.RecordType.ChangeRecordCorrection);
-                else if (rec.getChangeRecordDelete()!=null)
+                } else if (rec.getChangeRecordDelete() != null) {
                         
r.setRecordType(org.apache.juddi.model.ChangeRecord.RecordType.ChangeRecordDelete);
-                else if (rec.getChangeRecordDeleteAssertion()!=null)
+                } else if (rec.getChangeRecordDeleteAssertion() != null) {
                         
r.setRecordType(org.apache.juddi.model.ChangeRecord.RecordType.ChangeRecordDeleteAssertion);
-                else if (rec.getChangeRecordHide()!=null)
+                } else if (rec.getChangeRecordHide() != null) {
                         
r.setRecordType(org.apache.juddi.model.ChangeRecord.RecordType.ChangeRecordHide);
-                else if (rec.getChangeRecordNewDataConditional()!=null)
+                } else if (rec.getChangeRecordNewDataConditional() != null) {
                         
r.setRecordType(org.apache.juddi.model.ChangeRecord.RecordType.ChangeRecordNewDataConditional);
-                else if (rec.getChangeRecordNull()!=null)
+                } else if (rec.getChangeRecordNull() != null) {
                         
r.setRecordType(org.apache.juddi.model.ChangeRecord.RecordType.ChangeRecordNull);
-                else if (rec.getChangeRecordPublisherAssertion()!=null)
+                } else if (rec.getChangeRecordPublisherAssertion() != null) {
                         
r.setRecordType(org.apache.juddi.model.ChangeRecord.RecordType.ChangeRecordPublisherAssertion);
+                } else {
+                        throw new UnsupportedEncodingException("unknown 
type!");
+                }
                 r.setNodeID(rec.getChangeID().getNodeID());
+
                 StringWriter sw = new StringWriter();
                 JAXB.marshal(rec, sw);
                 r.setContents(sw.toString().getBytes("UTF8"));
@@ -1428,7 +1432,7 @@ public class MappingApiToModel {
                 model.setNodeId(operationalInfo.getNodeID());
 
         }
-        
+
         public static void mapOperationalInfoIncludingChildren(BusinessEntity 
model, OperationalInfo operationalInfo) {
                 if (operationalInfo == null || model == null) {
                         return;
@@ -1444,11 +1448,11 @@ public class MappingApiToModel {
                         
model.setModifiedIncludingChildren(operationalInfo.getModifiedIncludingChildren().toGregorianCalendar().getTime());
                 }
                 model.setNodeId(operationalInfo.getNodeID());
-                for (int i=0; i < model.getBusinessServices().size(); i++)
-                {
-                       mapOperationalInfo( model.getBusinessServices().get(i), 
operationalInfo);
-                       for (int k=0; k < 
model.getBusinessServices().get(i).getBindingTemplates().size(); k++)
-                               mapOperationalInfo( 
model.getBusinessServices().get(i).getBindingTemplates().get(k), 
operationalInfo);
+                for (int i = 0; i < model.getBusinessServices().size(); i++) {
+                        mapOperationalInfo(model.getBusinessServices().get(i), 
operationalInfo);
+                        for (int k = 0; k < 
model.getBusinessServices().get(i).getBindingTemplates().size(); k++) {
+                                
mapOperationalInfo(model.getBusinessServices().get(i).getBindingTemplates().get(k),
 operationalInfo);
+                        }
                 }
 
         }
@@ -1466,7 +1470,7 @@ public class MappingApiToModel {
                 
model.setMaximumTimeToSyncRegistry(replicationConfiguration.getMaximumTimeToSyncRegistry());
                 //this is set by the service when saving
                 model.setSerialNumber(null);
-               
+
                 //the spec doesn't specify what the format should be, however 
there was an example
                 //2002 03 04 1859Z
                 SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddkkmmZ");
@@ -1475,7 +1479,7 @@ public class MappingApiToModel {
                         
model.setContact(mapContact(replicationConfiguration.getRegistryContact().getContact(),
 model));
                 }
                 mapCommunicationGraph(model, 
replicationConfiguration.getCommunicationGraph(), em);
-                
model.setOperator(mapOperators(replicationConfiguration,model));
+                model.setOperator(mapOperators(replicationConfiguration, 
model));
                 if (replicationConfiguration.getSignature() != null) {
                         
model.setSignatures(mapApiSignaturesToModelSignatures(replicationConfiguration.getSignature()));
                 }
@@ -1494,7 +1498,9 @@ public class MappingApiToModel {
         }
 
         private static List<Operator> mapOperators(ReplicationConfiguration 
cfg, org.apache.juddi.model.ReplicationConfiguration modelparent) throws 
DispositionReportFaultMessage {
-                if (cfg==null) return null;
+                if (cfg == null) {
+                        return null;
+                }
                 List<org.uddi.repl_v3.Operator> api = cfg.getOperator();
                 if (api == null) {
                         return null;
@@ -1503,7 +1509,7 @@ public class MappingApiToModel {
                 for (int i = 0; i < api.size(); i++) {
                         Operator op = new Operator();
                         op.setParent(modelparent);
-                       
+
                         
op.setSoapReplicationURL(api.get(i).getSoapReplicationURL());
 
                         if (!api.get(i).getContact().isEmpty()) {
@@ -1553,7 +1559,6 @@ public class MappingApiToModel {
                 if (model == null) {
                         return;
                 }
-                
 
                 /**
                  * Following the listing of nodes is the controlledMessage
@@ -1572,11 +1577,11 @@ public class MappingApiToModel {
                         for (int k = 0; k < 
communicationGraph.getControlledMessage().size(); k++) {
                                 ControlMessage BC = new 
ControlMessage(communicationGraph.getControlledMessage().get(k));
                                 BC.setReplicationConfiguration(model);
-                                
+
                                 model.getControlMessage().add(BC);
                         }
                 }
-                
+
                 for (int i = 0; i < communicationGraph.getNode().size(); i++) {
                         ReplicationConfigurationNode 
replicationConfigurationNode = new ReplicationConfigurationNode();
 
@@ -1589,9 +1594,9 @@ public class MappingApiToModel {
                         for (int i = 0; i < 
communicationGraph.getEdge().size(); i++) {
                                 Edge e = new Edge();
                                 e.setReplicationConfiguration(model);
-                                
+
                                 
e.setMessageReceiver(communicationGraph.getEdge().get(i).getMessageReceiver());
-                               
e.setMessageSender(communicationGraph.getEdge().get(i).getMessageSender());
+                                
e.setMessageSender(communicationGraph.getEdge().get(i).getMessageSender());
 
                                 /**
                                  * The message elements contain the local name
@@ -1612,14 +1617,14 @@ public class MappingApiToModel {
                                 }
                                 if 
(communicationGraph.getEdge().get(i).getMessageReceiverAlternate() != null) {
                                         List<EdgeReceiverAlternate> eras = new 
ArrayList<EdgeReceiverAlternate>();
-                                        for (String s: 
communicationGraph.getEdge().get(i).getMessageReceiverAlternate() ){
+                                        for (String s : 
communicationGraph.getEdge().get(i).getMessageReceiverAlternate()) {
                                                 EdgeReceiverAlternate x = new 
EdgeReceiverAlternate();
                                                 x.setParent(e);
                                                 x.setReceiverAlternate(s);
                                                 eras.add(x);
                                         }
                                         e.setMessageReceiverAlternate(eras);
-                                      
+
                                 }
 
                                 ret.add(e);
@@ -1643,11 +1648,11 @@ public class MappingApiToModel {
                         
model.setModifiedIncludingChildren(operationalInfo.getModifiedIncludingChildren().toGregorianCalendar().getTime());
                 }
                 model.setNodeId(operationalInfo.getNodeID());
-               
-                       for (int k=0; k < model.getBindingTemplates().size(); 
k++)
-                               mapOperationalInfo( 
model.getBindingTemplates().get(k), operationalInfo);
-                
+
+                for (int k = 0; k < model.getBindingTemplates().size(); k++) {
+                        mapOperationalInfo(model.getBindingTemplates().get(k), 
operationalInfo);
+                }
+
         }
 
-        
 }

http://git-wip-us.apache.org/repos/asf/juddi/blob/d0bbde64/juddi-core/src/main/java/org/apache/juddi/validation/ValidateCustodyTransfer.java
----------------------------------------------------------------------
diff --git 
a/juddi-core/src/main/java/org/apache/juddi/validation/ValidateCustodyTransfer.java
 
b/juddi-core/src/main/java/org/apache/juddi/validation/ValidateCustodyTransfer.java
index 14b6d56..55d51e3 100644
--- 
a/juddi-core/src/main/java/org/apache/juddi/validation/ValidateCustodyTransfer.java
+++ 
b/juddi-core/src/main/java/org/apache/juddi/validation/ValidateCustodyTransfer.java
@@ -14,7 +14,6 @@
  * limitations under the License.
  *
  */
-
 package org.apache.juddi.validation;
 
 import java.util.ArrayList;
@@ -47,165 +46,194 @@ import org.uddi.v3_service.DispositionReportFaultMessage;
  */
 public class ValidateCustodyTransfer extends ValidateUDDIApi {
 
-       public ValidateCustodyTransfer(UddiEntityPublisher publisher) {
-               super(publisher);
-       }
-       
-       public void validateDiscardTransferToken(EntityManager em, 
DiscardTransferToken body) throws DispositionReportFaultMessage {
-               // No null input
-               if (body == null)
-                       throw new FatalErrorException(new 
ErrorMessage("errors.NullInput"));
-               
-               KeyBag keyBag = body.getKeyBag();
-               
-               // The call must contain at least a transfer token or keyBag
-               if (body.getTransferToken() == null && keyBag == null)
-                       throw new FatalErrorException(new 
ErrorMessage("errors.discardtransfertoken.NoInput"));
-               
-               if (keyBag != null) {
-                       List<String> keyList = keyBag.getKey();
-                       if (keyList == null || keyList.size() == 0)
-                               throw new ValueNotAllowedException(new 
ErrorMessage("errors.keybag.NoInput"));
-                       
-                       // Test that publisher owns keys using operational info.
-                       int i = 0;
-                       for (String key : keyList) {
-                               // Per section 4.4: keys must be case-folded
-                               key = key.toLowerCase();
-                               keyList.set(i, key);
-                               
-                               UddiEntity uddiEntity = 
em.find(UddiEntity.class, key);
-                               
+        public ValidateCustodyTransfer(UddiEntityPublisher publisher) {
+                super(publisher);
+        }
+
+        public void validateDiscardTransferToken(EntityManager em, 
DiscardTransferToken body) throws DispositionReportFaultMessage {
+                // No null input
+                if (body == null) {
+                        throw new FatalErrorException(new 
ErrorMessage("errors.NullInput"));
+                }
+
+                KeyBag keyBag = body.getKeyBag();
+
+                // The call must contain at least a transfer token or keyBag
+                if (body.getTransferToken() == null && keyBag == null) {
+                        throw new FatalErrorException(new 
ErrorMessage("errors.discardtransfertoken.NoInput"));
+                }
+
+                if (keyBag != null) {
+                        List<String> keyList = keyBag.getKey();
+                        if (keyList == null || keyList.size() == 0) {
+                                throw new ValueNotAllowedException(new 
ErrorMessage("errors.keybag.NoInput"));
+                        }
+
+                        // Test that publisher owns keys using operational 
info.
+                        int i = 0;
+                        for (String key : keyList) {
+                                // Per section 4.4: keys must be case-folded
+                                key = key.toLowerCase();
+                                keyList.set(i, key);
+
+                                UddiEntity uddiEntity = 
em.find(UddiEntity.class, key);
+
                                // According to spec, it's ok if a key doesn't 
match any known entities, it will just be ignored.  However, the publisher must 
own
-                               // the entity in order to discard the 
associated token.
-                               if (uddiEntity != null) {
-                                       if (!publisher.isOwner(uddiEntity))
-                                               throw new 
UserMismatchException(new ErrorMessage("errors.usermismatch.InvalidOwner", 
key));
-                                       
-                               }
-                       
-                               i++;
-                       }
-               
-               }
-               
-       }
-       
-       public void validateGetTransferToken(EntityManager em, KeyBag keyBag) 
throws DispositionReportFaultMessage {
-
-               // No null input
-               if (keyBag == null)
-                       throw new FatalErrorException(new 
ErrorMessage("errors.NullInput"));
-               
-               List<String> keyList = keyBag.getKey();
-               if (keyList == null || keyList.size() == 0)
-                       throw new ValueNotAllowedException(new 
ErrorMessage("errors.keybag.NoInput"));
-               
-               // Test that publisher owns keys using operational info.
-               Vector<DynamicQuery.Parameter> params = new 
Vector<DynamicQuery.Parameter>(0);
-               int i = 0;
-               for (String key : keyList) {
-                       // Per section 4.4: keys must be case-folded
-                       key = key.toLowerCase();
-                       keyList.set(i, key);
-
-                       UddiEntity uddiEntity = em.find(UddiEntity.class, key);
-                       
-                       if (uddiEntity == null)
-                               throw new InvalidKeyPassedException(new 
ErrorMessage("errors.invalidkey.EntityNotFound", key));
-                       
-                       // Only BusinessEntities or TModels are allowed to be 
transferred
-                       if (!(uddiEntity instanceof 
org.apache.juddi.model.BusinessEntity) &&
-                               !(uddiEntity instanceof 
org.apache.juddi.model.Tmodel))
-                               throw new InvalidKeyPassedException(new 
ErrorMessage("errors.gettransfertoken.InvalidEntity", key));
-                       
-                       if (!publisher.isOwner(uddiEntity))
-                               throw new UserMismatchException(new 
ErrorMessage("errors.usermismatch.InvalidOwner", key));
-                       
-                       // Creating parameters for key-checking query
-                       DynamicQuery.Parameter param = new 
DynamicQuery.Parameter("UPPER(ttk.entityKey)",   
-                                key.toUpperCase(), 
+                                // the entity in order to discard the 
associated token.
+                                if (uddiEntity != null) {
+                                        if (!publisher.isOwner(uddiEntity)) {
+                                                throw new 
UserMismatchException(new ErrorMessage("errors.usermismatch.InvalidOwner", 
key));
+                                        }
+
+                                }
+
+                                i++;
+                        }
+
+                }
+
+        }
+
+        public void validateGetTransferToken(EntityManager em, KeyBag keyBag) 
throws DispositionReportFaultMessage {
+
+                // No null input
+                if (keyBag == null) {
+                        throw new FatalErrorException(new 
ErrorMessage("errors.NullInput"));
+                }
+
+                List<String> keyList = keyBag.getKey();
+                if (keyList == null || keyList.size() == 0) {
+                        throw new ValueNotAllowedException(new 
ErrorMessage("errors.keybag.NoInput"));
+                }
+
+                // Test that publisher owns keys using operational info.
+                Vector<DynamicQuery.Parameter> params = new 
Vector<DynamicQuery.Parameter>(0);
+                int i = 0;
+                for (String key : keyList) {
+                        // Per section 4.4: keys must be case-folded
+                        key = key.toLowerCase();
+                        keyList.set(i, key);
+
+                        UddiEntity uddiEntity = em.find(UddiEntity.class, key);
+
+                        if (uddiEntity == null) {
+                                throw new InvalidKeyPassedException(new 
ErrorMessage("errors.invalidkey.EntityNotFound", key));
+                        }
+
+                        // Only BusinessEntities or TModels are allowed to be 
transferred
+                        if (!(uddiEntity instanceof 
org.apache.juddi.model.BusinessEntity)
+                                && !(uddiEntity instanceof 
org.apache.juddi.model.Tmodel)) {
+                                throw new InvalidKeyPassedException(new 
ErrorMessage("errors.gettransfertoken.InvalidEntity", key));
+                        }
+
+                        if (!publisher.isOwner(uddiEntity)) {
+                                throw new UserMismatchException(new 
ErrorMessage("errors.usermismatch.InvalidOwner", key));
+                        }
+
+                        // Creating parameters for key-checking query
+                        DynamicQuery.Parameter param = new 
DynamicQuery.Parameter("UPPER(ttk.entityKey)",
+                                key.toUpperCase(),
                                 DynamicQuery.PREDICATE_EQUALS);
-                       params.add(param);
+                        params.add(param);
+
+                }
+
+                // Make sure keys aren't implicated in another transfer request
+                DynamicQuery checkKeysQry = new DynamicQuery();
+                checkKeysQry.append("select ttk.entityKey from 
TransferTokenKey ttk ");
+                checkKeysQry.WHERE().pad().appendGroupedOr(params.toArray(new 
DynamicQuery.Parameter[0]));
+
+                Query qry = checkKeysQry.buildJPAQuery(em);
+                List<?> obj = qry.getResultList();
+                if (obj != null && obj.size() > 0) {
+                        throw new TokenAlreadyExistsException(new 
ErrorMessage("errors.gettransfertoken.KeyExists", (String) obj.get(0)));
+                }
 
-               }
+        }
+        
+        public void validateTransferLocalEntities(EntityManager em, String 
transferTokenId, List<String> apiKeyList) throws DispositionReportFaultMessage {
+                org.apache.juddi.model.TransferToken modelTransferToken = 
em.find(org.apache.juddi.model.TransferToken.class, transferTokenId);
+                        //JUDDI-272 only block transfer if the destination is 
not the originator of the token
+                        if (modelTransferToken == null) {
+                                throw new TransferNotAllowedException(new 
ErrorMessage("errors.transferentities.TokenNotFound", transferTokenId));
+                        }
 
-               // Make sure keys aren't implicated in another transfer request
-               DynamicQuery checkKeysQry = new DynamicQuery();
-               checkKeysQry.append("select ttk.entityKey from TransferTokenKey 
ttk ");
-               checkKeysQry.WHERE().pad().appendGroupedOr(params.toArray(new 
DynamicQuery.Parameter[0]));
+                        Date now = new Date();
+                        if (now.after(modelTransferToken.getExpirationDate())) 
{
+                                throw new TransferNotAllowedException(new 
ErrorMessage("errors.transferentities.TokenExpired", transferTokenId));
+                        }
 
-               Query qry = checkKeysQry.buildJPAQuery(em);
-               List<?> obj = qry.getResultList();
-               if (obj != null && obj.size() > 0)
-                       throw new TokenAlreadyExistsException(new 
ErrorMessage("errors.gettransfertoken.KeyExists", (String)obj.get(0)));
+                        List<TransferTokenKey> transferKeyList = 
modelTransferToken.getTransferKeys();
+                        List<String> modelKeyList = new ArrayList<String>(0);
+                        if (transferKeyList != null && transferKeyList.size() 
> 0) {
+                                for (TransferTokenKey ttk : transferKeyList) {
+                                        modelKeyList.add(ttk.getEntityKey());
+                                }
+                        }
+
+                        // The keys in the supplied key bag must match exactly 
the keys in the stored transfer and the entities must exist
+                        Collections.sort(apiKeyList);
+                        Collections.sort(modelKeyList);
+                        int count = 0;
+                        if (modelKeyList.size() != apiKeyList.size()) {
+                                throw new TransferNotAllowedException(new 
ErrorMessage("errors.transferentities.KeySizeMismatch"));
+                        }
+                        for (String key : apiKeyList) {
+                                // Per section 4.4: keys must be case-folded
+                                key = key.toLowerCase();
+                                apiKeyList.set(count, key);
+
+                                if 
(!key.equalsIgnoreCase(modelKeyList.get(count))) {
+                                        throw new 
TransferNotAllowedException(new 
ErrorMessage("errors.transferentities.KeyMismatch", key + " & " + 
modelKeyList.get(count)));
+                                }
+
+                                UddiEntity uddiEntity = 
em.find(UddiEntity.class, key);
+                                if (uddiEntity == null) {
+                                        throw new 
InvalidKeyPassedException(new ErrorMessage("errors.invalidkey.EntityNotFound", 
key));
+                                }
+                                count++;
+                        }
+
+        }
 
-       }
-       
         /**
-         * returns true if all items to be transfered are within this node (no 
node to node transfers)
+         * returns true if all items to be transfered are within this node (no
+         * node to node transfers) false for transfer between nodes
+         *
          * @param em
          * @param body
          * @return
-         * @throws DispositionReportFaultMessage 
+         * @throws DispositionReportFaultMessage
          */
-       public boolean validateTransferEntities(EntityManager em, 
TransferEntities body) throws DispositionReportFaultMessage {
+        public boolean validateTransferEntities(EntityManager em, 
TransferEntities body) throws DispositionReportFaultMessage {
 
                 boolean ret = true;
-               // No null input
-               if (body == null)
-                       throw new FatalErrorException(new 
ErrorMessage("errors.NullInput"));
-               
-               org.uddi.custody_v3.TransferToken apiTransferToken = 
body.getTransferToken();
-               if (apiTransferToken == null)
-                       throw new FatalErrorException(new 
ErrorMessage("errors.transfertoken.NullInput"));
-               
-               KeyBag keyBag = body.getKeyBag();
-               if (keyBag == null)
-                       throw new FatalErrorException(new 
ErrorMessage("errors.keybag.NullInput"));
-               
-               List<String> apiKeyList = keyBag.getKey();
-               if (apiKeyList == null || apiKeyList.size() == 0)
-                       throw new ValueNotAllowedException(new 
ErrorMessage("errors.keybag.NoInput"));
-               
-               String transferTokenId = new 
String(apiTransferToken.getOpaqueToken());
-               org.apache.juddi.model.TransferToken modelTransferToken = 
em.find(org.apache.juddi.model.TransferToken.class, transferTokenId);
-               if (modelTransferToken == null)
-                       throw new TransferNotAllowedException(new 
ErrorMessage("errors.transferentities.TokenNotFound", transferTokenId));
-               
-               Date now = new Date();
-               if (now.after(modelTransferToken.getExpirationDate()))
-                       throw new TransferNotAllowedException(new 
ErrorMessage("errors.transferentities.TokenExpired", transferTokenId));
-               
-               List<TransferTokenKey> transferKeyList = 
modelTransferToken.getTransferKeys();
-               List<String> modelKeyList = new ArrayList<String>(0);
-               if (transferKeyList != null && transferKeyList.size() > 0) {
-                       for (TransferTokenKey ttk : transferKeyList)
-                               modelKeyList.add(ttk.getEntityKey());
-               }
-               
-               // The keys in the supplied key bag must match exactly the keys 
in the stored transfer and the entities must exist
-               Collections.sort(apiKeyList);
-               Collections.sort(modelKeyList);
-               int count = 0;
-                if (modelKeyList.size()!=apiKeyList.size())
-                    throw new TransferNotAllowedException(new 
ErrorMessage("errors.transferentities.KeySizeMismatch"));
-               for (String key : apiKeyList) {
-                       // Per section 4.4: keys must be case-folded
-                       key = key.toLowerCase();
-                       apiKeyList.set(count, key);
-
-                       if (!key.equalsIgnoreCase(modelKeyList.get(count)))
-                               throw new TransferNotAllowedException(new 
ErrorMessage("errors.transferentities.KeyMismatch", key + " & " + 
modelKeyList.get(count)));
-                       
-                       UddiEntity uddiEntity = em.find(UddiEntity.class, key);
-                       if (uddiEntity == null)
-                               throw new InvalidKeyPassedException(new 
ErrorMessage("errors.invalidkey.EntityNotFound", key));
-                       if (!uddiEntity.getNodeId().equalsIgnoreCase(nodeID))
-                                ret = false;
-                       count++;
-               }
+                // No null input
+                if (body == null) {
+                        throw new FatalErrorException(new 
ErrorMessage("errors.NullInput"));
+                }
+
+                org.uddi.custody_v3.TransferToken apiTransferToken = 
body.getTransferToken();
+                if (apiTransferToken == null) {
+                        throw new FatalErrorException(new 
ErrorMessage("errors.transfertoken.NullInput"));
+                }
+
+                KeyBag keyBag = body.getKeyBag();
+                if (keyBag == null) {
+                        throw new FatalErrorException(new 
ErrorMessage("errors.keybag.NullInput"));
+                }
+
+                List<String> apiKeyList = keyBag.getKey();
+                if (apiKeyList == null || apiKeyList.size() == 0) {
+                        throw new ValueNotAllowedException(new 
ErrorMessage("errors.keybag.NoInput"));
+                }
 
+                String transferTokenId = new 
String(apiTransferToken.getOpaqueToken());
+                if (nodeID.equals(apiTransferToken.getNodeID())) {
+                        validateTransferLocalEntities(em, transferTokenId, 
apiKeyList);
+                } else {
+                        return false;
+                }
                 return ret;
-       }
+        }
 }

http://git-wip-us.apache.org/repos/asf/juddi/blob/d0bbde64/juddi-core/src/main/java/org/apache/juddi/validation/ValidateReplication.java
----------------------------------------------------------------------
diff --git 
a/juddi-core/src/main/java/org/apache/juddi/validation/ValidateReplication.java 
b/juddi-core/src/main/java/org/apache/juddi/validation/ValidateReplication.java
index 717b691..7884189 100644
--- 
a/juddi-core/src/main/java/org/apache/juddi/validation/ValidateReplication.java
+++ 
b/juddi-core/src/main/java/org/apache/juddi/validation/ValidateReplication.java
@@ -25,6 +25,7 @@ import org.apache.juddi.model.UddiEntityPublisher;
 import org.apache.juddi.v3.error.ErrorMessage;
 import org.apache.juddi.v3.error.FatalErrorException;
 import org.apache.juddi.v3.error.InvalidValueException;
+import org.apache.juddi.v3.error.TransferNotAllowedException;
 import org.apache.juddi.v3.error.ValueNotAllowedException;
 import org.uddi.custody_v3.TransferEntities;
 import org.uddi.repl_v3.CommunicationGraph.Edge;
@@ -182,18 +183,18 @@ public class ValidateReplication extends ValidateUDDIApi {
         public void validateTransfer(EntityManager em, TransferCustody body) 
throws DispositionReportFaultMessage {
                 
                  if (body == null)
-                       throw new FatalErrorException(new 
ErrorMessage("errors.NullInput"));
+                       throw new TransferNotAllowedException(new 
ErrorMessage("errors.NullInput"));
                if (body.getTransferToken()==null)
-                        throw new FatalErrorException(new 
ErrorMessage("errors.NullInput"));
+                        throw new TransferNotAllowedException(new 
ErrorMessage("errors.NullInput"));
                 if (body.getKeyBag()==null)
-                        throw new FatalErrorException(new 
ErrorMessage("errors.NullInput"));
+                        throw new TransferNotAllowedException(new 
ErrorMessage("errors.NullInput"));
                 if (body.getTransferOperationalInfo()==null)
-                        throw new FatalErrorException(new 
ErrorMessage("errors.NullInput"));
+                        throw new TransferNotAllowedException(new 
ErrorMessage("errors.NullInput"));
                 
                  if (body.getTransferOperationalInfo().getNodeID()==null)
-                        throw new FatalErrorException(new 
ErrorMessage("errors.NullInput"));
+                        throw new TransferNotAllowedException(new 
ErrorMessage("errors.NullInput"));
                  if 
(body.getTransferOperationalInfo().getAuthorizedName()==null)
-                        throw new FatalErrorException(new 
ErrorMessage("errors.NullInput"));
+                        throw new TransferNotAllowedException(new 
ErrorMessage("errors.NullInput"));
                 
                  
                 //confirm i own the records in question
@@ -202,7 +203,8 @@ public class ValidateReplication extends ValidateUDDIApi {
                 TransferEntities x = new TransferEntities();
                 x.setKeyBag(body.getKeyBag());
                 x.setTransferToken(body.getTransferToken());
-                new ValidateCustodyTransfer(null).validateTransferEntities(em, 
x);
+                String transferTokenId = new 
String(body.getTransferToken().getOpaqueToken());
+                new 
ValidateCustodyTransfer(null).validateTransferLocalEntities(em, 
transferTokenId, body.getKeyBag().getKey() );
                 
                
         }

http://git-wip-us.apache.org/repos/asf/juddi/blob/d0bbde64/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 bf11ed7..cdcace9 100644
--- a/juddi-core/src/main/resources/messages.properties
+++ b/juddi-core/src/main/resources/messages.properties
@@ -53,6 +53,7 @@ E_tooManyOptions=Too many options
 E_transferAborted=Transfer Aborted
 E_transferNotAllowed=The transfer request is not allowed
 E_transferNotAllowedUnknownNode=The transfer request is not allowed because 
the destination node is not in the replication config.
+E_transferBlocked=The transfer was blocked from it's originator (node to node 
transfer). 
 E_unknownUser=The user ID and password pair passed in a get_authToken API is 
not known to the UDDI node or is not valid.
 E_unrecognizedVersion=The value of the namespace attribute is unsupported by 
the node being queried.
 E_unsupported=Unsupported feature or API.


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to