<binaryStore path=""/> <!-- Default value will be repository/database name. Can be partial or full system path. Partial path is relative to Nuxeo's data dir -->
<xa-datasource>@XA_DATASOURCE@</xa-datasource> <!-- The transactional datasource for Nuxeo -->
<noDDL>false</noDDL>
+ <sqlInitFile>vcsconfig.sql.txt</sqlInitFile> <!-- see https://doc.nuxeo.com/display/ADMINDOC/VCS+Configuration#VCSConfiguration-DatabaseCreationOption -->
<aclOptimizations enabled="true"/>
<pathOptimizations enabled="true"/>
<idType>varchar</idType>
--- /dev/null
+#
+# A place to modify the Nuxeo database with SQL statements.
+# See https://doc.nuxeo.com/display/ADMINDOC/VCS+Configuration#VCSConfiguration-DatabaseCreationOption
+#
+
+
+#CATEGORY: afterTableCreation
+
+
+#
+# Add a unique constraint to the shortidentifier column of the vocabularies_common table.
+#
+LOG.INFO Adding a unique constraint to the shortidentifier column of the vocabularies_common table
+ALTER TABLE vocabularies_common add CONSTRAINT shortid_unique UNIQUE (shortidentifier);
\ No newline at end of file
# CollectionSpace loggers and default levels - all loggers using the rootLogger if not otherwise specified
#
log4j.logger.org.collectionspace=WARN
+log4j.logger.org.collectionspace.services.nuxeo.client.java.NuxeoClientEmbedded=TRACE
#log4j.logger.org.collectionspace.services.nuxeo.client.java=ERROR
#log4j.logger.org.collectionspace.services.common.storage.JDBCTools=ERROR
#log4j.logger.org.collectionspace.services.common.profile.CSpaceFilter=ERROR
// Instance variables specific to this test.
// final String SERVICE_PATH_COMPONENT = AcquisitionClient.SERVICE_PATH_COMPONENT;//"acquisitions";
- final String PERSON_AUTHORITY_NAME = "TestPersonAuth";
+ final String PERSON_AUTHORITY_NAME = "TestPersonAuthForAquisitionTest";
private String knownResourceId = null;
private List<String> acquisitionIdsCreated = new ArrayList<String>();
private List<String> personIdsCreated = new ArrayList<String>();
}
- @POST //FIXME: REM - 5/1/2012 - We can probably remove this method.
- public Response createAuthority(String xmlPayload) { //REM - This method is never reached by the JAX-RS client -instead the "create" method in ResourceBase.java is getting called.
- try {
- PoxPayloadIn input = new PoxPayloadIn(xmlPayload);
- ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = createServiceContext(input);
- DocumentHandler<?, AbstractCommonList, DocumentModel, DocumentModelList> handler = createDocumentHandler(ctx);
- String csid = getRepositoryClient(ctx).create(ctx, handler);
- UriBuilder path = UriBuilder.fromResource(resourceClass);
- path.path("" + csid);
- Response response = Response.created(path.build()).build();
- return response;
- } catch (Exception e) {
- throw bigReThrow(e, ServiceMessages.CREATE_FAILED);
- }
+ @POST
+ public Response createAuthority(String xmlPayload) {
+ //
+ // Requests to create new authorities come in on new threads. Unfortunately, we need to synchronize those threads on this block because, as of 8/27/2015, we can't seem to get Nuxeo
+ // transaction code to deal with a database level UNIQUE constraint violations on the 'shortidentifier' column of the vocabularies_common table.
+ // Therefore, to prevent having multiple authorities with the same shortid, we need to synchronize
+ // the code that creates new authorities. The authority document model handler will first check for authorities with the same short id before
+ // trying to create a new authority.
+ //
+ synchronized(AuthorityResource.class) {
+ try {
+ PoxPayloadIn input = new PoxPayloadIn(xmlPayload);
+ ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = createServiceContext(input);
+ DocumentHandler<?, AbstractCommonList, DocumentModel, DocumentModelList> handler = createDocumentHandler(ctx);
+ String csid = getRepositoryClient(ctx).create(ctx, handler);
+ UriBuilder path = UriBuilder.fromResource(resourceClass);
+ path.path("" + csid);
+ Response response = Response.created(path.build()).build();
+ return response;
+ } catch (Exception e) {
+ throw bigReThrow(e, ServiceMessages.CREATE_FAILED);
+ }
+ }
}
protected String buildWhereForAuthByName(String name) {
*
* @return the response
*/
- @DELETE
+ @Deprecated
+// @DELETE
@Path("{csid}")
- public Response deleteAuthority(@PathParam("csid") String csid) {
+ public Response old_deleteAuthority(@PathParam("csid") String csid) {
if (logger.isDebugEnabled()) {
logger.debug("deleteAuthority with csid=" + csid);
}
throw bigReThrow(e, ServiceMessages.DELETE_FAILED, csid);
}
}
+
+ /**
+ * Delete authority
+ *
+ * @param csid the csid or a URN specifier form -e.g., urn:cspace:name(OurMuseumPersonAuthority)
+ *
+ * @return the response
+ */
+ @DELETE
+ @Path("{csid}")
+ public Response deleteAuthority(
+ @Context Request request,
+ @Context UriInfo ui,
+ @PathParam("csid") String specifier) {
+ if (logger.isDebugEnabled()) {
+ logger.debug("deleteAuthority with specifier=" + specifier);
+ }
+
+ try {
+ ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = createServiceContext(ui);
+ DocumentHandler<?, AbstractCommonList, DocumentModel, DocumentModelList> handler = createDocumentHandler(ctx);
+
+ Specifier spec = 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 = buildWhereForAuthByName(spec.value);
+ getRepositoryClient(ctx).deleteWithWhereClause(ctx, whereClause, handler);
+ }
+
+ return Response.status(HttpResponseCodes.SC_OK).build();
+ } catch (Exception e) {
+ throw bigReThrow(e, ServiceMessages.DELETE_FAILED, specifier);
+ }
+ }
+
/*************************************************************************
* Create an AuthorityItem - this is a sub-resource of Authority
import org.collectionspace.services.common.api.RefName.Authority;
import org.collectionspace.services.common.api.Tools;
import org.collectionspace.services.common.context.ServiceContext;
+import org.collectionspace.services.common.document.DocumentException;
+import org.collectionspace.services.common.document.DocumentNotFoundException;
import org.collectionspace.services.common.document.DocumentWrapper;
import org.collectionspace.services.common.vocabulary.AuthorityJAXBSchema;
import org.collectionspace.services.config.service.ObjectPartType;
handleDisplayNameAsShortIdentifier(wrapDoc.getWrappedObject(), authorityCommonSchemaName);
updateRefnameForAuthority(wrapDoc, authorityCommonSchemaName);//CSPACE-3178
}
+
+ protected String buildWhereForShortId(String name) {
+ return authorityCommonSchemaName
+ + ":" + AuthorityJAXBSchema.SHORT_IDENTIFIER
+ + "='" + name + "'";
+ }
+
+ private boolean isUnique(DocumentModel docModel, String schemaName) throws DocumentException {
+ boolean result = true;
+
+ ServiceContext ctx = this.getServiceContext();
+ String shortIdentifier = (String) docModel.getProperty(schemaName, AuthorityJAXBSchema.SHORT_IDENTIFIER);
+ String nxqlWhereClause = buildWhereForShortId(shortIdentifier);
+ try {
+ DocumentWrapper<DocumentModel> searchResultWrapper = getRepositoryClient(ctx).findDoc(ctx, nxqlWhereClause);
+ if (searchResultWrapper != null) {
+ result = false;
+ if (logger.isInfoEnabled() == true) {
+ DocumentModel searchResult = searchResultWrapper.getWrappedObject();
+ String debugMsg = String.format("Could not create a new authority with a short identifier of '%s', because one already exists with the same short identifer: CSID = '%s'",
+ shortIdentifier, searchResult.getName());
+ logger.trace(debugMsg);
+ }
+ }
+ } catch (DocumentNotFoundException e) {
+ // Not a problem, just means we couldn't find another authority with that short ID
+ }
+
+ return result;
+ }
/**
* If no short identifier was provided in the input payload,
- * generate a short identifier from the display name.
+ * generate a short identifier from the display name. Either way though,
+ * the short identifier needs to be unique.
*/
private void handleDisplayNameAsShortIdentifier(DocumentModel docModel, String schemaName) throws Exception {
String shortIdentifier = (String) docModel.getProperty(schemaName, AuthorityJAXBSchema.SHORT_IDENTIFIER);
String displayName = (String) docModel.getProperty(schemaName, AuthorityJAXBSchema.DISPLAY_NAME);
String shortDisplayName = "";
+ String generateShortIdentifier = null;
if (Tools.isEmpty(shortIdentifier)) {
- String generatedShortIdentifier = AuthorityIdentifierUtils.generateShortIdentifierFromDisplayName(displayName, shortDisplayName);
- docModel.setProperty(schemaName, AuthorityJAXBSchema.SHORT_IDENTIFIER, generatedShortIdentifier);
+ generateShortIdentifier = AuthorityIdentifierUtils.generateShortIdentifierFromDisplayName(displayName, shortDisplayName);
+ docModel.setProperty(schemaName, AuthorityJAXBSchema.SHORT_IDENTIFIER, shortIdentifier);
+ }
+
+ if (isUnique(docModel, schemaName) == false) {
+ String shortId = generateShortIdentifier == null ? shortIdentifier : generateShortIdentifier;
+ String errMsgVerb = generateShortIdentifier == null ? "supplied" : "generated";
+ String errMsg = String.format("The %s short identifier '%s' was not unique, so the new authority could not be created.",
+ errMsgVerb, shortId);
+ throw new DocumentException(errMsg);
}
}
//
// Get the total count of non-deleted existing records
//
- String parentCsid = this.createTestObject("REM_" + testName);
+ String identifier = String.format("Test_Workflow_%d", System.currentTimeMillis());
+ String parentCsid = this.createTestObject(identifier);
//
// Create 3 new items
import org.apache.commons.httpclient.methods.PutMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.commons.io.FileUtils;
-
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.Assert;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.DataProvider;
import org.w3c.dom.Document;
-
import org.collectionspace.services.client.AuthorityClient;
import org.collectionspace.services.client.CollectionSpaceClient;
import org.collectionspace.services.client.PayloadInputPart;
Response.Status.OK.getStatusCode();
protected static final int STATUS_FORBIDDEN =
Response.Status.FORBIDDEN.getStatusCode();
+
+ //
+ // "Global flag to cancel cleanup() method
+ //
+ private static boolean cancelCleanup = false;
+
+ //
+ // Decide if cleanup should happen
+ //
+ protected boolean cleanupCancelled() {
+ if (cancelCleanup == false) {
+ String noTestCleanup = System.getProperty(NO_TEST_CLEANUP);
+ if (Boolean.TRUE.toString().equalsIgnoreCase(noTestCleanup)) {
+ cancelCleanup = true;
+ }
+ }
+
+ return cancelCleanup;
+ }
+
+ protected void cancelCleanup() {
+ cancelCleanup = true;
+ }
/**
* Instantiates a new base service test.
testExpectedStatusCode = expectedStatusCode;
testRequestType = reqType;
}
+
+ protected long randomPause(Random randomGenerator, long maxPauseMillis) {
+ long result = 0;
+
+ if (maxPauseMillis != 0) {
+ try {
+ Thread.sleep(result = randomGenerator.nextInt(500));
+ } catch (InterruptedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ result = -1;
+ }
+ }
+
+ return result;
+ }
/**
* Returns an error message indicating that the status code returned by a
*/
@AfterClass(alwaysRun = true)
public void cleanUp() {
- String noTestCleanup = System.getProperty(NO_TEST_CLEANUP);
- if (Boolean.TRUE.toString().equalsIgnoreCase(noTestCleanup)) {
+ if (cleanupCancelled() == true) {
if (logger.isDebugEnabled()) {
logger.debug("Skipping Cleanup phase ...");
}
return;
}
+
if (logger.isDebugEnabled()) {
logger.debug("Cleaning up temporary resources created for testing ...");
}
* @throws DocumentException
*/
void delete(ServiceContext ctx, String id) throws DocumentNotFoundException, DocumentException;
-
+
+ /**
+ * Delete with an NXQL 'WHERE' clause. If multiple documents match the clause, this method delete just
+ * the first document it finds.
+ * @param ctx
+ * @param specifier
+ * @throws DocumentNotFoundException
+ * @throws DocumentException
+ */
+ void deleteWithWhereClause(ServiceContext ctx, String whereClause, DocumentHandler handler) throws DocumentNotFoundException, DocumentException;
/**
* delete a entity from the persistence store
import java.util.Date;
import java.util.List;
+
import javax.persistence.RollbackException;
+
import java.sql.BatchUpdateException;
import javax.persistence.EntityManager;
import org.collectionspace.services.common.document.DocumentWrapper;
import org.collectionspace.services.common.document.DocumentWrapperImpl;
import org.collectionspace.services.common.document.JaxbUtils;
-
import org.collectionspace.services.common.storage.StorageClient;
import org.collectionspace.services.common.context.ServiceContextProperties;
import org.collectionspace.services.common.context.ServiceContext;
import org.collectionspace.services.common.query.QueryContext;
import org.collectionspace.services.lifecycle.TransitionDef;
-
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
DocumentException {
// Do nothing. JPA services do not support workflow.
}
+
+ @Override
+ public void deleteWithWhereClause(ServiceContext ctx, String whereClause,
+ DocumentHandler handler) throws DocumentNotFoundException,
+ DocumentException {
+ throw new UnsupportedOperationException();
+ }
}
import java.security.Principal;
+import org.collectionspace.services.nuxeo.util.NuxeoUtils;
import org.nuxeo.ecm.core.api.ClientException;
import org.nuxeo.ecm.core.api.DocumentModel;
import org.nuxeo.ecm.core.api.DocumentModelList;
import org.nuxeo.ecm.core.api.event.DocumentEventTypes;
import org.nuxeo.ecm.core.api.impl.LifeCycleFilter;
import org.nuxeo.ecm.core.api.CoreSession;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class CoreSessionWrapper implements CoreSessionInterface {
private CoreSession repoSession;
+ /** The logger. */
+ private static Logger logger = LoggerFactory.getLogger(CoreSessionWrapper.class);
+
+ private void logQuery(String query) {
+ logger.debug(String.format("NXQL: %s", query));
+ }
+
+ private void logQuery(String query, String queryType) {
+ logger.debug(String.format("Query Type: '%s' NXQL: %s", queryType, query));
+ }
+
+ private void logQuery(String query, Filter filter, long limit,
+ long offset, boolean countTotal) {
+ logger.debug(String.format("Filter: '%s', Limit: '%d', Offset: '%d', Count Total?: %b, NXQL: %s",
+ filter != null ? filter.toString() : "none", limit, offset, countTotal, query));
+ }
+
+
public CoreSessionWrapper(CoreSession repoSession) {
this.repoSession = repoSession;
}
@Override
public IterableQueryResult queryAndFetch(String query, String queryType,
Object... params) throws ClientException {
+ logQuery(query, queryType);
return repoSession.queryAndFetch(query, queryType, params);
}
@Override
public DocumentModelList query(String query, Filter filter, long limit,
long offset, boolean countTotal) throws ClientException {
+ logQuery(query, filter, limit, offset, countTotal);
return repoSession.query(query, filter, limit, offset, countTotal);
}
@Override
public DocumentModelList query(String query, int max) throws ClientException {
+ logQuery(query);
return repoSession.query(query, max);
}
@Override
public DocumentModelList query(String query) throws ClientException {
+ logQuery(query);
return repoSession.query(query);
}
private RepositoryManager repositoryMgr;
private static final NuxeoClientEmbedded instance = new NuxeoClientEmbedded();
+
+ private static final int MAX_CREATE_TRANSACTION_ATTEMPTS = 5;
/**
* Constructs a new NuxeoClient. NOTE: Using {@link #getInstance()} instead
*/
public CoreSessionInterface openRepository(String repoName) throws Exception {
return openRepository(repoName, ServiceContext.DEFAULT_TX_TIMEOUT);
- }
+ }
+
+ private boolean startTransaction() {
+ boolean startedTransaction = false;
+ int attempts = 0;
+
+ if (TransactionHelper.isTransactionActive() == false) {
+ while (startedTransaction == false && attempts <= MAX_CREATE_TRANSACTION_ATTEMPTS) {
+ try {
+ startedTransaction = TransactionHelper.startTransaction();
+ } catch (Exception e) {
+ String traceMsg = String.format("Could not start a new transaction on thread '%d'", Thread.currentThread().getId());
+ logger.trace(traceMsg);
+ boolean txState = TransactionHelper.isTransactionActive();
+ txState = TransactionHelper.isNoTransaction();
+ txState = TransactionHelper.isTransactionActiveOrMarkedRollback();
+ txState = TransactionHelper.isTransactionMarkedRollback();
+ }
+
+ if (startedTransaction == false) {
+ long currentThreadId = Thread.currentThread().getId();
+ boolean txState = TransactionHelper.isTransactionActive();
+ txState = TransactionHelper.isNoTransaction();
+ txState = TransactionHelper.isTransactionActiveOrMarkedRollback();
+ txState = TransactionHelper.isTransactionMarkedRollback();
+
+ if (TransactionHelper.isTransactionActiveOrMarkedRollback() == true) {
+ try {
+ TransactionHelper.commitOrRollbackTransaction();
+ } catch (Exception e) {
+ logger.error("Could not commit or rollback transaction.", e);
+ }
+ }
+ }
+ attempts++;
+ }
+ } else {
+ logger.warn("A request to start a new transaction was made, but a transaction is already open.");
+ startedTransaction = true;
+ }
+
+ if (startedTransaction == false) {
+ String errMsg = String.format("Attempted %d time(s) to start a new transaction, but failed.", attempts);
+ logger.error(errMsg);
+ }
+
+ return startedTransaction;
+ }
public CoreSessionInterface openRepository(String repoName, int timeoutSeconds) throws Exception {
CoreSessionInterface result = null;
//
boolean startedTransaction = false;
if (TransactionHelper.isTransactionActive() == false) {
- startedTransaction = TransactionHelper.startTransaction();
+ startedTransaction = startTransaction();
if (startedTransaction == false) {
- String errMsg = "Could not start a Nuxeo transaction with the TransactionHelper class.";
+ String errMsg = String.format("Could not start a Nuxeo transaction with the TransactionHelper class on thread '%d'.",
+ Thread.currentThread().getId());
logger.error(errMsg);
throw new Exception(errMsg);
}
logger.trace(String.format("Added a new repository instance to our repo list. Current count is now: %d",
repositoryInstances.size()));
} else {
+ //
+ // If we couldn't open a repo session, we need to close the transaction we started.
+ //
+ if (startedTransaction == true) {
+ TransactionHelper.commitOrRollbackTransaction();
+ }
String errMsg = String.format("Could not open a session to the Nuxeo repository='%s'", repoName);
logger.error(errMsg);
throw new Exception(errMsg);
}
-
return result;
}
String key = repoSession.getSessionId();
String name = repoSession.getRepositoryName();
+ //
+ // The caller should have already called the .save() method, but just in
+ // case they didn't, let's try calling it again.
+ //
try {
repoSession.save();
- repoSession.close();
} catch (Exception e) {
- String errMsg = String.format("Possible data loss. Could not save and/or close the Nuxeo repository name = '%s'.",
- name);
- logger.error(errMsg, e);
+ String errMsg = String.format("Possible data loss. Could not save and/or close the Nuxeo repository name = '%s'.", name);
+ logger.trace(errMsg, e);
throw e;
} finally {
+ repoSession.close();
CoreSessionInterface wasRemoved = repositoryInstances.remove(key);
if (logger.isTraceEnabled()) {
if (wasRemoved != null) {
//
if (TransactionHelper.isTransactionActiveOrMarkedRollback() == true) {
TransactionHelper.commitOrRollbackTransaction();
- UserTransaction ut = TransactionHelper.lookupUserTransaction();
- TransactionManager tm = TransactionHelper.lookupTransactionManager();
logger.trace(String.format("Transaction closed on thread '%d'", Thread.currentThread().getId()));
+ } else {
+ String warnMsg = String.format("Closed a Nuxeo repository session on thread '%d' without closing the containing transaction.",
+ Thread.currentThread().getId());
+ logger.warn(warnMsg);
}
}
}
try {
repoSession = getRepositorySession(ctx);
wrapDoc = findDoc(repoSession, ctx, whereClause);
+ } catch (DocumentNotFoundException dnfe) {
+ throw dnfe;
+ } catch (DocumentException de) {
+ throw de;
} catch (Exception e) {
- throw new NuxeoDocumentException("Unable to create a Nuxeo repository session.", e);
+ if (repoSession == null) {
+ throw new NuxeoDocumentException("Unable to create a Nuxeo repository session.", e);
+ } else {
+ throw new NuxeoDocumentException("Unexpected Nuxeo exception.", e);
+ }
} finally {
if (repoSession != null) {
releaseRepositorySession(ctx, repoSession);
}
}
+ @Override
+ public void deleteWithWhereClause(@SuppressWarnings("rawtypes") ServiceContext ctx, String whereClause,
+ @SuppressWarnings("rawtypes") DocumentHandler handler) throws
+ DocumentNotFoundException, DocumentException {
+ if (ctx == null) {
+ throw new IllegalArgumentException(
+ "delete(ctx, specifier): ctx is missing");
+ }
+ if (logger.isDebugEnabled()) {
+ logger.debug("Deleting document with whereClause=" + whereClause);
+ }
+
+ DocumentWrapper<DocumentModel> foundDocWrapper = this.findDoc(ctx, whereClause);
+ if (foundDocWrapper != null) {
+ DocumentModel docModel = foundDocWrapper.getWrappedObject();
+ String csid = docModel.getName();
+ this.delete(ctx, csid, handler);
+ }
+ }
+
/**
* delete a document from the Nuxeo repository
*
// Instance variables specific to this test.
final String SERVICE_NAME = "conditionchecks";
final String SERVICE_PATH_COMPONENT = "conditionchecks";
- final String PERSON_AUTHORITY_NAME = "TestPersonAuth";
+ final String PERSON_AUTHORITY_NAME = "TestPersonAuthForConditionCheck";
private String knownResourceId = null;
private List<String> conditioncheckIdsCreated = new ArrayList<String>();
private List<String> personIdsCreated = new ArrayList<String>();
final String SERVICE_PATH_COMPONENT = "movements";
// Instance variables specific to this test.
- final String PERSON_AUTHORITY_NAME = "TestPersonAuth";
+ final String PERSON_AUTHORITY_NAME = "TestPersonAuthForMovementTest";
private List<String> movementIdsCreated = new ArrayList<String>();
private List<String> personIdsCreated = new ArrayList<String>();
private String personAuthCSID = null;
private final Logger logger = LoggerFactory.getLogger(CLASS_NAME);
// Instance variables specific to this test.
- final String PERSON_AUTHORITY_NAME = "TestPersonAuth";
+ final String PERSON_AUTHORITY_NAME = "TestPersonAuthForOrgTest";
final String ORG_AUTHORITY_NAME = "TestOrgAuth";
@Override
/** The logger. */
private final String CLASS_NAME = RelationServiceTest.class.getName();
- private final String PERSON_AUTHORITY_NAME = "TestPersonAuth";
+ private final String PERSON_AUTHORITY_NAME = "TestPersonAuthForRelationTest";
private final Logger logger = LoggerFactory.getLogger(CLASS_NAME);
private List<String> personIdsCreated = new ArrayList<String>();
package org.collectionspace.services.client.test;
import java.util.HashMap;
-import javax.ws.rs.core.Response;
import org.collectionspace.services.common.vocabulary.AuthorityItemJAXBSchema;
import org.collectionspace.services.client.CollectionSpaceClient;
import org.collectionspace.services.client.VocabularyClientUtils;
import org.collectionspace.services.vocabulary.VocabulariesCommon;
import org.collectionspace.services.vocabulary.VocabularyitemsCommon;
-
-import org.jboss.resteasy.client.ClientResponse;
-
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.Assert;
import org.testng.annotations.Test;
+import javax.ws.rs.core.Response;
+
/**
* VocabularyServiceTest, carries out tests against a
* deployed and running Vocabulary Service.
}
}
}
+
+ @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
+ dependsOnMethods = {"createItem"})
+ public void createItemList(String testName) throws Exception {
+ knownAuthorityWithItems = createResource(testName, READITEMS_SHORT_IDENTIFIER);
+ for (int j = 0; j < nItemsToCreateInList; j++) {
+ createItemInAuthority(knownAuthorityWithItems);
+ }
+ }
+
+ @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
+ dependsOnMethods = {"CRUDTests"})
+ public void createWithNonuniqueShortId(String testName) throws Exception {
+ testSetup(STATUS_CREATED, ServiceRequestType.CREATE);
+
+ // Create a new vocabulary
+ VocabularyClient client = new VocabularyClient();
+ PoxPayloadOut multipart = VocabularyClientUtils.createEnumerationInstance(
+ "Vocab with non-unique Short Id", "nonunique", client.getCommonPartName());
+ Response res = client.create(multipart);
+ try {
+ assertStatusCode(res, testName);
+ String newId = extractId(res);
+ allResourceIdsCreated.add(newId); // save this so we can cleanup after ourselves
+ } finally {
+ if (res != null) {
+ res.close();
+ }
+ }
+
+ //
+ // Now try to create a duplicate, we should fail because we're using a non-unique short id
+ //
+ res = client.create(multipart);
+ try {
+ Assert.assertTrue(res.getStatus() != STATUS_CREATED, "Expect create to fail because of non unique short identifier.");
+ } catch (AssertionError ae) {
+ // We expected a failure, but we didn't get it. Therefore, we need to cleanup
+ // the vocabulary we just created.
+ String newId = extractId(res);
+ allResourceIdsCreated.add(newId); // save this so we can cleanup after ourselves.
+ throw ae; // rethrow the exception
+ } finally {
+ if (res != null) {
+ res.close();
+ }
+ }
+ }
+
@Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
dependsOnMethods = {"authorityTests"})