From: remillet Date: Thu, 18 Jan 2018 15:57:19 +0000 (-0800) Subject: DRYD-202: First support for POSTing vocab items along with vocab (container) payload. X-Git-Url: https://git.aero2k.de/?a=commitdiff_plain;h=07801cbc6bab7c3647b20003e77995c64a791402;p=tmp%2Fjakarta-migration.git DRYD-202: First support for POSTing vocab items along with vocab (container) payload. --- diff --git a/services/IntegrationTests/src/test/resources/test-data/xmlreplay/vocabulary/PostWithItems/postWithItems-vocab.xml b/services/IntegrationTests/src/test/resources/test-data/xmlreplay/vocabulary/PostWithItems/postWithItems-vocab.xml index b2e1809f2..4bb5382f2 100644 --- a/services/IntegrationTests/src/test/resources/test-data/xmlreplay/vocabulary/PostWithItems/postWithItems-vocab.xml +++ b/services/IntegrationTests/src/test/resources/test-data/xmlreplay/vocabulary/PostWithItems/postWithItems-vocab.xml @@ -8,13 +8,11 @@ - true 1 PostWithItems item PostWithItems1 PostWithItems1 - true 2 PostWithItems item PostWithItems2 ShowItemsItem2 diff --git a/services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/AuthorityResource.java b/services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/AuthorityResource.java index 7277ca066..883b4504d 100644 --- a/services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/AuthorityResource.java +++ b/services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/AuthorityResource.java @@ -86,7 +86,7 @@ import org.collectionspace.services.lifecycle.TransitionDef; import org.collectionspace.services.nuxeo.client.java.DocumentModelHandler; import org.collectionspace.services.nuxeo.client.java.CoreSessionInterface; import org.collectionspace.services.nuxeo.client.java.NuxeoDocumentFilter; -import org.collectionspace.services.nuxeo.client.java.RepositoryClientImpl; +import org.collectionspace.services.nuxeo.client.java.NuxeoRepositoryClientImpl; import org.collectionspace.services.nuxeo.util.NuxeoUtils; import org.collectionspace.services.workflow.WorkflowCommon; import org.collectionspace.services.common.vocabulary.RefNameServiceUtils.AuthorityItemSpecifier; @@ -162,23 +162,23 @@ public abstract class AuthorityResource */ protected DocumentHandler createItemDocumentHandler( ServiceContext ctx, - String inAuthority, String parentShortIdentifier) + String inAuthority, String containerShortIdentifier) throws Exception { String authorityRefNameBase; AuthorityItemDocumentModelHandler docHandler; - if (parentShortIdentifier == null) { + if (containerShortIdentifier == null) { authorityRefNameBase = null; } else { - ServiceContext parentCtx = createServiceContext(getServiceName()); - if (parentShortIdentifier.equals(FETCH_SHORT_ID)) { // We need to fetch this from the repo + ServiceContext containerCtx = createServiceContext(getServiceName()); + if (containerShortIdentifier.equals(FETCH_SHORT_ID)) { // We need to fetch this from the repo if (ctx.getCurrentRepositorySession() != null) { - parentCtx.setCurrentRepositorySession(ctx.getCurrentRepositorySession()); // We need to use the current repo session if one exists + containerCtx.setCurrentRepositorySession(ctx.getCurrentRepositorySession()); // We need to use the current repo session if one exists } // Get from parent document - parentShortIdentifier = getAuthShortIdentifier(parentCtx, inAuthority); + containerShortIdentifier = getAuthShortIdentifier(containerCtx, inAuthority); } - authorityRefNameBase = buildAuthorityRefNameBase(parentCtx, parentShortIdentifier); + authorityRefNameBase = buildAuthorityRefNameBase(containerCtx, containerShortIdentifier); } docHandler = (AuthorityItemDocumentModelHandler) createDocumentHandler(ctx, @@ -310,7 +310,7 @@ public abstract class AuthorityResource ServiceContext ctx = createServiceContext(item.inAuthority.resource); // HACK - this really must be moved to the doc handler, not here. No Nuxeo specific stuff here! - RepositoryClientImpl client = (RepositoryClientImpl)getRepositoryClient(ctx); + NuxeoRepositoryClientImpl client = (NuxeoRepositoryClientImpl)getRepositoryClient(ctx); String parentcsid = client.findDocCSID(repoSession, ctx, whereClause); String itemWhereClause = RefNameServiceUtils.buildWhereForAuthItemByName(authorityItemCommonSchemaName, item.getShortIdentifier(), parentcsid); @@ -322,7 +322,10 @@ public abstract class AuthorityResource @POST - public Response createAuthority(String xmlPayload) { + public Response createAuthority( + @Context ResourceMap resourceMap, + @Context UriInfo uriInfo, + 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. @@ -592,7 +595,7 @@ public abstract class AuthorityResource */ @DELETE @Path("{csid}") - public Response deleteAuthority( + public Response deleteAuthority( // # Delete this authority and all of it's items. @Context Request request, @Context UriInfo uriInfo, @PathParam("csid") String specifier) { @@ -1460,6 +1463,10 @@ public abstract class AuthorityResource ServiceDescription result = super.getDescription(ctx); result.setSubresourceDocumentType(this.getItemDocType(ctx.getTenantId())); return result; - } + } + + public Response createAuthority(String xmlPayload) { + return this.createAuthority(null, null, xmlPayload); + } } diff --git a/services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/nuxeo/AuthorityDocumentModelHandler.java b/services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/nuxeo/AuthorityDocumentModelHandler.java index d65cb2bca..86c8d47c2 100644 --- a/services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/nuxeo/AuthorityDocumentModelHandler.java +++ b/services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/nuxeo/AuthorityDocumentModelHandler.java @@ -62,7 +62,7 @@ import org.collectionspace.services.jaxb.AbstractCommonList.ListItem; import org.collectionspace.services.lifecycle.TransitionDef; import org.collectionspace.services.nuxeo.client.java.NuxeoDocumentModelHandler; import org.collectionspace.services.nuxeo.client.java.CoreSessionInterface; -import org.collectionspace.services.nuxeo.client.java.RepositoryClientImpl; +import org.collectionspace.services.nuxeo.client.java.NuxeoRepositoryClientImpl; import org.collectionspace.services.nuxeo.util.NuxeoUtils; import org.dom4j.Element; import org.nuxeo.ecm.core.api.ClientException; @@ -252,7 +252,8 @@ public abstract class AuthorityDocumentModelHandler } /** - * This method should only be used as part of a SAS synch operation. + * This method should ***only*** be used as part of a SAS synch operation. + * * @param ctx * @param refNameList * @return @@ -735,7 +736,7 @@ public abstract class AuthorityDocumentModelHandler CoreSessionInterface repoSession = null; boolean releaseSession = false; - RepositoryClientImpl nuxeoRepoClient = (RepositoryClientImpl)this.getRepositoryClient(ctx); + NuxeoRepositoryClientImpl nuxeoRepoClient = (NuxeoRepositoryClientImpl)this.getRepositoryClient(ctx); try { repoSession = nuxeoRepoClient.getRepositorySession(ctx); DocumentWrapper wrapDoc = nuxeoRepoClient.getDocFromCsid(ctx, repoSession, authCSID); diff --git a/services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/nuxeo/AuthorityItemDocumentModelHandler.java b/services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/nuxeo/AuthorityItemDocumentModelHandler.java index 7e0fb4b97..7cc8e3ed2 100644 --- a/services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/nuxeo/AuthorityItemDocumentModelHandler.java +++ b/services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/nuxeo/AuthorityItemDocumentModelHandler.java @@ -55,7 +55,7 @@ import org.collectionspace.services.config.service.ObjectPartType; import org.collectionspace.services.lifecycle.TransitionDef; import org.collectionspace.services.nuxeo.client.java.NuxeoDocumentModelHandler; import org.collectionspace.services.nuxeo.client.java.CoreSessionInterface; -import org.collectionspace.services.nuxeo.client.java.RepositoryClientImpl; +import org.collectionspace.services.nuxeo.client.java.NuxeoRepositoryClientImpl; import org.collectionspace.services.nuxeo.util.NuxeoUtils; import org.collectionspace.services.relation.RelationsCommonList; import org.collectionspace.services.vocabulary.VocabularyItemJAXBSchema; @@ -1009,7 +1009,7 @@ public abstract class AuthorityItemDocumentModelHandler boolean releaseRepoSession = false; try { - RepositoryClientImpl repoClient = (RepositoryClientImpl)this.getRepositoryClient(ctx); + NuxeoRepositoryClientImpl repoClient = (NuxeoRepositoryClientImpl)this.getRepositoryClient(ctx); repoSession = this.getRepositorySession(); if (repoSession == null) { repoSession = repoClient.getRepositorySession(ctx); @@ -1140,8 +1140,8 @@ public abstract class AuthorityItemDocumentModelHandler String filteredTerm; StringBuilder filteredTermBuilder = new StringBuilder(term); // Term contains no anchor or wildcard characters. - if ( (! term.contains(RepositoryClientImpl.USER_SUPPLIED_ANCHOR_CHAR)) - && (! term.contains(RepositoryClientImpl.USER_SUPPLIED_WILDCARD)) ) { + if ( (! term.contains(NuxeoRepositoryClientImpl.USER_SUPPLIED_ANCHOR_CHAR)) + && (! term.contains(NuxeoRepositoryClientImpl.USER_SUPPLIED_WILDCARD)) ) { filteredTerm = term; } else { // Term contains at least one such character. @@ -1149,10 +1149,10 @@ public abstract class AuthorityItemDocumentModelHandler // Filter the starting anchor or wildcard character, if any. String firstChar = filteredTermBuilder.substring(0,1); switch (firstChar) { - case RepositoryClientImpl.USER_SUPPLIED_ANCHOR_CHAR: + case NuxeoRepositoryClientImpl.USER_SUPPLIED_ANCHOR_CHAR: anchorAtStart = true; break; - case RepositoryClientImpl.USER_SUPPLIED_WILDCARD: + case NuxeoRepositoryClientImpl.USER_SUPPLIED_WILDCARD: filteredTermBuilder.deleteCharAt(0); break; } @@ -1163,12 +1163,12 @@ public abstract class AuthorityItemDocumentModelHandler int lastPos = filteredTermBuilder.length() - 1; String lastChar = filteredTermBuilder.substring(lastPos); switch (lastChar) { - case RepositoryClientImpl.USER_SUPPLIED_ANCHOR_CHAR: + case NuxeoRepositoryClientImpl.USER_SUPPLIED_ANCHOR_CHAR: filteredTermBuilder.deleteCharAt(lastPos); - filteredTermBuilder.insert(filteredTermBuilder.length(), RepositoryClientImpl.ENDING_ANCHOR_CHAR); + filteredTermBuilder.insert(filteredTermBuilder.length(), NuxeoRepositoryClientImpl.ENDING_ANCHOR_CHAR); anchorAtEnd = true; break; - case RepositoryClientImpl.USER_SUPPLIED_WILDCARD: + case NuxeoRepositoryClientImpl.USER_SUPPLIED_WILDCARD: filteredTermBuilder.deleteCharAt(lastPos); break; } @@ -1177,7 +1177,7 @@ public abstract class AuthorityItemDocumentModelHandler } filteredTerm = filteredTermBuilder.toString(); // Filter all other wildcards, if any. - filteredTerm = filteredTerm.replaceAll(RepositoryClientImpl.USER_SUPPLIED_WILDCARD_REGEX, ZERO_OR_MORE_ANY_CHAR_REGEX); + filteredTerm = filteredTerm.replaceAll(NuxeoRepositoryClientImpl.USER_SUPPLIED_WILDCARD_REGEX, ZERO_OR_MORE_ANY_CHAR_REGEX); if (logger.isTraceEnabled()) { logger.trace(String.format("After replacing user wildcards = %s", filteredTerm)); } diff --git a/services/batch/service/src/main/java/org/collectionspace/services/batch/nuxeo/BatchDocumentModelHandler.java b/services/batch/service/src/main/java/org/collectionspace/services/batch/nuxeo/BatchDocumentModelHandler.java index 86caddda4..62898cd81 100644 --- a/services/batch/service/src/main/java/org/collectionspace/services/batch/nuxeo/BatchDocumentModelHandler.java +++ b/services/batch/service/src/main/java/org/collectionspace/services/batch/nuxeo/BatchDocumentModelHandler.java @@ -39,7 +39,7 @@ import org.collectionspace.services.authorization.URIResourceImpl; import org.collectionspace.services.authorization.perms.ActionType; import org.collectionspace.services.nuxeo.client.java.NuxeoDocumentModelHandler; import org.collectionspace.services.nuxeo.client.java.CoreSessionInterface; -import org.collectionspace.services.nuxeo.client.java.RepositoryClientImpl; +import org.collectionspace.services.nuxeo.client.java.NuxeoRepositoryClientImpl; import org.collectionspace.services.batch.BatchCommon; import org.collectionspace.services.batch.BatchCommon.ForDocTypes; import org.collectionspace.services.batch.BatchCommon.ForRoles; @@ -222,7 +222,7 @@ public class BatchDocumentModelHandler extends NuxeoDocumentModelHandler { m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, false); //Marshal object into file. m.marshal(jaxbObject, outputStream); - text = outputStream.toString("UTF8"); + text = outputStream.toString("UTF8"); // FIXME: This method could/should be using JaxbUtils.toString() method Document doc = DocumentHelper.parseText(text); result = doc.getRootElement(); //FIXME: REM - call .detach() to free the element diff --git a/services/common/src/main/cspace/config/services/service-config.xml b/services/common/src/main/cspace/config/services/service-config.xml index 7353357fd..1561b7548 100644 --- a/services/common/src/main/cspace/config/services/service-config.xml +++ b/services/common/src/main/cspace/config/services/service-config.xml @@ -29,7 +29,7 @@ Administrator Administrator java - org.collectionspace.services.nuxeo.client.java.RepositoryClientImpl + org.collectionspace.services.nuxeo.client.java.NuxeoRepositoryClientImpl pageSizeDefault40 pageSizeMax2500 diff --git a/services/common/src/main/java/org/collectionspace/services/common/context/AbstractServiceContextImpl.java b/services/common/src/main/java/org/collectionspace/services/common/context/AbstractServiceContextImpl.java index 7bbd0bc86..75cc0501d 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/context/AbstractServiceContextImpl.java +++ b/services/common/src/main/java/org/collectionspace/services/common/context/AbstractServiceContextImpl.java @@ -893,6 +893,10 @@ public abstract class AbstractServiceContextImpl if (currentRepoSesssionRefCount == 0) { this.currentRepositorySession = null; } + + if (currentRepoSesssionRefCount < 0) { + throw new RuntimeException("Attempted to clear/close a repository session that has already been cleared/closed."); + } } @Override diff --git a/services/common/src/main/java/org/collectionspace/services/common/imaging/nuxeo/NuxeoBlobUtils.java b/services/common/src/main/java/org/collectionspace/services/common/imaging/nuxeo/NuxeoBlobUtils.java index 0202ab13b..8b2bd79e1 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/imaging/nuxeo/NuxeoBlobUtils.java +++ b/services/common/src/main/java/org/collectionspace/services/common/imaging/nuxeo/NuxeoBlobUtils.java @@ -92,7 +92,7 @@ import org.collectionspace.services.blob.MeasuredPartGroupList; import org.collectionspace.services.jaxb.BlobJAXBSchema; import org.collectionspace.services.nuxeo.client.java.CommonList; import org.collectionspace.services.nuxeo.client.java.CoreSessionInterface; -import org.collectionspace.services.nuxeo.client.java.RepositoryClientImpl; +import org.collectionspace.services.nuxeo.client.java.NuxeoRepositoryClientImpl; import org.collectionspace.services.nuxeo.extension.thumbnail.ThumbnailConstants; import org.collectionspace.services.nuxeo.util.NuxeoUtils; import org.collectionspace.services.config.service.ListResultField; @@ -633,7 +633,7 @@ public class NuxeoBlobUtils { static private CoreSessionInterface getRepositorySession(ServiceContext ctx, RepositoryClient repositoryClient) { CoreSessionInterface result = null; - RepositoryClientImpl nuxeoClient = (RepositoryClientImpl)repositoryClient; + NuxeoRepositoryClientImpl nuxeoClient = (NuxeoRepositoryClientImpl)repositoryClient; try { result = nuxeoClient.getRepositorySession(ctx); @@ -647,7 +647,7 @@ public class NuxeoBlobUtils { static private void releaseRepositorySession(ServiceContext ctx, RepositoryClient repositoryClient, CoreSessionInterface repoSession) throws TransactionException { - RepositoryClientImpl nuxeoClient = (RepositoryClientImpl)repositoryClient; + NuxeoRepositoryClientImpl nuxeoClient = (NuxeoRepositoryClientImpl)repositoryClient; nuxeoClient.releaseRepositorySession(ctx, repoSession); } diff --git a/services/common/src/main/java/org/collectionspace/services/common/relation/RelationUtils.java b/services/common/src/main/java/org/collectionspace/services/common/relation/RelationUtils.java index 812fda13e..b245b098a 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/relation/RelationUtils.java +++ b/services/common/src/main/java/org/collectionspace/services/common/relation/RelationUtils.java @@ -15,7 +15,7 @@ import org.collectionspace.services.common.document.DocumentNotFoundException; import org.collectionspace.services.common.document.DocumentWrapper; import org.collectionspace.services.common.repository.RepositoryClient; import org.collectionspace.services.nuxeo.client.java.CoreSessionInterface; -import org.collectionspace.services.nuxeo.client.java.RepositoryClientImpl; +import org.collectionspace.services.nuxeo.client.java.NuxeoRepositoryClientImpl; import org.nuxeo.ecm.core.api.ClientException; import org.nuxeo.ecm.core.api.DocumentModel; @@ -51,7 +51,7 @@ public class RelationUtils { // relations_common:subjectRefName = 'urn:cspace:core.collectionspace.org:placeauthorities:name(place):item:name(Amystan1348082103923)\'Amystan\''" String query = String.format("%s:%s = '%s'", IRelationsManager.SERVICE_COMMONPART_NAME, targetField, escapedRefName); - RepositoryClientImpl nuxeoRepoClient = (RepositoryClientImpl) repoClient; + NuxeoRepositoryClientImpl nuxeoRepoClient = (NuxeoRepositoryClientImpl) repoClient; DocumentWrapper docListWrapper = nuxeoRepoClient.findDocs(ctx, repoSession, docTypes, query, orderByClause, pageSize, pageNum, computeTotal); DocumentModelList docList = docListWrapper.getWrappedObject(); diff --git a/services/common/src/main/java/org/collectionspace/services/common/repository/RepositoryClient.java b/services/common/src/main/java/org/collectionspace/services/common/repository/RepositoryClient.java index 23f7376f8..4b674a190 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/repository/RepositoryClient.java +++ b/services/common/src/main/java/org/collectionspace/services/common/repository/RepositoryClient.java @@ -26,6 +26,8 @@ package org.collectionspace.services.common.repository; import java.util.Hashtable; import java.util.List; +import org.collectionspace.services.client.PoxPayloadIn; +import org.collectionspace.services.client.PoxPayloadOut; import org.collectionspace.services.common.context.ServiceContext; import org.collectionspace.services.common.document.DocumentException; import org.collectionspace.services.common.document.DocumentHandler; @@ -193,4 +195,12 @@ public interface RepositoryClient extends StorageClient { */ boolean delete(ServiceContext ctx, List idList, DocumentHandler handler) throws DocumentNotFoundException, DocumentException, TransactionException; + + /** + * + * @param ctx + * @return + * @throws Exception + */ + public CoreSessionInterface getRepositorySession(ServiceContext ctx) throws Exception; } diff --git a/services/common/src/main/java/org/collectionspace/services/common/storage/StorageClient.java b/services/common/src/main/java/org/collectionspace/services/common/storage/StorageClient.java index 168f64d71..bcc6419c5 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/storage/StorageClient.java +++ b/services/common/src/main/java/org/collectionspace/services/common/storage/StorageClient.java @@ -19,6 +19,8 @@ package org.collectionspace.services.common.storage; import java.util.List; +import org.collectionspace.services.client.PoxPayloadIn; +import org.collectionspace.services.client.PoxPayloadOut; import org.collectionspace.services.common.context.ServiceContext; import org.collectionspace.services.common.document.BadRequestException; import org.collectionspace.services.common.document.DocumentException; @@ -28,6 +30,7 @@ import org.collectionspace.services.common.document.TransactionException; import org.collectionspace.services.common.vocabulary.RefNameServiceUtils.AuthorityItemSpecifier; import org.collectionspace.services.common.vocabulary.RefNameServiceUtils.Specifier; import org.collectionspace.services.lifecycle.TransitionDef; +import org.collectionspace.services.nuxeo.client.java.CoreSessionInterface; /** * @@ -164,4 +167,7 @@ public interface StorageClient { boolean delete(ServiceContext ctx, Object entityFound, DocumentHandler handler) throws DocumentNotFoundException, DocumentException; + void releaseRepositorySession(ServiceContext ctx, Object repoSession) + throws TransactionException; + } diff --git a/services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaStorageClientImpl.java b/services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaStorageClientImpl.java index b0665fc8d..831f17954 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaStorageClientImpl.java +++ b/services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaStorageClientImpl.java @@ -38,6 +38,8 @@ import org.collectionspace.services.common.storage.StorageClient; import org.collectionspace.services.common.storage.TransactionContext; import org.collectionspace.services.common.vocabulary.RefNameServiceUtils.AuthorityItemSpecifier; import org.collectionspace.services.common.context.ServiceContextProperties; +import org.collectionspace.services.client.PoxPayloadIn; +import org.collectionspace.services.client.PoxPayloadOut; import org.collectionspace.services.common.api.Tools; import org.collectionspace.services.common.context.ServiceContext; import org.collectionspace.services.lifecycle.TransitionDef; @@ -588,4 +590,10 @@ public class JpaStorageClientImpl implements StorageClient { return true; } + @Override + public void releaseRepositorySession(ServiceContext ctx, Object repoSession) + throws TransactionException { + // TODO Auto-generated method stub + } + } diff --git a/services/common/src/main/java/org/collectionspace/services/common/vocabulary/RefNameServiceUtils.java b/services/common/src/main/java/org/collectionspace/services/common/vocabulary/RefNameServiceUtils.java index 189798e77..691ab4402 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/vocabulary/RefNameServiceUtils.java +++ b/services/common/src/main/java/org/collectionspace/services/common/vocabulary/RefNameServiceUtils.java @@ -68,7 +68,7 @@ import org.collectionspace.services.common.relation.RelationUtils; import org.collectionspace.services.common.repository.RepositoryClient; import org.collectionspace.services.nuxeo.client.java.CoreSessionInterface; import org.collectionspace.services.nuxeo.client.java.NuxeoDocumentModelHandler; -import org.collectionspace.services.nuxeo.client.java.RepositoryClientImpl; +import org.collectionspace.services.nuxeo.client.java.NuxeoRepositoryClientImpl; import org.collectionspace.services.common.security.SecurityUtils; import org.collectionspace.services.config.service.ServiceBindingType; import org.collectionspace.services.jaxb.AbstractCommonList; @@ -406,7 +406,7 @@ public class RefNameServiceUtils { Map queriedServiceBindings = new HashMap(); Map> authRefFieldsByService = new HashMap>(); - RepositoryClientImpl nuxeoRepoClient = (RepositoryClientImpl) repoClient; + NuxeoRepositoryClientImpl nuxeoRepoClient = (NuxeoRepositoryClientImpl) repoClient; try { // Ignore any provided page size and number query parameters in // the following call, as they pertain to the list of authority @@ -563,7 +563,7 @@ public class RefNameServiceUtils { final String ORDER_BY_VALUE = CollectionSpaceClient.CORE_CREATED_AT // "collectionspace_core:createdAt"; + ", " + IQueryManager.NUXEO_UUID; // CSPACE-6333: Add secondary sort on uuid, in case records have the same createdAt timestamp. - if (repoClient instanceof RepositoryClientImpl == false) { + if (repoClient instanceof NuxeoRepositoryClientImpl == false) { throw new InternalError("updateAuthorityRefDocs() called with unknown repoClient type!"); } @@ -598,7 +598,7 @@ public class RefNameServiceUtils { queriedServiceBindings, authRefFieldsByService, // Perform the refName updates on the list of document models newRefName); if (nRefsFoundThisPage > 0) { - ((RepositoryClientImpl) repoClient).saveDocListWithoutHandlerProcessing(ctx, repoSession, docList, true); // Flush the document model list out to Nuxeo storage + ((NuxeoRepositoryClientImpl) repoClient).saveDocListWithoutHandlerProcessing(ctx, repoSession, docList, true); // Flush the document model list out to Nuxeo storage nRefsFound += nRefsFoundThisPage; } @@ -675,7 +675,7 @@ public class RefNameServiceUtils { query += " AND " + whereClauseAdditions; } // Now we have to issue the search - RepositoryClientImpl nuxeoRepoClient = (RepositoryClientImpl) repoClient; + NuxeoRepositoryClientImpl nuxeoRepoClient = (NuxeoRepositoryClientImpl) repoClient; DocumentWrapper docListWrapper = nuxeoRepoClient.findDocs(ctx, repoSession, docTypes, query, orderByClause, pageSize, pageNum, computeTotal); // Now we gather the info for each document into the list and return diff --git a/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/NuxeoDocumentModelHandler.java b/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/NuxeoDocumentModelHandler.java index 3e8bf0fac..162b982d2 100644 --- a/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/NuxeoDocumentModelHandler.java +++ b/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/NuxeoDocumentModelHandler.java @@ -219,7 +219,7 @@ public abstract class NuxeoDocumentModelHandler extends RemoteDocumentModelHa public AbstractCommonList extractCommonPartList(DocumentWrapper wrapDoc) throws Exception { CommonList commonList = new CommonList(); CoreSessionInterface repoSession = null; - RepositoryClientImpl repoClient = null; + NuxeoRepositoryClientImpl repoClient = null; boolean releaseRepoSession = false; AbstractServiceContextImpl ctx = (AbstractServiceContextImpl) getServiceContext(); @@ -245,8 +245,8 @@ public abstract class NuxeoDocumentModelHandler extends RemoteDocumentModelHa try { if (markRtSbj != null) { - repoClient = (RepositoryClientImpl) this.getRepositoryClient(ctx); - RepositoryClientImpl nuxeoRepoClient = (RepositoryClientImpl) repoClient; + repoClient = (NuxeoRepositoryClientImpl) this.getRepositoryClient(ctx); + NuxeoRepositoryClientImpl nuxeoRepoClient = (NuxeoRepositoryClientImpl) repoClient; repoSession = this.getRepositorySession(); if (repoSession == null) { repoSession = repoClient.getRepositorySession(ctx); diff --git a/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RepositoryClientImpl.java b/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/NuxeoRepositoryClientImpl.java similarity index 99% rename from services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RepositoryClientImpl.java rename to services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/NuxeoRepositoryClientImpl.java index e95c958da..0a97f3c71 100644 --- a/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RepositoryClientImpl.java +++ b/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/NuxeoRepositoryClientImpl.java @@ -97,12 +97,12 @@ import org.slf4j.LoggerFactory; * * $LastChangedRevision: $ $LastChangedDate: $ */ -public class RepositoryClientImpl implements RepositoryClient { +public class NuxeoRepositoryClientImpl implements RepositoryClient { /** * The logger. */ - private final Logger logger = LoggerFactory.getLogger(RepositoryClientImpl.class); + private final Logger logger = LoggerFactory.getLogger(NuxeoRepositoryClientImpl.class); // private final Logger profilerLogger = LoggerFactory.getLogger("remperf"); // private String foo = Profiler.createLogger(); public static final String NUXEO_CORE_TYPE_DOMAIN = "Domain"; @@ -120,7 +120,7 @@ public class RepositoryClientImpl implements RepositoryClient ctx) throws Exception { return getRepositorySession(ctx, ctx.getRepositoryName(), ctx.getTimeoutSecs()); } @@ -2075,8 +2076,10 @@ public class RepositoryClientImpl implements RepositoryClient ctx, CoreSessionInterface repoSession) throws TransactionException { + @Override + public void releaseRepositorySession(ServiceContext ctx, Object repositorySession) throws TransactionException { try { + CoreSessionInterface repoSession = (CoreSessionInterface)repositorySession; NuxeoClientEmbedded client = NuxeoConnectorEmbedded.getInstance().getClient(); // release session if (ctx != null) { diff --git a/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RemoteDocumentModelHandlerImpl.java b/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RemoteDocumentModelHandlerImpl.java index 2dacf87d8..52166f156 100644 --- a/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RemoteDocumentModelHandlerImpl.java +++ b/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RemoteDocumentModelHandlerImpl.java @@ -767,7 +767,7 @@ public abstract class RemoteDocumentModelHandlerImpl boolean releaseRepoSession = false; ServiceContext ctx = this.getServiceContext(); - RepositoryClientImpl repoClient = (RepositoryClientImpl)this.getRepositoryClient(ctx); + NuxeoRepositoryClientImpl repoClient = (NuxeoRepositoryClientImpl)this.getRepositoryClient(ctx); CoreSessionInterface repoSession = this.getRepositorySession(); if (repoSession == null) { repoSession = repoClient.getRepositorySession(ctx); diff --git a/services/relation/service/src/main/java/org/collectionspace/services/relation/nuxeo/RelationDocumentModelHandler.java b/services/relation/service/src/main/java/org/collectionspace/services/relation/nuxeo/RelationDocumentModelHandler.java index 09f2a1d4a..e79d37eca 100644 --- a/services/relation/service/src/main/java/org/collectionspace/services/relation/nuxeo/RelationDocumentModelHandler.java +++ b/services/relation/service/src/main/java/org/collectionspace/services/relation/nuxeo/RelationDocumentModelHandler.java @@ -52,7 +52,7 @@ import org.collectionspace.services.client.workflow.WorkflowClient; import org.collectionspace.services.config.service.ServiceBindingType; import org.collectionspace.services.nuxeo.client.java.RemoteDocumentModelHandlerImpl; import org.collectionspace.services.nuxeo.client.java.CoreSessionInterface; -import org.collectionspace.services.nuxeo.client.java.RepositoryClientImpl; +import org.collectionspace.services.nuxeo.client.java.NuxeoRepositoryClientImpl; import org.nuxeo.ecm.core.api.ClientException; import org.nuxeo.ecm.core.api.DocumentModel; @@ -397,7 +397,7 @@ public class RelationDocumentModelHandler // provided as an alternate identifier. } if (Tools.notBlank(csid)) { - RepositoryClientImpl nuxeoRepoClient = (RepositoryClientImpl)getRepositoryClient(ctx); + NuxeoRepositoryClientImpl nuxeoRepoClient = (NuxeoRepositoryClientImpl)getRepositoryClient(ctx); DocumentWrapper docWrapper = nuxeoRepoClient.getDocFromCsid(ctx, repoSession, csid); docModel = docWrapper.getWrappedObject(); } else { // if (Tools.isBlank(objectCsid)) { diff --git a/services/report/service/src/main/java/org/collectionspace/services/report/nuxeo/ReportDocumentModelHandler.java b/services/report/service/src/main/java/org/collectionspace/services/report/nuxeo/ReportDocumentModelHandler.java index ae572bc94..0256887eb 100644 --- a/services/report/service/src/main/java/org/collectionspace/services/report/nuxeo/ReportDocumentModelHandler.java +++ b/services/report/service/src/main/java/org/collectionspace/services/report/nuxeo/ReportDocumentModelHandler.java @@ -75,7 +75,7 @@ import org.collectionspace.services.common.storage.JDBCTools; import org.collectionspace.services.jaxb.InvocableJAXBSchema; import org.collectionspace.services.nuxeo.client.java.NuxeoDocumentModelHandler; import org.collectionspace.services.nuxeo.client.java.CoreSessionInterface; -import org.collectionspace.services.nuxeo.client.java.RepositoryClientImpl; +import org.collectionspace.services.nuxeo.client.java.NuxeoRepositoryClientImpl; import org.collectionspace.services.nuxeo.util.NuxeoUtils; import org.jfree.util.Log; import org.nuxeo.ecm.core.api.DocumentModel; @@ -152,7 +152,7 @@ public class ReportDocumentModelHandler extends NuxeoDocumentModelHandler serviceGroupNames, Map queriedServiceBindings, CoreSessionInterface repoSession, - RepositoryClientImpl repoClient) throws Exception { + NuxeoRepositoryClientImpl repoClient) throws Exception { - RepositoryClientImpl nuxeoRepoClient = (RepositoryClientImpl)repoClient; + NuxeoRepositoryClientImpl nuxeoRepoClient = (NuxeoRepositoryClientImpl)repoClient; // Get the service bindings for this tenant TenantBindingConfigReaderImpl tReader = ServiceMain.getInstance().getTenantBindingConfigReader(); // We need to get all the procedures, authorities, and objects. @@ -241,7 +241,7 @@ public class ServiceGroupDocumentModelHandler list.setPageNum(pageNum); list.setPageSize(pageSize); - RepositoryClientImpl repoClient = (RepositoryClientImpl)this.getRepositoryClient(ctx); + NuxeoRepositoryClientImpl repoClient = (NuxeoRepositoryClientImpl)this.getRepositoryClient(ctx); repoSession = this.getRepositorySession(); if (repoSession == null) { repoSession = repoClient.getRepositorySession(ctx); @@ -307,7 +307,7 @@ public class ServiceGroupDocumentModelHandler String tenantId = ctx.getTenantId(); CoreSessionInterface repoSession = null; - RepositoryClientImpl repoClient = null; + NuxeoRepositoryClientImpl repoClient = null; boolean releaseRepoSession = false; MultivaluedMap queryParams = getServiceContext().getQueryParams(); @@ -329,8 +329,8 @@ public class ServiceGroupDocumentModelHandler try { if (markRtSbj != null) { - repoClient = (RepositoryClientImpl) this.getRepositoryClient(ctx); - RepositoryClientImpl nuxeoRepoClient = (RepositoryClientImpl) repoClient; + repoClient = (NuxeoRepositoryClientImpl) this.getRepositoryClient(ctx); + NuxeoRepositoryClientImpl nuxeoRepoClient = (NuxeoRepositoryClientImpl) repoClient; repoSession = this.getRepositorySession(); if (repoSession == null) { repoSession = repoClient.getRepositorySession(ctx); diff --git a/services/vocabulary/service/src/main/java/org/collectionspace/services/vocabulary/VocabularyResource.java b/services/vocabulary/service/src/main/java/org/collectionspace/services/vocabulary/VocabularyResource.java index db1a002c0..034535d64 100644 --- a/services/vocabulary/service/src/main/java/org/collectionspace/services/vocabulary/VocabularyResource.java +++ b/services/vocabulary/service/src/main/java/org/collectionspace/services/vocabulary/VocabularyResource.java @@ -24,28 +24,46 @@ package org.collectionspace.services.vocabulary; import org.collectionspace.services.client.IClientQueryParams; +import org.collectionspace.services.client.PayloadInputPart; +import org.collectionspace.services.client.PoxPayload; import org.collectionspace.services.client.PoxPayloadIn; import org.collectionspace.services.client.PoxPayloadOut; import org.collectionspace.services.client.VocabularyClient; +import org.collectionspace.services.client.workflow.WorkflowClient; import org.collectionspace.services.common.CSWebApplicationException; +import org.collectionspace.services.common.ResourceMap; import org.collectionspace.services.common.ServiceMessages; import org.collectionspace.services.common.UriInfoWrapper; import org.collectionspace.services.common.api.Tools; import org.collectionspace.services.common.context.ServiceBindingUtils; import org.collectionspace.services.common.context.ServiceContext; +import org.collectionspace.services.common.document.DocumentException; +import org.collectionspace.services.common.document.DocumentHandler; +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.jaxb.AbstractCommonList; +import org.collectionspace.services.jaxb.AbstractCommonList.ListItem; +import org.collectionspace.services.nuxeo.client.java.CoreSessionInterface; +import org.collectionspace.services.nuxeo.client.java.NuxeoRepositoryClientImpl; import org.collectionspace.services.vocabulary.nuxeo.VocabularyItemDocumentModelHandler; - +import org.collectionspace.services.workflow.WorkflowCommon; +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; import javax.ws.rs.GET; +import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.core.Context; import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Request; import javax.ws.rs.core.Response; +import javax.ws.rs.core.UriBuilder; import javax.ws.rs.core.UriInfo; @Path("/" + VocabularyClient.SERVICE_PATH_COMPONENT) @@ -66,7 +84,132 @@ public class VocabularyResource extends VOCABULARIES_COMMON, VOCABULARYITEMS_COMMON); } - @GET + @Override + @POST + public Response createAuthority( + @Context ResourceMap resourceMap, + @Context UriInfo uriInfo, + 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 ctx = createServiceContext(input); + RepositoryClient repoClient = this.getRepositoryClient(ctx); + + CoreSessionInterface repoSession = repoClient.getRepositorySession(ctx); + try { + DocumentHandler handler = createDocumentHandler(ctx); + String csid = repoClient.create(ctx, handler); + handleItemsPayload(repoSession, csid, resourceMap, uriInfo, input); + UriBuilder path = UriBuilder.fromResource(resourceClass); + path.path("" + csid); + Response response = Response.created(path.build()).build(); + return response; + } catch (Throwable t) { + repoSession.setTransactionRollbackOnly(); + throw t; + } finally { + repoClient.releaseRepositorySession(ctx, repoSession); + } + } catch (Exception e) { + throw bigReThrow(e, ServiceMessages.CREATE_FAILED); + } + } + } + + private void handleItemsPayload(CoreSessionInterface repoSession, + String parentIdentifier, + ResourceMap resourceMap, + UriInfo uriInfo, + PoxPayloadIn input) throws Exception { + PayloadInputPart abstractCommonListPart = input.getPart(PoxPayload.ABSTRACT_COMMON_LIST_ROOT_ELEMENT_LABEL); + if (abstractCommonListPart != null) { + AbstractCommonList itemsList = (AbstractCommonList) abstractCommonListPart.getBody(); + for (ListItem item : itemsList.getListItem()) { + PoxPayloadIn itemXmlPayload = getItemXmlPayload(item); + Response res = this.createAuthorityItem(repoSession, resourceMap, uriInfo, parentIdentifier, itemXmlPayload); + } + } + + } + + /** + * This is very brittle. If the class VocabularyitemsCommon changed with new fields we'd have to + * update this method. + * + * @param item + * @return + * @throws DocumentException + */ + private PoxPayloadIn getItemXmlPayload(ListItem item) throws DocumentException { + PoxPayloadIn result = null; + + VocabularyitemsCommon vocabularyItem = new VocabularyitemsCommon(); + for (Element ele : item.getAny()) { + String fieldName = ele.getTagName(); + String fieldValue = ele.getTextContent(); + switch (fieldName) { + case "displayName": + vocabularyItem.setDisplayName(fieldValue); + break; + + case "shortIdentifier": + vocabularyItem.setShortIdentifier(fieldValue); + break; + + case "order": + vocabularyItem.setOrder(fieldValue); + break; + + case "source": + vocabularyItem.setSource(fieldValue); + break; + + case "sourcePage": + vocabularyItem.setSourcePage(fieldValue); + break; + + case "description": + vocabularyItem.setDescription(fieldValue); + + default: + throw new DocumentException(String.format("Unknown field '%s' in vocabulary item payload.", + fieldName)); + } + } + + result = new PoxPayloadIn(VocabularyClient.SERVICE_ITEM_PAYLOAD_NAME, vocabularyItem, + VOCABULARYITEMS_COMMON); + + return result; + } + + private Response createAuthorityItem( + CoreSessionInterface repoSession, + ResourceMap resourceMap, + UriInfo uriInfo, + String parentIdentifier, // Either a CSID or a URN form -e.g., a8ad38ec-1d7d-4bf2-bd31 or urn:cspace:name(bugsbunny) + PoxPayloadIn input) throws Exception { + Response result = null; + + ServiceContext ctx = createServiceContext(getItemServiceName(), input, resourceMap, uriInfo); + ctx.setCurrentRepositorySession(repoSession); + + result = createAuthorityItem(ctx, parentIdentifier, AuthorityServiceUtils.UPDATE_REV, + AuthorityServiceUtils.PROPOSED, AuthorityServiceUtils.NOT_SAS_ITEM); + + return result; + } + + + @GET @Path("{csid}") @Override public Response get(