]> git.aero2k.de Git - tmp/jakarta-migration.git/commitdiff
Adding support for POST and PUT vocabulary payloads containing term lists. Adding...
authorremillet <remillet@yahoo.com>
Sat, 20 Jan 2018 01:39:27 +0000 (17:39 -0800)
committerremillet <remillet@yahoo.com>
Sat, 20 Jan 2018 01:39:27 +0000 (17:39 -0800)
19 files changed:
services/IntegrationTests/src/main/java/org/collectionspace/services/IntegrationTests/xmlreplay/XmlReplay.java
services/IntegrationTests/src/main/java/org/collectionspace/services/IntegrationTests/xmlreplay/XmlReplayEval.java
services/IntegrationTests/src/main/java/org/collectionspace/services/IntegrationTests/xmlreplay/XmlReplayTransport.java
services/IntegrationTests/src/test/resources/test-data/xmlreplay/vocabulary/DeleteVocabJustItems/responses/DeleteVocabJustItems.res.xml [new file with mode: 0644]
services/IntegrationTests/src/test/resources/test-data/xmlreplay/vocabulary/DeleteVocabWithItems/objectExit.xml [new file with mode: 0644]
services/IntegrationTests/src/test/resources/test-data/xmlreplay/vocabulary/ReplaceVocabItems/replaceWithItems-vocab.xml [new file with mode: 0644]
services/IntegrationTests/src/test/resources/test-data/xmlreplay/vocabulary/ReplaceVocabItems/responses/ReplaceVocabItems.res.xml [new file with mode: 0644]
services/IntegrationTests/src/test/resources/test-data/xmlreplay/vocabulary/ShowItems/responses/showVocab.res.xml [moved from services/IntegrationTests/src/test/resources/test-data/xmlreplay/vocabulary/ShowItems/res/showVocab.res.xml with 100% similarity]
services/IntegrationTests/src/test/resources/test-data/xmlreplay/vocabulary/ShowItems/responses/showVocabWithItems.res.xml [moved from services/IntegrationTests/src/test/resources/test-data/xmlreplay/vocabulary/ShowItems/res/showVocabWithItems.res.xml with 100% similarity]
services/IntegrationTests/src/test/resources/test-data/xmlreplay/vocabulary/ShowItems/responses/showVocabWithItemsLastPage.res.xml [moved from services/IntegrationTests/src/test/resources/test-data/xmlreplay/vocabulary/ShowItems/res/showVocabWithItemsLastPage.res.xml with 100% similarity]
services/IntegrationTests/src/test/resources/test-data/xmlreplay/vocabulary/ShowItems/responses/showVocabWithItemsPaged.res.xml [moved from services/IntegrationTests/src/test/resources/test-data/xmlreplay/vocabulary/ShowItems/res/showVocabWithItemsPaged.res.xml with 100% similarity]
services/IntegrationTests/src/test/resources/test-data/xmlreplay/vocabulary/ShowItems/showItems-item-template.xml
services/IntegrationTests/src/test/resources/test-data/xmlreplay/vocabulary/responses/GetVocabularyItems.res.xml [moved from services/IntegrationTests/src/test/resources/test-data/xmlreplay/vocabulary/res/GetVocabularyItems.res.xml with 100% similarity]
services/IntegrationTests/src/test/resources/test-data/xmlreplay/vocabulary/vocab-Item-template.xml [new file with mode: 0644]
services/IntegrationTests/src/test/resources/test-data/xmlreplay/vocabulary/vocab-Template.xml [new file with mode: 0644]
services/IntegrationTests/src/test/resources/test-data/xmlreplay/vocabulary/vocabulary.xml
services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/AuthorityResource.java
services/common/src/main/java/org/collectionspace/services/common/document/DocumentReferenceException.java
services/vocabulary/service/src/main/java/org/collectionspace/services/vocabulary/VocabularyResource.java

index b9ae62c5c34c082656cb21a8ef5e6351e6fd2aaa..587a41906fffd4cab2dc3b576d3f845648c4149b 100644 (file)
@@ -3,6 +3,7 @@ package org.collectionspace.services.IntegrationTests.xmlreplay;
 import org.apache.commons.cli.*;
 
 import org.apache.commons.io.FileUtils;
+import org.apache.commons.jexl2.JexlContext;
 import org.apache.commons.jexl2.JexlEngine;
 import org.collectionspace.services.common.api.Tools;
 import org.dom4j.*;
