]> git.aero2k.de Git - tmp/jakarta-migration.git/commitdiff
CSPACE-5728: Skip soft-deleted CollectionObject records when batch updating computedC...
authorAron Roberts <aron@socrates.berkeley.edu>
Thu, 10 Jan 2013 04:42:54 +0000 (20:42 -0800)
committerAron Roberts <aron@socrates.berkeley.edu>
Thu, 10 Jan 2013 04:42:54 +0000 (20:42 -0800)
services/IntegrationTests/src/test/resources/test-data/xmlreplay/batch/batch-update-object-loc.xml
services/batch/service/src/main/java/org/collectionspace/services/batch/nuxeo/UpdateObjectLocationBatchJob.java
services/common/src/main/java/org/collectionspace/services/common/AbstractMultiPartCollectionSpaceResourceImpl.java
services/common/src/main/java/org/collectionspace/services/common/ResourceBase.java

index d8bd2b63a2fdb3a1223a8088c3259f437db18a86..0f4e5d0ebf2b012dffa580ada0d0b429715bcf0d 100644 (file)
         </test>\r
         \r
         <!-- Test with a soft-deleted related Movement record -->\r
-        <test ID="softDeleteMovement2">\r
+        \r
+        <test ID="softDeleteMovement4">\r
             <method>PUT</method>\r
             <uri>/cspace-services/movements/${createMovement4.CSID}/workflow/delete</uri>\r
             <expectedCodes>200</expectedCodes>\r
             <expectedCodes>200</expectedCodes>\r
         </test>\r
         \r
+        <!-- Test with a soft-deleted CollectionObject record -->\r
+\r
+        <!-- After deleting Movement record 2 outright, the computedCurrentLocation -->\r
+        <!-- value should then be drawn from the currentLocation value of Movement record 1, -->\r
+        <!-- the next most-recent Movement record. -->\r
+        <test ID="deleteMovement2">\r
+            <method>DELETE</method>\r
+            <uri>/cspace-services/movements/${createMovement2.CSID}</uri>\r
+            <expectedCodes>200</expectedCodes>\r
+        </test>\r
+        \r
+        <!-- However, now we soft-delete the CollectionObject record itself. -->\r
+        <test ID="softDeleteCollectionObject">\r
+            <method>PUT</method>\r
+            <uri>/cspace-services/collectionobjects/${createCollectionObject.CSID}/workflow/delete</uri>\r
+            <expectedCodes>200</expectedCodes>\r
+            <filename>relation/res/workflowState.res.xml</filename>\r
+            <vars>\r
+                <var ID="workflowState">deleted</var>\r
+            </vars>\r
+        </test>\r
+        \r
+        <test ID="invokeBatchAfterSoftDeletingCollectionObject" auth="test" autoDeletePOSTS="false">\r
+            <method>POST</method>\r
+            <uri>/cspace-services/batch/${createBatchRecord.CSID}</uri>\r
+            <filename>batch/batch-invoke-updateobjloc-single.xml</filename>\r
+            <vars>\r
+                <var ID="collectionObjectCSID">${createCollectionObject.CSID}</var>\r
+            </vars>\r
+            <expectedCodes>200</expectedCodes>\r
+        </test>\r
+        \r
+        <!-- On re-reading the CollectionObject, its computedCurrentLocation -->\r
+        <!-- value should remain at its value prior to its having been soft-deleted. -->\r
+        <test ID="readUpdatedCollectionObjectRecordAfterSoftDeletion">\r
+            <method>GET</method>\r
+            <uri>/cspace-services/collectionobjects/${createCollectionObject.CSID}</uri>\r
+            <filename>batch/updateobjloc.xml</filename>\r
+            <response>\r
+                <expected level="ADDOK" />\r
+                <filename>batch/res/collectionobject.res.xml</filename>\r
+                <vars>\r
+                    <var ID="computedCurrentLocationValue">${createMovement2.currentLocation}</var>\r
+                </vars>\r
+            </response>\r
+            <expectedCodes>200</expectedCodes>\r
+        </test>\r
+        \r
     </testGroup>\r
     \r
     <testGroup ID="invocationModeModeList" autoDeletePOSTS="true">\r
index e7f721f1d78f57c4680b77795b65989af0830a9b..60be464f312e8f63a7b07dbd1ec2d3814bf53882 100644 (file)
@@ -10,17 +10,17 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 import javax.ws.rs.core.PathSegment;
+import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriInfo;
 import org.collectionspace.services.batch.AbstractBatchInvocable;
 import org.collectionspace.services.client.AbstractCommonListUtils;
 import org.collectionspace.services.client.CollectionObjectClient;
 import org.collectionspace.services.client.MovementClient;
-import org.collectionspace.services.client.workflow.WorkflowClient;
 import org.collectionspace.services.client.PoxPayloadOut;
+import org.collectionspace.services.client.workflow.WorkflowClient;
 import org.collectionspace.services.common.ResourceBase;
 import org.collectionspace.services.common.ResourceMap;
 import org.collectionspace.services.common.api.Tools;
