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/JUDDI-241 Commit: 7aa78f62cc66ff3484d105e293b361345a939b86 Parents: 455149a Author: Alex <[email protected]> Authored: Sat Nov 15 13:16:09 2014 -0500 Committer: Alex <[email protected]> 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:[email protected]">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: [email protected] For additional commands, e-mail: [email protected]
