From 667872b109c2a9abea52d9bc667264df8d4b809d Mon Sep 17 00:00:00 2001 From: Ray Lee Date: Tue, 11 Mar 2014 22:33:30 -0700 Subject: [PATCH] CSPACE-6333: Add secondary sort on uuid when querying for refobjs and relations containing refnames. Also refactor RelationUtils.findRelationsWithRefName to use RepositoryJavaClientImpl.findDocs. --- .../services/client/IQueryManager.java | 1 + .../common/relation/RelationUtils.java | 151 +++++++++--------- .../vocabulary/RefNameServiceUtils.java | 6 +- 3 files changed, 81 insertions(+), 77 deletions(-) diff --git a/services/client/src/main/java/org/collectionspace/services/client/IQueryManager.java b/services/client/src/main/java/org/collectionspace/services/client/IQueryManager.java index 88bb3736c..dcc01c692 100644 --- a/services/client/src/main/java/org/collectionspace/services/client/IQueryManager.java +++ b/services/client/src/main/java/org/collectionspace/services/client/IQueryManager.java @@ -46,6 +46,7 @@ public interface IQueryManager { // // Nuxeo pseudo-values (and filters) for special document properties. // + final static String NUXEO_UUID = "ecm:uuid"; final static String NUXEO_IS_PROXY = "ecm:isProxy"; final static String NUXEO_IS_PROXY_FILTER = NUXEO_IS_PROXY + " = 0"; final static String NUXEO_IS_VERSION = "ecm:isCheckedInVersion"; 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 d52778a20..2846194d6 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 @@ -1,6 +1,10 @@ package org.collectionspace.services.common.relation; +import java.util.Arrays; +import java.util.List; + import org.collectionspace.services.client.CollectionSpaceClient; +import org.collectionspace.services.client.IQueryManager; import org.collectionspace.services.client.IRelationsManager; import org.collectionspace.services.client.PoxPayloadIn; import org.collectionspace.services.client.PoxPayloadOut; @@ -8,6 +12,7 @@ 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.repository.RepositoryClient; import org.collectionspace.services.nuxeo.client.java.RepositoryInstanceInterface; import org.collectionspace.services.nuxeo.client.java.RepositoryJavaClientImpl; @@ -29,42 +34,29 @@ public class RelationUtils { */ private static DocumentModelList findRelationsWithRefName( ServiceContext ctx, + RepositoryClient repoClient, RepositoryInstanceInterface repoSession, String refName, String targetField, - String orderByField, + String orderByClause, int pageSize, int pageNum, - boolean computeTotal) { - DocumentModelList result = null; + boolean computeTotal) throws DocumentException, DocumentNotFoundException { + List docTypes = Arrays.asList(IRelationsManager.DOC_TYPE); + String escapedRefName = refName.replace("'", "\\'"); // We need to escape single quotes for NXQL // e.g., "SELECT * FROM Relation WHERE // collectionspace_core:tenantid = '1' AND // relations_common:subjectRefName = 'urn:cspace:core.collectionspace.org:placeauthorities:name(place):item:name(Amystan1348082103923)\'Amystan\''" - String query = String.format("SELECT * FROM %s WHERE %s:%s = '%s' AND %s:%s = '%s'", - IRelationsManager.DOC_TYPE, - CollectionSpaceClient.COLLECTIONSPACE_CORE_SCHEMA, - CollectionSpaceClient.COLLECTIONSPACE_CORE_TENANTID, - ctx.getTenantId(), - IRelationsManager.SERVICE_COMMONPART_NAME, - targetField, - escapedRefName); + String query = String.format("%s:%s = '%s'", IRelationsManager.SERVICE_COMMONPART_NAME, targetField, escapedRefName); - if (logger.isDebugEnabled() == true) { - logger.debug(String.format("findRelationsWithRefName NXQL query is %s", query)); - } - - try { - result = repoSession.query(query, null, pageSize, pageNum, computeTotal); - } catch (ClientException e) { - if (logger.isDebugEnabled() == true) { - logger.debug(String.format("Exception caught while looking for refNames in relationship records for updating: refName %s", - refName), e); - } - } - - return result; + RepositoryJavaClientImpl nuxeoRepoClient = (RepositoryJavaClientImpl) repoClient; + DocumentWrapper docListWrapper = nuxeoRepoClient.findDocs(ctx, repoSession, + docTypes, query, orderByClause, pageSize, pageNum, computeTotal); + DocumentModelList docList = docListWrapper.getWrappedObject(); + + return docList; } /* @@ -77,65 +69,74 @@ public class RelationUtils { RepositoryInstanceInterface repoSession, String targetField, String oldRefName, - String newRefName) { + String newRefName) throws Exception { int docsUpdated = 0; int currentPage = 0; int docsInCurrentPage = 0; + final String ORDER_BY_VALUE = CollectionSpaceClient.CORE_CREATED_AT + + ", " + IQueryManager.NUXEO_UUID; // CSPACE-6333: Add secondary sort on uuid, in case records have the same createdAt timestamp. - boolean morePages = true; - while (morePages) { - - DocumentModelList docModelList = findRelationsWithRefName( - ctx, - repoSession, - oldRefName, - targetField, - CollectionSpaceClient.CORE_CREATED_AT, - DEFAULT_PAGE_SIZE, - currentPage, - true); - - if (docModelList == null) { - logger.trace("updateRefNamesInRelations: no documents could be found that referenced the old refName"); - break; - } - docsInCurrentPage = docModelList.size(); - logger.trace("updateRefNamesInRelations: current page=" + currentPage + " documents included in page=" + docsInCurrentPage); - if (docsInCurrentPage == 0) { - logger.trace("updateRefNamesInRelations: no more documents requiring refName updates could be found"); - break; - } - if (docsInCurrentPage < DEFAULT_PAGE_SIZE) { - logger.trace("updateRefNamesInRelations: assuming no more documents requiring refName updates will be found, as docsInCurrentPage < pageSize"); - morePages = false; - } - - for (DocumentModel docModel : docModelList) { + try { + boolean morePages = true; + while (morePages) { + + DocumentModelList docModelList = findRelationsWithRefName( + ctx, + repoClient, + repoSession, + oldRefName, + targetField, + ORDER_BY_VALUE, + DEFAULT_PAGE_SIZE, + currentPage, + true); + + if (docModelList == null) { + logger.trace("updateRefNamesInRelations: no documents could be found that referenced the old refName"); + break; + } + docsInCurrentPage = docModelList.size(); + logger.trace("updateRefNamesInRelations: current page=" + currentPage + " documents included in page=" + docsInCurrentPage); + if (docsInCurrentPage == 0) { + logger.trace("updateRefNamesInRelations: no more documents requiring refName updates could be found"); + break; + } + if (docsInCurrentPage < DEFAULT_PAGE_SIZE) { + logger.trace("updateRefNamesInRelations: assuming no more documents requiring refName updates will be found, as docsInCurrentPage < pageSize"); + morePages = false; + } + + for (DocumentModel docModel : docModelList) { + try { + docModel.setProperty(IRelationsManager.SERVICE_COMMONPART_NAME, targetField, newRefName); + repoSession.saveDocument(docModel); + } catch (ClientException e) { + logger.error(String.format("Could not update field '%s' with updated refName '%s' for relations record CSID=%s", + targetField, newRefName, docModel.getName())); + } + } + // + // Flush the results + // try { - docModel.setProperty(IRelationsManager.SERVICE_COMMONPART_NAME, targetField, newRefName); - repoSession.saveDocument(docModel); + repoSession.save(); } catch (ClientException e) { - logger.error(String.format("Could not update field '%s' with updated refName '%s' for relations record CSID=%s", - targetField, newRefName, docModel.getName())); + // TODO Auto-generated catch block + logger.error("Could not flush results of relation-refName payload updates to Nuxeo repository"); + } + + // FIXME: Per REM, set a limit of num objects - something like + // 1000K objects - and also add a log Warning after some threshold + docsUpdated += docsInCurrentPage; + if (morePages) { + currentPage++; } } - // - // Flush the results - // - try { - repoSession.save(); - } catch (ClientException e) { - // TODO Auto-generated catch block - logger.error("Could not flush results of relation-refName payload updates to Nuxeo repository"); - } - - // FIXME: Per REM, set a limit of num objects - something like - // 1000K objects - and also add a log Warning after some threshold - docsUpdated += docsInCurrentPage; - if (morePages) { - currentPage++; - } + } catch (Exception e) { + logger.error("Internal error updating the ref names in relations: " + e.getLocalizedMessage()); + logger.debug(Tools.errorToString(e, true)); + throw e; } logger.debug("updateRefNamesInRelations updated " + docsUpdated + " relations document(s)" 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 254a63f59..96d6fc649 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 @@ -41,6 +41,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.collectionspace.services.client.CollectionSpaceClient; +import org.collectionspace.services.client.IQueryManager; import org.collectionspace.services.client.IRelationsManager; import org.collectionspace.services.client.PoxPayloadIn; import org.collectionspace.services.client.PoxPayloadOut; @@ -217,7 +218,7 @@ public class RefNameServiceUtils { RepositoryClient repoClient, RepositoryInstanceInterface repoSession, String oldRefName, - String newRefName) { + String newRefName) throws Exception { // // First, look for and update all the places where the refName is the "subject" of the relationship // @@ -416,7 +417,8 @@ public class RefNameServiceUtils { int currentPage = 0; int docsInCurrentPage = 0; final String WHERE_CLAUSE_ADDITIONS_VALUE = null; - final String ORDER_BY_VALUE = CollectionSpaceClient.CORE_CREATED_AT; // "collectionspace_core:createdAt"; + 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 RepositoryJavaClientImpl == false) { throw new InternalError("updateAuthorityRefDocs() called with unknown repoClient type!"); -- 2.47.3