-import org.collectionspace.services.common.invocable.InvocationContext;
 import org.collectionspace.services.common.invocable.InvocationResults;
 import org.collectionspace.services.jaxb.AbstractCommonList;
 import org.dom4j.DocumentException;
@@ -35,11 +35,20 @@ import org.slf4j.LoggerFactory;
 public class UpdateObjectLocationBatchJob extends AbstractBatchInvocable {
 
     // FIXME: Where appropriate, get from existing constants rather than local declarations
-    private final static String COLLECTIONOBJECTS_COMMON_SCHEMA_NAME = "collectionobjects_common";
     private final static String CSID_ELEMENT_NAME = "csid";
     private final static String CURRENT_LOCATION_ELEMENT_NAME = "currentLocation";
+    private final static String LIFECYCLE_STATE_ELEMENT_NAME = "currentLifeCycleState";
     private final static String LOCATION_DATE_ELEMENT_NAME = "locationDate";
     private final static String OBJECT_NUMBER_ELEMENT_NAME = "objectNumber";
+    private final static String WORKFLOW_COMMON_SCHEMA_NAME = "workflow_common";
+    private final static String WORKFLOW_COMMON_NAMESPACE_PREFIX = "ns2";
+    private final static String WORKFLOW_COMMON_NAMESPACE_URI =
+            "http://collectionspace.org/services/workflow";
+    private final static Namespace WORKFLOW_COMMON_NAMESPACE =
+            Namespace.getNamespace(
+            WORKFLOW_COMMON_NAMESPACE_PREFIX,
+            WORKFLOW_COMMON_NAMESPACE_URI);
+    private final static String COLLECTIONOBJECTS_COMMON_SCHEMA_NAME = "collectionobjects_common";
     private final static String COLLECTIONOBJECTS_COMMON_NAMESPACE_PREFIX = "ns2";
     private final static String COLLECTIONOBJECTS_COMMON_NAMESPACE_URI =
             "http://collectionspace.org/services/collectionobject";
@@ -47,6 +56,9 @@ public class UpdateObjectLocationBatchJob extends AbstractBatchInvocable {
             Namespace.getNamespace(
             COLLECTIONOBJECTS_COMMON_NAMESPACE_PREFIX,
             COLLECTIONOBJECTS_COMMON_NAMESPACE_URI);
+    private final static String NONDELETED_QUERY_COMPONENT =
+            "&" + WorkflowClient.WORKFLOW_QUERY_NONDELETED + "=false";
+    private PoxPayloadOut payloadOut;
     private final String CLASSNAME = this.getClass().getSimpleName();
     private final Logger logger = LoggerFactory.getLogger(this.getClass());
 
@@ -128,7 +140,6 @@ public class UpdateObjectLocationBatchJob extends AbstractBatchInvocable {
     // #################################################################
     // Other convenience methods
     // #################################################################
-    
     protected UriInfo createRelatedRecordsUriInfo(String query) throws URISyntaxException {
         URI uri = new URI(null, null, null, query, null);
         return createUriInfo(uri.getRawQuery());
@@ -161,6 +172,21 @@ public class UpdateObjectLocationBatchJob extends AbstractBatchInvocable {
         return value;
     }
 
+    private boolean isRecordDeleted(ResourceBase resource, String collectionObjectCsid) throws URISyntaxException, DocumentException {
+        boolean isDeleted = false;
+        byte[] workflowResponse = resource.getWorkflow(createUriInfo(), collectionObjectCsid);
+        if (workflowResponse != null) {
+            payloadOut = new PoxPayloadOut(workflowResponse);
+            String workflowState =
+                    getFieldElementValue(payloadOut, WORKFLOW_COMMON_SCHEMA_NAME,
+                    WORKFLOW_COMMON_NAMESPACE, LIFECYCLE_STATE_ELEMENT_NAME);
+            if (Tools.notBlank(workflowState) && workflowState.contentEquals(WorkflowClient.WORKFLOWSTATE_DELETED)) {
+                isDeleted = true;
+            }
+        }
+        return isDeleted;
+    }
+
     private InvocationResults updateComputedCurrentLocations(List<String> csids) {
 
         ResourceMap resourcemap = getResourceMap();
@@ -170,6 +196,8 @@ public class UpdateObjectLocationBatchJob extends AbstractBatchInvocable {
         String computedCurrentLocation;
         String objectNumber;
         String movementCsid;
+        PoxPayloadOut payloadOut;
+        String queryString;
         int numAffected = 0;
 
         try {
@@ -177,7 +205,11 @@ public class UpdateObjectLocationBatchJob extends AbstractBatchInvocable {
             // For each CollectionObject record
             for (String collectionObjectCsid : csids) {
 
-                if (recordIsDeleted(collectionObjectCsid)) {
+                // Skip over soft-deleted CollectionObject records
+                if (isRecordDeleted(collectionObjectResource, collectionObjectCsid)) {
+                    if (logger.isTraceEnabled()) {
+                        logger.trace("Skipping soft-deleted CollectionObject record with CSID " + collectionObjectCsid);
+                    }
                     continue;
                 }
 
@@ -185,28 +217,26 @@ public class UpdateObjectLocationBatchJob extends AbstractBatchInvocable {
 
                 // Get movement records related to this record where the CollectionObject
                 // record is the subject of the relation
-                // FIXME: Get query string(s) from constant(s)
-                String queryString = "rtObj=" + collectionObjectCsid
-                        + "&" + WorkflowClient.WORKFLOW_QUERY_NONDELETED + "=false";
+                // FIXME: Get query string(s) from constant(s), where appropriate
+                queryString = "rtObj=" + collectionObjectCsid + NONDELETED_QUERY_COMPONENT;
                 UriInfo uriInfo = createRelatedRecordsUriInfo(queryString);
 
                 AbstractCommonList relatedMovements = movementResource.getList(uriInfo);
                 if (logger.isTraceEnabled()) {
                     logger.trace("Identified " + relatedMovements.getTotalItems()
-                            + " Movement records related to the object CollectionObject record " + collectionObjectCsid);
+                            + " Movement record(s) related to the object CollectionObject record " + collectionObjectCsid);
                 }
 
                 // Get movement records related to this record where the CollectionObject
                 // record is the object of the relation
-                // FIXME: Get query string(s) from constant(s)
-                queryString = "rtSbj=" + collectionObjectCsid
-                        + "&" + WorkflowClient.WORKFLOW_QUERY_NONDELETED + "=false";
+                // FIXME: Get query string(s) from constant(s), where appropriate
+                queryString = "rtSbj=" + collectionObjectCsid + NONDELETED_QUERY_COMPONENT;
                 uriInfo = createRelatedRecordsUriInfo(queryString);
 
                 AbstractCommonList reverseRelatedMovements = movementResource.getList(uriInfo);
                 if (logger.isTraceEnabled()) {
                     logger.trace("Identified " + reverseRelatedMovements.getTotalItems()
-                            + " Movement records related to the subject CollectionObject record " + collectionObjectCsid);
+                            + " Movement record(s) related to the subject CollectionObject record " + collectionObjectCsid);
                 }
 
                 if ((relatedMovements.getTotalItems() == 0) && reverseRelatedMovements.getTotalItems() == 0) {
@@ -215,6 +245,11 @@ public class UpdateObjectLocationBatchJob extends AbstractBatchInvocable {
 
                 // Merge the two lists of related movement records
                 relatedMovements.getListItem().addAll(reverseRelatedMovements.getListItem());
+                
+                if (logger.isTraceEnabled()) {
+                    logger.trace("Identified a total of " + relatedMovements.getListItem().size()
+                            + " Movement record(s) related to the subject CollectionObject record " + collectionObjectCsid);
+                }
 
                 // Get the latest movement record from among those, and extract
                 // its current location value
@@ -307,13 +342,8 @@ public class UpdateObjectLocationBatchJob extends AbstractBatchInvocable {
             return getResults();
         }
 
-        logger.info("Updated computedCurrentLocation values in " + numAffected + " CollectionObject records.");
+        logger.info("Updated computedCurrentLocation values in " + numAffected + " CollectionObject record(s).");
         getResults().setNumAffected(numAffected);
         return getResults();
     }
-
-    private boolean recordIsDeleted(String collectionObjectCsid) {
-        return false;
-        // throw new UnsupportedOperationException("Not yet implemented");
-    }
 }
index 726b1420d8557805d355be61340bd0145233ae3f..75bf77a5710f591e4870d5de236e2681f6802ec8 100644 (file)
@@ -176,6 +176,15 @@ public abstract class AbstractMultiPartCollectionSpaceResourceImpl extends Abstr
     public byte[] getWorkflow(\r
                @Context UriInfo uriInfo,\r
             @PathParam("csid") String csid) {\r
+        return getWorkflow(uriInfo, csid, null);\r
+        \r
+    }\r
+    \r
+    // Added to expose this functionality to batch jobs via the ResourceMap\r
+    // of ResourceBase classes.\r
+    //\r
+    // Argument 'params' is unused, and exists only to avoid duplicating method signatures.\r
+    public byte[] getWorkflow(UriInfo uriInfo, String csid, String params) {\r
         PoxPayloadOut result = null;\r
 \r
         try {\r
index 2d1dcb27f1e33072076be644943d376918d2016a..03e2c3532e5924f0098f921bc6abd3aa2e886242 100644 (file)
@@ -33,6 +33,7 @@ import org.collectionspace.services.client.IClientQueryParams;
 import org.collectionspace.services.client.IQueryManager;\r
 import org.collectionspace.services.client.PoxPayloadIn;\r
 import org.collectionspace.services.client.PoxPayloadOut;\r
+import org.collectionspace.services.client.workflow.WorkflowClient;\r
 \r
 import org.collectionspace.services.common.api.RefName;\r
 import org.collectionspace.services.common.api.Tools;\r