diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/comments/comments.post.json.js b/config/alfresco/templates/webscripts/org/alfresco/repository/comments/comments.post.json.js index 945340d55a..978d75d0cf 100644 --- a/config/alfresco/templates/webscripts/org/alfresco/repository/comments/comments.post.json.js +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/comments/comments.post.json.js @@ -21,6 +21,12 @@ function addComment(node) // get a unique name var name = getUniqueChildName(commentsFolder, "comment"); + // Add the comments rollup aspect to the commented-upon node. + if (!node.hasAspect("fm:commentsRollup")) + { + node.addAspect("fm:commentsRollup"); + } + // create the comment var commentNode = commentsFolder.createNode(name, "fm:post"); commentNode.mimetype = "text/html"; diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/forms/form.post.js b/config/alfresco/templates/webscripts/org/alfresco/repository/forms/form.post.js index a115121ada..8d37d17839 100644 --- a/config/alfresco/templates/webscripts/org/alfresco/repository/forms/form.post.js +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/forms/form.post.js @@ -1,8 +1,8 @@ function main() { // Extract template args - var itemKind = url.templateArgs["item_kind"]; - var itemId = url.templateArgs["item_id"]; + var itemKind = decodeURIComponent(url.templateArgs["item_kind"]); + var itemId = decodeURIComponent(url.templateArgs["item_id"]); if (logger.isLoggingEnabled()) { diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/forms/form.post.json.js b/config/alfresco/templates/webscripts/org/alfresco/repository/forms/form.post.json.js index 56a5dae4c8..53e6f35db5 100644 --- a/config/alfresco/templates/webscripts/org/alfresco/repository/forms/form.post.json.js +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/forms/form.post.json.js @@ -1,8 +1,8 @@ function main() { // Extract template args - var itemKind = url.templateArgs["item_kind"]; - var itemId = url.templateArgs["item_id"]; + var itemKind = decodeURIComponent(url.templateArgs["item_kind"]); + var itemId = decodeURIComponent(url.templateArgs["item_id"]); if (logger.isLoggingEnabled()) { diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/forms/formdefinition.post.json.js b/config/alfresco/templates/webscripts/org/alfresco/repository/forms/formdefinition.post.json.js index e7553f1940..9be6d7a239 100644 --- a/config/alfresco/templates/webscripts/org/alfresco/repository/forms/formdefinition.post.json.js +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/forms/formdefinition.post.json.js @@ -96,10 +96,9 @@ function main() var submissionUrl = formScriptObj.submissionUrl; if (submissionUrl === null) { - // replace characters that can cause issues in URLs - var escapedItemId = itemId.replace(':', '_'); - - submissionUrl = '/api/' + itemKind + '/' + escapedItemId + '/formprocessor'; + // encode the item id and item kind using URI encoding scheme, however, the encoded / character + // causes problems when posting back to Apache so change these back + submissionUrl = '/api/' + encodeURIComponent(itemKind) + '/' + encodeURIComponent(itemId).replace(/%2f/g, "/") + '/formprocessor'; } // create form model diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/solr/aclChangeSets.get.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/solr/aclChangeSets.get.desc.xml index 00acd29eaa..812a849a5f 100644 --- a/config/alfresco/templates/webscripts/org/alfresco/repository/solr/aclChangeSets.get.desc.xml +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/solr/aclChangeSets.get.desc.xml @@ -7,4 +7,18 @@ required internal SOLR + + + fromId + Smallest changset ID (inclusive) + + + fromTime + Smallest commit time (inclusive) + + + maxResults + Maximum number of results (optional: default 1024) + + \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/solr/acls.post.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/solr/acls.post.desc.xml new file mode 100644 index 0000000000..736ca07ab1 --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/solr/acls.post.desc.xml @@ -0,0 +1,26 @@ + + Get ACLs + Get the ACLs for given ChangeSets. + /api/solr/acls?fromId={fromId?}&maxResults={maxResults?} + argument + admin + required + internal + SOLR + + + fromId + Minimum ACL ID that can be specified when exactly one ACL ChangeSet ID is given + + + maxResults + Maximum number of results (optional: default 1024) + + + POST content + + { aclChangeSetIds : [ 1, 2, ..., n] } + + + + \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/solr/acls.post.json.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/solr/acls.post.json.ftl new file mode 100644 index 0000000000..abe52028cd --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/solr/acls.post.json.ftl @@ -0,0 +1,10 @@ +<#import "solr.lib.ftl" as solrLib/> +{ + "acls" : + [ + <#list acls as acl> + <@solrLib.aclJSON acl=acl/> + <#if acl_has_next>, + + ] +} \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/solr/aclsReaders.post.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/solr/aclsReaders.post.desc.xml new file mode 100644 index 0000000000..93bf614bdf --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/solr/aclsReaders.post.desc.xml @@ -0,0 +1,18 @@ + + Get ACLs readers + Get the readers for given ACLs. + /api/solr/aclsReaders + argument + admin + required + internal + SOLR + + + POST content + + { aclIds: [1, 2, 3, ..., N] } + + + + \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/solr/aclsReaders.post.json.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/solr/aclsReaders.post.json.ftl new file mode 100644 index 0000000000..4669dec557 --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/solr/aclsReaders.post.json.ftl @@ -0,0 +1,10 @@ +<#import "solr.lib.ftl" as solrLib/> +{ + "aclsReaders" : + [ + <#list aclsReaders as aclReaders> + <@solrLib.aclReadersJSON aclReaders=aclReaders/> + <#if aclReaders_has_next>, + + ] +} \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/solr/solr.lib.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/solr/solr.lib.ftl index d43c81d64a..cd0a62e974 100644 --- a/config/alfresco/templates/webscripts/org/alfresco/repository/solr/solr.lib.ftl +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/solr/solr.lib.ftl @@ -6,6 +6,26 @@ } +<#macro aclJSON acl> + { + "id": ${acl.id?c}, + "aclChangeSetId": ${acl.aclChangeSetId?c} + } + + +<#macro aclReadersJSON aclReaders> + { + "aclId": ${aclReaders.aclId?c}, + "readers" : + [ + <#list aclReaders.readers as reader> + ${reader?string} + <#if reader_has_next>, + + ] + } + + <#macro transactionJSON txn> { "id": ${txn.id?c}, diff --git a/config/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary/doclist.get.js b/config/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary/doclist.get.js index 912ef5d58d..ad1ea906a7 100644 --- a/config/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary/doclist.get.js +++ b/config/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary/doclist.get.js @@ -22,6 +22,7 @@ function getDoclist() // Try to find a filter query based on the passed-in arguments var allNodes = [], totalRecords, + totalRecordsUpper, paged = false, favourites = Common.getFavourites(), filterParams = Filters.getFilterParams(filter, parsedArgs, @@ -56,11 +57,14 @@ function getDoclist() var sortField = (args.sortField == null ? "cm:name" : args.sortField); var sortAsc = (((args.sortAsc == null) || (args.sortAsc == "true")) ? true : false); + + // TODO review + var pagedResult = parentNode.childFileFolders(true, true, ignoreTypes, skip, max, (skip + 1000), sortField, sortAsc, "TODO"); - var pagedResult = parentNode.childFileFolders(true, true, ignoreTypes, skip, max, sortField, sortAsc); + allNodes = pagedResult.page; - allNodes = pagedResult.result; - totalRecords = pagedResult.totalCount; + totalRecords = pagedResult.totalResultCountLower; + totalRecordsUpper = pagedResult.totalResultCountUpper; paged = true; } @@ -240,15 +244,22 @@ function getDoclist() } } } - + + var paging = + { + totalRecords: totalRecords, + startIndex: startIndex + }; + + if (paged && (! (totalRecords === totalRecordsUpper))) + { + paging.totalRecordsUpper = totalRecordsUpper; + } + return ( { luceneQuery: query, - paging: - { - totalRecords: totalRecords, - startIndex: startIndex - }, + paging: paging, container: parsedArgs.rootNode, parent: parent, onlineEditing: utils.moduleInstalled("org.alfresco.module.vti"), diff --git a/config/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary/doclist.get.json.ftl b/config/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary/doclist.get.json.ftl index 489362a34c..101de008c3 100644 --- a/config/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary/doclist.get.json.ftl +++ b/config/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary/doclist.get.json.ftl @@ -2,6 +2,9 @@ <#escape x as jsonUtils.encodeJSONString(x)> { "totalRecords": ${doclist.paging.totalRecords?c}, + <#if doclist.paging.totalRecordsUpper??> + "totalRecordsUpper": ${doclist.paging.totalRecordsUpper?c}, + "startIndex": ${doclist.paging.startIndex?c}, "metadata": { diff --git a/config/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary/treenode.get.js b/config/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary/treenode.get.js index 487d514dcd..5997b71bd2 100644 --- a/config/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary/treenode.get.js +++ b/config/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary/treenode.get.js @@ -24,32 +24,29 @@ function getTreeNode() { return; } - - // Look for folders in the pathNode - var folders = parsedArgs.pathNode.childFileFolders(false, true, ignoredTypes); - for each (item in folders) + + // Look for folders in the pathNode - sort by ascending name + var pagedResult = parsedArgs.pathNode.childFileFolders(false, true, ignoredTypes, 0, maxItems, 0, "cm:name", true, "TODO"); + + if (pagedResult.hasMoreItems() == true) + { + resultsTrimmed = true; + } + + for each (item in pagedResult.page) { if (evalChildFolders) { - hasSubfolders = item.childFileFolders(false, true, "fm:forum").length > 0; + hasSubfolders = item.childFileFolders(false, true, ignoredTypes, 1).page.length > 0; } - + items.push( { - node: item, - hasSubfolders: hasSubfolders + node: item, + hasSubfolders: hasSubfolders }); - - if (maxItems !== -1 && items.length > maxItems) - { - items.pop(); - resultsTrimmed = true; - break; - } } - - items.sort(sortByName); - + return ( { parent: parsedArgs.pathNode, @@ -62,11 +59,4 @@ function getTreeNode() status.setCode(status.STATUS_INTERNAL_SERVER_ERROR, e.toString()); return; } -} - - -/* Sort the results by case-insensitive name */ -function sortByName(a, b) -{ - return (b.node.name.toLowerCase() > a.node.name.toLowerCase() ? -1 : 1); } \ No newline at end of file diff --git a/config/alfresco/web-scripts-application-context.xml b/config/alfresco/web-scripts-application-context.xml index 040a21811c..74f7b85c70 100644 --- a/config/alfresco/web-scripts-application-context.xml +++ b/config/alfresco/web-scripts-application-context.xml @@ -1233,6 +1233,24 @@ + + + + + + + + + + + + diff --git a/source/java/org/alfresco/repo/web/scripts/RepoStore.java b/source/java/org/alfresco/repo/web/scripts/RepoStore.java index 173d6a7878..535f48d88c 100644 --- a/source/java/org/alfresco/repo/web/scripts/RepoStore.java +++ b/source/java/org/alfresco/repo/web/scripts/RepoStore.java @@ -34,7 +34,7 @@ import java.util.regex.Pattern; import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.model.ContentModel; import org.alfresco.repo.model.filefolder.FileFolderServiceImpl; -import org.alfresco.repo.search.impl.lucene.LuceneQueryParser; +import org.alfresco.repo.search.impl.lucene.AbstractLuceneQueryParser; import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.tenant.TenantAdminService; import org.alfresco.repo.tenant.TenantDeployer; @@ -483,12 +483,12 @@ public class RepoStore extends AbstractStore implements TenantDeployer } else { - result.append(LuceneQueryParser.escape(token)); + result.append(AbstractLuceneQueryParser.escape(token)); } } else { - result.append(LuceneQueryParser.escape(token)); + result.append(AbstractLuceneQueryParser.escape(token)); } } return result.toString(); diff --git a/source/java/org/alfresco/repo/web/scripts/site/SiteServiceTest.java b/source/java/org/alfresco/repo/web/scripts/site/SiteServiceTest.java index 4b6ed636f9..5c13d4b833 100644 --- a/source/java/org/alfresco/repo/web/scripts/site/SiteServiceTest.java +++ b/source/java/org/alfresco/repo/web/scripts/site/SiteServiceTest.java @@ -171,8 +171,7 @@ public class SiteServiceTest extends BaseWebScriptTest Response response = sendRequest(new GetRequest(URL_SITES), 200); JSONArray result = new JSONArray(response.getContentAsString()); assertNotNull(result); - int sitesBefore = result.length(); - assertTrue("There should be at least one site present", sitesBefore > 0); + final int preexistingSiteCount = result.length(); createSite("myPreset", GUID.generate(), "myTitle", "myDescription", SiteVisibility.PUBLIC, 200); createSite("myPreset", GUID.generate(), "myTitle", "myDescription", SiteVisibility.PUBLIC, 200); @@ -183,17 +182,17 @@ public class SiteServiceTest extends BaseWebScriptTest response = sendRequest(new GetRequest(URL_SITES), 200); result = new JSONArray(response.getContentAsString()); assertNotNull(result); - assertEquals(5 + sitesBefore, result.length()); + assertEquals("Wrong site count", preexistingSiteCount + 5, result.length()); response = sendRequest(new GetRequest(URL_SITES + "?size=3"), 200); result = new JSONArray(response.getContentAsString()); assertNotNull(result); - assertEquals(3, result.length()); + assertEquals("Wrong site count (?size=3)", 3, result.length()); response = sendRequest(new GetRequest(URL_SITES + "?size=13"), 200); result = new JSONArray(response.getContentAsString()); assertNotNull(result); - assertEquals(5 + sitesBefore, result.length()); + assertEquals("Wrong site count (?size=13)", Math.min(13, preexistingSiteCount + 5), result.length()); } /** diff --git a/source/java/org/alfresco/repo/web/scripts/solr/AclsGet.java b/source/java/org/alfresco/repo/web/scripts/solr/AclsGet.java new file mode 100644 index 0000000000..4b74d6690f --- /dev/null +++ b/source/java/org/alfresco/repo/web/scripts/solr/AclsGet.java @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2005-2011 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.repo.web.scripts.solr; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.alfresco.repo.solr.Acl; +import org.alfresco.repo.solr.SOLRTrackingComponent; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; +import org.springframework.extensions.surf.util.Content; +import org.springframework.extensions.webscripts.DeclarativeWebScript; +import org.springframework.extensions.webscripts.Status; +import org.springframework.extensions.webscripts.WebScriptException; +import org.springframework.extensions.webscripts.WebScriptRequest; + +/** + * Support for SOLR: Track ACLs + * + * @since 4.0 + */ +public class AclsGet extends DeclarativeWebScript +{ + protected static final Log logger = LogFactory.getLog(AclsGet.class); + + private SOLRTrackingComponent solrTrackingComponent; + + public void setSolrTrackingComponent(SOLRTrackingComponent solrTrackingComponent) + { + this.solrTrackingComponent = solrTrackingComponent; + } + + protected Map executeImpl(WebScriptRequest req, Status status) + { + try + { + Map model = buildModel(req); + if (logger.isDebugEnabled()) + { + logger.debug("Result: \n\tRequest: " + req + "\n\tModel: " + model); + } + return model; + } + catch(IOException e) + { + throw new WebScriptException("IO exception parsing request", e); + } + catch(JSONException e) + { + throw new WebScriptException("Invalid JSON", e); + } + } + + private Map buildModel(WebScriptRequest req) throws JSONException, IOException + { + List aclChangeSetIds = null; + + Content content = req.getContent(); + if (content == null) + { + throw new WebScriptException("Request content is empty"); + } + JSONObject o = new JSONObject(content.getContent()); + JSONArray aclChangeSetIdsJSON = o.has("aclChangeSetIds") ? o.getJSONArray("aclChangeSetIds") : null; + if (aclChangeSetIdsJSON == null) + { + throw new WebScriptException( + Status.STATUS_BAD_REQUEST, + "Parameter 'aclChangeSetIds' not provided in request content."); + } + else if (aclChangeSetIdsJSON.length() == 0 || aclChangeSetIdsJSON.length() > 512) + { + throw new WebScriptException( + Status.STATUS_BAD_REQUEST, + "Parameter 'aclChangeSetIds' must hold from 1 to 512 IDs."); + } + aclChangeSetIds = new ArrayList(aclChangeSetIdsJSON.length()); + for (int i = 0; i < aclChangeSetIdsJSON.length(); i++) + { + aclChangeSetIds.add(aclChangeSetIdsJSON.getLong(i)); + } + + String fromIdParam = req.getParameter("fromId"); + String maxResultsParam = req.getParameter("maxResults"); + + Long fromId = (fromIdParam == null ? null : Long.valueOf(fromIdParam)); + int maxResults = (maxResultsParam == null ? 1024 : Integer.valueOf(maxResultsParam)); + + // Request according to the paging query style required + List acls = solrTrackingComponent.getAcls(aclChangeSetIds, fromId, maxResults); + + Map model = new HashMap(1, 1.0f); + model.put("acls", acls); + + if (logger.isDebugEnabled()) + { + logger.debug("Result: \n\tRequest: " + req + "\n\tModel: " + model); + } + + return model; + } +} diff --git a/source/java/org/alfresco/repo/web/scripts/solr/AclsReadersGet.java b/source/java/org/alfresco/repo/web/scripts/solr/AclsReadersGet.java new file mode 100644 index 0000000000..5f8c5ab021 --- /dev/null +++ b/source/java/org/alfresco/repo/web/scripts/solr/AclsReadersGet.java @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2005-2011 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.repo.web.scripts.solr; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.alfresco.repo.solr.AclReaders; +import org.alfresco.repo.solr.SOLRTrackingComponent; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; +import org.springframework.extensions.surf.util.Content; +import org.springframework.extensions.webscripts.DeclarativeWebScript; +import org.springframework.extensions.webscripts.Status; +import org.springframework.extensions.webscripts.WebScriptException; +import org.springframework.extensions.webscripts.WebScriptRequest; + +/** + * Support for SOLR: Track ACLs + * + * @since 4.0 + */ +public class AclsReadersGet extends DeclarativeWebScript +{ + protected static final Log logger = LogFactory.getLog(AclsReadersGet.class); + + private SOLRTrackingComponent solrTrackingComponent; + + public void setSolrTrackingComponent(SOLRTrackingComponent solrTrackingComponent) + { + this.solrTrackingComponent = solrTrackingComponent; + } + + protected Map executeImpl(WebScriptRequest req, Status status) + { + try + { + Map model = buildModel(req); + if (logger.isDebugEnabled()) + { + logger.debug("Result: \n\tRequest: " + req + "\n\tModel: " + model); + } + return model; + } + catch(IOException e) + { + throw new WebScriptException("IO exception parsing request", e); + } + catch(JSONException e) + { + throw new WebScriptException("Invalid JSON", e); + } + } + + private Map buildModel(WebScriptRequest req) throws JSONException, IOException + { + List aclIds = null; + + Content content = req.getContent(); + if (content == null) + { + throw new WebScriptException("Request content is empty"); + } + JSONObject o = new JSONObject(content.getContent()); + JSONArray aclIdsJSON = o.has("aclIds") ? o.getJSONArray("aclIds") : null; + if (aclIdsJSON == null) + { + throw new WebScriptException( + Status.STATUS_BAD_REQUEST, + "Parameter 'aclIds' not provided in request content."); + } + else if (aclIdsJSON.length() == 0 || aclIdsJSON.length() > 512) + { + throw new WebScriptException( + Status.STATUS_BAD_REQUEST, + "Parameter 'aclIds' must hold from 1 to 512 IDs."); + } + aclIds = new ArrayList(aclIdsJSON.length()); + for (int i = 0; i < aclIdsJSON.length(); i++) + { + aclIds.add(aclIdsJSON.getLong(i)); + } + + // Request according to the paging query style required + List aclsReaders = solrTrackingComponent.getAclsReaders(aclIds); + + Map model = new HashMap(1, 1.0f); + model.put("aclsReaders", aclsReaders); + + if (logger.isDebugEnabled()) + { + logger.debug("Result: \n\tRequest: " + req + "\n\tModel: " + model); + } + + return model; + } +} diff --git a/source/java/org/alfresco/repo/web/scripts/solr/NodesGet.java b/source/java/org/alfresco/repo/web/scripts/solr/NodesGet.java index 8f3398a51d..4a1fadd135 100644 --- a/source/java/org/alfresco/repo/web/scripts/solr/NodesGet.java +++ b/source/java/org/alfresco/repo/web/scripts/solr/NodesGet.java @@ -180,19 +180,20 @@ public class NodesGet extends DeclarativeWebScript /** * Callback for DAO get nodes query - * */ private static class WebNodeQueryCallback implements NodeQueryCallback { private ArrayList nodes; - public WebNodeQueryCallback(int count) { + public WebNodeQueryCallback(int count) + { super(); nodes = new ArrayList(count == 0 || count == Integer.MAX_VALUE ? 100 : count); } @Override - public boolean handleNode(Node node) { + public boolean handleNode(Node node) + { nodes.add(node); // continue - get next node @@ -204,5 +205,4 @@ public class NodesGet extends DeclarativeWebScript return nodes; } } - } \ No newline at end of file diff --git a/source/java/org/alfresco/repo/web/scripts/solr/SOLRSerializer.java b/source/java/org/alfresco/repo/web/scripts/solr/SOLRSerializer.java index 16d7ab7599..66d791b7a2 100644 --- a/source/java/org/alfresco/repo/web/scripts/solr/SOLRSerializer.java +++ b/source/java/org/alfresco/repo/web/scripts/solr/SOLRSerializer.java @@ -41,6 +41,7 @@ import org.alfresco.service.cmr.repository.Path; import org.alfresco.service.cmr.repository.Path.AttributeElement; import org.alfresco.service.cmr.repository.Path.ChildAssocElement; import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter; +import org.alfresco.service.cmr.repository.datatype.TypeConversionException; import org.alfresco.service.cmr.repository.datatype.TypeConverter; import org.alfresco.service.cmr.repository.datatype.TypeConverter.Converter; import org.alfresco.service.namespace.NamespaceService; @@ -92,16 +93,24 @@ import org.json.JSONObject; this.namespaceService = namespaceService; } + public String serializeToString(Serializable value) + { + if (value != null && typeConverter.INSTANCE.getConverter(value.getClass(), String.class) == null) + { + // There is no converter + return value.toString(); + } + else + { + return typeConverter.INSTANCE.convert(String.class, value); + } + } + public T serializeValue(Class targetClass, Object value) throws JSONException { return typeConverter.INSTANCE.convert(targetClass, value); } - public String serializeToString(Serializable value) - { - return typeConverter.INSTANCE.convert(String.class, value); - } - @SuppressWarnings("unchecked") public PropertyValue serialize(QName propName, Serializable value) throws IOException, JSONException { @@ -111,13 +120,12 @@ import org.json.JSONObject; } PropertyDefinition propertyDef = dictionaryService.getProperty(propName); - if(propertyDef == null) + if (propertyDef == null) { - throw new IllegalArgumentException("Could not find property definition for property " + propName); + // Treat it as text + return new PropertyValue(true, serializeToString(value)); } - - boolean isMulti = propertyDef.isMultiValued(); - if(isMulti) + else if (propertyDef.isMultiValued()) { if(!(value instanceof Collection)) { @@ -129,7 +137,7 @@ import org.json.JSONObject; JSONArray body = new JSONArray(); for(Serializable o : c) { - body.put(serializeValue(String.class, o)); + body.put(serializeToString(o)); } return new PropertyValue(false, body.toString()); @@ -151,7 +159,7 @@ import org.json.JSONObject; { encodeString = true; } - return new PropertyValue(encodeString, serializeValue(String.class, value)); + return new PropertyValue(encodeString, serializeToString(value)); } } diff --git a/source/java/org/alfresco/repo/web/scripts/solr/SOLRWebScriptTest.java b/source/java/org/alfresco/repo/web/scripts/solr/SOLRWebScriptTest.java index b1b7ffcd8f..2eb5292529 100644 --- a/source/java/org/alfresco/repo/web/scripts/solr/SOLRWebScriptTest.java +++ b/source/java/org/alfresco/repo/web/scripts/solr/SOLRWebScriptTest.java @@ -26,17 +26,21 @@ import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Set; import org.alfresco.model.ContentModel; import org.alfresco.repo.domain.node.NodeDAO; import org.alfresco.repo.security.authentication.AuthenticationUtil; +import org.alfresco.repo.solr.Acl; +import org.alfresco.repo.solr.AclChangeSet; +import org.alfresco.repo.solr.AclReaders; +import org.alfresco.repo.solr.SOLRTrackingComponent; import org.alfresco.repo.transaction.RetryingTransactionHelper; import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; import org.alfresco.repo.web.scripts.BaseWebScriptTest; import org.alfresco.service.ServiceRegistry; import org.alfresco.service.cmr.model.FileFolderService; import org.alfresco.service.cmr.model.FileInfo; -import org.alfresco.service.cmr.repository.ContentService; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.Path; @@ -61,19 +65,15 @@ import org.springframework.extensions.webscripts.TestWebScriptServer.Response; * * @since 4.0 */ -// TODO check txn ids are correct - how to get txn ids? -// TODO create a node in txn1 and delete it in txn2 - only the delete in txn2 appears. Will SOLR not then see this as deletion of a non-existent node? -// TODO test getTxns: combinations of fromTxnId, fromCommitTime, maxResults -// TODO move/duplicate tests to SOLRDAO tests public class SOLRWebScriptTest extends BaseWebScriptTest { protected static final Log logger = LogFactory.getLog(SOLRWebScriptTest.class); private ApplicationContext ctx; + private SOLRTrackingComponent solrTrackingComponent; private NodeDAO nodeDAO; private TransactionService transactionService; private NodeService nodeService; - private ContentService contentService; private FileFolderService fileFolderService; private RetryingTransactionHelper txnHelper; private NamespaceService namespaceService; @@ -81,33 +81,8 @@ public class SOLRWebScriptTest extends BaseWebScriptTest private String admin; private StoreRef storeRef; - private StoreRef storeRef1; private NodeRef rootNodeRef; - private NodeRef rootNodeRef1; - - private NodeRef container1; - private NodeRef container2; private NodeRef container3; - private NodeRef container4; - private NodeRef container5; - private NodeRef content1; - private NodeRef content2; - private NodeRef content3; - - private long container1NodeID; - private long container2NodeID; - private long container3NodeID; - private long container4NodeID; - private long container5NodeID; - private long content1NodeID; - private long content2NodeID; - private long content3NodeID; - private long content4NodeID; - private long content5NodeID; - - private JSONObject firstNode; - private JSONObject secondNode; - private JSONObject thirdNode; private ArrayList contents = new ArrayList(100); private List nodeIDs = new ArrayList(100); @@ -121,11 +96,11 @@ public class SOLRWebScriptTest extends BaseWebScriptTest ServiceRegistry serviceRegistry = (ServiceRegistry) ctx.getBean(ServiceRegistry.SERVICE_REGISTRY); transactionService = serviceRegistry.getTransactionService(); nodeService = serviceRegistry.getNodeService(); - contentService = serviceRegistry.getContentService(); fileFolderService = serviceRegistry.getFileFolderService(); namespaceService = serviceRegistry.getNamespaceService(); txnHelper = transactionService.getRetryingTransactionHelper(); nodeDAO = (NodeDAO)ctx.getBean("nodeDAO"); + solrTrackingComponent = (SOLRTrackingComponent) ctx.getBean("solrTrackingComponent"); admin = AuthenticationUtil.getAdminUserName(); @@ -133,9 +108,6 @@ public class SOLRWebScriptTest extends BaseWebScriptTest storeRef = nodeService.createStore(StoreRef.PROTOCOL_WORKSPACE, getName() + ".1." + System.currentTimeMillis()); rootNodeRef = nodeService.getRootNode(storeRef); - - storeRef1 = nodeService.createStore(StoreRef.PROTOCOL_WORKSPACE, getName() + ".2." + System.currentTimeMillis()); - rootNodeRef1 = nodeService.getRootNode(storeRef1); } @Override @@ -160,7 +132,7 @@ public class SOLRWebScriptTest extends BaseWebScriptTest JSONArray transactions = json.getJSONArray("transactions"); - System.out.println("Got " + transactions.length() + " txns in " + (endTime - startTime) + " ms"); + logger.debug("Got " + transactions.length() + " txns in " + (endTime - startTime) + " ms"); return transactions; } @@ -181,7 +153,119 @@ public class SOLRWebScriptTest extends BaseWebScriptTest JSONArray aclChangeSets = json.getJSONArray("aclChangeSets"); - System.out.println("Got " + aclChangeSets.length() + " txns in " + (endTime - startTime) + " ms"); + logger.debug("Got " + aclChangeSets.length() + " txns in " + (endTime - startTime) + " ms"); + } + + public void testAclsGet() throws Exception + { + List aclChangeSets = solrTrackingComponent.getAclChangeSets(null, null, 100); + if (aclChangeSets.size() == 0) + { + return; // Can't test, but very unlikely + } + // Build JSON using these + JSONObject json = new JSONObject(); + JSONArray aclChangeSetIdsJSON = new JSONArray(); + int count = 0; + List aclChangeSetIds = new ArrayList(); + for (AclChangeSet aclChangeSet : aclChangeSets) + { + if (count >= 512) + { + break; + } + if (aclChangeSet.getAclCount() == 0) + { + continue; // No ACLs + } + Long aclChangeSetId = aclChangeSet.getId(); + aclChangeSetIdsJSON.put(aclChangeSetId); + aclChangeSetIds.add(aclChangeSetId); + count++; + } + json.put("aclChangeSetIds", aclChangeSetIdsJSON); + + String url = "/api/solr/acls"; + TestWebScriptServer.PostRequest req = new TestWebScriptServer.PostRequest(url, json.toString(), "application/json"); + Response response = sendRequest(req, Status.STATUS_OK, admin); + if(logger.isDebugEnabled()) + { + logger.debug(response.getContentAsString()); + } + json = new JSONObject(response.getContentAsString()); + JSONArray acls = json.getJSONArray("acls"); + + // Check + List aclsCheck = solrTrackingComponent.getAcls(aclChangeSetIds, null, 512); + assertEquals("Script and API returned different number of results", aclsCheck.size(), acls.length()); + } + + public void testAclReadersGet() throws Exception + { + List aclChangeSets = solrTrackingComponent.getAclChangeSets(null, null, 1024); + List aclChangeSetIds = new ArrayList(50); + for (AclChangeSet aclChangeSet : aclChangeSets) + { + if (aclChangeSet.getAclCount() > 0) + { + aclChangeSetIds.add(aclChangeSet.getId()); + break; + } + } + if (aclChangeSetIds.size() == 0) + { + // No ACLs; not likely + } + List acls = solrTrackingComponent.getAcls(aclChangeSetIds, null, 1024); + List aclIds = new ArrayList(acls.size()); + JSONObject json = new JSONObject(); + JSONArray aclIdsJSON = new JSONArray(); + for (Acl acl : acls) + { + Long aclId = acl.getId(); + aclIds.add(aclId); + aclIdsJSON.put(aclId); + } + json.put("aclIds", aclIdsJSON); + + // Now get the readers + List aclsReaders = solrTrackingComponent.getAclsReaders(aclIds); + assertEquals("Should have same number of ACLs as supplied", aclIds.size(), aclsReaders.size()); + assertTrue("Must have *some* ACLs here", aclIds.size() > 0); + Map> readersByAclId = new HashMap>(); + for (AclReaders aclReaders : aclsReaders) + { + readersByAclId.put(aclReaders.getAclId(), aclReaders.getReaders()); + } + + // Now query using the webscript + String url = "/api/solr/aclsReaders"; + TestWebScriptServer.PostRequest req = new TestWebScriptServer.PostRequest(url, json.toString(), "application/json"); + Response response = sendRequest(req, Status.STATUS_OK, admin); + if(logger.isDebugEnabled()) + { + logger.debug(response.getContentAsString()); + } + json = new JSONObject(response.getContentAsString()); + JSONArray aclsReadersJSON = json.getJSONArray("aclsReaders"); + // Check + assertEquals("Script and API returned different number of results", readersByAclId.size(), aclsReadersJSON.length()); + + // Iterate of the JSON and ensure that the list of ACL readers is correct + for (int i = 0; i < aclsReadersJSON.length(); i++) + { + // Choose an ACL and check the readers + JSONObject aclReadersJSON = aclsReadersJSON.getJSONObject(i); + Long aclIdJSON = aclReadersJSON.getLong("aclId"); + Set readersCheck = readersByAclId.get(aclIdJSON); + JSONArray readersJSON = aclReadersJSON.getJSONArray("readers"); + assertEquals("Readers list for ACL " + aclIdJSON + " is wrong. ", readersCheck.size(), readersJSON.length()); + for (int j = 0; j < readersJSON.length(); j++) + { + String readerJSON = readersJSON.getString(j); + assertTrue("Found reader not in check set: " + readerJSON, readersCheck.contains(readerJSON)); + } + } } private JSONArray getNodes(GetNodesParameters parameters, int maxResults, int expectedNumNodes) throws Exception @@ -253,7 +337,7 @@ public class SOLRWebScriptTest extends BaseWebScriptTest { logger.debug(response.getContentAsString()); } - //System.out.println("getNodes: " + response.getContentAsString()); + //logger.debug("getNodes: " + response.getContentAsString()); JSONObject jsonResponse = new JSONObject(response.getContentAsString()); jsonResponse.write(new PrintWriter(System.out)); @@ -261,129 +345,13 @@ public class SOLRWebScriptTest extends BaseWebScriptTest //assertEquals("Node count is incorrect", nodes.length(), json.getInt("count")); - System.out.println("Got " + nodes.length() + " nodes in " + (endTime - startTime) + " ms"); + logger.debug("Got " + nodes.length() + " nodes in " + (endTime - startTime) + " ms"); assertEquals("Number of returned node meta data results is incorrect", expectedNumNodes, nodes.length()); return nodes; } - private void buildTransactions1() - { - txnHelper.doInTransaction(new RetryingTransactionCallback() - { - public Void execute() throws Throwable - { - PropertyMap props = new PropertyMap(); - props.put(ContentModel.PROP_NAME, "Container1"); - container1 = nodeService.createNode( - rootNodeRef, - ContentModel.ASSOC_CHILDREN, - ContentModel.ASSOC_CHILDREN, - ContentModel.TYPE_FOLDER, - props).getChildRef(); - - System.out.println("container1 = " + container1); - - FileInfo content1Info = fileFolderService.create(container1, "Content1", ContentModel.TYPE_CONTENT); - content1 = content1Info.getNodeRef(); - - container1NodeID = getNodeID(container1); - content1NodeID = getNodeID(content1); - - if(logger.isDebugEnabled()) - { - logger.debug("content1 = " + content1); - } - - return null; - } - }); - - txnHelper.doInTransaction(new RetryingTransactionCallback() - { - public Void execute() throws Throwable - { - FileInfo content2Info = fileFolderService.create(container1, "Content2", ContentModel.TYPE_CONTENT); - content2 = content2Info.getNodeRef(); - content2NodeID = getNodeID(content2); - - if(logger.isDebugEnabled()) - { - logger.debug("content2 = " + content2); - } - - nodeService.addAspect(content1, ContentModel.ASPECT_TEMPORARY, null); - fileFolderService.delete(content1); - - return null; - } - }); - } - - private void buildTransactions2() - { - txnHelper.doInTransaction(new RetryingTransactionCallback() - { - public Void execute() throws Throwable - { - PropertyMap props = new PropertyMap(); - props.put(ContentModel.PROP_NAME, "Container2"); - container2 = nodeService.createNode( - rootNodeRef, - ContentModel.ASSOC_CHILDREN, - ContentModel.ASSOC_CHILDREN, - ContentModel.TYPE_FOLDER, - props).getChildRef(); - container2NodeID = getNodeID(container2); - if(logger.isDebugEnabled()) - { - logger.debug("container2 = " + container2); - } - - FileInfo content1Info = fileFolderService.create(container2, "Content1", ContentModel.TYPE_CONTENT); - content1 = content1Info.getNodeRef(); - content1NodeID = getNodeID(content1); - - if(logger.isDebugEnabled()) - { - logger.debug("content1 = " + content1); - } - - FileInfo content2Info = fileFolderService.create(container2, "Content2", ContentModel.TYPE_CONTENT); - content2 = content2Info.getNodeRef(); - content2NodeID = getNodeID(content2); - if(logger.isDebugEnabled()) - { - logger.debug("content2 = " + content2); - } - - return null; - } - }); - - txnHelper.doInTransaction(new RetryingTransactionCallback() - { - public Void execute() throws Throwable - { - FileInfo content3Info = fileFolderService.create(container2, "Content3", ContentModel.TYPE_CONTENT); - content3 = content3Info.getNodeRef(); - content3NodeID = getNodeID(content3); - if(logger.isDebugEnabled()) - { - logger.debug("content3 = " + content3); - } - - nodeService.addAspect(content1, ContentModel.ASPECT_TEMPORARY, null); - fileFolderService.delete(content1); - - nodeService.setProperty(content3, ContentModel.PROP_NAME, "Content 3 New Name"); - - return null; - } - }); - } - private List getTransactionIds(JSONArray transactions) throws JSONException { List txnIds = new ArrayList(transactions.length()); @@ -398,18 +366,20 @@ public class SOLRWebScriptTest extends BaseWebScriptTest return txnIds; } - public static String join(Collection s, String delimiter) { + public static String join(Collection s, String delimiter) + { StringBuffer buffer = new StringBuffer(); - Iterator iter = s.iterator(); - while (iter.hasNext()) { + Iterator iter = s.iterator(); + while (iter.hasNext()) + { buffer.append(iter.next()); - if (iter.hasNext()) { + if (iter.hasNext()) + { buffer.append(delimiter); } } return buffer.toString(); } - private void buildTransactions3() { @@ -425,7 +395,6 @@ public class SOLRWebScriptTest extends BaseWebScriptTest ContentModel.ASSOC_CHILDREN, ContentModel.TYPE_FOLDER, props).getChildRef(); - container3NodeID = getNodeID(container3); if(logger.isDebugEnabled()) { logger.debug("container3 = " + container3); @@ -449,79 +418,6 @@ public class SOLRWebScriptTest extends BaseWebScriptTest }); } - private void buildTransactions4() - { - txnHelper.doInTransaction(new RetryingTransactionCallback() - { - public Void execute() throws Throwable - { - PropertyMap props = new PropertyMap(); - props.put(ContentModel.PROP_NAME, "Container4"); - container4 = nodeService.createNode( - rootNodeRef, - ContentModel.ASSOC_CHILDREN, - ContentModel.ASSOC_CHILDREN, - ContentModel.TYPE_FOLDER, - props).getChildRef(); - container4NodeID = getNodeID(container4); - if(logger.isDebugEnabled()) - { - logger.debug("container4 = " + container4); - } - - for(int i = 0; i < 100; i++) - { - FileInfo content1Info = fileFolderService.create(container4, "Content" + i, ContentModel.TYPE_CONTENT); - NodeRef nodeRef = content1Info.getNodeRef(); - contents.add(nodeRef); - nodeIDs.add(getNodeID(nodeRef)); - - if(i % 2 == 1) - { - nodeService.addAspect(nodeRef, ContentModel.ASPECT_TEMPORARY, null); - } - } - - return null; - } - }); - - txnHelper.doInTransaction(new RetryingTransactionCallback() - { - public Void execute() throws Throwable - { - PropertyMap props = new PropertyMap(); - props.put(ContentModel.PROP_NAME, "Container5"); - container5 = nodeService.createNode( - rootNodeRef1, - ContentModel.ASSOC_CHILDREN, - ContentModel.ASSOC_CHILDREN, - ContentModel.TYPE_FOLDER, - props).getChildRef(); - container5NodeID = getNodeID(container5); - if(logger.isDebugEnabled()) - { - logger.debug("container5 = " + container5); - } - - for(int i = 0; i < 100; i++) - { - FileInfo content1Info = fileFolderService.create(container5, "Content" + i, ContentModel.TYPE_CONTENT); - NodeRef nodeRef = content1Info.getNodeRef(); - contents.add(nodeRef); - nodeIDs.add(getNodeID(nodeRef)); - - if(i % 2 == 1) - { - nodeService.addAspect(nodeRef, ContentModel.ASPECT_TEMPORARY, null); - } - } - - return null; - } - }); - } - private NodeRef container6; private void buildTransactions5() @@ -584,7 +480,7 @@ public class SOLRWebScriptTest extends BaseWebScriptTest JSONArray nodes = jsonResponse.getJSONArray("nodes"); - System.out.println("Got metadata for " + nodes.length() + " nodes in " + (endTime - startTime) + " ms"); + logger.debug("Got metadata for " + nodes.length() + " nodes in " + (endTime - startTime) + " ms"); assertEquals("Number of returned nodes is incorrect", numMetaDataNodes, nodes.length()); @@ -605,7 +501,6 @@ public class SOLRWebScriptTest extends BaseWebScriptTest ContentModel.ASSOC_CHILDREN, ContentModel.TYPE_FOLDER, props).getChildRef(); - long container6NodeID = getNodeID(container6); if(logger.isDebugEnabled()) { logger.debug("container6 = " + container6); @@ -628,406 +523,6 @@ public class SOLRWebScriptTest extends BaseWebScriptTest }); } -/* public void testGetTransactions1() throws Exception - { - long fromCommitTime = System.currentTimeMillis(); - - buildTransactions1(); - - String url = "/api/solr/transactions?fromCommitTime=" + fromCommitTime; - TestWebScriptServer.GetRequest req = new TestWebScriptServer.GetRequest(url); - Response response = sendRequest(req, Status.STATUS_OK, admin); - -// assertEquals("Expected application/json content type", "application/json[;charset=UTF-8]", response.getContentType()); - -// System.out.println(response.getContentAsString()); - JSONObject json = new JSONObject(response.getContentAsString()); - - JSONArray transactions = json.getJSONArray("transactions"); - assertEquals("Number of transactions is incorrect", 2, transactions.length()); - - int[] updates = new int[] {1, 1}; - int[] deletes = new int[] {0, 1}; - //StringBuilder txnIds = new StringBuilder(); - int numTxns = transactions.length(); - List transactionIds = getTransactionIds(transactions); - for(int i = 0; i < numTxns; i++) - { - JSONObject txn = transactions.getJSONObject(i); - assertEquals("Number of deletes is incorrect", deletes[i], txn.getLong("deletes")); - assertEquals("Number of updates is incorrect", updates[i], txn.getLong("updates")); - -// txnIds.append(txn.getString("id")); -// if(i < (numTxns - 1)) -// { -// txnIds.append(","); -// } - } - - // get all nodes at once - if(logger.isDebugEnabled()) - { - logger.debug("txnIds = " + transactions.toString()); - } - - GetNodesParameters parameters = new GetNodesParameters(); - parameters.setTransactionIds(transactionIds); - JSONArray nodes = getNodes(parameters, 0, 3); - if(logger.isDebugEnabled()) - { - logger.debug("nodes:"); - logger.debug(nodes.toString(3)); - } - - JSONObject lastNode = nodes.getJSONObject(2); - assertTrue("nodeID is missing", lastNode.has("id")); - Long fromNodeId = lastNode.getLong("id"); - if(logger.isDebugEnabled()) - { - logger.debug("fromNodeId = " + fromNodeId); - } - assertNotNull("Unexpected null fromNodeId", fromNodeId); - - firstNode = nodes.getJSONObject(0); - secondNode = nodes.getJSONObject(1); - //assertEquals("Expected transaction ids to be the same", firstNode.getLong("txnID") == secondNode.getLong("txnID")); - assertEquals("Expected node update", "u", firstNode.getString("status")); - assertEquals("Expected node deleted", "d", secondNode.getString("status")); - assertEquals("Node id is incorrect", container1NodeID, firstNode.getLong("id")); - assertEquals("Node id is incorrect", content1NodeID, secondNode.getLong("id")); - - // get first 2 nodes - parameters = new GetNodesParameters(); - parameters.setTransactionIds(transactionIds); - nodes = getNodes(parameters, 2, 2); - if(logger.isDebugEnabled()) - { - logger.debug("nodes:"); - logger.debug(nodes.toString(3)); - } - - lastNode = nodes.getJSONObject(1); - assertTrue("nodeID is missing", lastNode.has("id")); - fromNodeId = lastNode.getLong("id"); - if(logger.isDebugEnabled()) - { - logger.debug("fromNodeId = " + fromNodeId); - } - assertNotNull("Unexpected null fromNodeId", fromNodeId); - - // get 4 nodes starting with fromNodeId, should return only 2 nodes (including fromNodeId) - parameters = new GetNodesParameters(); - parameters.setTransactionIds(transactionIds); - parameters.setFromNodeId(fromNodeId); - nodes = getNodes(parameters, 4, 2); - if(logger.isDebugEnabled()) - { - logger.debug("nodes:"); - logger.debug(nodes.toString(3)); - } - - firstNode = nodes.getJSONObject(0); - secondNode = nodes.getJSONObject(1); - assertEquals("Expected node deleted", "d", firstNode.getString("status")); - assertEquals("Expected node updated", "u", secondNode.getString("status")); - assertEquals("Node id is incorrect", content1NodeID, firstNode.getLong("id")); - assertEquals("Node id is incorrect", content2NodeID, secondNode.getLong("id")); - - // get 0 (all) nodes starting with fromNodeId, should return 2 nodes - parameters = new GetNodesParameters(); - parameters.setTransactionIds(transactionIds); - parameters.setFromNodeId(fromNodeId); - nodes = getNodes(parameters, 0, 2); - if(logger.isDebugEnabled()) - { - logger.debug("nodes:"); - logger.debug(nodes.toString(3)); - } - - // get 2 nodes ending with toNodeId, should return 2 nodes - long toNodeId = content2NodeID; - parameters = new GetNodesParameters(); - parameters.setTransactionIds(transactionIds); - parameters.setToNodeId(toNodeId); - nodes = getNodes(parameters, 2, 2); - if(logger.isDebugEnabled()) - { - logger.debug("nodes:"); - logger.debug(nodes.toString(3)); - } - - firstNode = nodes.getJSONObject(0); - secondNode = nodes.getJSONObject(1); - assertEquals("Expected node deleted", "u", firstNode.getString("status")); - assertEquals("Node id is incorrect", container1NodeID, firstNode.getLong("id")); - assertEquals("Expected node updated", "d", secondNode.getString("status")); - assertEquals("Node id is incorrect", content1NodeID, secondNode.getLong("id")); - - // get 1 node ending with toNodeId, should return 1 nodes - toNodeId = content2NodeID; - parameters = new GetNodesParameters(); - parameters.setTransactionIds(transactionIds); - parameters.setToNodeId(toNodeId); - nodes = getNodes(parameters, 1, 1); - if(logger.isDebugEnabled()) - { - logger.debug("nodes:"); - logger.debug(nodes.toString(3)); - } - - firstNode = nodes.getJSONObject(0); - assertEquals("Expected node updated", "u", firstNode.getString("status")); - assertEquals("Node id is incorrect", container1NodeID, firstNode.getLong("id")); - - // get 3 nodes ending with toNodeId, should return 3 nodes - toNodeId = content2NodeID; - parameters = new GetNodesParameters(); - parameters.setTransactionIds(transactionIds); - parameters.setToNodeId(toNodeId); - nodes = getNodes(parameters, 3, 3); - if(logger.isDebugEnabled()) - { - logger.debug("nodes:"); - logger.debug(nodes.toString(3)); - } - - firstNode = nodes.getJSONObject(0); - assertEquals("Expected node updated", "u", firstNode.getString("status")); - assertEquals("Node id is incorrect", container1NodeID, firstNode.getLong("id")); - - secondNode = nodes.getJSONObject(1); - assertEquals("Expected node deleted", "d", secondNode.getString("status")); - assertEquals("Node id is incorrect", content1NodeID, secondNode.getLong("id")); - - thirdNode = nodes.getJSONObject(2); - assertEquals("Expected node updated", "u", thirdNode.getString("status")); - assertEquals("Node id is incorrect", content2NodeID, thirdNode.getLong("id")); - } - - public void testGetNodesStoreName() throws Exception - { - long fromCommitTime = System.currentTimeMillis(); - - buildTransactions4(); - - String url = "/api/solr/transactions?fromCommitTime=" + fromCommitTime; - TestWebScriptServer.GetRequest req = new TestWebScriptServer.GetRequest(url); - Response response = sendRequest(req, Status.STATUS_OK, admin); - - if(logger.isDebugEnabled()) - { - logger.debug(response.getContentAsString()); - } - JSONObject json = new JSONObject(response.getContentAsString()); - - JSONArray transactions = json.getJSONArray("transactions"); - assertEquals("Number of transactions is incorrect", 2, transactions.length()); - - // first txn has 2 updates rather than three because content1 is deleted in txn 2 and therefore - // "belongs" to that txn (because txn2 was the last to alter the node) - - List transactionIds = getTransactionIds(transactions); - - // exact store name - GetNodesParameters parameters = new GetNodesParameters(); - parameters.setTransactionIds(transactionIds); - parameters.setStoreProtocol(storeRef.getProtocol()); - parameters.setStoreIdentifier(storeRef.getIdentifier()); - JSONArray nodes = getNodes(parameters, 0, 101); - - nodes = getNodes(parameters, 50, 50); - - // store protocol - parameters = new GetNodesParameters(); - parameters.setTransactionIds(transactionIds); - parameters.setStoreProtocol(storeRef.getProtocol()); - nodes = getNodes(parameters, 0, 202); - - // store identifier - parameters = new GetNodesParameters(); - parameters.setTransactionIds(transactionIds); - parameters.setStoreIdentifier(storeRef.getIdentifier()); - nodes = getNodes(parameters, 0, 101); - } - - public void testGetTransactions2() throws Exception - { - long fromCommitTime = System.currentTimeMillis(); - - buildTransactions2(); - - String url = "/api/solr/transactions?fromCommitTime=" + fromCommitTime; - TestWebScriptServer.GetRequest req = new TestWebScriptServer.GetRequest(url); - Response response = sendRequest(req, Status.STATUS_OK, admin); - - if(logger.isDebugEnabled()) - { - logger.debug("txns ="); - logger.debug(response.getContentAsString()); - } - JSONObject json = new JSONObject(response.getContentAsString()); - - JSONArray transactions = json.getJSONArray("transactions"); - assertEquals("Number of transactions is incorrect", 2, transactions.length()); - - // first txn has 2 updates rather than three because content1 is deleted in txn 2 and therefore - // "belongs" to that txn (because txn2 was the last to alter the node) - int[] updates = new int[] {2, 1}; - int[] deletes = new int[] {0, 1}; - StringBuilder txnIds = new StringBuilder(); - int numTxns = transactions.length(); - for(int i = 0; i < numTxns; i++) - { - JSONObject txn = transactions.getJSONObject(i); - assertEquals("Number of deletes is incorrect", deletes[i], txn.getLong("deletes")); - assertEquals("Number of updates is incorrect", updates[i], txn.getLong("updates")); - - txnIds.append(txn.getString("id")); - if(i < (numTxns - 1)) - { - txnIds.append(","); - } - } - - // get all nodes at once - if(logger.isDebugEnabled()) - { - logger.debug("txnIds = " + txnIds.toString()); - } - - List transactionIds = getTransactionIds(transactions); - - // get all nodes in the txns - GetNodesParameters parameters = new GetNodesParameters(); - parameters.setTransactionIds(transactionIds); - JSONArray nodes = getNodes(parameters, 0, 4); - JSONObject lastNode = nodes.getJSONObject(nodes.length() - 1); - Long fromNodeId = lastNode.getLong("id"); - assertNotNull("Unexpected null fromNodeId", fromNodeId); - - // get first 2 nodes - parameters = new GetNodesParameters(); - parameters.setTransactionIds(transactionIds); - nodes = getNodes(parameters, 2, 2); - if(logger.isDebugEnabled()) - { - logger.debug("nodes:"); - logger.debug(nodes.toString(3)); - } - - firstNode = nodes.getJSONObject(0); - assertTrue("nodeID is missing", firstNode.has("id")); - secondNode = nodes.getJSONObject(1); - assertTrue("nodeID is missing", secondNode.has("id")); - fromNodeId = secondNode.getLong("id"); - if(logger.isDebugEnabled()) - { - logger.debug("fromNodeId = " + fromNodeId); - } - assertNotNull("Unexpected null nodeID", fromNodeId); - - //assertEquals("Expected transaction ids to be the same", firstNode.getLong("txnID"), secondNode.getLong("txnID")); - assertEquals("Expected node update", "u", firstNode.getString("status")); - assertEquals("Expected node delete", "d", secondNode.getString("status")); - assertEquals("Incorrect node id", container2NodeID, firstNode.getLong("id")); - assertEquals("Incorrect node id", content1NodeID, secondNode.getLong("id")); - - // get 10 nodes (including fromNodeId) starting with fromNodeId, should return only 3 nodes - parameters = new GetNodesParameters(); - parameters.setTransactionIds(transactionIds); - parameters.setFromNodeId(fromNodeId); - nodes = getNodes(parameters, 10, 3); - - firstNode = nodes.getJSONObject(0); - assertTrue("nodeID is missing", firstNode.has("id")); - secondNode = nodes.getJSONObject(1); - assertTrue("nodeID is missing", secondNode.has("id")); - thirdNode = nodes.getJSONObject(2); - assertTrue("nodeID is missing", thirdNode.has("id")); - - assertEquals("Expected node delete", "d", firstNode.getString("status")); - assertEquals("Expected node update", "u", secondNode.getString("status")); - assertEquals("Expected node update", "u", thirdNode.getString("status")); - assertEquals("Incorrect node id", content1NodeID, firstNode.getLong("id")); - assertEquals("Incorrect node id", content2NodeID, secondNode.getLong("id")); - assertEquals("Incorrect node id", content3NodeID, thirdNode.getLong("id")); - - // test with from and to node ids - parameters = new GetNodesParameters(); - parameters.setTransactionIds(transactionIds); - parameters.setFromNodeId(container2NodeID); - parameters.setToNodeId(content3NodeID); - nodes = getNodes(parameters, 2, 2); - - firstNode = nodes.getJSONObject(0); - assertTrue("nodeID is missing", firstNode.has("id")); - secondNode = nodes.getJSONObject(1); - assertTrue("nodeID is missing", secondNode.has("id")); - assertEquals("Incorrect node id", container2NodeID, firstNode.getLong("id")); - assertEquals("Incorrect node id", content1NodeID, secondNode.getLong("id")); - - // test right truncation - parameters = new GetNodesParameters(); - parameters.setTransactionIds(transactionIds); - parameters.setToNodeId(content3NodeID); - nodes = getNodes(parameters, 2, 2); - - firstNode = nodes.getJSONObject(0); - assertTrue("nodeID is missing", firstNode.has("id")); - secondNode = nodes.getJSONObject(1); - assertTrue("nodeID is missing", secondNode.has("id")); - assertEquals("Incorrect node id", container2NodeID, firstNode.getLong("id")); - assertEquals("Incorrect node id", content1NodeID, secondNode.getLong("id")); - - // test left truncation, specifying from node only - parameters = new GetNodesParameters(); - parameters.setTransactionIds(transactionIds); - parameters.setFromNodeId(container2NodeID); - nodes = getNodes(parameters, 2, 2); - - firstNode = nodes.getJSONObject(0); - assertTrue("nodeID is missing", firstNode.has("id")); - secondNode = nodes.getJSONObject(1); - assertTrue("nodeID is missing", secondNode.has("id")); - assertEquals("Incorrect node id", container2NodeID, firstNode.getLong("id")); - assertEquals("Incorrect node id", content1NodeID, secondNode.getLong("id")); - } - - public void testGetNodesExcludeAspects() throws Exception - { - long fromCommitTime = System.currentTimeMillis(); - - buildTransactions3(); - - String url = "/api/solr/transactions?fromCommitTime=" + fromCommitTime; - TestWebScriptServer.GetRequest req = new TestWebScriptServer.GetRequest(url); - Response response = sendRequest(req, Status.STATUS_OK, admin); - - if(logger.isDebugEnabled()) - { - logger.debug("txns = "); - logger.debug(response.getContentAsString()); - } - JSONObject json = new JSONObject(response.getContentAsString()); - - JSONArray transactions = json.getJSONArray("transactions"); - assertEquals("Number of transactions is incorrect", 1, transactions.length()); - - // first txn has 2 updates rather than three because content1 is deleted in txn 2 and therefore - // "belongs" to that txn (because txn2 was the last to alter the node) - - List transactionIds = getTransactionIds(transactions); - - Set excludeAspects = new HashSet(1); - excludeAspects.add(ContentModel.ASPECT_TEMPORARY); - - // get all nodes, exclude nodes with temporary aspect - GetNodesParameters parameters = new GetNodesParameters(); - parameters.setTransactionIds(transactionIds); - parameters.setExcludeAspects(excludeAspects); - JSONArray nodes = getNodes(parameters, 0, 51); - }*/ - public void testNodeMetaData() throws Exception { long fromCommitTime = System.currentTimeMillis(); @@ -1064,7 +559,6 @@ public class SOLRWebScriptTest extends BaseWebScriptTest JSONObject properties = node.getJSONObject("properties"); Map propertyMap = getPropertyMap(properties); -// assertEquals("Incorrect number of aspects", 1, aspects.length()); assertTrue("Expected author aspect", containsAspect(aspects, ContentModel.ASPECT_AUTHOR)); assertTrue("Expected author property", containsProperty(propertyMap, ContentModel.PROP_AUTHOR, "steve")); @@ -1104,6 +598,7 @@ public class SOLRWebScriptTest extends BaseWebScriptTest } // make sure caches are warm - time last call + @SuppressWarnings("unused") JSONArray nodesMetaData = getNodesMetaData(nodeIds, 0, 2001); nodesMetaData = getNodesMetaData(nodeIds, 0, 2001); @@ -1176,63 +671,9 @@ public class SOLRWebScriptTest extends BaseWebScriptTest String value = propertyMap.get(propName); return (value == null ? false : value.equals(propValue)); -// boolean success = false; -// for(int i = 0; i < propertiesArray.length(); i++) -// { -// JSONObject prop = propertiesArray.getJSONObject(i); -// prop.keys(); -// String qName = prop.getString("name"); -// String value = prop.getString("value"); -// if(qName.equals(QName.createQName(qName))) -// { -// success |= (propValue == null ? true : value.equals(propValue)); -// } -// if(success) -// { -// break; -// } -// } -// -// return success; } -/* private void buildTransactions3() - { - txnHelper.doInTransaction(new RetryingTransactionCallback() - { - public Void execute() throws Throwable - { - PropertyMap props = new PropertyMap(); - props.put(ContentModel.PROP_NAME, "Container1"); - container3 = nodeService.createNode( - rootNodeRef, - ContentModel.ASSOC_CHILDREN, - ContentModel.ASSOC_CHILDREN, - ContentModel.TYPE_FOLDER, - props).getChildRef(); - - System.out.println("container1 = " + container1); - - FileInfo content1Info = fileFolderService.create(container3, "Content1", ContentModel.TYPE_CONTENT); - content1 = content1Info.getNodeRef(); - - container3NodeID = getNodeID(container3); - content1NodeID = getNodeID(content1); - - ContentWriter writer = contentService.getWriter(content1Info.getNodeRef(), ContentModel.PROP_CONTENT, true); - writer.putContent("test content"); - - if(logger.isDebugEnabled()) - { - logger.debug("content1 = " + content1); - } - - return null; - } - }); - } - - public void testGetContent() throws Exception + public void DISABLED_testGetContent() throws Exception { long nodeId = -1l; String propertyName = ContentModel.PROP_CONTENT.toString(); @@ -1242,14 +683,12 @@ public class SOLRWebScriptTest extends BaseWebScriptTest String url = "/api/solr/content?nodeId=" + nodeId + "&propertyName=" + propertyName; TestWebScriptServer.GetRequest req = new TestWebScriptServer.GetRequest(url); Response response = sendRequest(req, Status.STATUS_OK, admin); - if(logger.isDebugEnabled()) + if (logger.isDebugEnabled()) { logger.debug("content1 = " + response.getContentAsString()); } - assertEquals("Content length is incorrect", "test content".length(), response.getContentLength()); - - }*/ + } private long getNodeID(NodeRef nodeRef) {