@@ -247,7 +248,7 @@ public class XmlReplay {
         for (ServiceResult pr : serviceResultsMap.values()) {
             try {
                 if (pr.autoDelete == true && Tools.notEmpty(pr.deleteURL)){
-                    ServiceResult deleteResult = XmlReplayTransport.doDELETE(pr.deleteURL, defaultAuths.getDefaultAuth(), pr.testID, "[autodelete:"+logName+"]");
+                    ServiceResult deleteResult = XmlReplayTransport.doDELETE(pr.deleteURL, pr.adminAuth, pr.testID, "[autodelete:"+logName+"]");
                     if (deleteResult.gotExpectedResult() == false || deleteResult.responseCode != 200) {
                        reattemptList.put(REATTEMPT_KEY + deleteFailures++, pr); // We need to try again after our dependents have been deleted. cow()
                     }
@@ -347,21 +348,21 @@ public class XmlReplay {
         String startElement = "";
         String label = "";
 
-        public static PartsStruct readParts(Node testNode, final String testID, String xmlReplayBaseDir){
-            PartsStruct resultPartsStruct = new PartsStruct();
-            resultPartsStruct.responseFilename = testNode.valueOf("filename");
-            resultPartsStruct.startElement = testNode.valueOf("startElement");
-            resultPartsStruct.label = testNode.valueOf("label");
-            String responseFilename = testNode.valueOf("filename");
-            if (Tools.notEmpty(responseFilename)){
-                resultPartsStruct.responseFilename = xmlReplayBaseDir + '/' + responseFilename;
-                List<Node> varNodes = testNode.selectNodes("vars/var");
-                readVars(testNode, varNodes, resultPartsStruct);
-            }
-            return resultPartsStruct;
-        }
+               public static PartsStruct readParts(Node testNode, final String testID, String xmlReplayBaseDir) {
+                       PartsStruct resultPartsStruct = new PartsStruct();
+                       resultPartsStruct.responseFilename = testNode.valueOf("filename");
+                       resultPartsStruct.startElement = testNode.valueOf("startElement");
+                       resultPartsStruct.label = testNode.valueOf("label");
+                       String responseFilename = testNode.valueOf("filename");
+                       if (Tools.notEmpty(responseFilename)) {
+                               resultPartsStruct.responseFilename = xmlReplayBaseDir + '/' + responseFilename;
+                               List<Node> varNodes = testNode.selectNodes("vars/var");
+                               readVars(testNode, varNodes, resultPartsStruct);
+                       }
+                       return resultPartsStruct;
+               }
 
-        private static void readVars(Node testNode, List<Node> varNodes, PartsStruct resultPartsStruct){
+        private static void readVars(Node testNode, List<Node> varNodes, PartsStruct resultPartsStruct) {
             Map<String,String> vars = new HashMap<String,String>();
             resultPartsStruct.varsList.add(vars);
             //System.out.println("### vars: "+vars.size()+" ########");
@@ -476,7 +477,7 @@ public class XmlReplay {
 
     public static List<ServiceResult> runXmlReplayFile(String xmlReplayBaseDir,
                                           String controlFileName,
-                                          String testGroupID,
+                                          String targetedTestGroupID,
                                           String oneTestID,
                                           Map<String, ServiceResult> serviceResultsMap,
                                           boolean param_autoDeletePOSTS,
@@ -519,12 +520,12 @@ public class XmlReplay {
             authsMapINFO = "Using AuthsMap from control file: "+authsMap;
         }
 
-        report.addTestGroup(testGroupID, controlFileName);   //controlFileName is just the short name, without the full path.
+        report.addTestGroup(targetedTestGroupID, controlFileName);   //controlFileName is just the short name, without the full path.
         String xmlReplayHeader = "========================================================================"
                           +"\r\nXmlReplay running:"
                           +"\r\n   controlFile: "+ (new File(controlFile).getCanonicalPath())
                           +"\r\n   protoHostPort: "+protoHostPort
-                          +"\r\n   testGroup: "+testGroupID
+                          +"\r\n   testGroup: "+targetedTestGroupID
                           + (Tools.notEmpty(oneTestID) ? "\r\n   oneTestID: "+oneTestID : "")
                           +"\r\n   AuthsMap: "+authsMapINFO
                           +"\r\n   param_autoDeletePOSTS: "+param_autoDeletePOSTS
@@ -536,9 +537,10 @@ public class XmlReplay {
         System.out.println(xmlReplayHeader);
 
         String autoDeletePOSTS = "";
+        String authIDForCleanup = "";
         List<Node> testgroupNodes;
-        if (Tools.notEmpty(testGroupID)){
-            testgroupNodes = document.selectNodes("//testGroup[@ID='"+testGroupID+"']");
+        if (Tools.notEmpty(targetedTestGroupID)){
+            testgroupNodes = document.selectNodes("//testGroup[@ID='"+targetedTestGroupID+"']");
         } else {
             testgroupNodes = document.selectNodes("//testGroup");
         }
@@ -549,11 +551,25 @@ public class XmlReplay {
         evalStruct.jexl = jexl;
 
         for (Node testgroup : testgroupNodes) {
-
+               String testGroupID = testgroup.valueOf("@autoDeletePOSTS");
             XmlReplayEval.MapContextWKeys jc = new XmlReplayEval.MapContextWKeys();//MapContext();  //Get a new JexlContext for each test group.
             evalStruct.jc = jc;
-
             autoDeletePOSTS = testgroup.valueOf("@autoDeletePOSTS");
+            //
+            // Decide which auth to use for POST request cleanups
+            //
+            String authForCleanup = null;
+            authIDForCleanup = testgroup.valueOf("@authForCleanup");
+            if (Tools.isEmpty(authIDForCleanup) == false) {
+               authForCleanup = authsMap.map.get(authIDForCleanup);
+               if (Tools.isEmpty(authForCleanup)) {
+                       String msg = String.format("The 'authForCleanup' attribute value '%s' declared for test group '%s' is not defined.",
+                                       authIDForCleanup, testGroupID);
+                       throw new Exception(msg);
+                }
+            }
+            authForCleanup = authForCleanup != null ? authForCleanup : defaultAuths.getDefaultAuth();            
+            
             List<Node> tests;
             if (Tools.notEmpty(oneTestID)){
                 tests = testgroup.selectNodes("test[@ID='"+oneTestID+"']");
@@ -588,9 +604,13 @@ public class XmlReplay {
                     
                     String currentAuthForTest = null;
                     String authIDForTest = testNode.valueOf("@auth");
-                    
-                    if (Tools.notEmpty(authIDForTest)){
+                    if (Tools.notEmpty(authIDForTest)) {
                         currentAuthForTest = authsMap.map.get(authIDForTest);
+                        if (currentAuthForTest == null) {
+                               String msg = String.format("The 'auth' attribute value '%s' declared for test '%s' is not defined.",
+                                               authIDForTest, testIDLabel);
+                               throw new Exception(msg);
+                        }
                     } else {
                         String tokenAuthExpression = testNode.valueOf("@tokenauth");
                         if (Tools.notEmpty(tokenAuthExpression)){
@@ -598,12 +618,12 @@ public class XmlReplay {
                         }
                     }
                     
-                    if (Tools.notEmpty(currentAuthForTest)){
+                    if (Tools.notEmpty(currentAuthForTest)) {
                         authForTest = currentAuthForTest; //else just run with current from last loop;
                     }
-                    if (Tools.isEmpty(authForTest)){
+                    if (Tools.isEmpty(authForTest)) {
                         authForTest = defaultAuths.getDefaultAuth();
-                    }
+                    }                    
 
                     if (uri.indexOf("$")>-1){
                         uri = XmlReplayEval.eval(uri, serviceResultsMap, null, jexl, jc);
@@ -699,6 +719,7 @@ public class XmlReplay {
                     serviceResult.testID = testID;
                     serviceResult.fullURL = fullURL;
                     serviceResult.auth = authForTest;
+                    serviceResult.adminAuth = authForCleanup;
                     serviceResult.method = method;
                     if (expectedCodes.size()>0){
                         serviceResult.expectedCodes = expectedCodes;
@@ -770,24 +791,22 @@ public class XmlReplay {
         //=== Now spit out the HTML report file ===
         File m = new File(controlFileName);
         String localName = m.getName();//don't instantiate, just use File to extract file name without directory.
-        String reportName = localName+'-'+testGroupID+".html";
+        String reportName = localName+'-'+targetedTestGroupID+".html";
 
         File resultFile = report.saveReport(xmlReplayBaseDir, reportsDir, reportName);
         if (resultFile!=null) {
             String toc = report.getTOC(reportName);
             reportsList.add(toc);
         }
-        //================================
 
         return results;
     }
 
-               private static String timeString() {
-                       java.util.Date date= new java.util.Date();
-                       java.sql.Timestamp ts = new java.sql.Timestamp(date.getTime());
-                       return ts.toString();
-               }
-               
+       private static String timeString() {
+               java.util.Date date = new java.util.Date();
+               java.sql.Timestamp ts = new java.sql.Timestamp(date.getTime());
+               return ts.toString();
+       }
 
     //======================== MAIN ===================================================================
 
index fde549e783f1a51fd1dcc7b5316c61aea1e4a219..b042a8befbf9127dac846adb395fc3b68e0ca682 100644 (file)
@@ -56,37 +56,46 @@ public class XmlReplayEval {
      * uri = eval(uri, serviceResultsMap, jexl, jc);  <br />
      * RESULT:    "/cspace-services/orgauthorities/43a2739c-4f40-49c8-a6d5/items/"
      */
-     public static String eval(String inputJexlExpression, Map<String, ServiceResult> serviceResultsMap, Map<String,String> vars, JexlEngine jexl, JexlContext jc) {
-        //System.out.println("\r\n---- REPLACE.init-uri:        "+inputJexlExpression);
-        String result;
-        try {
-             jc.set("itemCSID", "${itemCSID}"); //noiseless passthru.
-            //System.out.println("eval :: serviceResultsMap "+serviceResultsMap.size());
-            for (ServiceResult serviceResult : serviceResultsMap.values()) {
-                jc.set(serviceResult.testID, serviceResult);
-                //System.out.println("eval :: "+serviceResult.testID+"==>"+serviceResult.minimal());
-            }
-            if (vars!=null){
-                for (Map.Entry<String,String> entry: vars.entrySet()) {
-                    String value = entry.getValue();
-                    String key = entry.getKey();
-                    try {
-                        value = parse(value, jexl, jc);
-                        vars.put(key, value); //replace template value with actual value.
-                    } catch (Exception e){
-                        value = "ERROR: "+e;
-                    }
-                    jc.set(key, value);
-                }
-            }
-            result = parse(inputJexlExpression, jexl, jc);
-        } catch (Throwable t) {
-            System.err.println("ERROR: " + t);
-            result = "ERROR";
-        }
-        //System.out.println("---- REPLACE.uri:        "+result+"\r\n");
-        return result;
-    }
+       public static String eval(String inputJexlExpression, Map<String, ServiceResult> serviceResultsMap,
+                       Map<String, String> vars, JexlEngine jexl, JexlContext jc) {
+               // System.out.println("\r\n---- REPLACE.init-uri:
+               // "+inputJexlExpression);
+               String result;
+               try {
+                       jc.set("itemCSID", "${itemCSID}"); // noiseless passthru.
+                       // System.out.println("eval :: serviceResultsMap
+                       // "+serviceResultsMap.size());
+
+                       if (serviceResultsMap != null) {
+                               for (ServiceResult serviceResult : serviceResultsMap.values()) {
+                                       jc.set(serviceResult.testID, serviceResult);
+                                       // System.out.println("eval ::
+                                       // "+serviceResult.testID+"==>"+serviceResult.minimal());
+                               }
+                       }
+                       
+                       if (vars != null) {
+                               for (Map.Entry<String, String> entry : vars.entrySet()) {
+                                       String value = entry.getValue();
+                                       String key = entry.getKey();
+                                       try {
+                                               value = parse(value, jexl, jc);
+                                               vars.put(key, value); // replace template value with
+                                                                                               // actual value.
+                                       } catch (Exception e) {
+                                               value = "ERROR: " + e;
+                                       }
+                                       jc.set(key, value);
+                               }
+                       }
+                       result = parse(inputJexlExpression, jexl, jc);
+               } catch (Throwable t) {
+                       System.err.println("ERROR: " + t);
+                       result = "ERROR";
+               }
+               // System.out.println("---- REPLACE.uri: "+result+"\r\n");
+               return result;
+       }
 
     private static String parse(String in, JexlEngine jexl, JexlContext jc) {
         StringBuffer result = new StringBuffer();
index 31dd26038b0585eeeee931ed5e4aba4c9669ed3d..04ebb6857f7d521c7733d55e4278aa016e381d5f 100644 (file)
@@ -181,23 +181,32 @@ public class XmlReplayTransport {
     */
 
     /** Use this overload for NON-multipart messages, that is, regular POSTs. */
-    public static ServiceResult doPOST_PUTFromXML(String fileName,
-                                                      Map<String,String> vars,
-                                                      String protoHostPort,
-                                                      String uri,
-                                                      String method,
-                                                      String contentType,
-                                                      XmlReplayEval evalStruct,
-                                                      String authForTest,
-                                                      String fromTestID)
-    throws Exception {
-        byte[] b = FileUtils.readFileToByteArray(new File(fileName));
-        String xmlString = new String(b);
-        String contentRaw = xmlString;
-        xmlString = evalStruct.eval(xmlString, evalStruct.serviceResultsMap, vars, evalStruct.jexl, evalStruct.jc);
-        String urlString = protoHostPort+uri;
-        return doPOST_PUT(urlString, xmlString, contentRaw, BOUNDARY, method, contentType, authForTest, fromTestID); //method is POST or PUT.
-    }
+       public static ServiceResult doPOST_PUTFromXML(
+                       String fileName, 
+                       Map<String, 
+                       String> vars, 
+                       String protoHostPort,
+                       String uri, 
+                       String method, 
+                       String contentType, 
+                       XmlReplayEval evalStruct, 
+                       String authForTest,
+                       String fromTestID) throws Exception {
+               byte[] b = FileUtils.readFileToByteArray(new File(fileName));
+               String xmlString = new String(b);
+               String contentRaw = xmlString;
+               //
+               // Add the test ID so we can substitute instances of "${testID}" in the
+               // payload with the test ID.
+               //
+               String testId = fromTestID.split("\\.")[1]; // Get the unqualified (without the group ID part) test name
+               vars.put("Test.ID", testId);
+
+               xmlString = evalStruct.eval(xmlString, evalStruct.serviceResultsMap, vars, evalStruct.jexl, evalStruct.jc);
+               String urlString = protoHostPort + uri;
+               
+               return doPOST_PUT(urlString, xmlString, contentRaw, BOUNDARY, method, contentType, authForTest, fromTestID); // method  is POST or PUT.
+       }
 
         //HACK for speed testing in doPOST_PUT.
         //  Result: XmlReplay takes 9ms to process one test
@@ -208,18 +217,21 @@ public class XmlReplayTransport {
         //if (true) return result;
         //END-HACK
 
-    public static ServiceResult doPOST_PUT(String urlString,
-                                                                     String content,
-                                                                     String contentRaw,
-                                                                     String boundary,
-                                                                     String method,
-                                                                     String contentType,
-                                                                     String authForTest,
-                                                                     String fromTestID) throws Exception {
+    private static ServiceResult doPOST_PUT(
+               String urlString,
+               String content,
+                       String contentRaw,
+                       String boundary,
+                       String method,
+                       String contentType,
+                       String authForTest,
+                       String fromTestID) throws Exception {
         ServiceResult result = new ServiceResult();
         result.method = method;
+        
         String deleteURL = "";
         String location = "";
+        
         try {
             URL url = new URL(urlString);
             HttpURLConnection conn;
@@ -273,56 +285,83 @@ public class XmlReplayTransport {
         } catch (Throwable t2){
             result.error = "ERROR in XmlReplayTransport: "+t2;
         }
+        
         return result;
     }
 
-    public static ServiceResult doPOST_PUT_PostMethod(String urlString, String content, Map<String,String> contentRaw,
-                                           String boundary, String method, String contentType,
-                                           String authForTest, String fromTestID) throws Exception {
-        ServiceResult result = new ServiceResult();
-        result.method = method;
-        String deleteURL = "";
-        String location = "";
-        try {
-            HttpClient client = new HttpClient();
-            PostMethod postMethod = new PostMethod(urlString);
-            postMethod.setRequestHeader("Accept", "multipart/mixed");
-            postMethod.addRequestHeader("Accept", "application/xml");
-            postMethod.setRequestHeader("Authorization", formatAuth(authForTest));
-            postMethod.setRequestHeader("X-XmlReplay-fromTestID", fromTestID);
-            //this method takes an array of params.  Not sure what they expect us to do with a raw post:
-            //   postMethod.setRequestBody();
-            int statusCode1 = 0;
-            String res = "";
-            try {
-                statusCode1 = client.executeMethod(postMethod);
-                result.responseCode = statusCode1;
-                //System.out.println("statusCode: "+statusCode1+" statusLine ==>" + postMethod.getStatusLine());
-                result.responseMessage = postMethod.getStatusText();
-                res = postMethod.getResponseBodyAsString();
-                Header[] headers = postMethod.getResponseHeaders("Location");
-                if (headers.length>0) {
-                    System.out.println("headers[0]:  "+headers[0]);
-                    String locationZero = headers[0].getValue();
-                    if (locationZero != null){
-                        String[] segments = locationZero.split("/");
-                        location = segments[segments.length - 1];
-                        deleteURL = Tools.glue(urlString, "/", location);
-                    }
-                }
-                postMethod.releaseConnection();
-            } catch (Throwable t){
-                result.error = t.toString();
-            }
-            result.result = res;
-            result.location = location;
-            result.deleteURL = deleteURL;
-            result.CSID = location;
-        } catch (Throwable t2){
-            result.error = "ERROR in XmlReplayTransport: "+t2;
-        }
-        return result;
-    }
+    @Deprecated
+    /**
+     * This method is not used and is a good candidate for removal.
+     * 
+     * @param urlString
+     * @param content
+     * @param contentRaw
+     * @param boundary
+     * @param method
+     * @param contentType
+     * @param authForTest
+     * @param fromTestID
+     * @return
+     * @throws Exception
+     */
+       private static ServiceResult doPOST_PUT_PostMethod(
+                       String urlString, 
+                       String content, 
+                       Map<String, String> contentRaw,
+                       String boundary, 
+                       String method, 
+                       String contentType, 
+                       String authForTest, 
+                       String fromTestID)
+                       throws Exception {
+               ServiceResult result = new ServiceResult();
+               result.method = method;
+               String deleteURL = "";
+               String location = "";
+               
+               try {
+                       HttpClient client = new HttpClient();
+                       PostMethod postMethod = new PostMethod(urlString);
+                       postMethod.setRequestHeader("Accept", "multipart/mixed");
+                       postMethod.addRequestHeader("Accept", "application/xml");
+                       postMethod.setRequestHeader("Authorization", formatAuth(authForTest));
+                       postMethod.setRequestHeader("X-XmlReplay-fromTestID", fromTestID);
+                       // this method takes an array of params. Not sure what they expect
+                       // us to do with a raw post:
+                       // postMethod.setRequestBody();
+                       int statusCode1 = 0;
+                       String res = "";
+                       try {
+                               statusCode1 = client.executeMethod(postMethod);
+                               result.responseCode = statusCode1;
+                               // System.out.println("statusCode: "+statusCode1+" statusLine
+                               // ==>" + postMethod.getStatusLine());
+                               result.responseMessage = postMethod.getStatusText();
+                               res = postMethod.getResponseBodyAsString();
+                               Header[] headers = postMethod.getResponseHeaders("Location");
+                               if (headers.length > 0) {
+                                       System.out.println("headers[0]:  " + headers[0]);
+                                       String locationZero = headers[0].getValue();
+                                       if (locationZero != null) {
+                                               String[] segments = locationZero.split("/");
+                                               location = segments[segments.length - 1];
+                                               deleteURL = Tools.glue(urlString, "/", location);
+                                       }
+                               }
+                               postMethod.releaseConnection();
+                       } catch (Throwable t) {
+                               result.error = t.toString();
+                       }
+                       result.result = res;
+                       result.location = location;
+                       result.deleteURL = deleteURL;
+                       result.CSID = location;
+               } catch (Throwable t2) {
+                       result.error = "ERROR in XmlReplayTransport: " + t2;
+               }
+               
+               return result;
+       }
 
     private static void readStream(HttpURLConnection  conn, ServiceResult result) throws Throwable {
         BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
diff --git a/services/IntegrationTests/src/test/resources/test-data/xmlreplay/vocabulary/DeleteVocabJustItems/responses/DeleteVocabJustItems.res.xml b/services/IntegrationTests/src/test/resources/test-data/xmlreplay/vocabulary/DeleteVocabJustItems/responses/DeleteVocabJustItems.res.xml
new file mode 100644 (file)
index 0000000..6a843d4
--- /dev/null
@@ -0,0 +1,25 @@
+<document name="vocabularies">
+    <ns2:vocabularies_common xmlns:ns2="http://collectionspace.org/services/vocabulary" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+        <rev>6</rev>
+        <shortIdentifier>createEmptyVocab100</shortIdentifier>
+        <csid>${csid}</csid>
+        <displayName>createEmptyVocab100 Vocabulary</displayName>
+        <description>
+            This is a test vocabulary for test createEmptyVocab100
+        </description>
+        <source>createEmptyVocab100</source>
+        <refName>
+            urn:cspace:testsci.collectionspace.org:vocabularies:name(createEmptyVocab100)'createEmptyVocab100 Vocabulary'
+        </refName>
+        <vocabType>enum</vocabType>
+    </ns2:vocabularies_common>
+    <ns2:abstract-common-list xmlns:ns2="http://collectionspace.org/services/jaxb">
+        <pageNum>0</pageNum>
+        <pageSize>2500</pageSize>
+        <itemsInPage>0</itemsInPage>
+        <totalItems>0</totalItems>
+        <fieldsReturned>
+            csid|uri|refName|updatedAt|workflowState|rev|sourcePage|sas|proposed|deprecated|termStatus|description|source|order|displayName|shortIdentifier
+        </fieldsReturned>
+    </ns2:abstract-common-list>
+</document>
\ No newline at end of file
diff --git a/services/IntegrationTests/src/test/resources/test-data/xmlreplay/vocabulary/DeleteVocabWithItems/objectExit.xml b/services/IntegrationTests/src/test/resources/test-data/xmlreplay/vocabulary/DeleteVocabWithItems/objectExit.xml
new file mode 100644 (file)
index 0000000..94e1483
--- /dev/null
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<document name="objectexit">
+    <ns2:objectexit_common
+            xmlns:ns2="http://collectionspace.org/services/objectexit"
+            xmlns:ns3="http://collectionspace.org/services/jaxb">
+        <exitNumber>${exitNumber}</exitNumber>
+    </ns2:objectexit_common>
+    <ns2:objectexit_testsci
+        xmlns:ns2="http://collectionspace.org/services/objectexit"
+        xmlns:ns3="http://collectionspace.org/services/jaxb">
+        <testField>${itemRefName}</testField>
+    </ns2:objectexit_testsci>
+</document>
\ No newline at end of file
diff --git a/services/IntegrationTests/src/test/resources/test-data/xmlreplay/vocabulary/ReplaceVocabItems/replaceWithItems-vocab.xml b/services/IntegrationTests/src/test/resources/test-data/xmlreplay/vocabulary/ReplaceVocabItems/replaceWithItems-vocab.xml
new file mode 100644 (file)
index 0000000..8e4ff94
--- /dev/null
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document name="vocabularies">
+    <ns3:vocabularies_common xmlns:ns3="http://collectionspace.org/services/vocabulary" xmlns:ns2="http://collectionspace.org/services/jaxb">
+        <displayName>Updated createReplaceVocabItems Vocabulary</displayName>
+        <shortIdentifier>createReplaceVocabItems</shortIdentifier>
+        <description>This is an updated test vocabulary created in the createReplaceVocabItems XMLReplay test group</description>
+        <source>Some updated mythical book posted with item terms in createReplaceVocabItems test group</source>
+    </ns3:vocabularies_common>
+    <ns2:abstract-common-list xmlns:ns2="http://collectionspace.org/services/jaxb">
+        <list-item>
+            <order>1</order>
+            <displayName>Replacement item A</displayName>
+            <shortIdentifier>replacementitema</shortIdentifier>
+        </list-item>
+        <list-item>
+            <order>2</order>
+            <displayName>Replacement item B</displayName>
+            <shortIdentifier>replacementitemb</shortIdentifier>
+        </list-item>
+        <list-item>
+            <order>3</order>
+            <displayName>Replacement item C</displayName>
+            <shortIdentifier>replacementitemc</shortIdentifier>
+        </list-item>
+    </ns2:abstract-common-list>
+</document>
diff --git a/services/IntegrationTests/src/test/resources/test-data/xmlreplay/vocabulary/ReplaceVocabItems/responses/ReplaceVocabItems.res.xml b/services/IntegrationTests/src/test/resources/test-data/xmlreplay/vocabulary/ReplaceVocabItems/responses/ReplaceVocabItems.res.xml
new file mode 100644 (file)
index 0000000..c6f84fd
--- /dev/null
@@ -0,0 +1,25 @@
+<document name="vocabularies">
+    <ns2:vocabularies_common xmlns:ns2="http://collectionspace.org/services/vocabulary" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+        <rev>6</rev>
+        <shortIdentifier>createReplaceVocabItems</shortIdentifier>
+        <csid>${csid}</csid>
+        <displayName>createReplaceVocabItems Vocabulary</displayName>
+        <description>
+            This is a test vocabulary for test createReplaceVocabItems
+        </description>
+        <source>createReplaceVocabItems</source>
+        <refName>
+            urn:cspace:testsci.collectionspace.org:vocabularies:name(createReplaceVocabItems)'createReplaceVocabItems Vocabulary'
+        </refName>
+        <vocabType>enum</vocabType>
+    </ns2:vocabularies_common>
+    <ns2:abstract-common-list xmlns:ns2="http://collectionspace.org/services/jaxb">
+        <pageNum>0</pageNum>
+        <pageSize>2500</pageSize>
+        <itemsInPage>0</itemsInPage>
+        <totalItems>0</totalItems>
+        <fieldsReturned>
+            csid|uri|refName|updatedAt|workflowState|rev|sourcePage|sas|proposed|deprecated|termStatus|description|source|order|displayName|shortIdentifier
+        </fieldsReturned>
+    </ns2:abstract-common-list>
+</document>
\ No newline at end of file
index 2d61b5003f0c387e395aaa15e1382ec7739bafc9..6176fe8d1eca9086dbe4dca7c37cd4a64b697680 100644 (file)
@@ -4,7 +4,6 @@
   xmlns:ns2="http://collectionspace.org/services/jaxb">
     <displayName>${displayName}</displayName>
     <shortIdentifier>${itemID}</shortIdentifier>
-    <refName>urn:cspace:org.collectionspace.demo:vocabulary:name(TestOrderVocab):item:name(${itemID})'${displayName}'</refName>
     <order>${order}</order>
     <description>This is a test vocabulary item</description>
     <source>Some mythical book</source>
diff --git a/services/IntegrationTests/src/test/resources/test-data/xmlreplay/vocabulary/vocab-Item-template.xml b/services/IntegrationTests/src/test/resources/test-data/xmlreplay/vocabulary/vocab-Item-template.xml
new file mode 100644 (file)
index 0000000..a82a534
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document name="vocabularyitems">
+    <ns3:vocabularyitems_common xmlns:ns3="http://collectionspace.org/services/vocabulary" xmlns:ns2="http://collectionspace.org/services/jaxb">
+        <displayName>${Test.ID}</displayName>
+        <shortIdentifier>${Test.ID}</shortIdentifier>
+        <order>${order}</order>
+        <description>This is a test vocabulary item for test ${Test.ID}</description>
+        <source>Some mythical book for test ${Test.ID}</source>
+        <sourcePage>The page should match the order:${order}</sourcePage>
+    </ns3:vocabularyitems_common>
+</document>
diff --git a/services/IntegrationTests/src/test/resources/test-data/xmlreplay/vocabulary/vocab-Template.xml b/services/IntegrationTests/src/test/resources/test-data/xmlreplay/vocabulary/vocab-Template.xml
new file mode 100644 (file)
index 0000000..8f65a95
--- /dev/null
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    Use this template to create a new vocabulary. Instances of ${Test.ID} will get substituted with the ID of the test using this template.
+-->
+<document name="vocabularies">
+    <ns3:vocabularies_common xmlns:ns3="http://collectionspace.org/services/vocabulary" xmlns:ns2="http://collectionspace.org/services/jaxb">
+        <displayName>${Test.ID} Vocabulary</displayName>
+        <shortIdentifier>${Test.ID}</shortIdentifier>
+        <vocabType>enum</vocabType>
+        <description>This is a test vocabulary for test ${Test.ID}</description>
+        <source>${Test.ID}</source>
+    </ns3:vocabularies_common>
+</document>
index b91cce90feb59c8bab22391892fccf16821600ea..f9bb9190e0418f4621cf145d6b006f1dbdb9d8e6 100644 (file)
@@ -3,9 +3,239 @@
        <auths>
                <!-- IMPORTANT: THESE ARE STICKY :: THEY STICK AROUND UNTIL RESET, IN EXEC ORDER OF THIS FILE. -->
                <auth ID="admin@core.collectionspace.org">YWRtaW5AY29yZS5jb2xsZWN0aW9uc3BhY2Uub3JnOkFkbWluaXN0cmF0b3I=</auth>
-               <auth ID="testAdministator">YWRtaW5AY29sbGVjdGlvbnNwYWNlLm9yZzpBZG1pbmlzdHJhdG9y</auth>
+           <auth ID="admin@testsci.collectionspace.org">YWRtaW5AdGVzdHNjaS5jb2xsZWN0aW9uc3BhY2Uub3JnOkFkbWluaXN0cmF0b3I=</auth>
        </auths>
     
+    <!--
+        Test replace a vocabulary's terms with an entirely new set of terms.
+    -->
+    <testGroup ID="ReplaceVocabItems" autoDeletePOSTS="true" authForCleanup="admin@testsci.collectionspace.org">
+        <test ID="createReplaceVocabItems" auth="admin@testsci.collectionspace.org">
+            <method>POST</method>
+            <uri>/cspace-services/vocabularies/</uri>
+            <filename>vocabulary/vocab-Template.xml</filename>
+        </test>
+        <test ID="createItem101">
+            <method>POST</method>
+            <uri>/cspace-services/vocabularies/${createReplaceVocabItems.CSID}/items/</uri>
+            <filename>vocabulary/vocab-Item-template.xml</filename>
+            <vars>
+                <var ID="order">1</var>
+            </vars>
+        </test>
+        <test ID="createItem201">
+            <method>POST</method>
+            <uri>/cspace-services/vocabularies/${createReplaceVocabItems.CSID}/items/</uri>
+            <filename>vocabulary/vocab-Item-template.xml</filename>
+            <vars>
+                <var ID="order">2</var>
+            </vars>
+        </test>
+        <test ID="createItem301">
+            <method>POST</method>
+            <uri>/cspace-services/vocabularies/${createReplaceVocabItems.CSID}/items/</uri>
+            <filename>vocabulary/vocab-Item-template.xml</filename>
+            <vars>
+                <var ID="order">3</var>
+            </vars>
+        </test>
+        <test ID="updateReplaceVocabItems" auth="admin@testsci.collectionspace.org">
+            <method>PUT</method>
+            <uri>/cspace-services/vocabularies/${createReplaceVocabItems.CSID}</uri>
+            <filename>vocabulary/ReplaceVocabItems/ReplaceVocabItems.res.xml</filename>
+        </test>
+<!-- 
+        <test ID="deleteReplaceVocabItems">
+            <method>DELETE</method>
+            <uri>/cspace-services/vocabularies/${createReplaceVocabItems.CSID}/items</uri>
+        </test>
+        <test ID="getReplaceVocabItems">
+            <method>GET</method>
+            <uri>/cspace-services/vocabularies/${createReplaceVocabItems.CSID}</uri>
+        </test>
+        <test ID="getReplaceVocabItems">
+            <method>GET</method>
+            <uri>/cspace-services/vocabularies/${createReplaceVocabItems.CSID}?showItems=true</uri>
+            <response>
+                <vars>
+                    <var ID="csid">${createReplaceVocabItems.CSID}</var>
+                </vars>
+                <expected level="ADDOK" />
+                <label>vocabularies_common</label>
+                <filename>vocabulary/ReplaceVocabItems/responses/ReplaceVocabItems.res.xml</filename>
+            </response>            
+        </test>
+ -->        
+    </testGroup>    
+    
+    <testGroup ID="DeleteVocabJustItems" autoDeletePOSTS="true" authForCleanup="admin@testsci.collectionspace.org">
+        <test ID="createEmptyVocab100" auth="admin@testsci.collectionspace.org">
+            <method>POST</method>
+            <uri>/cspace-services/vocabularies/</uri>
+            <filename>vocabulary/vocab-Template.xml</filename>
+        </test>
+        <test ID="createItem10">
+            <method>POST</method>
+            <uri>/cspace-services/vocabularies/${createEmptyVocab100.CSID}/items/</uri>
+            <filename>vocabulary/vocab-Item-template.xml</filename>
+            <vars>
+                <var ID="order">1</var>
+            </vars>
+        </test>
+        <test ID="createItem20">
+            <method>POST</method>
+            <uri>/cspace-services/vocabularies/${createEmptyVocab100.CSID}/items/</uri>
+            <filename>vocabulary/vocab-Item-template.xml</filename>
+            <vars>
+                <var ID="order">2</var>
+            </vars>
+        </test>
+        <test ID="createItem30">
+            <method>POST</method>
+            <uri>/cspace-services/vocabularies/${createEmptyVocab100.CSID}/items/</uri>
+            <filename>vocabulary/vocab-Item-template.xml</filename>
+            <vars>
+                <var ID="order">3</var>
+            </vars>
+        </test>
+        <test ID="deleteEmptyVocab100">
+            <method>DELETE</method>
+            <uri>/cspace-services/vocabularies/${createEmptyVocab100.CSID}/items</uri>
+        </test>
+        <test ID="getEmptyVocab100">
+            <method>GET</method>
+            <uri>/cspace-services/vocabularies/${createEmptyVocab100.CSID}</uri>
+        </test>
+        <test ID="getEmptyVocab100Items">
+            <method>GET</method>
+            <uri>/cspace-services/vocabularies/${createEmptyVocab100.CSID}?showItems=true</uri>
+            <response>
+                <vars>
+                    <var ID="csid">${createEmptyVocab100.CSID}</var>
+                </vars>
+                <expected level="ADDOK" />
+                <label>vocabularies_common</label>
+                <filename>vocabulary/DeleteVocabJustItems/responses/DeleteVocabJustItems.res.xml</filename>
+            </response>            
+        </test>
+    </testGroup>
+    
+    <!--
+        Test trying to delete an authority (and its terms) when one or more of its terms
+        is being reference in another record.
+        
+        1. Create a new authority and add 3 items to it.
+        2. Create an ObjectExit record referencing one of the items
+        3. Try to delete the authority (should fail)
+        4. Delete the ObjectExit record.
+        5. Delete to the authority (should work now).
+    -->
+    <testGroup ID="DeleteVocabWithReferencedItem" autoDeletePOSTS="true">
+        <test ID="createEmptyVocab" auth="admin@testsci.collectionspace.org">
+            <method>POST</method>
+            <uri>/cspace-services/vocabularies/</uri>
+            <filename>vocabulary/vocab-Template.xml</filename>
+        </test>
+        <test ID="createItem1">
+            <method>POST</method>
+            <uri>/cspace-services/vocabularies/${createEmptyVocab.CSID}/items/</uri>
+            <filename>vocabulary/vocab-Item-template.xml</filename>
+            <vars>
+                <var ID="order">1</var>
+            </vars>
+        </test>
+        <test ID="createItem2">
+            <method>POST</method>
+            <uri>/cspace-services/vocabularies/${createEmptyVocab.CSID}/items/</uri>
+            <filename>vocabulary/vocab-Item-template.xml</filename>
+            <vars>
+                <var ID="order">2</var>
+            </vars>
+        </test>
+        <test ID="createItem3">
+            <method>POST</method>
+            <uri>/cspace-services/vocabularies/${createEmptyVocab.CSID}/items/</uri>
+            <filename>vocabulary/vocab-Item-template.xml</filename>
+            <vars>
+                <var ID="order">3</var>
+            </vars>
+        </test>
+        <test ID="createObjectExit">
+            <method>POST</method>
+            <uri>/cspace-services/objectexit</uri>
+            <filename>vocabulary/DeleteVocabWithItems/objectExit.xml</filename>
+            <vars>
+                <var ID="exitNumber">2</var>
+                <var ID="itemRefName">urn:cspace:testsci.collectionspace.org:vocabularies:name(createEmptyVocab):item:name(createItem2)'createItem2'</var>                
+            </vars>
+        </test>        
+        <test ID="deleteEmptyVocab">
+            <expectedCodes>409</expectedCodes>
+            <method>DELETE</method>
+            <uri>/cspace-services/vocabularies/${createEmptyVocab.CSID}</uri>
+        </test>
+        <test ID="deleteObjectExit">
+            <method>DELETE</method>
+            <uri>/cspace-services/objectexit/${createObjectExit.CSID}</uri>
+        </test>
+        <test ID="deleteEmptyVocab">
+            <method>DELETE</method>
+            <uri>/cspace-services/vocabularies/${createEmptyVocab.CSID}</uri>
+        </test>
+        <test ID="getEmptyVocab">
+            <expectedCodes>404</expectedCodes>
+            <method>GET</method>
+            <uri>/cspace-services/vocabularies/${createEmptyVocab.CSID}</uri>
+        </test>
+    </testGroup>
+    
+    <!--
+        1. Create a new vocabulary.
+        2. Add three terms to it.
+        3. Delete the vocabulary (all items should automatically get deleted as well)
+        4. Try to get the deleted vocabulary (expect a 404)
+    -->
+    <testGroup ID="DeleteVocabWithItems" autoDeletePOSTS="false">
+        <test ID="createEmptyVocab" auth="admin@core.collectionspace.org">
+            <method>POST</method>
+            <uri>/cspace-services/vocabularies/</uri>
+            <filename>vocabulary/vocab-Template.xml</filename>
+        </test>
+        <test ID="createItem1" auth="cpw">
+            <method>POST</method>
+            <uri>/cspace-services/vocabularies/${createEmptyVocab.CSID}/items/</uri>
+            <filename>vocabulary/vocab-Item-template.xml</filename>
+            <vars>
+                <var ID="order">1</var>
+            </vars>
+        </test>
+        <test ID="createItem2">
+            <method>POST</method>
+            <uri>/cspace-services/vocabularies/${createEmptyVocab.CSID}/items/</uri>
+            <filename>vocabulary/vocab-Item-template.xml</filename>
+            <vars>
+                <var ID="order">2</var>
+            </vars>
+        </test>
+        <test ID="createItem3">
+            <method>POST</method>
+            <uri>/cspace-services/vocabularies/${createEmptyVocab.CSID}/items/</uri>
+            <filename>vocabulary/vocab-Item-template.xml</filename>
+            <vars>
+                <var ID="order">3</var>
+            </vars>
+        </test>
+        <test ID="deleteEmptyVocab">
+            <method>DELETE</method>
+            <uri>/cspace-services/vocabularies/${createEmptyVocab.CSID}</uri>
+        </test>
+        <test ID="getEmptyVocab">
+            <expectedCodes>404</expectedCodes>
+            <method>GET</method>
+            <uri>/cspace-services/vocabularies/${createEmptyVocab.CSID}</uri>
+        </test>
+    </testGroup>
+        
     <!--
           Test creation of Vocabulary (TermList) that includes (via an abstract-common-list element) term items.
        -->
             <uri>/cspace-services/vocabularies/</uri>
             <filename>vocabulary/ShowItems/showItems-vocab.xml</filename>
         </test>
-        <test ID="createItem1" auth="test">
+        <test ID="createItem1">
             <method>POST</method>
             <uri>/cspace-services/vocabularies/${createShowItemsVocab.CSID}/items/</uri>
             <filename>vocabulary/ShowItems/showItems-item-template.xml</filename>
                 <var ID="displayName">ShowsItems item ${itemID}</var>
             </vars>
         </test>
-        <test ID="createItem2" auth="test">
+        <test ID="createItem2">
             <method>POST</method>
             <uri>/cspace-services/vocabularies/${createShowItemsVocab.CSID}/items/</uri>
             <filename>vocabulary/ShowItems/showItems-item-template.xml</filename>
                 <var ID="displayName">ShowsItems item ${itemID}</var>
             </vars>
         </test>
-        <test ID="createItem3" auth="test">
+        <test ID="createItem3">
             <method>POST</method>
             <uri>/cspace-services/vocabularies/${createShowItemsVocab.CSID}/items/</uri>
             <filename>vocabulary/ShowItems/showItems-item-template.xml</filename>
                 </vars>
                 <expected level="ADDOK" />
                 <label>vocabularies_common</label>
-                <filename>vocabulary/ShowItems/res/showVocab.res.xml</filename>
+                <filename>vocabulary/ShowItems/responses/showVocab.res.xml</filename>
             </response>
         </test>
         <test ID="getShowItemsVocabWithItems">
                     <var ID="createItem3">${createItem3.CSID}</var>
                 </vars>
                 <expected level="ADDOK" />
-                <filename>vocabulary/ShowItems/res/showVocabWithItems.res.xml</filename>
+                <filename>vocabulary/ShowItems/responses/showVocabWithItems.res.xml</filename>
             </response>
         </test>
         <test ID="getShowItemsVocabWithItemsPaged">
                     <var ID="createItem3">${createItem3.CSID}</var>
                 </vars>
                 <expected level="ADDOK" />
-                <filename>vocabulary/ShowItems/res/showVocabWithItemsPaged.res.xml</filename>
+                <filename>vocabulary/ShowItems/responses/showVocabWithItemsPaged.res.xml</filename>
             </response>
         </test>
         <test ID="getShowItemsVocabWithItemsLastPage">
                     <var ID="createItem3">${createItem3.CSID}</var>
                 </vars>
                 <expected level="ADDOK" />
-                <filename>vocabulary/ShowItems/res/showVocabWithLastPage.res.xml</filename>
+                <filename>vocabulary/ShowItems/responses/showVocabWithLastPage.res.xml</filename>
             </response>
         </test>
     </testGroup>
        
-       <!--
-          Comments needed to describe this test group.
-       -->
+    <!--
+        The purpose of this testGroup is to test the new "order" field
+           that was added in http://issues.collectionspace.org/browse/CSPACE-573
+           and to ensure that this order field is returned in list results, 
+           and that duplicate values for the order field is accepted.
+    -->
     <testGroup ID="TestOrder" autoDeletePOSTS="true">
-               <!-- The purpose of this testGroup is to test the new "order" field
-             that was added in http://issues.collectionspace.org/browse/CSPACE-573
-             and to ensure that this order field is returned in list results, 
-             and that duplicate values for the order field is accepted.
-           -->
-               <test ID="Vocabulary1" auth="test">
+               <test ID="Vocabulary1">
                        <method>POST</method>
                        <uri>/cspace-services/vocabularies/</uri>
                        <filename>vocabulary/1-vocab.xml</filename>
                </test>
-               <test ID="Item1" auth="test">
+               <test ID="Item1">
                        <method>POST</method>
                        <uri>/cspace-services/vocabularies/${Vocabulary1.CSID}/items/</uri>
                        <filename>vocabulary/2-item.xml</filename>
                                <var ID="displayName">TestOrder item ${itemID} order ${order}</var>
                        </vars>
                </test>
-               <test ID="Item2" auth="test">
+               <test ID="Item2">
                        <method>POST</method>
                        <uri>/cspace-services/vocabularies/${Vocabulary1.CSID}/items/</uri>
                        <filename>vocabulary/2-item.xml</filename>
                                <var ID="displayName">TestOrder item ${itemID} order ${order}</var>
                        </vars>
                </test>
-               <test ID="Item3DupeOrder" auth="test">
+               <test ID="Item3DupeOrder">
                        <method>POST</method>
                        <uri>/cspace-services/vocabularies/${Vocabulary1.CSID}/items/</uri>
                        <filename>vocabulary/2-item.xml</filename>
                        </vars>
                </test>
 
-               <test ID="GetVocabularies" auth="admin@core.collectionspace.org">
+               <test ID="GetVocabularies">
                        <method>GET</method>
                        <uri>/cspace-services/vocabularies/</uri>
                </test>
 
-               <test ID="GetVocabularyItems" auth="admin@core.collectionspace.org">
+               <test ID="GetVocabularyItems">
                        <method>GET</method>
                        <uri>/cspace-services/vocabularies/${Vocabulary1.CSID}/items/</uri>
                        <response>
                                <expected level="ADDOK"/>
-                               <filename>vocabulary/res/GetVocabularyItems.res.xml</filename>
+                               <filename>vocabulary/responses/GetVocabularyItems.res.xml</filename>
                                <vars>
                                        <var ID="I3displayName">${Item3DupeOrder.displayName}</var>
                                </vars>
                        </response>
                </test>
 
-               <test ID="GetVocabularyItem" auth="admin@core.collectionspace.org">
+               <test ID="GetVocabularyItem">
                        <method>GET</method>
                        <uri>/cspace-services/vocabularies/${Vocabulary1.CSID}/items/${Item1.CSID}</uri>
                </test>
 
-               <test ID="GetVocabularyItemRefObjs" auth="admin@core.collectionspace.org">
+               <test ID="GetVocabularyItemRefObjs">
                        <method>GET</method>
                        <uri>/cspace-services/vocabularies/${Vocabulary1.CSID}/items/${Item1.CSID}/refObjs</uri>
                </test>
index 883b4504d87e198034985a8bc7ca42a739c1b191..cd910aae5c9b992222e277066076ac3f38a5fc7d 100644 (file)
@@ -76,12 +76,14 @@ import org.collectionspace.services.common.document.DocumentReferenceException;
 import org.collectionspace.services.common.document.DocumentWrapper;
 import org.collectionspace.services.common.document.Hierarchy;
 import org.collectionspace.services.common.query.QueryManager;
+import org.collectionspace.services.common.repository.RepositoryClient;
 import org.collectionspace.services.common.vocabulary.nuxeo.AuthorityDocumentModelHandler;
 import org.collectionspace.services.common.vocabulary.nuxeo.AuthorityItemDocumentModelHandler;
 import org.collectionspace.services.common.workflow.service.nuxeo.WorkflowDocumentModelHandler;
 import org.collectionspace.services.config.ClientType;
 import org.collectionspace.services.config.service.ServiceBindingType;
 import org.collectionspace.services.jaxb.AbstractCommonList;
+import org.collectionspace.services.jaxb.AbstractCommonList.ListItem;
 import org.collectionspace.services.lifecycle.TransitionDef;
 import org.collectionspace.services.nuxeo.client.java.DocumentModelHandler;
 import org.collectionspace.services.nuxeo.client.java.CoreSessionInterface;
@@ -98,6 +100,7 @@ import org.nuxeo.ecm.core.api.DocumentModel;
 import org.nuxeo.ecm.core.api.DocumentModelList;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.w3c.dom.Element;
 
 /**
  * The Class AuthorityResource.
@@ -563,6 +566,8 @@ public abstract class AuthorityResource<AuthCommon, AuthItemHandler>
     @PUT
     @Path("{csid}")
     public byte[] updateAuthority(
+               @Context ResourceMap resourceMap,
+               @Context UriInfo uriInfo,               
             @PathParam("csid") String specifier,
             String xmlPayload) {
         PoxPayloadOut result = null;
@@ -586,6 +591,46 @@ public abstract class AuthorityResource<AuthCommon, AuthItemHandler>
         return result.getBytes();
     }
     
+    /**
+     * Delete all the items in an authority list.
+     * 
+     * @param specifier
+     * @param uriInfo
+     * @return
+     */
+    @DELETE
+    @Path("{csid}/items")
+    public Response deleteAuthorityItemList(@PathParam("csid") String specifier,
+            @Context UriInfo uriInfo) {
+        uriInfo = new UriInfoWrapper(uriInfo);
+
+        try {
+            ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = createServiceContext(uriInfo);
+                       RepositoryClient<PoxPayloadIn, PoxPayloadOut> repoClient = this.getRepositoryClient(ctx);
+            
+                       CoreSessionInterface repoSession = repoClient.getRepositorySession(ctx);
+                       try {
+                   DocumentHandler<?, AbstractCommonList, DocumentModel, DocumentModelList> handler = createDocumentHandler(ctx);
+                   //
+                   // Delete all the items one by one
+                   //
+                       AbstractCommonList itemsList = this.getAuthorityItemList(ctx, specifier, uriInfo);
+                       for (ListItem item : itemsList.getListItem()) {
+                       deleteAuthorityItem(ctx, specifier, getCsid(item), AuthorityServiceUtils.UPDATE_REV);
+                       }
+                       } catch (Throwable t) {
+               repoSession.setTransactionRollbackOnly();
+               throw t;
+            } finally {
+               repoClient.releaseRepositorySession(ctx, repoSession);
+            }
+
+            return Response.status(HttpResponseCodes.SC_OK).build();
+        } catch (Exception e) {
+            throw bigReThrow(e, ServiceMessages.DELETE_FAILED, specifier);
+        }
+    }
+    
     /**
      * Delete authority
      * 
@@ -607,30 +652,64 @@ public abstract class AuthorityResource<AuthCommon, AuthItemHandler>
         
         try {
             ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = createServiceContext(uriInfo);
-            DocumentHandler<?, AbstractCommonList, DocumentModel, DocumentModelList> handler = createDocumentHandler(ctx);
-
             Specifier spec = Specifier.getSpecifier(specifier, "getAuthority", "GET");
-            if (spec.form == SpecifierForm.CSID) {
-                if (logger.isDebugEnabled()) {
-                    logger.debug("deleteAuthority with csid=" + spec.value);
-                }
-                ensureCSID(spec.value, ServiceMessages.DELETE_FAILED, "Authority.csid");
-                getRepositoryClient(ctx).delete(ctx, spec.value, handler);
-            } else {
-                if (logger.isDebugEnabled()) {
-                    logger.debug("deleteAuthority with specifier=" + spec.value);
-                }              
-                String whereClause = RefNameServiceUtils.buildWhereForAuthByName(authorityCommonSchemaName, spec.value);
-                getRepositoryClient(ctx).deleteWithWhereClause(ctx, whereClause, handler);
-            }
+                       RepositoryClient<PoxPayloadIn, PoxPayloadOut> repoClient = this.getRepositoryClient(ctx);
             
+                       CoreSessionInterface repoSession = repoClient.getRepositorySession(ctx);
+                       try {
+                   DocumentHandler<?, AbstractCommonList, DocumentModel, DocumentModelList> handler = createDocumentHandler(ctx);
+                   //
+                   // First try to delete all the items
+                   //
+                       AbstractCommonList itemsList = this.getAuthorityItemList(ctx, specifier, uriInfo);
+                       for (ListItem item : itemsList.getListItem()) {
+                       deleteAuthorityItem(ctx, specifier, getCsid(item), AuthorityServiceUtils.UPDATE_REV);
+                       }
+
+                   //
+                   // Lastly, delete the parent/container
+                   //
+                   if (spec.form == SpecifierForm.CSID) {
+                       if (logger.isDebugEnabled()) {
+                           logger.debug("deleteAuthority with csid=" + spec.value);
+                       }
+                       ensureCSID(spec.value, ServiceMessages.DELETE_FAILED, "Authority.csid");
+                       getRepositoryClient(ctx).delete(ctx, spec.value, handler);
+                   } else {
+                       if (logger.isDebugEnabled()) {
+                           logger.debug("deleteAuthority with specifier=" + spec.value);
+                       }               
+                       String whereClause = RefNameServiceUtils.buildWhereForAuthByName(authorityCommonSchemaName, spec.value);
+                       getRepositoryClient(ctx).deleteWithWhereClause(ctx, whereClause, handler);
+                   }
+                       } catch (Throwable t) {
+               repoSession.setTransactionRollbackOnly();
+               throw t;
+            } finally {
+               repoClient.releaseRepositorySession(ctx, repoSession);
+            }
+
             return Response.status(HttpResponseCodes.SC_OK).build();
         } catch (Exception e) {
             throw bigReThrow(e, ServiceMessages.DELETE_FAILED, specifier);
         }
     }
     
-    /**
+       private String getCsid(ListItem item) {
+               String result = null;
+               
+               for (Element ele : item.getAny()) {
+                       String elementName = ele.getTagName().toLowerCase();
+                       if (elementName.equals("csid")) {
+                               result = ele.getTextContent();
+                               break;
+                       }
+               }
+               
+               return result;
+       }
+
+       /**
      * 
      * @param ctx
      * @param parentspecifier          - ID of the container. Can be URN or CSID form
@@ -662,6 +741,49 @@ public abstract class AuthorityResource<AuthCommon, AuthItemHandler>
 
        return result;
     }
+    
+    public PoxPayloadOut updateAuthorityItem(
+               ServiceContext<PoxPayloadIn, PoxPayloadOut> itemServiceCtx, // Ok to be null.  Will be null on PUT calls, but not on sync calls
+               ResourceMap resourceMap, 
+            UriInfo uriInfo,
+            String parentspecifier,
+            String itemspecifier,
+            PoxPayloadIn theUpdate,
+            boolean shouldUpdateRevNumber,
+            Boolean isProposed,
+            Boolean isSASItem
+            ) throws Exception {
+        PoxPayloadOut result = null;
+        
+        CsidAndShortIdentifier csidAndShortId = lookupParentCSIDAndShortIdentifer(itemServiceCtx, parentspecifier, "updateAuthorityItem(parent)", "UPDATE_ITEM", null);
+        String parentcsid = csidAndShortId.CSID;
+        String parentShortId = csidAndShortId.shortIdentifier;
+        //
+        // If the itemServiceCtx context is not null, use it.  Otherwise, create a new context
+        //
+        ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = itemServiceCtx;
+        if (ctx == null) {
+               ctx = createServiceContext(getItemServiceName(), theUpdate, resourceMap, uriInfo);
+        } else {
+               ctx.setInput(theUpdate); // the update payload
+        }
+        
+        String itemcsid = lookupItemCSID(ctx, itemspecifier, parentcsid, "updateAuthorityItem(item)", "UPDATE_ITEM"); //use itemServiceCtx if it is not null
+
+        // We omit the parentShortId, only needed when doing a create...
+        AuthorityItemDocumentModelHandler handler = (AuthorityItemDocumentModelHandler)createItemDocumentHandler(ctx, parentcsid, parentShortId);
+        handler.setShouldUpdateRevNumber(shouldUpdateRevNumber);
+        if (isProposed != null) {
+               handler.setIsProposed(isProposed);
+        }
+        if (isSASItem != null) {
+               handler.setIsSASItem(isSASItem);
+        }
+        getRepositoryClient(ctx).update(ctx, itemcsid, handler);
+        result = ctx.getOutput();
+
+        return result;
+    }    
 
     /**
      * Called with an existing context.
@@ -1282,48 +1404,7 @@ public abstract class AuthorityResource<AuthCommon, AuthItemHandler>
         return result.getBytes();
     }
     
-    public PoxPayloadOut updateAuthorityItem(
-               ServiceContext<PoxPayloadIn, PoxPayloadOut> itemServiceCtx, // Ok to be null.  Will be null on PUT calls, but not on sync calls
-               ResourceMap resourceMap, 
-            UriInfo uriInfo,
-            String parentspecifier,
-            String itemspecifier,
-            PoxPayloadIn theUpdate,
-            boolean shouldUpdateRevNumber,
-            Boolean isProposed,
-            Boolean isSASItem
-            ) throws Exception {
-        PoxPayloadOut result = null;
-        
-        CsidAndShortIdentifier csidAndShortId = lookupParentCSIDAndShortIdentifer(itemServiceCtx, parentspecifier, "updateAuthorityItem(parent)", "UPDATE_ITEM", null);
-        String parentcsid = csidAndShortId.CSID;
-        String parentShortId = csidAndShortId.shortIdentifier;
-        //
-        // If the itemServiceCtx context is not null, use it.  Otherwise, create a new context
-        //
-        ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = itemServiceCtx;
-        if (ctx == null) {
-               ctx = createServiceContext(getItemServiceName(), theUpdate, resourceMap, uriInfo);
-        } else {
-               ctx.setInput(theUpdate); // the update payload
-        }
-        
-        String itemcsid = lookupItemCSID(ctx, itemspecifier, parentcsid, "updateAuthorityItem(item)", "UPDATE_ITEM"); //use itemServiceCtx if it is not null
 
-        // We omit the parentShortId, only needed when doing a create...
-        AuthorityItemDocumentModelHandler handler = (AuthorityItemDocumentModelHandler)createItemDocumentHandler(ctx, parentcsid, parentShortId);
-        handler.setShouldUpdateRevNumber(shouldUpdateRevNumber);
-        if (isProposed != null) {
-               handler.setIsProposed(isProposed);
-        }
-        if (isSASItem != null) {
-               handler.setIsSASItem(isSASItem);
-        }
-        getRepositoryClient(ctx).update(ctx, itemcsid, handler);
-        result = ctx.getOutput();
-
-        return result;
-    }
 
     /**
      * Delete authorityItem.
@@ -1383,8 +1464,10 @@ public abstract class AuthorityResource<AuthCommon, AuthItemHandler>
         try {
                parentcsid = lookupParentCSID(ctx, parentIdentifier, "deleteAuthorityItem(parent)", "DELETE_ITEM", null);
         } catch (DocumentNotFoundException de) {
-               logger.warn(String.format("Could not find parent with ID='%s' when trying to delete item ID='%s'",
-                               parentIdentifier, itemIdentifier));
+               String msg = String.format("Could not find parent with ID='%s' when trying to delete item ID='%s'",
+                               parentIdentifier, itemIdentifier);
+               logger.warn(msg);
+               throw de;
         }
         String itemCsid = lookupItemCSID(ctx, itemIdentifier, parentcsid, "deleteAuthorityItem(item)", "DELETE_ITEM"); //use itemServiceCtx if it is not null
         
index 2affc2a4d4fad1285c0eadb3263649e55f6cbe44..aee8388201f648b5b29d48b84a4e8e56d513d41c 100644 (file)
@@ -5,7 +5,7 @@ public class DocumentReferenceException extends DocumentException {
         * 
         */
        private static final long serialVersionUID = 1L;
-       final public static int HTTP_CODE = 500;
+       final public static int HTTP_CODE = 409; // Conflict response.  There may be a dependency issue.  For example, trying to delete a term from an authority that is being referenced in another record.
 
     /**
      * Creates a new instance of <code>DocumentNotFoundException</code> without detail message.
index 034535d643bf81e247c008e126576e8ef413b694..caa828e7f0556f60603bdcc6f23bae2fecb7ae42 100644 (file)
@@ -43,6 +43,9 @@ import org.collectionspace.services.common.document.JaxbUtils;
 import org.collectionspace.services.common.repository.RepositoryClient;
 import org.collectionspace.services.common.vocabulary.AuthorityResource;
 import org.collectionspace.services.common.vocabulary.AuthorityServiceUtils;
+import org.collectionspace.services.common.vocabulary.RefNameServiceUtils;
+import org.collectionspace.services.common.vocabulary.RefNameServiceUtils.Specifier;
+import org.collectionspace.services.common.vocabulary.RefNameServiceUtils.SpecifierForm;
 import org.collectionspace.services.jaxb.AbstractCommonList;
 import org.collectionspace.services.jaxb.AbstractCommonList.ListItem;
 import org.collectionspace.services.nuxeo.client.java.CoreSessionInterface;
@@ -57,6 +60,7 @@ import org.w3c.dom.Element;
 
 import javax.ws.rs.GET;
 import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
 import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
 import javax.ws.rs.core.Context;
@@ -70,6 +74,10 @@ import javax.ws.rs.core.UriInfo;
 public class VocabularyResource extends 
        AuthorityResource<VocabulariesCommon, VocabularyItemDocumentModelHandler> {
 
+       private enum Method {
+        POST, PUT;
+    }
+       
     private final static String vocabularyServiceName = VocabularyClient.SERVICE_PATH_COMPONENT;
 
        private final static String VOCABULARIES_COMMON = "vocabularies_common";
@@ -84,8 +92,8 @@ public class VocabularyResource extends
                                VOCABULARIES_COMMON, VOCABULARYITEMS_COMMON);
        }
 
-    @Override
        @POST
+    @Override
     public Response createAuthority(
                @Context ResourceMap resourceMap,
                @Context UriInfo uriInfo,
@@ -107,7 +115,7 @@ public class VocabularyResource extends
                                try {
                            DocumentHandler<?, AbstractCommonList, DocumentModel, DocumentModelList> handler = createDocumentHandler(ctx);                          
                            String csid = repoClient.create(ctx, handler);
-                           handleItemsPayload(repoSession, csid, resourceMap, uriInfo, input);
+                           handleItemsPayload(Method.POST, repoSession, csid, resourceMap, uriInfo, input);
                            UriBuilder path = UriBuilder.fromResource(resourceClass);
                            path.path("" + csid);
                            Response response = Response.created(path.build()).build();
@@ -123,24 +131,139 @@ public class VocabularyResource extends
                }
        }
     }
+        
+    @PUT
+    @Path("{csid}")
+    @Override
+    public byte[] updateAuthority(
+               @Context ResourceMap resourceMap,
+               @Context UriInfo uriInfo,
+            @PathParam("csid") String specifier,
+            String xmlPayload) {
+        PoxPayloadOut result = null;
+        try {
+            PoxPayloadIn theUpdate = new PoxPayloadIn(xmlPayload);
+            Specifier spec = Specifier.getSpecifier(specifier, "updateAuthority", "UPDATE");
+            ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = createServiceContext(theUpdate);
+                       RepositoryClient<PoxPayloadIn, PoxPayloadOut> repoClient = this.getRepositoryClient(ctx);
+
+                       CoreSessionInterface repoSession = repoClient.getRepositorySession(ctx);
+                       try {
+                   DocumentHandler<?, AbstractCommonList, DocumentModel, DocumentModelList> handler = createDocumentHandler(ctx);
+                   String csid;
+                   if (spec.form == SpecifierForm.CSID) {
+                       csid = spec.value;
+                   } else {
+                       String whereClause = RefNameServiceUtils.buildWhereForAuthByName(authorityCommonSchemaName, spec.value);
+                       csid = getRepositoryClient(ctx).findDocCSID(null, ctx, whereClause);
+                   }
+                   getRepositoryClient(ctx).update(ctx, csid, handler);
+                   handleItemsPayload(Method.PUT, repoSession, csid, resourceMap, uriInfo, theUpdate);
+                   result = ctx.getOutput();
+            } catch (Throwable t) {
+               repoSession.setTransactionRollbackOnly();
+               throw t;
+            } finally {
+               repoClient.releaseRepositorySession(ctx, repoSession);
+            }
+        } catch (Exception e) {
+            throw bigReThrow(e, ServiceMessages.UPDATE_FAILED);
+        }
+        return result.getBytes();
+    }
     
-    private void handleItemsPayload(CoreSessionInterface repoSession,
+    private boolean handleItemsPayload(
+               Method method,
+               CoreSessionInterface repoSession,
                String parentIdentifier,
                ResourceMap resourceMap,
                UriInfo uriInfo,
                PoxPayloadIn input) throws Exception {
+       boolean result = true;
+       
        PayloadInputPart abstractCommonListPart  = input.getPart(PoxPayload.ABSTRACT_COMMON_LIST_ROOT_ELEMENT_LABEL);
        if (abstractCommonListPart != null) {
                AbstractCommonList itemsList = (AbstractCommonList) abstractCommonListPart.getBody();
                for (ListItem item : itemsList.getListItem()) {
+                       String errMsg = null;
+                       boolean success = true;
+                       Response response = null;
+                       PoxPayloadOut payloadOut = null;
                        PoxPayloadIn itemXmlPayload = getItemXmlPayload(item);
-                       Response res = this.createAuthorityItem(repoSession, resourceMap, uriInfo, parentIdentifier, itemXmlPayload);
+                       switch (method) {
+                               case POST:
+                                       response = this.createAuthorityItem(repoSession, resourceMap, uriInfo, parentIdentifier, itemXmlPayload);
+                                       if (response.getStatus() != Response.Status.CREATED.getStatusCode()) {
+                                               success = false;
+                                               errMsg = String.format("Could not create the term list payload of vocabuary '%s'.", parentIdentifier);
+                                       }
+                                       break;
+                               case PUT:
+                                       String itemSpecifier = getSpecifier(item);
+                                       if (itemSpecifier != null) {
+                                               payloadOut = updateAuthorityItem(repoSession, resourceMap, uriInfo, parentIdentifier, itemSpecifier, itemXmlPayload);
+                                               if (payloadOut == null) {
+                                                       success = false;
+                                                       errMsg = String.format("Could not update the term list payload of vocabuary '%s'.", parentIdentifier);
+                                               }
+                                       } else {
+                                               success = false;
+                                               errMsg = String.format("Could not update the term list payload of vocabuary '%s' because one of the item is missing a CSID or short identifier value.",
+                                                               parentIdentifier);
+                                       }
+                                       break;                                  
+                       }
+                       //
+                       // Throw an exception as soon as we have problems with any item
+                       //
+                       if (success == false) {
+                                       throw new DocumentException(errMsg);
+                       }
                }
        }
        
-       }
+       return result;
+       }    
     
     /**
+     * We'll return null if we can create a specifier from the list item.
+     * 
+     * @param item
+     * @return
+     */
+    private String getSpecifier(ListItem item) {
+               String result = null;
+
+               String csid = null;
+               for (Element ele : item.getAny()) {
+                       String fieldName = ele.getTagName();
+                       String fieldValue = ele.getTextContent();
+                       if (fieldName.equalsIgnoreCase("csid")) {
+                               result = csid = fieldValue;
+                               break;
+                       }
+               }
+               
+               if (csid == null) {
+                       String shortId = null;
+                       for (Element ele : item.getAny()) {
+                               String fieldName = ele.getTagName();
+                               String fieldValue = ele.getTextContent();
+                               if (fieldName.equalsIgnoreCase("shortIdentifier")) {
+                                       shortId = fieldValue;
+                                       break;
+                               }
+                       }
+                       
+                       if (shortId != null) {
+                               result = Specifier.createShortIdURNValue(shortId);
+                       }
+               }
+
+               return result;
+       }
+
+       /**
      * This is very brittle.  If the class VocabularyitemsCommon changed with new fields we'd have to
      * update this method.
      * 
@@ -178,7 +301,12 @@ public class VocabularyResource extends
                                        
                                case "description":
                                        vocabularyItem.setDescription(fieldValue);
+                                       break;
                                        
+                               case "csid":
+                                       vocabularyItem.setCsid(fieldValue);
+                                       break;
+
                                default:
                                        throw new DocumentException(String.format("Unknown field '%s' in vocabulary item payload.",
                                                        fieldName));
@@ -207,7 +335,26 @@ public class VocabularyResource extends
 
         return result;
     }
-    
+       
+       private PoxPayloadOut updateAuthorityItem(
+               CoreSessionInterface repoSession,
+               ResourceMap resourceMap,
+               UriInfo uriInfo,
+               String parentSpecifier, // Either a CSID or a URN form -e.g., a8ad38ec-1d7d-4bf2-bd31 or urn:cspace:name(bugsbunny)
+               String itemSpecifier,   // Either a CSID or a URN form.
+               PoxPayloadIn theUpdate) throws Exception {
+       PoxPayloadOut result = null;
+       
+        ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = createServiceContext(getItemServiceName(), theUpdate, resourceMap, uriInfo);
+        ctx.setCurrentRepositorySession(repoSession);
+        
+        result = updateAuthorityItem(ctx, resourceMap, uriInfo, parentSpecifier, itemSpecifier, theUpdate,
+                       AuthorityServiceUtils.UPDATE_REV,                       // passing TRUE so rev num increases, passing
+                       AuthorityServiceUtils.NO_CHANGE,        // don't change the state of the "proposed" field -we could be performing a sync or just a plain update
+                       AuthorityServiceUtils.NO_CHANGE);       // don't change the state of the "sas" field -we could be performing a sync or just a plain update
+
+        return result;
+    }
 
        @GET
     @Path("{csid}")