]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
5459dce866cf98fccb349ea14b144acd7d1a5508
[tmp/jakarta-migration.git] /
1 package org.collectionspace.services.client.test;
2
3 import java.lang.reflect.Array;
4 import java.util.ArrayList;
5 import java.util.HashMap;
6 import java.util.List;
7 import java.util.Map;
8
9 import javax.ws.rs.core.Response;
10
11 import org.collectionspace.services.client.AbstractCommonListUtils;
12 import org.collectionspace.services.client.AuthorityClient;
13 import org.collectionspace.services.client.AuthorityClientImpl;
14 import org.collectionspace.services.client.AuthorityProxy;
15 import org.collectionspace.services.client.CollectionSpaceClient;
16 import org.collectionspace.services.client.PayloadInputPart;
17 import org.collectionspace.services.client.PayloadOutputPart;
18 import org.collectionspace.services.client.PoxPayloadIn;
19 import org.collectionspace.services.client.PoxPayloadOut;
20 import org.collectionspace.services.client.XmlTools;
21 import org.collectionspace.services.client.workflow.WorkflowClient;
22 import org.collectionspace.services.jaxb.AbstractCommonList;
23 import org.dom4j.Document;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
26 import org.testng.Assert;
27 import org.testng.annotations.Test;
28
29 /**
30  * 
31  * @author remillet
32  *
33  * @param <AUTHORITY_COMMON_TYPE>
34  * @param <AUTHORITY_ITEM_TYPE>
35  * 
36  * All CRUD related authority test classes should extend this class.
37  * 
38  */
39 public abstract class AbstractAuthorityServiceTest<AUTHORITY_COMMON_TYPE, AUTHORITY_ITEM_TYPE> 
40         extends AbstractPoxServiceTestImpl<AbstractCommonList, AUTHORITY_COMMON_TYPE> {
41
42     private final Logger logger = LoggerFactory.getLogger(AbstractAuthorityServiceTest.class);
43         
44     protected String knownResourceShortIdentifer = null;
45         protected static final String READITEMS_SHORT_IDENTIFIER = "resourceWithItems" + random.nextInt(1000); 
46         protected String knownAuthorityWithItems = null;
47         protected String knownAuthorityWithItemsIdentifier = null;
48         
49         protected static final String SAS_IDENTIFIER = "SAS";
50
51         private static final int SAS_ITEMLIST_SIZE = 5; 
52         protected String knownSASAuthorityResourceId = null;
53         protected String knownSASAuthorityResourceIdentifier = null;
54         protected List<String> knownSASItemIdentifiersList = new ArrayList<String>();
55         protected String knownSASItemResourceId = null;
56         protected HashMap<String, String> allSASResourceItemIdsCreated = new HashMap<String, String>(); /* itemURN, parentURN */;
57
58         protected String knownResourceRefName = null;
59     protected String knownItemResourceId = null;
60     protected String knownItemResourceShortIdentifer = null;    
61     protected int nItemsToCreateInList = 5;
62     protected String TEST_SHORTID = "johnWayneActor";
63
64     /*
65      * Abstract methods that subclasses must override/implement
66      */
67     
68     /**
69      * 
70      * @param testName
71      */
72     public abstract void authorityTests(String testName);
73         
74         /**
75          * 
76          * @param client
77          * @param vcsid
78          * @return
79          */
80         abstract protected String createItemInAuthority(AuthorityClient client, String vcsid, String shortId);
81         
82     
83     /**
84      * 
85      * @param authorityItem
86      * @return
87      */
88     protected abstract AUTHORITY_ITEM_TYPE updateItemInstance(final AUTHORITY_ITEM_TYPE authorityItem);    
89     
90     /**
91      * 
92      * @param original
93      * @param updated
94      * @throws Exception
95      */
96     protected abstract void compareUpdatedItemInstances(AUTHORITY_ITEM_TYPE original,
97                 AUTHORITY_ITEM_TYPE updated,
98                 boolean compareRevNumbers) throws Exception;
99     
100     /**
101      * 
102      * @param original
103      * @param updated
104      * @throws Exception
105      */
106     protected void compareUpdatedItemInstances(AUTHORITY_ITEM_TYPE original,
107                 AUTHORITY_ITEM_TYPE updated) throws Exception {
108         compareUpdatedItemInstances(original, updated, false);
109     }
110     
111     /**
112      * 
113      * @param id
114      * @param shortIdentifer
115      */
116     protected void setKnownItemResource(String id, String shortIdentifer ) {
117         knownItemResourceId = id;
118         knownItemResourceShortIdentifer = shortIdentifer;
119     }
120
121     /**
122      * 
123      * @param id
124      * @param shortIdentifer
125      * @param refName
126      */
127     protected void setKnownResource(String id, String shortIdentifer,
128             String refName) {
129         knownResourceId = id;
130         knownResourceShortIdentifer = shortIdentifer;
131         knownResourceRefName = refName;
132     }
133
134     /**
135      * 
136      * @return
137      */
138         protected String getSASAuthorityIdentifier() {
139                 // TODO Auto-generated method stub
140                 return this.getKnowResourceIdentifier() + SAS_IDENTIFIER;
141         }
142     
143         /**
144          * 
145          * @param shortId
146          * @return
147          */
148         protected String getUrnIdentifier(String shortId) {
149                 return String.format("urn:cspace:name(%s)", shortId);
150         }
151         
152     /**
153      * Sets up create tests.
154      */
155     protected void setupSync() {
156         testExpectedStatusCode = this.STATUS_OK;
157         testRequestType = ServiceRequestType.SYNC;
158         testSetup(testExpectedStatusCode, testRequestType);
159     }
160     
161     /**
162      * Gets a client to the SAS (Shared Authority Server)
163      *
164      * @return the client
165      */
166     protected AuthorityClient getSASClientInstance() {
167         return (AuthorityClient) this.getClientInstance(CollectionSpaceClient.SAS_CLIENT_PROPERTIES_FILENAME);
168     }
169
170     /**
171      * Returns the root URL for a service.
172      *
173      * This URL consists of a base URL for all services, followed by
174      * a path component for the owning vocabulary, followed by the 
175      * path component for the items.
176      *
177      * @return The root URL for a service.
178      */
179     protected String getItemServiceRootURL(String parentResourceIdentifier) {
180         return getResourceURL(parentResourceIdentifier) + "/" + getServicePathItemsComponent();
181     }
182
183     /**
184      * Returns the URL of a specific resource managed by a service, and
185      * designated by an identifier (such as a universally unique ID, or UUID).
186      *
187      * @param  resourceIdentifier  An identifier (such as a UUID) for a resource.
188      *
189      * @return The URL of a specific resource managed by a service.
190      */
191     protected String getItemResourceURL(String parentResourceIdentifier, String resourceIdentifier) {
192         return getItemServiceRootURL(parentResourceIdentifier) + "/" + resourceIdentifier;
193     }
194         
195     /**
196      * For authorities we override this method so we can save the shortid.
197      */
198     @Override
199     protected String createWithIdentifier(String testName, String identifier) throws Exception {
200         String csid = createResource(testName, identifier);
201         // Store the ID returned from the first resource created
202         // for additional tests below.
203         if (getKnowResourceId() == null) {
204                 setKnownResource(csid, identifier /*shortId*/, null /*refname*/ );
205             if (logger.isDebugEnabled()) {
206                 logger.debug(testName + ": Setting knownResourceId=" + getKnowResourceId());
207             }
208         }
209         
210         return identifier;
211     }    
212     
213     @Test(dependsOnMethods = {"readItem", "CRUDTests"})
214     public void testItemSubmitRequest() {
215
216         // Expected status code: 200 OK
217         final int EXPECTED_STATUS = Response.Status.OK.getStatusCode();
218
219         // Submit the request to the service and store the response.
220         String method = ServiceRequestType.READ.httpMethodName();
221         String url = getItemResourceURL(knownResourceId, knownItemResourceId);
222         int statusCode = submitRequest(method, url);
223
224         // Check the status code of the response: does it match
225         // the expected response(s)?
226         if (logger.isDebugEnabled()) {
227             logger.debug("testItemSubmitRequest: url=" + url
228                     + " status=" + statusCode);
229         }
230         Assert.assertEquals(statusCode, EXPECTED_STATUS);
231     }    
232
233     
234     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
235         dependsOnMethods = {"readItem"})
236     public void verifyIgnoredUpdateWithInAuthority(String testName) throws Exception {
237         // Perform setup.
238         setupUpdate();
239
240         // Submit the request to the service and store the response.
241         AuthorityClient client = (AuthorityClient)this.getClientInstance();
242         Response res = client.readItem(knownResourceId, knownItemResourceId);
243         AUTHORITY_ITEM_TYPE vitem = null;
244         try {
245                 int statusCode = res.getStatus();
246         
247                 // Check the status code of the response: does it match
248                 // the expected response(s)?
249                 if (logger.isDebugEnabled()) {
250                         logger.debug(testName + " read authority:" + knownResourceId + "/Item:"
251                                         + knownItemResourceId + " status = " + statusCode);
252                 }
253                 Assert.assertTrue(testRequestType.isValidStatusCode(statusCode),
254                                 invalidStatusCodeMessage(testRequestType, statusCode));
255                 Assert.assertEquals(statusCode, Response.Status.OK.getStatusCode());
256         
257                 vitem = extractItemCommonPartValue(res);
258                 Assert.assertNotNull(vitem);
259                 // Try to Update with new parent vocab (use self, for test).
260                 Assert.assertEquals(client.getInAuthority(vitem), knownResourceId,
261                                 "VocabularyItem inAuthority does not match knownResourceId.");
262                 client.setInAuthority(vitem, knownItemResourceId);
263
264         } finally {
265                 res.close();
266         }
267         
268         // Submit the updated resource to the service and store the response.
269         PoxPayloadOut output = this.createItemRequestTypeInstance(vitem);
270         res = client.updateItem(knownResourceId, knownItemResourceId, output);
271         try {
272                 int statusCode = res.getStatus();
273         
274                 // Check the status code of the response: does it match the expected response(s)?
275                 if (logger.isDebugEnabled()) {
276                         logger.debug(testName + ": status = " + statusCode);
277                 }
278                 Assert.assertTrue(testRequestType.isValidStatusCode(statusCode),
279                                 invalidStatusCodeMessage(testRequestType, statusCode));
280                 Assert.assertEquals(statusCode, testExpectedStatusCode);
281         } finally {
282                 res.close();
283         }
284         
285         res = client.readItem(knownResourceId, knownItemResourceId);
286         try {
287                 // Retrieve the updated resource and verify that the parent did not change
288                 AUTHORITY_ITEM_TYPE updatedVocabularyItem = extractItemCommonPartValue(res);
289                 Assert.assertNotNull(updatedVocabularyItem);
290         
291                 // Verify that the updated resource received the correct data.
292                 Assert.assertEquals(client.getInAuthority(updatedVocabularyItem),
293                                 knownResourceId,
294                                 "VocabularyItem allowed update to the parent (inAuthority).");
295         } finally {
296                 res.close();
297         }
298     }
299     
300     @Test(dataProvider = "testName", dependsOnMethods = {"CRUDTests"})
301     public void createItem(String testName) {
302         // Perform setup.
303         setupCreate();
304
305         String newID = createItemInAuthority((AuthorityClient) getClientInstance(), knownResourceId, getTestAuthorityItemShortId());
306
307         // Store the ID returned from the first item resource created
308         // for additional tests below.
309         if (knownItemResourceId == null) {
310             knownItemResourceId = newID;
311             if (null != testName && logger.isDebugEnabled()) {
312                 logger.debug(testName + ": knownItemResourceId=" + knownItemResourceId);
313             }
314         }
315     }
316         
317     /**
318      * Sync the local with the SAS
319      * @throws Exception 
320      */
321     @Test(dataProvider = "testName", dependsOnMethods = {"createSASItemList", "CRUDTests"})
322     public void syncWithSAS(String testName) throws Exception {
323         //
324         // First check to see if the authority supports synchronization.
325         //
326         AuthorityClient client = (AuthorityClient) this.getClientInstance();
327         if (client.supportsSync() == false) {
328                 return; // Exit the test since this authority doesn't support synchronization
329         }
330         
331         //
332         // Create an empty instance of the authority, so we can sync items with it.  We're
333         // using the short ID of the SAS authority.  The short ID of the local and the SAS will (must) be the same.
334         //
335         String localAuthorityId = null;
336         try {
337                         localAuthorityId = createResource(client, testName, knownSASAuthorityResourceIdentifier, false);
338                 } catch (Exception e) {
339                         Assert.assertNotNull(localAuthorityId);
340                 }
341
342         //
343         // Now we can try to sync the SAS authority with the local one we just created.
344         //
345         setupSync();
346         Response response = client.syncByName(knownSASAuthorityResourceIdentifier); // Notice we're using the Short ID (short ID is the same on the local and SAS)
347         try {
348                 int statusCode = response.getStatus();
349                 Assert.assertTrue(testRequestType.isValidStatusCode(statusCode),
350                         invalidStatusCodeMessage(testRequestType, statusCode));
351                 Assert.assertEquals(statusCode, testExpectedStatusCode);
352         } finally {
353                 response.close();
354         }
355         
356         //
357         // Check to see if the parent authority (local) is in the "Replicated" state.
358         //
359         setupRead();
360         response = client.readByName(knownSASAuthorityResourceIdentifier); // Notice we're using the Short ID (short ID is the same on the local and SAS)
361         try {
362                 int statusCode = response.getStatus();
363                 Assert.assertTrue(testRequestType.isValidStatusCode(statusCode),
364                         invalidStatusCodeMessage(testRequestType, statusCode));
365                 Assert.assertEquals(statusCode, testExpectedStatusCode);
366                         String workflowState = this.extractAuthorityWorkflowState(response);
367                         Assert.assertTrue(workflowState.contains(WorkflowClient.WORKFLOWSTATE_REPLICATED));  // After a sync, the parent should be in the "Replicated" state
368         } finally {
369                 response.close();
370         }        
371         
372     }
373     
374     /**
375      * Check to make sure the sync with the SAS returned the correct number of items as well as items
376      * with the correct short IDs.
377      * 
378      */
379     @Test(dataProvider = "testName", dependsOnMethods = {"syncWithSAS", "CRUDTests"})
380     public void veryifySyncWithSAS(String testName) {
381         //
382         // First check to see if we support sync.
383         //
384         AuthorityClient client = (AuthorityClient) getClientInstance();
385         if (client.supportsSync() == false) {
386                 return; // Exit the test since this authority doesn't support synchronization
387         }        
388
389         // Perform setup.
390         setupReadList();
391
392         // Submit the request to the service and store the response.
393         Response res = null;
394         res = client.readItemListForNamedAuthority(knownSASAuthorityResourceIdentifier, null, null);
395
396         try {
397                 int statusCode = res.getStatus();
398         
399                 // Check the status code of the response: does it match
400                 // the expected response(s)?
401                 if (logger.isDebugEnabled()) {
402                     logger.debug("  " + testName + ": status = " + statusCode);
403                 }
404                 Assert.assertTrue(testRequestType.isValidStatusCode(statusCode),
405                         invalidStatusCodeMessage(testRequestType, statusCode));
406                 Assert.assertEquals(statusCode, testExpectedStatusCode);
407         
408                 AbstractCommonList list = res.readEntity(AbstractCommonList.class);
409                 List<AbstractCommonList.ListItem> items = list.getListItem();
410                 int nItemsReturned = items.size();
411                 long nItemsTotal = list.getTotalItems();
412                 if (logger.isDebugEnabled()) {
413                     logger.debug("  " + testName + ": Expected "
414                             + nItemsToCreateInList + " items; got: " + nItemsReturned + " of: " + nItemsTotal);
415                 }
416                 Assert.assertEquals(nItemsTotal, SAS_ITEMLIST_SIZE);
417         
418                         for (AbstractCommonList.ListItem item : items) {
419                                 String shortId = AbstractCommonListUtils.ListItemGetElementValue(
420                                                 item, AuthorityClient.SHORT_IDENTIFIER);
421                                 Assert.assertTrue(knownSASItemIdentifiersList.contains(shortId)); // The local short ID should be in SAS list
422                                 
423                                 String workflowState = AbstractCommonListUtils.ListItemGetElementValue(
424                                                 item, CollectionSpaceClient.COLLECTIONSPACE_CORE_WORKFLOWSTATE);
425                                 Assert.assertTrue(workflowState.contains(WorkflowClient.WORKFLOWSTATE_REPLICATED)); // Workflow state must show up in a "replicated" state
426                                 
427                                 String refName = AbstractCommonListUtils.ListItemGetElementValue(
428                                                 item, AuthorityClient.REF_NAME);
429                                 Assert.assertTrue((refName != null), "Item refName is null or not set in the item list!");
430                                 String termDisplayName = AbstractCommonListUtils.ListItemGetElementValue(item,
431                                                 AuthorityClient.TERM_DISPLAY_NAME);
432                                 String vocabDisplayName = AbstractCommonListUtils.ListItemGetElementValue(item,
433                                                 AuthorityClient.VOCAB_DISPLAY_NAME);
434                                 // One of these names needs to be set.
435                                 Assert.assertTrue(!(termDisplayName == null && vocabDisplayName == null), "The item's display name is null or not set in the item list!");
436                         }
437                 
438                 if(logger.isTraceEnabled()){
439                         AbstractCommonListUtils.ListItemsInAbstractCommonList(list, logger, testName);
440                 }
441         } finally {
442                 res.close();
443         }
444     }
445         
446     /**
447      * SAS - Create a new authority on the SAS server.
448      * @param testName
449      */    
450     @Test(dataProvider = "testName", dependsOnMethods = {"createItem", "CRUDTests"})
451     public void createSASAuthority(String testName) {
452         //
453         // First check to see if the authority supports synchronization.
454         //
455         AuthorityClient client = (AuthorityClient) this.getClientInstance();
456         if (client.supportsSync() == false) {
457                 return; // Exit the test since this authority doesn't support synchronization
458         }
459         
460         // Perform setup.
461         setupCreate();
462
463         try {
464                 String newID = createResource(getSASClientInstance(), testName, getSASAuthorityIdentifier(), true);
465                 knownSASAuthorityResourceId = newID;
466                 knownSASAuthorityResourceIdentifier = getShortId(getSASClientInstance(), knownSASAuthorityResourceId);
467             if (logger.isDebugEnabled()) {
468                 String.format("Created SAS authority '%s' with CSID=%s.", getSASAuthorityIdentifier(), newID);
469             }
470         } catch (Exception e) {
471                 logger.info(String.format("Failed to create SAS authority '%s'.", getSASAuthorityIdentifier()));
472         }
473     }
474
475     /**
476      * SAS - Create an item in the SAS authority on the SAS server.
477      * @param testName
478      */
479     @Test(dataProvider = "testName", dependsOnMethods = {"createSASAuthority", "CRUDTests"})
480     public void createSASItemList(String testName) {
481         //
482         // First check to see if the authority supports synchronization.
483         //
484         AuthorityClient client = (AuthorityClient) this.getClientInstance();
485         if (client.supportsSync() == false) {
486                 return; // Exit the test since this authority doesn't support synchronization
487         }
488         
489         // Perform setup.
490         setupCreate();
491
492         for (int i = 0; i < SAS_ITEMLIST_SIZE; i++) {
493                 String shortId = "SassyActor" + System.currentTimeMillis() + Math.abs(random.nextInt()); // short ID needs to be unique
494                 String newID = createItemInAuthority(getSASClientInstance(), knownSASAuthorityResourceId, shortId);
495         
496                         // Store the ID returned from the first item resource created
497                 // for additional tests below.
498                 if (knownSASItemResourceId == null) {
499                         knownSASItemResourceId = newID;
500                     if (null != testName && logger.isDebugEnabled()) {
501                         logger.debug(testName + ": knownSASItemResourceId=" + knownSASItemResourceId);
502                     }
503                 }
504                 
505                 knownSASItemIdentifiersList.add(shortId);
506
507                 //
508                 // Keep track of the SAS authority items we create, so we can delete them from
509                 // the *local* authority after we perform a sync operation.  We need to keep track
510                 // of the URN (not the CSID) since the CSIDs will differ on the SAS vs local.
511                 //
512                 this.allSASResourceItemIdsCreated.put(this.getUrnIdentifier(shortId), getUrnIdentifier(getSASAuthorityIdentifier()));
513         }
514         
515     }
516     
517     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
518                 dependsOnMethods = {"createItem"})
519     public void createItemList(String testName) throws Exception {
520         knownAuthorityWithItems = createResource(testName, READITEMS_SHORT_IDENTIFIER);
521         knownAuthorityWithItemsIdentifier = getShortId(knownAuthorityWithItems);
522         for (int j = 0; j < nItemsToCreateInList; j++) {
523                 createItemInAuthority((AuthorityClient) getClientInstance(), knownAuthorityWithItems, this.getTestAuthorityItemShortId(true));
524         }
525     }
526     
527     private String getShortId(AuthorityClient client, String authorityCsid) throws Exception {
528         String result = null;
529         
530         // Submit the request to the service and store the response.
531         Response res = client.read(authorityCsid);
532         try {
533                 int statusCode = res.getStatus();
534                 result = this.extractAuthorityShortId(res);
535         } finally {
536                 res.close();
537         }
538         
539         return result;
540     }
541     
542     private String getShortId(String authorityCsid) throws Exception {
543         AuthorityClient client = (AuthorityClient) getClientInstance();
544         return getShortId(client, authorityCsid);
545     }
546
547     /**
548      * Read by name.
549      *
550      * @param testName the test name
551      * @throws Exception the exception
552      */
553     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
554                 dependsOnMethods = {"CRUDTests"})
555     public void readByName(String testName) throws Exception {
556         // Perform setup.
557         setupRead();
558
559         // Submit the request to the service and store the response.
560         AuthorityClient client = (AuthorityClient) this.getClientInstance();
561         Response res = client.readByName(getKnowResourceIdentifier());
562         try {
563                 int statusCode = res.getStatus();
564         
565                 // Check the status code of the response: does it match
566                 // the expected response(s)?
567                 if (logger.isDebugEnabled()) {
568                     logger.debug(testName + ": status = " + statusCode);
569                 }
570                 Assert.assertTrue(testRequestType.isValidStatusCode(statusCode),
571                         invalidStatusCodeMessage(testRequestType, statusCode));
572                 Assert.assertEquals(statusCode, testExpectedStatusCode);
573                 
574                 AUTHORITY_COMMON_TYPE commonPart = extractCommonPartValue(res);
575                 Assert.assertNotNull(commonPart);
576         } finally {
577                 res.close();
578         }
579     }
580     
581     /**
582      * Extracts the common part item from a service's item payload.
583      * 
584      * @param res
585      * @return
586      * @throws Exception
587      */
588         public AUTHORITY_ITEM_TYPE extractItemCommonPartValue(Response res) throws Exception {
589                 AUTHORITY_ITEM_TYPE result = null;
590                 
591         AuthorityClient client = (AuthorityClient) getClientInstance();
592                 PayloadInputPart payloadInputPart = extractPart(res, client.getItemCommonPartName());
593                 if (payloadInputPart != null) {
594                         result = (AUTHORITY_ITEM_TYPE) payloadInputPart.getBody();
595                 }
596                 Assert.assertNotNull(result,
597                                 "Part or body of part " + client.getCommonPartName() + " was unexpectedly null.");
598                 
599                 return result;
600         }
601                 
602         
603     /**
604      * Extracts the short ID from a service request payload
605      * 
606      * @param res
607      * @return
608      * @throws Exception
609      */
610         protected String extractAuthorityShortId(Response res) throws Exception {
611                 String result = null;
612                 
613         PoxPayloadIn input = new PoxPayloadIn((String)res.readEntity(getEntityResponseType()));         
614                 Document document = input.getDOMDocument();
615                 result = XmlTools.getElementValue(document, "//" + AuthorityClient.SHORT_IDENTIFIER);
616
617                 return result;
618         }    
619         
620     
621     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
622                 dependsOnMethods = {"readItem"})
623     public void readItemNonExistent(String testName) {
624         // Perform setup.
625         setupReadNonExistent();
626
627         // Submit the request to the service and store the response.
628         AuthorityClient client = (AuthorityClient) getClientInstance();
629         Response res = client.readItem(knownResourceId, NON_EXISTENT_ID);
630         try {
631                 int statusCode = res.getStatus();
632         
633                 // Check the status code of the response: does it match
634                 // the expected response(s)?
635                 if (logger.isDebugEnabled()) {
636                     logger.debug(testName + ": status = " + statusCode);
637                 }
638                 Assert.assertTrue(testRequestType.isValidStatusCode(statusCode),
639                         invalidStatusCodeMessage(testRequestType, statusCode));
640                 Assert.assertEquals(statusCode, testExpectedStatusCode);
641         } finally {
642                 res.close();
643         }
644     }
645         
646     @Test(dataProvider = "testName",
647                 dependsOnMethods = {"createItem"})
648     public void readItem(String testName) throws Exception {
649         // Perform setup.
650         setupRead();
651
652         // Submit the request to the service and store the response.
653         AuthorityClient client = (AuthorityClient) getClientInstance();
654         Response res = client.readItem(knownResourceId, knownItemResourceId);
655         try {
656                 int statusCode = res.getStatus();
657         
658                 // Check the status code of the response: does it match
659                 // the expected response(s)?
660                 if (logger.isDebugEnabled()) {
661                     logger.debug(testName + ": status = " + statusCode);
662                 }
663                 Assert.assertTrue(testRequestType.isValidStatusCode(statusCode),
664                         invalidStatusCodeMessage(testRequestType, statusCode));
665                 Assert.assertEquals(statusCode, testExpectedStatusCode);
666         
667                 AUTHORITY_ITEM_TYPE itemCommonPart = extractItemCommonPartValue(res);
668                 Assert.assertNotNull(itemCommonPart);
669                 Assert.assertEquals(client.getInAuthority(itemCommonPart), knownResourceId);
670                 verifyReadItemInstance(itemCommonPart);
671         } finally {
672                 res.close();
673         }
674     }
675     
676     protected abstract void verifyReadItemInstance(AUTHORITY_ITEM_TYPE item) throws Exception;
677         
678     @Test(dataProvider = "testName",
679                 dependsOnMethods = {"testItemSubmitRequest", "updateItem", "verifyIgnoredUpdateWithInAuthority"})    
680     public void deleteItem(String testName) throws Exception {
681         // Perform setup.
682         setupDelete();
683
684         // Submit the request to the service and store the response.
685         AuthorityClient client = (AuthorityClient) getClientInstance();
686         Response res = client.deleteItem(knownResourceId, knownItemResourceId);
687         int statusCode;
688         try {
689                 statusCode = res.getStatus();
690         } finally {
691                 res.close();
692         }
693
694         // Check the status code of the response: does it match
695         // the expected response(s)?
696         if (logger.isDebugEnabled()) {
697             logger.debug("delete: status = " + statusCode);
698         }
699         Assert.assertTrue(testRequestType.isValidStatusCode(statusCode),
700                 invalidStatusCodeMessage(testRequestType, statusCode));
701         Assert.assertEquals(statusCode, testExpectedStatusCode);
702     }
703     
704     protected void readItemListInt(String vcsid, String shortId, String testName) {
705         // Perform setup.
706         setupReadList();
707
708         // Submit the request to the service and store the response.
709         AuthorityClient client = (AuthorityClient) getClientInstance();
710         Response res = null;
711         if (vcsid != null) {
712             res = client.readItemList(vcsid, null, null);
713         } else if (shortId != null) {
714             res = client.readItemListForNamedAuthority(shortId, null, null);
715         } else {
716             Assert.fail("Internal Error: readItemList both vcsid and shortId are null!");
717         }
718         try {
719                 int statusCode = res.getStatus();
720         
721                 // Check the status code of the response: does it match
722                 // the expected response(s)?
723                 if (logger.isDebugEnabled()) {
724                     logger.debug("  " + testName + ": status = " + statusCode);
725                 }
726                 Assert.assertTrue(testRequestType.isValidStatusCode(statusCode),
727                         invalidStatusCodeMessage(testRequestType, statusCode));
728                 Assert.assertEquals(statusCode, testExpectedStatusCode);
729         
730                 AbstractCommonList list = res.readEntity(AbstractCommonList.class);
731                 List<AbstractCommonList.ListItem> items = list.getListItem();
732                 int nItemsReturned = items.size();
733                 long nItemsTotal = list.getTotalItems();
734                 if (logger.isDebugEnabled()) {
735                     logger.debug("  " + testName + ": Expected "
736                             + nItemsToCreateInList + " items; got: " + nItemsReturned + " of: " + nItemsTotal);
737                 }
738                 Assert.assertEquals(nItemsTotal, nItemsToCreateInList);
739         
740                         for (AbstractCommonList.ListItem item : items) {
741                                 String refName = AbstractCommonListUtils.ListItemGetElementValue(
742                                                 item, AuthorityClient.REF_NAME);
743                                 Assert.assertTrue((refName != null), "Item refName is null or not set in the item list!");
744                                 String termDisplayName = AbstractCommonListUtils.ListItemGetElementValue(item,
745                                                 AuthorityClient.TERM_DISPLAY_NAME);
746                                 String vocabDisplayName = AbstractCommonListUtils.ListItemGetElementValue(item,
747                                                 AuthorityClient.VOCAB_DISPLAY_NAME);
748                                 // One of these names needs to be set.
749                                 Assert.assertTrue(!(termDisplayName == null && vocabDisplayName == null), "The item's display name is null or not set in the item list!");
750                         }
751                 
752                 if(logger.isTraceEnabled()){
753                         AbstractCommonListUtils.ListItemsInAbstractCommonList(list, logger, testName);
754                 }
755         } finally {
756                 res.close();
757         }
758     }
759     
760     @Test(dataProvider = "testName", dependsOnMethods = {"createItemList"})
761     public void readItemList(String testName) {
762         readItemListInt(knownAuthorityWithItems, null, testName);
763     }
764
765     @Test(dataProvider = "testName", dependsOnMethods = {"readItemList"})
766     public void readItemListByName(String testName) {
767         readItemListInt(null, knownAuthorityWithItemsIdentifier, testName);
768     }
769
770     @Test(dataProvider = "testName",
771                 dependsOnMethods = {"deleteItem"})
772     public void deleteNonExistentItem(String testName) {
773         // Perform setup.
774         setupDeleteNonExistent();
775
776         // Submit the request to the service and store the response.
777         AuthorityClient client = (AuthorityClient) getClientInstance();
778         Response res = client.deleteItem(knownResourceId, NON_EXISTENT_ID);
779         int statusCode;
780         try {
781                 statusCode = res.getStatus();
782         } finally {
783                 res.close();
784         }
785
786         // Check the status code of the response: does it match
787         // the expected response(s)?
788         if (logger.isDebugEnabled()) {
789             logger.debug(testName + ": status = " + statusCode);
790         }
791         Assert.assertTrue(testRequestType.isValidStatusCode(statusCode),
792                 invalidStatusCodeMessage(testRequestType, statusCode));
793         Assert.assertEquals(statusCode, testExpectedStatusCode);
794     }
795     
796     protected String getServicePathItemsComponent() {
797         return AuthorityClient.ITEMS;
798     }
799     
800         public PoxPayloadOut createItemRequestTypeInstance(AUTHORITY_ITEM_TYPE itemTypeInstance) {
801                 PoxPayloadOut result = null;
802                 
803         AuthorityClient client = (AuthorityClient) getClientInstance();
804         PoxPayloadOut payloadOut = new PoxPayloadOut(this.getServicePathItemsComponent());
805         PayloadOutputPart part = payloadOut.addPart(client.getItemCommonPartName(), itemTypeInstance);
806         result = payloadOut;
807                 
808                 return result;
809         }
810
811         /**
812          * Update an Authority item.
813          * 
814          * @param testName
815          * @throws Exception
816          */
817     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
818                 dependsOnMethods = {"readItem", "CRUDTests", "verifyIgnoredUpdateWithInAuthority"})
819     public void updateItem(String testName) throws Exception {
820         // Perform setup.
821         setupUpdate();
822         AUTHORITY_ITEM_TYPE theUpdate = null;
823
824         // Retrieve the contents of a resource to update.
825         AuthorityClient client = (AuthorityClient)this.getClientInstance();
826         Response res = client.readItem(knownResourceId, knownItemResourceId);
827         try {
828                 if (logger.isDebugEnabled()) {
829                     logger.debug(testName + ": read status = " + res.getStatus());
830                 }
831                 Assert.assertEquals(res.getStatus(), testExpectedStatusCode);
832         
833                 if (logger.isDebugEnabled()) {
834                     logger.debug("got Authority item to update with ID: "
835                             + knownItemResourceId
836                             + " in authority: " + knownResourceId);
837                 }
838                 AUTHORITY_ITEM_TYPE authorityItem = extractItemCommonPartValue(res);
839                 Assert.assertNotNull(authorityItem);
840
841                 // Update the contents of this resource.
842                 theUpdate = updateItemInstance(authorityItem);
843                 if (logger.isDebugEnabled()) {
844                     logger.debug("\n\nTo be updated fields: CSID = "  + knownItemResourceId + "\n"
845                                 + objectAsXmlString(theUpdate));
846                 }
847         } finally {
848                 res.close();
849         }
850
851         // Submit the updated resource to the service and store the response.
852         PoxPayloadOut output = this.createItemRequestTypeInstance(theUpdate);
853         res = client.updateItem(knownResourceId, knownItemResourceId, output);
854         try {
855                 int statusCode = res.getStatus();
856         
857                 // Check the status code of the response: does it match the expected response(s)?
858                 if (logger.isDebugEnabled()) {
859                     logger.debug("updateItem: status = " + statusCode);
860                 }
861                 Assert.assertTrue(testRequestType.isValidStatusCode(statusCode),
862                         invalidStatusCodeMessage(testRequestType, statusCode));
863                 Assert.assertEquals(statusCode, testExpectedStatusCode);
864         
865                 // Retrieve the updated resource and verify that its contents exist.
866                 AUTHORITY_ITEM_TYPE updatedVocabularyItem = extractItemCommonPartValue(res);
867                 Assert.assertNotNull(updatedVocabularyItem);
868
869                 compareUpdatedItemInstances(theUpdate, updatedVocabularyItem);
870         } finally {
871                 res.close();
872         }
873     }
874     
875     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
876                 dependsOnMethods = {"veryifySyncWithSAS", "CRUDTests"})
877     public void updateLocalItemWithSync(String testName) throws Exception {
878         //
879         // First check to see if we support sync.
880         //
881         AuthorityClient client = (AuthorityClient) getClientInstance();
882         if (client.supportsSync() == false) {
883                 return; // Exit the test since this authority doesn't support synchronization
884         }        
885         
886         // Perform setup.
887         setupUpdate();
888         AUTHORITY_ITEM_TYPE theUpdate = null;
889
890         // Retrieve the contents of a shared authority item that we're going to update.
891         AUTHORITY_ITEM_TYPE sasAuthorityItem = null;
892         AuthorityClient sasClient = (AuthorityClient) this.getSASClientInstance();
893         Response res = sasClient.readNamedItemInNamedAuthority(knownSASAuthorityResourceIdentifier, knownSASItemIdentifiersList.get(0));
894         try {
895                 if (logger.isDebugEnabled()) {
896                     logger.debug(testName + ": read status = " + res.getStatus());
897                 }
898                 Assert.assertEquals(res.getStatus(), testExpectedStatusCode);
899         
900                 sasAuthorityItem = extractItemCommonPartValue(res);  // This is a SAS authority item
901                 Assert.assertNotNull(sasAuthorityItem);
902         } finally {
903                 res.close();
904         }
905
906         // Update the contents of this authority item so we can post an UPDATE to the server
907         theUpdate = updateItemInstance(sasAuthorityItem);
908
909         // Submit the updated authority item and check the response.
910         PoxPayloadOut output = this.createItemRequestTypeInstance(theUpdate);
911         res = sasClient.updateNamedItemInNamedAuthority(knownSASAuthorityResourceIdentifier, knownSASItemIdentifiersList.get(0), output);
912         AUTHORITY_ITEM_TYPE updatedSASAuthorityItem = null;
913         try {
914                 int statusCode = res.getStatus();
915         
916                 // Check the status code of the response: does it match the expected response(s)?
917                 if (logger.isDebugEnabled()) {
918                     logger.debug("updateItem: status = " + statusCode);
919                 }
920                 Assert.assertTrue(testRequestType.isValidStatusCode(statusCode),
921                         invalidStatusCodeMessage(testRequestType, statusCode));
922                 Assert.assertEquals(statusCode, testExpectedStatusCode);
923         
924                 // Retrieve the updated authority item and verify that its contents exist.
925                 updatedSASAuthorityItem = extractItemCommonPartValue(res);
926                 Assert.assertNotNull(updatedSASAuthorityItem);
927
928                 compareUpdatedItemInstances(theUpdate, updatedSASAuthorityItem);
929         } finally {
930                 res.close();
931         }
932         
933         // Synchronize the local item's parent authority and verify the update we just made
934         // to the SAS item appears locally after the sync
935         setupSync();
936         AuthorityClient localClient = (AuthorityClient) this.getClientInstance();
937         Response response = localClient.syncByName(knownSASAuthorityResourceIdentifier); // Notice we're using the Short ID (short ID is the same on the local and SAS)
938         try {
939                 int statusCode = response.getStatus();
940                 Assert.assertTrue(testRequestType.isValidStatusCode(statusCode), invalidStatusCodeMessage(testRequestType, statusCode));
941                 Assert.assertEquals(statusCode, testExpectedStatusCode);
942         } finally {
943                 response.close();
944         }        
945         
946         setupRead();
947         res = localClient.readNamedItemInNamedAuthority(knownSASAuthorityResourceIdentifier, knownSASItemIdentifiersList.get(0));
948         try {
949                 Assert.assertEquals(res.getStatus(), testExpectedStatusCode);
950                 AUTHORITY_ITEM_TYPE syncedAuthorityItem = extractItemCommonPartValue(res);
951                 Assert.assertNotNull(syncedAuthorityItem);
952                 compareUpdatedItemInstances(syncedAuthorityItem, updatedSASAuthorityItem);
953         } finally {
954                 res.close();
955         }
956     }    
957     
958     protected abstract PoxPayloadOut createNonExistenceItemInstance(String commonPartName, String identifier);
959     
960     /* (non-Javadoc)
961      * @see org.collectionspace.services.client.test.ServiceTest#updateNonExistent(java.lang.String)
962      */
963     @Test(dataProvider = "testName",
964         dependsOnMethods = {"create", "update", "updateNonExistent"})
965     public void updateNonExistentItem(String testName) throws Exception {
966         // Perform setup.
967         setupUpdateNonExistent();
968
969         // Submit the request to the service and store the response.
970         // Note: The ID used in this 'create' call may be arbitrary.
971         // The only relevant ID may be the one used in update(), below.
972         AuthorityClient client = (AuthorityClient)this.getClientInstance();
973         PoxPayloadOut multipart = createNonExistenceItemInstance(client.getItemCommonPartName(), NON_EXISTENT_ID);
974         Response res = client.updateItem(knownResourceId, NON_EXISTENT_ID, multipart);
975         try {
976                 int statusCode = res.getStatus();
977         
978                 // Check the status code of the response: does it match
979                 // the expected response(s)?
980                 if (logger.isDebugEnabled()) {
981                         logger.debug(testName + ": status = " + statusCode);
982                 }
983                 Assert.assertTrue(testRequestType.isValidStatusCode(statusCode),
984                                 invalidStatusCodeMessage(testRequestType, statusCode));
985                 Assert.assertEquals(statusCode, testExpectedStatusCode);
986         } finally {
987                 res.close();
988         }
989     }
990         
991     //
992     // Methods to persuade TestNG to follow the correct test dependency path
993     //
994     
995     @Test(dataProvider = "testName",
996                 dependsOnMethods = {"createItem"})
997     public void baseAuthorityTests(String testName) {
998         // Do nothing.  Here just to setup a test dependency chain.
999     }
1000     
1001     /*
1002      * For convenience and terseness, this test method is the base of the test execution dependency chain.  Other test methods may
1003      * refer to this method in their @Test annotation declarations.
1004      */
1005     @Override
1006     @Test(dataProvider = "testName",
1007                 dependsOnMethods = {
1008                         "org.collectionspace.services.client.test.AbstractServiceTestImpl.baseCRUDTests"})    
1009         public void CRUDTests(String testName) {
1010                 // TODO Auto-generated method stub
1011         }
1012         
1013     @Override
1014     public void cleanUp() {
1015         String noTest = System.getProperty("noTestCleanup");
1016         if (Boolean.TRUE.toString().equalsIgnoreCase(noTest)) {
1017             if (logger.isDebugEnabled()) {
1018                 logger.debug("Skipping Cleanup phase ...");
1019             }
1020             return;
1021         }
1022         
1023         AuthorityClient client = (AuthorityClient) this.getClientInstance();
1024         String parentResourceId;
1025         String itemResourceId;
1026         //
1027         // Clean up all authority item resources.
1028         //
1029         for (Map.Entry<String, String> entry : allResourceItemIdsCreated.entrySet()) {
1030             itemResourceId = entry.getKey();
1031             parentResourceId = entry.getValue();
1032             Response response = client.deleteItem(parentResourceId, itemResourceId);
1033             try {
1034                 int status = response.getStatus();
1035                 if (status != Response.Status.OK.getStatusCode()) {
1036                         logger.debug(String.format("Could not deleted authority item '%s' in authority '%s'.",
1037                                         itemResourceId, parentResourceId));
1038                 }
1039             } finally {
1040                 response.close();
1041             }
1042         }
1043         //
1044         // Clean up authority items that were the result of a sync with the SAS
1045         // all the IDs are URN (not CSIDs).  The URNs work for the local items as well
1046         // as the SAS items.
1047         //
1048         for (Map.Entry<String, String> entry : allSASResourceItemIdsCreated.entrySet()) {
1049             itemResourceId = entry.getKey();
1050             parentResourceId = entry.getValue();
1051             // Note: Any non-success responses from the delete operation
1052             // below are ignored and not reported.
1053             client.deleteItem(parentResourceId, itemResourceId).close();
1054         }
1055         //
1056         // Clean up authority items on the SAS using the SAS client.
1057         //
1058         client = (AuthorityClient) this.getSASClientInstance();
1059         for (Map.Entry<String, String> entry : allSASResourceItemIdsCreated.entrySet()) {
1060             itemResourceId = entry.getKey();
1061             parentResourceId = entry.getValue();
1062             client.deleteItem(parentResourceId, itemResourceId).close();
1063         }
1064         //
1065         // Finally, call out superclass's cleanUp method to deleted the local authorities
1066         //
1067         super.cleanUp();
1068         //
1069         // Call out superclass's cleanUp method to delete the SAS authorities
1070         //
1071         super.cleanUp(client);        
1072     }
1073     
1074         protected String getTestAuthorityItemShortId() {
1075                 return getTestAuthorityItemShortId(false);
1076         }
1077
1078         protected String getTestAuthorityItemShortId(boolean makeUnique) {
1079                 String result = TEST_SHORTID;
1080                 
1081                 if (makeUnique == true) {
1082                         result = result + System.currentTimeMillis() + Math.abs(random.nextInt());
1083                 }
1084                 
1085                 return result;
1086         }
1087 }