From 80074845a7cdd4fec46d4ae2290200b290886c20 Mon Sep 17 00:00:00 2001 From: Aron Roberts Date: Tue, 25 Sep 2012 16:18:11 -0700 Subject: [PATCH] CSPACE-5552: Added internal pagination to updates of display names in the refName fields of relation records. Added tenant ID constraint on NXQL query. --- .../common/relation/RelationUtils.java | 187 +++++++++++------- 1 file changed, 114 insertions(+), 73 deletions(-) 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 c0c3ccf51..846b589f6 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 @@ -4,10 +4,12 @@ import org.collectionspace.services.client.CollectionSpaceClient; import org.collectionspace.services.client.IRelationsManager; 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.common.document.DocumentException; import org.collectionspace.services.common.document.DocumentNotFoundException; import org.collectionspace.services.common.repository.RepositoryClient; +import org.collectionspace.services.nuxeo.client.java.RepositoryJavaClientImpl; import org.nuxeo.ecm.core.api.ClientException; import org.nuxeo.ecm.core.api.DocumentModel; import org.nuxeo.ecm.core.api.DocumentModelList; @@ -15,52 +17,59 @@ import org.nuxeo.ecm.core.api.repository.RepositoryInstance; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class RelationUtils { +public class RelationUtils { + private static final Logger logger = LoggerFactory.getLogger(RelationUtils.class); - - private static final int DEFAUT_PAGE_SIZE = 1000; + private static final int DEFAULT_PAGE_SIZE = 1000; + - /* - * Performs an NXQL query to find refName references in relationship records. - */ - private static DocumentModelList findRelationsWithRefName( + /* + * Performs an NXQL query to find refName references in relationship records. + */ + private static DocumentModelList findRelationsWithRefName( + ServiceContext ctx, RepositoryInstance repoSession, - String refName, - String targetField, - String orderByField, + String refName, + String targetField, + String orderByField, int pageSize, int pageNum, boolean computeTotal) { - DocumentModelList result = null; - - String escapedRefName = refName.replace("'", "\\'"); // We need to escape single quotes for NXQL - String query = String.format("SELECT * FROM %s WHERE %s:%s = '%s'", // e.g., "SELECT * FROM Relation WHERE relations_common:subjectRefName = 'urn:cspace:core.collectionspace.org:placeauthorities:name(place):item:name(Amystan1348082103923)\'Amystan\''" - IRelationsManager.DOC_TYPE, - 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; - } - - /* - * Find all the relationship records with the targetField (either subjectRefName or objectRefName) set to the old refName and - * update it to contain the new refName. - */ + DocumentModelList result = null; + + 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); + + 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; + } + + /* + * Find all the relationship records with the targetField (either subjectRefName or objectRefName) set to the old refName and + * update it to contain the new refName. + */ public static void updateRefNamesInRelations( ServiceContext ctx, RepositoryClient repoClient, @@ -68,37 +77,69 @@ public class RelationUtils { String targetField, String oldRefName, String newRefName) { - - DocumentModelList docModelList = findRelationsWithRefName( // FIXME: REM - Step through the pages correctly. - repoSession, - oldRefName, - targetField, - CollectionSpaceClient.CORE_CREATED_AT, - DEFAUT_PAGE_SIZE, - 0, - true); - - if (docModelList != null) { - 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 { - repoSession.save(); - } catch (ClientException e) { - // TODO Auto-generated catch block - logger.error("Could not flush results of relation-refName payload updates to Nuxeo repository"); - } - } else { - // if docModelList was null then we already wrote out the error message to the logs - } + + int docsUpdated = 0; + int currentPage = 0; + int docsInCurrentPage = 0; + + 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 { + 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 { + 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++; + } + } + + logger.debug("updateRefNamesInRelations updated " + docsUpdated + " relations document(s)" + + " with new refName " + newRefName + + " where " + targetField + " contained old refName " + oldRefName); + } -} +} \ No newline at end of file -- 2.47.3