From 4feb74244f9c3e1171653444aa21126995a3c53d Mon Sep 17 00:00:00 2001 From: Alan Davis Date: Tue, 6 Sep 2016 14:40:00 +0000 Subject: [PATCH 01/10] Merged 5.2.N (5.2.1) to HEAD (5.2) 129519 msuzuki: Search-95, updating solr features from the latest solr development branch git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@130210 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../java/org/alfresco/solr/adapters/IOpenBitSet.java | 10 +++++----- .../org/alfresco/solr/client/SOLRAPIClientFactory.java | 7 +++++++ 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/search-services/alfresco-solrclient-lib/source/java/org/alfresco/solr/adapters/IOpenBitSet.java b/search-services/alfresco-solrclient-lib/source/java/org/alfresco/solr/adapters/IOpenBitSet.java index 5e4b03ec8..ded45fb78 100644 --- a/search-services/alfresco-solrclient-lib/source/java/org/alfresco/solr/adapters/IOpenBitSet.java +++ b/search-services/alfresco-solrclient-lib/source/java/org/alfresco/solr/adapters/IOpenBitSet.java @@ -34,14 +34,14 @@ package org.alfresco.solr.adapters; public interface IOpenBitSet { - void set(long txid); + public void set(long txid); - void or(IOpenBitSet duplicatedTxInIndex); + public void or(IOpenBitSet duplicatedTxInIndex); - long nextSetBit(long l); + public long nextSetBit(long l); - long cardinality(); + public long cardinality(); - boolean get(long i); + public boolean get(long i); } \ No newline at end of file diff --git a/search-services/alfresco-solrclient-lib/source/java/org/alfresco/solr/client/SOLRAPIClientFactory.java b/search-services/alfresco-solrclient-lib/source/java/org/alfresco/solr/client/SOLRAPIClientFactory.java index 1b39e764f..554089d8b 100644 --- a/search-services/alfresco-solrclient-lib/source/java/org/alfresco/solr/client/SOLRAPIClientFactory.java +++ b/search-services/alfresco-solrclient-lib/source/java/org/alfresco/solr/client/SOLRAPIClientFactory.java @@ -77,6 +77,13 @@ public class SOLRAPIClientFactory private int maxHostConnections = 40; private int socketTimeout = 120000; + + public static void close() { + for(SOLRAPIClient client : clientsPerAlfresco.values()) { + client.close(); + } + } + /** * Gets the client resource from the pool. * From b12d1e0a1f1e630b7ef66f1967b494275f90316e Mon Sep 17 00:00:00 2001 From: Alan Davis Date: Tue, 6 Sep 2016 14:40:21 +0000 Subject: [PATCH 02/10] Merged 5.2.N (5.2.1) to HEAD (5.2) 129538 msuzuki: Search-95, added missing methods that were lost in the merge. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@130212 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../java/org/alfresco/solr/TrackerState.java | 28 +++++++++++++++---- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/search-services/alfresco-solrclient-lib/source/java/org/alfresco/solr/TrackerState.java b/search-services/alfresco-solrclient-lib/source/java/org/alfresco/solr/TrackerState.java index eb6bef102..c10d4f852 100644 --- a/search-services/alfresco-solrclient-lib/source/java/org/alfresco/solr/TrackerState.java +++ b/search-services/alfresco-solrclient-lib/source/java/org/alfresco/solr/TrackerState.java @@ -60,14 +60,15 @@ public class TrackerState private volatile boolean checkedLastTransactionTime = false; private volatile boolean check = false; - + private volatile int trackerCycles; private long timeToStopIndexing; private long lastGoodChangeSetCommitTimeInIndex; private long lastGoodTxCommitTimeInIndex; - private long timeBeforeWhichThereCanBeNoHoles; + private long timeBeforeWhichThereCanBeNoHoles; + private volatile long lastStartTime = 0; public long getLastChangeSetIdOnServer() { @@ -227,8 +228,16 @@ public class TrackerState public void setLastGoodTxCommitTimeInIndex(long lastGoodTxCommitTimeInIndex) { this.lastGoodTxCommitTimeInIndex = lastGoodTxCommitTimeInIndex; - } - + } + + public int getTrackerCycles() { + return this.trackerCycles; + } + + public void incrementTrackerCycles() { + this.trackerCycles++; + } + public long getTimeBeforeWhichThereCanBeNoHoles() { return timeBeforeWhichThereCanBeNoHoles; @@ -296,6 +305,15 @@ public class TrackerState public void setCheckedLastAclTransactionTime(boolean checkedLastAclTransactionTime) { this.checkedLastAclTransactionTime = checkedLastAclTransactionTime; + } + + public long getLastStartTime() + { + return this.lastStartTime; + } + + public void setLastStartTime(long lastStartTime) + { + this.lastStartTime = lastStartTime; } - } From 47ff8bf5074e8071e45be045a606f5ed7cac6fb9 Mon Sep 17 00:00:00 2001 From: Alan Davis Date: Tue, 6 Sep 2016 14:40:30 +0000 Subject: [PATCH 03/10] Merged 5.2.N (5.2.1) to HEAD (5.2) 129612 jbernstein: SEARCH-95: Add the SOLRAPIQueueCLient git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@130213 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../solr/client/SOLRAPIClientFactory.java | 334 +++++++++--------- .../solr/client/SOLRAPIQueueClient.java | 324 +++++++++++++++++ 2 files changed, 494 insertions(+), 164 deletions(-) create mode 100644 search-services/alfresco-solrclient-lib/source/java/org/alfresco/solr/client/SOLRAPIQueueClient.java diff --git a/search-services/alfresco-solrclient-lib/source/java/org/alfresco/solr/client/SOLRAPIClientFactory.java b/search-services/alfresco-solrclient-lib/source/java/org/alfresco/solr/client/SOLRAPIClientFactory.java index 554089d8b..b2a8efac2 100644 --- a/search-services/alfresco-solrclient-lib/source/java/org/alfresco/solr/client/SOLRAPIClientFactory.java +++ b/search-services/alfresco-solrclient-lib/source/java/org/alfresco/solr/client/SOLRAPIClientFactory.java @@ -1,6 +1,6 @@ /* * #%L - * Alfresco Solr Client + * Alfresco Data model classes * %% * Copyright (C) 2005 - 2016 Alfresco Software Limited * %% @@ -23,60 +23,60 @@ * along with Alfresco. If not, see . * #L% */ - -package org.alfresco.solr.client; - -import java.util.HashMap; -import java.util.Map; -import java.util.Properties; - -import org.alfresco.encryption.KeyResourceLoader; -import org.alfresco.encryption.KeyStoreParameters; -import org.alfresco.encryption.ssl.SSLEncryptionParameters; -import org.alfresco.httpclient.AlfrescoHttpClient; -import org.alfresco.httpclient.HttpClientFactory; -import org.alfresco.httpclient.HttpClientFactory.SecureCommsType; -import org.alfresco.repo.dictionary.NamespaceDAO; -import org.alfresco.service.cmr.dictionary.DictionaryService; - -/** - * This factory encapsulates the creation of a SOLRAPIClient and the management of that resource. - * - * @author Ahmed Owian - */ -public class SOLRAPIClientFactory -{ - /* - * Pool of cached client resources keyed on alfresco instances - */ - private static Map clientsPerAlfresco = new HashMap<>(); - - // encryption related parameters - private String secureCommsType; // "none", "https" - private String keyStoreType; - private String keyStoreProvider; - private String passwordFileLocation; - private String keyStoreLocation; - - // ssl - private String sslKeyStoreType; - private String sslKeyStoreProvider; - private String sslKeyStoreLocation; - private String sslKeyStorePasswordFileLocation; - private String sslTrustStoreType; - private String sslTrustStoreProvider; - private String sslTrustStoreLocation; - private String sslTrustStorePasswordFileLocation; - private String alfrescoHost; - private int alfrescoPort; - private int alfrescoPortSSL; - private String baseUrl; - - // http client - private int maxTotalConnections = 40; - private int maxHostConnections = 40; - private int socketTimeout = 120000; - + +package org.alfresco.solr.client; + +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +import org.alfresco.encryption.KeyResourceLoader; +import org.alfresco.encryption.KeyStoreParameters; +import org.alfresco.encryption.ssl.SSLEncryptionParameters; +import org.alfresco.httpclient.AlfrescoHttpClient; +import org.alfresco.httpclient.HttpClientFactory; +import org.alfresco.httpclient.HttpClientFactory.SecureCommsType; +import org.alfresco.repo.dictionary.NamespaceDAO; +import org.alfresco.service.cmr.dictionary.DictionaryService; + +/** + * This factory encapsulates the creation of a SOLRAPIClient and the management of that resource. + * + * @author Ahmed Owian + */ +public class SOLRAPIClientFactory +{ + /* + * Pool of cached client resources keyed on alfresco instances + */ + private static Map clientsPerAlfresco = new HashMap<>(); + + // encryption related parameters + private String secureCommsType; // "none", "https" + private String keyStoreType; + private String keyStoreProvider; + private String passwordFileLocation; + private String keyStoreLocation; + + // ssl + private String sslKeyStoreType; + private String sslKeyStoreProvider; + private String sslKeyStoreLocation; + private String sslKeyStorePasswordFileLocation; + private String sslTrustStoreType; + private String sslTrustStoreProvider; + private String sslTrustStoreLocation; + private String sslTrustStorePasswordFileLocation; + private String alfrescoHost; + private int alfrescoPort; + private int alfrescoPortSSL; + private String baseUrl; + + // http client + private int maxTotalConnections = 40; + private int maxHostConnections = 40; + private int socketTimeout = 120000; + public static void close() { for(SOLRAPIClient client : clientsPerAlfresco.values()) { @@ -84,112 +84,118 @@ public class SOLRAPIClientFactory } } - /** - * Gets the client resource from the pool. - * - * @param alfrescoHost String - * @param alfrescoPort int - * @param alfrescoPortSSL int - * @return SOLRAPIClient - */ - private SOLRAPIClient getCachedClient(String alfrescoHost, int alfrescoPort, int alfrescoPortSSL) - { - String key = constructKey(alfrescoHost, alfrescoPort, alfrescoPortSSL); - return clientsPerAlfresco.get(key); - } - - /** - * Constructs a key to identify a unique alfresco instance to which the client will connect. - * - * @param alfrescoHost String - * @param alfrescoPort int - * @param alfrescoPortSSL int - * @return the key to get a client - */ - private String constructKey(String alfrescoHost, int alfrescoPort, int alfrescoPortSSL) - { - return alfrescoHost + alfrescoPort + alfrescoPortSSL; - } - - /** - * Sets the client in the resource pool. - * - * @param alfrescoHost String - * @param alfrescoPort int - * @param alfrescoPortSSL int - * @param client SOLRAPIClient - */ - private void setCachedClient(String alfrescoHost, int alfrescoPort, int alfrescoPortSSL, SOLRAPIClient client) - { - String key = constructKey(alfrescoHost, alfrescoPort, alfrescoPortSSL); - clientsPerAlfresco.put(key, client); - } - - /** - * Creates the SOLRAPIClient or gets it from a pool - * - * @param props solrcore.properties in the /conf directory - * @param keyResourceLoader reads encryption key resources - * @param dictionaryService represents the Repository Data Dictionary - * @param namespaceDAO allows retrieving and creating Namespace definitions - * @return an instance of SOLRAPIClient - */ - public SOLRAPIClient getSOLRAPIClient(Properties props, KeyResourceLoader keyResourceLoader, - DictionaryService dictionaryService, NamespaceDAO namespaceDAO) - { - alfrescoHost = props.getProperty("alfresco.host", "localhost"); - alfrescoPort = Integer.parseInt(props.getProperty("alfresco.port", "8080")); - alfrescoPortSSL = Integer.parseInt(props.getProperty("alfresco.port.ssl", "8443")); - - SOLRAPIClient client = getCachedClient(alfrescoHost, alfrescoPort, alfrescoPortSSL); - if (client == null) - { - baseUrl = props.getProperty("alfresco.baseUrl", "/alfresco"); - keyStoreType = props.getProperty("alfresco.encryption.keystore.type", "JCEKS"); - keyStoreProvider = props.getProperty("alfresco.encryption.keystore.provider"); - passwordFileLocation = props.getProperty("alfresco.encryption.keystore.passwordFileLocation"); - keyStoreLocation = props.getProperty("alfresco.encryption.keystore.location"); - sslKeyStoreType = props.getProperty("alfresco.encryption.ssl.keystore.type", "JCEKS"); - sslKeyStoreProvider = props.getProperty("alfresco.encryption.ssl.keystore.provider", ""); - sslKeyStoreLocation = props.getProperty("alfresco.encryption.ssl.keystore.location", - "ssl.repo.client.keystore"); - sslKeyStorePasswordFileLocation = props.getProperty( - "alfresco.encryption.ssl.keystore.passwordFileLocation", "ssl-keystore-passwords.properties"); - sslTrustStoreType = props.getProperty("alfresco.encryption.ssl.truststore.type", "JCEKS"); - sslTrustStoreProvider = props.getProperty("alfresco.encryption.ssl.truststore.provider", ""); - sslTrustStoreLocation = props.getProperty("alfresco.encryption.ssl.truststore.location", - "ssl.repo.client.truststore"); - sslTrustStorePasswordFileLocation = props.getProperty( - "alfresco.encryption.ssl.truststore.passwordFileLocation", - "ssl-truststore-passwords.properties"); - secureCommsType = props.getProperty("alfresco.secureComms", "none"); - maxTotalConnections = Integer.parseInt(props.getProperty("alfresco.maxTotalConnections", "40")); - maxHostConnections = Integer.parseInt(props.getProperty("alfresco.maxHostConnections", "40")); - socketTimeout = Integer.parseInt(props.getProperty("alfresco.socketTimeout", "60000")); - - client = new SOLRAPIClient(getRepoClient(keyResourceLoader), dictionaryService, namespaceDAO); - setCachedClient(alfrescoHost, alfrescoPort, alfrescoPortSSL, client); - } - - return client; - } - - protected AlfrescoHttpClient getRepoClient(KeyResourceLoader keyResourceLoader) - { - // TODO i18n - KeyStoreParameters keyStoreParameters = new KeyStoreParameters("SSL Key Store", sslKeyStoreType, - sslKeyStoreProvider, sslKeyStorePasswordFileLocation, sslKeyStoreLocation); - KeyStoreParameters trustStoreParameters = new KeyStoreParameters("SSL Trust Store", sslTrustStoreType, - sslTrustStoreProvider, sslTrustStorePasswordFileLocation, sslTrustStoreLocation); - SSLEncryptionParameters sslEncryptionParameters = new SSLEncryptionParameters(keyStoreParameters, - trustStoreParameters); - - HttpClientFactory httpClientFactory = new HttpClientFactory(SecureCommsType.getType(secureCommsType), - sslEncryptionParameters, keyResourceLoader, null, null, alfrescoHost, alfrescoPort, - alfrescoPortSSL, maxTotalConnections, maxHostConnections, socketTimeout); - // TODO need to make port configurable depending on secure comms, or just make redirects work - AlfrescoHttpClient repoClient = httpClientFactory.getRepoClient(alfrescoHost, alfrescoPortSSL); - repoClient.setBaseUrl(baseUrl); - return repoClient; - } -} + /** + * Gets the client resource from the pool. + * + * @param alfrescoHost String + * @param alfrescoPort int + * @param alfrescoPortSSL int + * @return SOLRAPIClient + */ + private SOLRAPIClient getCachedClient(String alfrescoHost, int alfrescoPort, int alfrescoPortSSL) + { + String key = constructKey(alfrescoHost, alfrescoPort, alfrescoPortSSL); + return clientsPerAlfresco.get(key); + } + + /** + * Constructs a key to identify a unique alfresco instance to which the client will connect. + * + * @param alfrescoHost String + * @param alfrescoPort int + * @param alfrescoPortSSL int + * @return the key to get a client + */ + private String constructKey(String alfrescoHost, int alfrescoPort, int alfrescoPortSSL) + { + return alfrescoHost + alfrescoPort + alfrescoPortSSL; + } + + /** + * Sets the client in the resource pool. + * + * @param alfrescoHost String + * @param alfrescoPort int + * @param alfrescoPortSSL int + * @param client SOLRAPIClient + */ + private void setCachedClient(String alfrescoHost, int alfrescoPort, int alfrescoPortSSL, SOLRAPIClient client) + { + String key = constructKey(alfrescoHost, alfrescoPort, alfrescoPortSSL); + clientsPerAlfresco.put(key, client); + } + + /** + * Creates the SOLRAPIClient or gets it from a pool + * + * @param props solrcore.properties in the /conf directory + * @param keyResourceLoader reads encryption key resources + * @param dictionaryService represents the Repository Data Dictionary + * @param namespaceDAO allows retrieving and creating Namespace definitions + * @return an instance of SOLRAPIClient + */ + public SOLRAPIClient getSOLRAPIClient(Properties props, KeyResourceLoader keyResourceLoader, + DictionaryService dictionaryService, NamespaceDAO namespaceDAO) + { + + if(Boolean.parseBoolean(System.getProperty("alfresco.test", "false"))) + { + return new SOLRAPIQueueClient(namespaceDAO); + } + + alfrescoHost = props.getProperty("alfresco.host", "localhost"); + alfrescoPort = Integer.parseInt(props.getProperty("alfresco.port", "8080")); + alfrescoPortSSL = Integer.parseInt(props.getProperty("alfresco.port.ssl", "8443")); + + SOLRAPIClient client = getCachedClient(alfrescoHost, alfrescoPort, alfrescoPortSSL); + if (client == null) + { + baseUrl = props.getProperty("alfresco.baseUrl", "/alfresco"); + keyStoreType = props.getProperty("alfresco.encryption.keystore.type", "JCEKS"); + keyStoreProvider = props.getProperty("alfresco.encryption.keystore.provider"); + passwordFileLocation = props.getProperty("alfresco.encryption.keystore.passwordFileLocation"); + keyStoreLocation = props.getProperty("alfresco.encryption.keystore.location"); + sslKeyStoreType = props.getProperty("alfresco.encryption.ssl.keystore.type", "JCEKS"); + sslKeyStoreProvider = props.getProperty("alfresco.encryption.ssl.keystore.provider", ""); + sslKeyStoreLocation = props.getProperty("alfresco.encryption.ssl.keystore.location", + "ssl.repo.client.keystore"); + sslKeyStorePasswordFileLocation = props.getProperty( + "alfresco.encryption.ssl.keystore.passwordFileLocation", "ssl-keystore-passwords.properties"); + sslTrustStoreType = props.getProperty("alfresco.encryption.ssl.truststore.type", "JCEKS"); + sslTrustStoreProvider = props.getProperty("alfresco.encryption.ssl.truststore.provider", ""); + sslTrustStoreLocation = props.getProperty("alfresco.encryption.ssl.truststore.location", + "ssl.repo.client.truststore"); + sslTrustStorePasswordFileLocation = props.getProperty( + "alfresco.encryption.ssl.truststore.passwordFileLocation", + "ssl-truststore-passwords.properties"); + secureCommsType = props.getProperty("alfresco.secureComms", "none"); + maxTotalConnections = Integer.parseInt(props.getProperty("alfresco.maxTotalConnections", "40")); + maxHostConnections = Integer.parseInt(props.getProperty("alfresco.maxHostConnections", "40")); + socketTimeout = Integer.parseInt(props.getProperty("alfresco.socketTimeout", "60000")); + + client = new SOLRAPIClient(getRepoClient(keyResourceLoader), dictionaryService, namespaceDAO); + setCachedClient(alfrescoHost, alfrescoPort, alfrescoPortSSL, client); + } + + return client; + } + + protected AlfrescoHttpClient getRepoClient(KeyResourceLoader keyResourceLoader) + { + // TODO i18n + KeyStoreParameters keyStoreParameters = new KeyStoreParameters("SSL Key Store", sslKeyStoreType, + sslKeyStoreProvider, sslKeyStorePasswordFileLocation, sslKeyStoreLocation); + KeyStoreParameters trustStoreParameters = new KeyStoreParameters("SSL Trust Store", sslTrustStoreType, + sslTrustStoreProvider, sslTrustStorePasswordFileLocation, sslTrustStoreLocation); + SSLEncryptionParameters sslEncryptionParameters = new SSLEncryptionParameters(keyStoreParameters, + trustStoreParameters); + + HttpClientFactory httpClientFactory = new HttpClientFactory(SecureCommsType.getType(secureCommsType), + sslEncryptionParameters, keyResourceLoader, null, null, alfrescoHost, alfrescoPort, + alfrescoPortSSL, maxTotalConnections, maxHostConnections, socketTimeout); + // TODO need to make port configurable depending on secure comms, or just make redirects work + AlfrescoHttpClient repoClient = httpClientFactory.getRepoClient(alfrescoHost, alfrescoPortSSL); + repoClient.setBaseUrl(baseUrl); + return repoClient; + } +} diff --git a/search-services/alfresco-solrclient-lib/source/java/org/alfresco/solr/client/SOLRAPIQueueClient.java b/search-services/alfresco-solrclient-lib/source/java/org/alfresco/solr/client/SOLRAPIQueueClient.java new file mode 100644 index 000000000..01a8d4020 --- /dev/null +++ b/search-services/alfresco-solrclient-lib/source/java/org/alfresco/solr/client/SOLRAPIQueueClient.java @@ -0,0 +1,324 @@ +/* + * #%L + * Alfresco Data model classes + * %% + * Copyright (C) 2005 - 2016 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * 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 . + * #L% + */ + +package org.alfresco.solr.client; + +import java.io.*; +import java.util.*; + +import org.alfresco.httpclient.AuthenticationException; +import org.alfresco.httpclient.Response; +import org.alfresco.repo.dictionary.NamespaceDAO; +import org.alfresco.repo.index.shard.ShardState; +import org.alfresco.service.namespace.QName; +import org.apache.commons.codec.EncoderException; +import org.apache.commons.httpclient.HttpStatus; +import org.json.JSONException; + +// TODO error handling, including dealing with a repository that is not responsive (ConnectException in sendRemoteRequest) +// TODO get text content transform status handling +/** + * A client that reads from an internal queue. This is used for test cases. + */ + +public class SOLRAPIQueueClient extends SOLRAPIClient +{ + public static List aclChangeSetQueue = Collections.synchronizedList(new ArrayList()); + public static Map> aclMap = Collections.synchronizedMap(new HashMap()); + public static Map aclReadersMap = Collections.synchronizedMap(new HashMap()); + + public static List transactionQueue = Collections.synchronizedList(new ArrayList()); + public static Map> nodeMap = Collections.synchronizedMap(new HashMap()); + public static Map nodeMetaDataMap = Collections.synchronizedMap(new HashMap()); + + public SOLRAPIQueueClient(NamespaceDAO namespaceDAO) + { + super(null,null,namespaceDAO); + } + + /** + * Get the ACL ChangeSets + * + * @param fromCommitTime the lowest commit time (optional) + * @param minAclChangeSetId the lowest ChangeSet ID (optional) + * @param maxResults the maximum number of results (a reasonable value only) + * @return the ACL ChangeSets in order of commit time and ID + */ + + + public AclChangeSets getAclChangeSets(Long fromCommitTime, Long minAclChangeSetId, Long toCommitTime, Long maxAclChangeSetId, int maxResults) + throws AuthenticationException, IOException, JSONException + { + int size = aclChangeSetQueue.size(); + long maxTime = 0L; + long maxId = 0L; + + if(fromCommitTime == null && toCommitTime == null) + { + List aclChangeSetList = new ArrayList(); + for(int i=0; i= minAclChangeSetId && aclChangeSet.getId() < maxAclChangeSetId) + { + aclChangeSetList.add(aclChangeSet); + maxTime = Math.max(aclChangeSet.getCommitTimeMs(), maxTime); + maxId = Math.max(aclChangeSet.getId(), maxId); + } + + if(aclChangeSetList.size() == maxResults) { + break; + } + } + + return new AclChangeSets(aclChangeSetList, maxTime, maxId); + } + + List aclChangeSetList = new ArrayList(); + + for(int i=0; i toCommitTime) + { + //We have not yet reached this alcChangeSet so break out of the loop + break; + } + else + { + aclChangeSetList.add(aclChangeSet); + maxTime = aclChangeSet.getCommitTimeMs(); + maxId = aclChangeSet.getId(); + + if(aclChangeSetList.size() == maxResults) + { + break; + } + } + } + + return new AclChangeSets(aclChangeSetList, maxTime, maxId); + } + + /** + * Get the ACLs associated with a given list of ACL ChangeSets. The ACLs may be truncated for + * the last ACL ChangeSet in the return values - the ACL count from the + * {@link #getAclChangeSets(Long, Long, Long, Long, int) ACL ChangeSets}. + * + * @param aclChangeSets the ACL ChangeSets to include + * @param minAclId the lowest ACL ID (may be null) + * @param maxResults the maximum number of results to retrieve + * @return the ACLs (includes ChangeSet ID) + */ + public List getAcls(List aclChangeSets, Long minAclId, int maxResults) throws AuthenticationException, IOException, JSONException + { + List allAcls = new ArrayList(); + for(AclChangeSet aclChangeSet : aclChangeSets) + { + List aclList = aclMap.get(aclChangeSet.getId()); + allAcls.addAll(aclList); + } + return allAcls; + } + + /** + * Get the ACL readers for a given list of ACLs + * + * @param acls the ACLs + * @return the readers for the ACLs + */ + public List getAclReaders(List acls) throws AuthenticationException, IOException, JSONException + { + List allAclReaders = new ArrayList(); + for(Acl acl : acls) + { + AclReaders aclReaders = aclReadersMap.get(acl.getId()); + allAclReaders.add(aclReaders); + } + return allAclReaders; + } + + + public List getModelsDiff(List currentModels) throws AuthenticationException, IOException, JSONException + { + return new ArrayList(); + } + + + public Transactions getTransactions(Long fromCommitTime, Long minTxnId, Long toCommitTime, Long maxTxnId, int maxResults) throws AuthenticationException, IOException, JSONException + { + try + { + return getTransactions(fromCommitTime, minTxnId, toCommitTime, maxTxnId, maxResults, null); + } + catch(EncoderException e) + { + throw new IOException(e); + } + } + + + + + public Transactions getTransactions(Long fromCommitTime, Long minTxnId, Long toCommitTime, Long maxTxnId, int maxResults, ShardState shardState) throws AuthenticationException, IOException, JSONException, EncoderException + { + int size = transactionQueue.size(); + + long maxTime = 0L; + long maxId = 0L; + + if(fromCommitTime == null && toCommitTime == null) + { + List transactionList = new ArrayList(); + + for(int i=0; i= minTxnId && txn.getId() < maxTxnId) + { + transactionList.add(txn); + maxTime = Math.max(txn.getCommitTimeMs(), maxTime); + maxId = Math.max(txn.getId(), maxId); + } + + if(transactionList.size() == maxResults) { + break; + } + } + + return new Transactions(transactionList, maxTime, maxId); + } + + List transactionList = new ArrayList(); + + for(int i=0; i toCommitTime) + { + //We have not yet reached this transaction so break out of the loop + break; + } + else + { + //We have a transaction to work with + transactionList.add(txn); + maxTime = txn.getCommitTimeMs(); + maxId = txn.getId(); + + if(transactionList.size() == maxResults) + { + break; + } + } + } + + return new Transactions(transactionList, maxTime, maxId); + } + + public List getNodes(GetNodesParameters parameters, int maxResults) throws AuthenticationException, IOException, JSONException + { + List txnIds = parameters.getTransactionIds(); + List allNodes = new ArrayList(); + for(long txnId : txnIds) + { + List nodes = nodeMap.get(txnId); + allNodes.addAll(nodes); + } + + return allNodes; + } + + public List getNodesMetaData(NodeMetaDataParameters params, int maxResults) throws AuthenticationException, IOException, JSONException + { + List nodeMetaDatas = new ArrayList(); + List nodeIds = params.getNodeIds(); + if(nodeIds != null) { + for (long nodeId : nodeIds) { + NodeMetaData nodeMetaData = nodeMetaDataMap.get(nodeId); + nodeMetaDatas.add(nodeMetaData); + } + } else { + Long fromId = params.getFromNodeId(); + NodeMetaData nodeMetaData = nodeMetaDataMap.get(fromId); + nodeMetaDatas.add(nodeMetaData); + } + + return nodeMetaDatas; + } + + public GetTextContentResponse getTextContent(Long nodeId, QName propertyQName, Long modifiedSince) throws AuthenticationException, IOException + { + //Just put the nodeId innto the content so we query for this in tests. + return new GetTextContentResponse(new DummyResponse("Hello world "+nodeId)); + } + + private class DummyResponse implements Response + { + private String text; + + public DummyResponse(String text) + { + this.text = text; + } + + public InputStream getContentAsStream() + { + return new ByteArrayInputStream(text.getBytes()); + } + + public int getStatus() { + return HttpStatus.SC_OK; + } + + public void release() + { + + } + + public String getHeader(String key) { + return null; + } + + public String getContentType() { + return "text/html"; + } + } + + public void close() + { + + } +} From b8d3593cb57216bb5111ffff6ec834a670fd7de8 Mon Sep 17 00:00:00 2001 From: Alan Davis Date: Tue, 6 Sep 2016 22:08:29 +0000 Subject: [PATCH 04/10] Merged 5.2.N (5.2.1) to HEAD (5.2) 130284 gjames: Merged searchapi (5.2.1) to 5.2.N (5.2.1) 130021 gjames: Merged 5.2.N-AHIND (5.2.1) to searchapi (5.2.1) 129885 ahind: SEARCH-31 SOLR 6 - Shard based on date - SOLR implementation - SOLRAPIClient changes to support requesting a property value to use for sharding git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@130356 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../solr/client/GetNodesParameters.java | 18 ++++++++- .../java/org/alfresco/solr/client/Node.java | 37 ++++++++++++++----- .../alfresco/solr/client/SOLRAPIClient.java | 12 +++++- 3 files changed, 55 insertions(+), 12 deletions(-) diff --git a/search-services/alfresco-solrclient-lib/source/java/org/alfresco/solr/client/GetNodesParameters.java b/search-services/alfresco-solrclient-lib/source/java/org/alfresco/solr/client/GetNodesParameters.java index bfb797571..6eb6b3fbf 100644 --- a/search-services/alfresco-solrclient-lib/source/java/org/alfresco/solr/client/GetNodesParameters.java +++ b/search-services/alfresco-solrclient-lib/source/java/org/alfresco/solr/client/GetNodesParameters.java @@ -48,7 +48,9 @@ public class GetNodesParameters private Set excludeNodeTypes; private Set includeAspects; - private Set excludeAspects; + private Set excludeAspects; + + private QName shardProperty; public boolean getStoreFilter() { @@ -143,5 +145,17 @@ public class GetNodesParameters public void setExcludeAspects(Set excludeAspects) { this.excludeAspects = excludeAspects; - } + } + + public QName getShardProperty() + { + return this.shardProperty; + } + + public void setShardProperty(QName shardProperty) + { + this.shardProperty = shardProperty; + } + + } diff --git a/search-services/alfresco-solrclient-lib/source/java/org/alfresco/solr/client/Node.java b/search-services/alfresco-solrclient-lib/source/java/org/alfresco/solr/client/Node.java index b846c9fe2..6f199fe7f 100644 --- a/search-services/alfresco-solrclient-lib/source/java/org/alfresco/solr/client/Node.java +++ b/search-services/alfresco-solrclient-lib/source/java/org/alfresco/solr/client/Node.java @@ -37,7 +37,8 @@ public class Node private long txnId; private SolrApiNodeStatus status; private String tenant; - private long aclId; + private long aclId; + private String shardPropertyValue; public long getId() { @@ -98,14 +99,32 @@ public class Node public void setAclId(long aclId) { this.aclId = aclId; - } - /* (non-Javadoc) - * @see java.lang.Object#toString() + } + + + /** + * The property value to use for sharding - as requested + * + * @return null - if the node does not have the property, the standard "String" value of the property if it is present on the node. + * For dates and datetime properties this will be the ISO formatted datetime. */ - @Override - public String toString() - { - return "Node [id=" + id + ", nodeRef=" + nodeRef + ", txnId=" + txnId + ", status=" + status + ", tenant=" + tenant + ", aclId=" + aclId + "]"; - } + public String getShardPropertyValue() + { + return this.shardPropertyValue; + } + + public void setShardPropertyValue(String shardPropertyValue) + { + this.shardPropertyValue = shardPropertyValue; + } + @Override + public String toString() + { + return "Node [id=" + this.id + ", nodeRef=" + this.nodeRef + ", txnId=" + this.txnId + + ", status=" + this.status + ", tenant=" + this.tenant + ", aclId=" + + this.aclId + ", shardPropertyValue=" + this.shardPropertyValue + "]"; + } + + } diff --git a/search-services/alfresco-solrclient-lib/source/java/org/alfresco/solr/client/SOLRAPIClient.java b/search-services/alfresco-solrclient-lib/source/java/org/alfresco/solr/client/SOLRAPIClient.java index fed813ebc..e5a0e00bd 100644 --- a/search-services/alfresco-solrclient-lib/source/java/org/alfresco/solr/client/SOLRAPIClient.java +++ b/search-services/alfresco-solrclient-lib/source/java/org/alfresco/solr/client/SOLRAPIClient.java @@ -602,7 +602,12 @@ public class SOLRAPIClient } body.put("maxResults", maxResults); - + + if(parameters.getShardProperty() != null) + { + body.put("shardProperty", parameters.getShardProperty().toString()); + } + PostRequest req = new PostRequest(url.toString(), body.toString(), "application/json"); Response response = null; @@ -655,6 +660,11 @@ public class SOLRAPIClient if(jsonNodeInfo.has("aclId")) { nodeInfo.setAclId(jsonNodeInfo.getLong("aclId")); + } + + if(jsonNodeInfo.has("shardPropertyValue")) + { + nodeInfo.setShardPropertyValue(jsonNodeInfo.getString("shardPropertyValue")); } if(jsonNodeInfo.has("tenant")) From d509d5bc5a7f73ffb1614508adfbbe2426bd76bb Mon Sep 17 00:00:00 2001 From: Alan Davis Date: Tue, 6 Sep 2016 22:08:39 +0000 Subject: [PATCH 05/10] Merged 5.2.N (5.2.1) to HEAD (5.2) 130285 gjames: Merged searchapi (5.2.1) to 5.2.N (5.2.1) 130022 gjames: Merged 5.2.N-AHIND (5.2.1) to searchapi (5.2.1) 129926 ahind: SEARCH-31 SOLR 6 - Shard based on date - SOLR implementation - Support returning a date, datetime or string property to use for sharding git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@130357 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../org/alfresco/solr/client/SOLRAPIClient.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/search-services/alfresco-solrclient-lib/source/java/org/alfresco/solr/client/SOLRAPIClient.java b/search-services/alfresco-solrclient-lib/source/java/org/alfresco/solr/client/SOLRAPIClient.java index e5a0e00bd..957c38c7b 100644 --- a/search-services/alfresco-solrclient-lib/source/java/org/alfresco/solr/client/SOLRAPIClient.java +++ b/search-services/alfresco-solrclient-lib/source/java/org/alfresco/solr/client/SOLRAPIClient.java @@ -715,7 +715,7 @@ public class SOLRAPIClient { JSONObject pair = a.getJSONObject(k); Locale locale = deserializer.deserializeValue(Locale.class, pair.getString("locale")); - String mlValue = pair.has("value") ? pair.getString("value") : null; + String mlValue = pair.has("value") && !pair.isNull("value") ? pair.getString("value") : null; mlValues.put(locale, mlValue); } @@ -725,15 +725,15 @@ public class SOLRAPIClient { JSONObject o = (JSONObject)value; - String localeStr = o.has("locale") ? o.getString("locale") : null; - Locale locale = (o.has("locale") ? deserializer.deserializeValue(Locale.class, localeStr) : null); + String localeStr = o.has("locale") && !o.isNull("locale") ? o.getString("locale") : null; + Locale locale = (o.has("locale") && !o.isNull("locale") ? deserializer.deserializeValue(Locale.class, localeStr) : null); - Long size = o.has("size") ? o.getLong("size") : null; + Long size = o.has("size") && !o.isNull("size") ? o.getLong("size") : null; - String encoding = o.has("encoding") ? o.getString("encoding") : null; - String mimetype = o.has("mimetype") ? o.getString("mimetype") : null; + String encoding = o.has("encoding") && !o.isNull("encoding") ? o.getString("encoding") : null; + String mimetype = o.has("mimetype") && !o.isNull("mimetype") ? o.getString("mimetype") : null; - Long id = o.has("contentId") ? o.getLong("contentId") : null; + Long id = o.has("contentId") && !o.isNull("contentId") ? o.getLong("contentId") : null; ret = new ContentPropertyValue(locale, size, encoding, mimetype, id); } @@ -942,7 +942,7 @@ public class SOLRAPIClient List> paths = new ArrayList>(jsonPaths.length()); for(int j = 0; j < jsonPaths.length(); j++) { - JSONObject path = new JSONObject(jsonPaths.getString(j)); + JSONObject path = jsonPaths.getJSONObject(j); String pathValue = path.getString("path"); QName qname = path.has("qname") ? deserializer.deserializeValue(QName.class, path.getString("qname")) : null; paths.add(new Pair(pathValue, qname)); From 8a34293e848e2b01f83d1c0a77811ac798b4cb23 Mon Sep 17 00:00:00 2001 From: Alan Davis Date: Thu, 3 Nov 2016 13:15:53 +0000 Subject: [PATCH 06/10] Merged 5.2.N (5.2.1) to HEAD (5.2) 130755 jbernstein: SEARCH-165: Simulate down repo in test cases git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@132175 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../solr/client/SOLRAPIQueueClient.java | 47 +++++++++++++++---- 1 file changed, 38 insertions(+), 9 deletions(-) diff --git a/search-services/alfresco-solrclient-lib/source/java/org/alfresco/solr/client/SOLRAPIQueueClient.java b/search-services/alfresco-solrclient-lib/source/java/org/alfresco/solr/client/SOLRAPIQueueClient.java index 01a8d4020..d4395d5f2 100644 --- a/search-services/alfresco-solrclient-lib/source/java/org/alfresco/solr/client/SOLRAPIQueueClient.java +++ b/search-services/alfresco-solrclient-lib/source/java/org/alfresco/solr/client/SOLRAPIQueueClient.java @@ -27,6 +27,7 @@ package org.alfresco.solr.client; import java.io.*; +import java.net.ConnectException; import java.util.*; import org.alfresco.httpclient.AuthenticationException; @@ -53,25 +54,24 @@ public class SOLRAPIQueueClient extends SOLRAPIClient public static List transactionQueue = Collections.synchronizedList(new ArrayList()); public static Map> nodeMap = Collections.synchronizedMap(new HashMap()); public static Map nodeMetaDataMap = Collections.synchronizedMap(new HashMap()); + private static boolean throwException; public SOLRAPIQueueClient(NamespaceDAO namespaceDAO) { super(null,null,namespaceDAO); } - /** - * Get the ACL ChangeSets - * - * @param fromCommitTime the lowest commit time (optional) - * @param minAclChangeSetId the lowest ChangeSet ID (optional) - * @param maxResults the maximum number of results (a reasonable value only) - * @return the ACL ChangeSets in order of commit time and ID - */ - + public static void setThrowException(boolean _throwException) { + throwException = _throwException; + } public AclChangeSets getAclChangeSets(Long fromCommitTime, Long minAclChangeSetId, Long toCommitTime, Long maxAclChangeSetId, int maxResults) throws AuthenticationException, IOException, JSONException { + if(throwException) { + throw new ConnectException("THROWING EXCEPTION, better be ready!"); + } + int size = aclChangeSetQueue.size(); long maxTime = 0L; long maxId = 0L; @@ -140,6 +140,10 @@ public class SOLRAPIQueueClient extends SOLRAPIClient */ public List getAcls(List aclChangeSets, Long minAclId, int maxResults) throws AuthenticationException, IOException, JSONException { + if(throwException) { + throw new ConnectException("THROWING EXCEPTION, better be ready!"); + } + List allAcls = new ArrayList(); for(AclChangeSet aclChangeSet : aclChangeSets) { @@ -157,6 +161,10 @@ public class SOLRAPIQueueClient extends SOLRAPIClient */ public List getAclReaders(List acls) throws AuthenticationException, IOException, JSONException { + if(throwException) { + throw new ConnectException("THROWING EXCEPTION, better be ready!"); + } + List allAclReaders = new ArrayList(); for(Acl acl : acls) { @@ -169,12 +177,18 @@ public class SOLRAPIQueueClient extends SOLRAPIClient public List getModelsDiff(List currentModels) throws AuthenticationException, IOException, JSONException { + if(throwException) { + throw new ConnectException("THROWING EXCEPTION, better be ready!"); + } return new ArrayList(); } public Transactions getTransactions(Long fromCommitTime, Long minTxnId, Long toCommitTime, Long maxTxnId, int maxResults) throws AuthenticationException, IOException, JSONException { + if(throwException) { + throw new ConnectException("THROWING EXCEPTION, better be ready!"); + } try { return getTransactions(fromCommitTime, minTxnId, toCommitTime, maxTxnId, maxResults, null); @@ -190,6 +204,10 @@ public class SOLRAPIQueueClient extends SOLRAPIClient public Transactions getTransactions(Long fromCommitTime, Long minTxnId, Long toCommitTime, Long maxTxnId, int maxResults, ShardState shardState) throws AuthenticationException, IOException, JSONException, EncoderException { + if(throwException) { + throw new ConnectException("THROWING EXCEPTION, better be ready!"); + } + int size = transactionQueue.size(); long maxTime = 0L; @@ -250,6 +268,10 @@ public class SOLRAPIQueueClient extends SOLRAPIClient public List getNodes(GetNodesParameters parameters, int maxResults) throws AuthenticationException, IOException, JSONException { + if(throwException) { + throw new ConnectException("THROWING EXCEPTION, better be ready!"); + } + List txnIds = parameters.getTransactionIds(); List allNodes = new ArrayList(); for(long txnId : txnIds) @@ -263,6 +285,10 @@ public class SOLRAPIQueueClient extends SOLRAPIClient public List getNodesMetaData(NodeMetaDataParameters params, int maxResults) throws AuthenticationException, IOException, JSONException { + if(throwException) { + throw new ConnectException("THROWING EXCEPTION, better be ready!"); + } + List nodeMetaDatas = new ArrayList(); List nodeIds = params.getNodeIds(); if(nodeIds != null) { @@ -281,6 +307,9 @@ public class SOLRAPIQueueClient extends SOLRAPIClient public GetTextContentResponse getTextContent(Long nodeId, QName propertyQName, Long modifiedSince) throws AuthenticationException, IOException { + if(throwException) { + throw new ConnectException("THROWING EXCEPTION, better be ready!"); + } //Just put the nodeId innto the content so we query for this in tests. return new GetTextContentResponse(new DummyResponse("Hello world "+nodeId)); } From d59dc30b655ec5ac0a53a51be325cb750b835f1e Mon Sep 17 00:00:00 2001 From: Alan Davis Date: Thu, 3 Nov 2016 13:26:09 +0000 Subject: [PATCH 07/10] Merged 5.2.N (5.2.1) to HEAD (5.2) 130784 amukha: REPO-1006: Move Alfresco 'data-model' to Git - removed project files - changed the dependencies git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@132180 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- search-services/alfresco-solrclient-lib/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/search-services/alfresco-solrclient-lib/pom.xml b/search-services/alfresco-solrclient-lib/pom.xml index 7938b54ab..7937d8a9a 100644 --- a/search-services/alfresco-solrclient-lib/pom.xml +++ b/search-services/alfresco-solrclient-lib/pom.xml @@ -15,7 +15,7 @@ org.alfresco alfresco-data-model - ${project.version} + ${dependency.alfresco-data-model.version} From c73f6cc7f1e0db5847894c3851ca11be7afaf121 Mon Sep 17 00:00:00 2001 From: Alan Davis Date: Thu, 3 Nov 2016 13:29:58 +0000 Subject: [PATCH 08/10] Merged 5.2.N (5.2.1) to HEAD (5.2) 130920 jbernstein: SEARCH-2: Update SolrAPIQueueClient to support fingerprint tests git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@132208 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../java/org/alfresco/solr/client/SOLRAPIQueueClient.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/search-services/alfresco-solrclient-lib/source/java/org/alfresco/solr/client/SOLRAPIQueueClient.java b/search-services/alfresco-solrclient-lib/source/java/org/alfresco/solr/client/SOLRAPIQueueClient.java index d4395d5f2..2e5385b51 100644 --- a/search-services/alfresco-solrclient-lib/source/java/org/alfresco/solr/client/SOLRAPIQueueClient.java +++ b/search-services/alfresco-solrclient-lib/source/java/org/alfresco/solr/client/SOLRAPIQueueClient.java @@ -54,6 +54,8 @@ public class SOLRAPIQueueClient extends SOLRAPIClient public static List transactionQueue = Collections.synchronizedList(new ArrayList()); public static Map> nodeMap = Collections.synchronizedMap(new HashMap()); public static Map nodeMetaDataMap = Collections.synchronizedMap(new HashMap()); + public static Map nodeContentMap = Collections.synchronizedMap(new HashMap()); + private static boolean throwException; public SOLRAPIQueueClient(NamespaceDAO namespaceDAO) @@ -310,7 +312,13 @@ public class SOLRAPIQueueClient extends SOLRAPIClient if(throwException) { throw new ConnectException("THROWING EXCEPTION, better be ready!"); } + //Just put the nodeId innto the content so we query for this in tests. + + if(nodeContentMap.containsKey(nodeId)) { + return new GetTextContentResponse(new DummyResponse(nodeContentMap.get(nodeId))); + } + return new GetTextContentResponse(new DummyResponse("Hello world "+nodeId)); } From 39763c0e525bb4da2473cb62beabcd09d06e636f Mon Sep 17 00:00:00 2001 From: Alan Davis Date: Thu, 3 Nov 2016 13:50:08 +0000 Subject: [PATCH 09/10] Merged 5.2.N (5.2.1) to HEAD (5.2) 131370 adavis: Merged 5.2.N-SERVLET-3.0 (5.2.1) to 5.2.N (5.2.1) 130708: REPO-843 / REPO-1246: Upgrade to Servlet 3.0 (part I), 130714: REPO-843 / REPO-1246: Upgrade to Servlet 3.0 (part 1b) - fix web.xml (web-app), 130727: REPO-843 / REPO-1246: Upgrade to Servlet 3.0 (part 1b) - update other web.xml's (other than web-client project), 130844: REPO-843 / REPO-1251: Upgrade to Servlet API 3.0.x (part 2) - update to Spring WebScripts 6.9 (ACE-5584) - update to servlet-api 3.0.1, 130847: REPO-843 / REPO-1251: Upgrade to Servlet API 3.0.x (part 2) - update to Spring WebScripts 6.9 (ACE-5584) - follow-on to commit the correct pom.xml (ie. parent rather than overlay), 130852: REPO-843 / REPO-1251: Upgrade to Servlet API 3.0.x (part 2) - update to Spring WebScripts 6.9 (ACE-5584) - follow-on git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@132252 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- search-services/alfresco-solrclient-lib/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/search-services/alfresco-solrclient-lib/pom.xml b/search-services/alfresco-solrclient-lib/pom.xml index 7937d8a9a..4eb2f1b96 100644 --- a/search-services/alfresco-solrclient-lib/pom.xml +++ b/search-services/alfresco-solrclient-lib/pom.xml @@ -26,7 +26,7 @@ javax.servlet - servlet-api + javax.servlet-api provided From ce00e498a6368325b82249393b98683c5597afa3 Mon Sep 17 00:00:00 2001 From: Alan Davis Date: Thu, 3 Nov 2016 13:57:49 +0000 Subject: [PATCH 10/10] Merged 5.2.N (5.2.1) to HEAD (5.2) 131769 ahind: Fix for SEARCH-222 SOLR 6 - Improved indexing for categories - return ancestor based path for better support to internationalise categories etc (by UUID matching the public AIP) git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@132297 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../java/org/alfresco/solr/client/NodeMetaData.java | 13 ++++++++++++- .../org/alfresco/solr/client/SOLRAPIClient.java | 13 ++++++++++--- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/search-services/alfresco-solrclient-lib/source/java/org/alfresco/solr/client/NodeMetaData.java b/search-services/alfresco-solrclient-lib/source/java/org/alfresco/solr/client/NodeMetaData.java index a747176eb..6fb038834 100644 --- a/search-services/alfresco-solrclient-lib/source/java/org/alfresco/solr/client/NodeMetaData.java +++ b/search-services/alfresco-solrclient-lib/source/java/org/alfresco/solr/client/NodeMetaData.java @@ -56,7 +56,8 @@ public class NodeMetaData private String owner; private long txnId; private Set ancestors; - private String tenantDomain; + private String tenantDomain; + private List ancestorPaths; public long getId() { @@ -117,6 +118,16 @@ public class NodeMetaData public void setPaths(List> paths) { this.paths = paths; + } + + public List getAncestorPaths() + { + return ancestorPaths; + } + + public void setAncestorPaths(List ancestorPaths) + { + this.ancestorPaths = ancestorPaths; } public List> getNamePaths() diff --git a/search-services/alfresco-solrclient-lib/source/java/org/alfresco/solr/client/SOLRAPIClient.java b/search-services/alfresco-solrclient-lib/source/java/org/alfresco/solr/client/SOLRAPIClient.java index 957c38c7b..d40590165 100644 --- a/search-services/alfresco-solrclient-lib/source/java/org/alfresco/solr/client/SOLRAPIClient.java +++ b/search-services/alfresco-solrclient-lib/source/java/org/alfresco/solr/client/SOLRAPIClient.java @@ -939,15 +939,22 @@ public class SOLRAPIClient if(jsonNodeInfo.has("paths")) { JSONArray jsonPaths = jsonNodeInfo.getJSONArray("paths"); - List> paths = new ArrayList>(jsonPaths.length()); + List> paths = new ArrayList>(jsonPaths.length()); + List ancestorPaths = new ArrayList(); for(int j = 0; j < jsonPaths.length(); j++) { JSONObject path = jsonPaths.getJSONObject(j); String pathValue = path.getString("path"); QName qname = path.has("qname") ? deserializer.deserializeValue(QName.class, path.getString("qname")) : null; - paths.add(new Pair(pathValue, qname)); + paths.add(new Pair(pathValue, qname)); + if(path.has("apath")) + { + String ancestorPath = path.getString("apath"); + ancestorPaths.add(ancestorPath); + } } - metaData.setPaths(paths); + metaData.setPaths(paths); + metaData.setAncestorPaths(ancestorPaths); } if(jsonNodeInfo.has("namePaths"))