From cb40a133a75840fc4c01d7500d542fe9b3abb2aa Mon Sep 17 00:00:00 2001 From: agazzarini Date: Tue, 15 Oct 2019 10:59:44 +0200 Subject: [PATCH 01/42] [ SEARCH-1606 ] Formal code refactoring (formatting) --- .../solr/tracker/AbstractTracker.java | 6 +++-- .../alfresco/solr/tracker/ModelTracker.java | 22 +++++++------------ 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/AbstractTracker.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/AbstractTracker.java index 7915ea9b3..ae944dd4b 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/AbstractTracker.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/AbstractTracker.java @@ -327,15 +327,17 @@ public abstract class AbstractTracker implements Tracker throw new IndexTrackingShutdownException(); } } - + + @Override public void setShutdown(boolean shutdown) { this.shutdown = shutdown; } + @Override public void shutdown() { - log.warn("Core "+ coreName+" shutdown called on tracker. " + getClass().getSimpleName() + " " + hashCode()); + log.warn("Core " + coreName + " shutdown called on tracker. " + getClass().getSimpleName() + " " + hashCode()); setShutdown(true); if(this.threadHandler != null) { diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/ModelTracker.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/ModelTracker.java index ba4e00fa9..c19c31eaa 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/ModelTracker.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/ModelTracker.java @@ -115,12 +115,16 @@ public class ModelTracker extends AbstractTracker implements Tracker loadPersistedModels(); } - public boolean hasMaintenance() { + @Override + public boolean hasMaintenance() + { return false; } - public void maintenance() { - + @Override + public void maintenance() + { + // Nothing to be done here } /** @@ -203,7 +207,7 @@ public class ModelTracker extends AbstractTracker implements Tracker public void trackModels(boolean onlyFirstTime) throws AuthenticationException, IOException, JSONException { - boolean requiresWriteLock = false; + boolean requiresWriteLock; modelLock.readLock().lock(); try { @@ -271,10 +275,6 @@ public class ModelTracker extends AbstractTracker implements Tracker /** * Tracks models. Reflects changes and updates on disk copy - * - * @throws AuthenticationException - * @throws IOException - * @throws JSONException */ private void trackModelsImpl() throws AuthenticationException, IOException, JSONException { @@ -480,16 +480,10 @@ public class ModelTracker extends AbstractTracker implements Tracker } return expandedQName; - } - /** - * @param alfrescoModelDir - * @param modelName - */ private void removeMatchingModels(File alfrescoModelDir, QName modelName) { - final String prefix = modelName.toPrefixString(this.infoSrv.getNamespaceDAO()).replace(":", ".") + "."; final String postFix = ".xml"; From 2e7e565bf58a97031465e9acbcfef88d0650d7fd Mon Sep 17 00:00:00 2001 From: Meenal Bhave Date: Tue, 15 Oct 2019 16:37:42 +0100 Subject: [PATCH 02/42] Feature/search 1835 gs compatibility: Fix inconsistent Tests --- .../functional/AbstractE2EFunctionalTest.java | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/e2e-test/src/test/java/org/alfresco/test/search/functional/AbstractE2EFunctionalTest.java b/e2e-test/src/test/java/org/alfresco/test/search/functional/AbstractE2EFunctionalTest.java index dedd48b10..daded7776 100644 --- a/e2e-test/src/test/java/org/alfresco/test/search/functional/AbstractE2EFunctionalTest.java +++ b/e2e-test/src/test/java/org/alfresco/test/search/functional/AbstractE2EFunctionalTest.java @@ -28,6 +28,7 @@ import org.alfresco.utility.model.UserModel; import org.alfresco.utility.network.ServerHealth; import org.apache.chemistry.opencmis.client.api.CmisObject; import org.apache.chemistry.opencmis.client.api.Session; +import org.hamcrest.Matchers; import org.slf4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; @@ -38,6 +39,7 @@ import org.testng.annotations.BeforeSuite; import lombok.Getter; +import static java.util.Optional.ofNullable; import static lombok.AccessLevel.PROTECTED; /** @@ -84,6 +86,14 @@ public abstract class AbstractE2EFunctionalTest extends AbstractTestNGSpringCont protected SiteModel testSite; protected static String unique_searchString; + + protected static final String SEARCH_LANGUAGE_CMIS = "cmis"; + + protected enum SearchLanguage { + CMIS, + AFTS + } + @BeforeSuite(alwaysRun = true) public void beforeSuite() throws Exception @@ -386,4 +396,33 @@ public abstract class AbstractE2EFunctionalTest extends AbstractTestNGSpringCont query.setQuery(queryReq); return query; } + + /** + * Helper method to test if the search query works and count matches where provided + * @param query: AFTS or cmis query string + * @param expectedCount: Only successful response is checked, when expectedCount is null (can not be exactly specified), + * @param setCmis: Query language is set to cmis when setCmis is true, AFTS when false + * @return SearchResponse + */ + protected SearchResponse testSearchQuery(String query, Integer expectedCount, SearchLanguage queryLanguage) + { + RestRequestQueryModel queryModel = new RestRequestQueryModel(); + queryModel.setQuery(query); + + if (ofNullable(queryLanguage).isPresent()) + { + queryModel.setLanguage(queryLanguage.toString()); + } + + SearchResponse response = queryAsUser(testUser, queryModel); + + restClient.assertStatusCodeIs(HttpStatus.OK); + + if (ofNullable(expectedCount).isPresent()) + { + restClient.onResponse().assertThat().body("list.pagination.count", Matchers.equalTo(expectedCount)); + } + + return response; + } } From 6d41769950bd400ae0c81707e6b6bd14ed8cec6f Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 16 Oct 2019 06:26:59 +0000 Subject: [PATCH 03/42] Bump alfresco-data-model from 8.52 to 8.53 in /search-services Bumps [alfresco-data-model](https://github.com/Alfresco/alfresco-data-model) from 8.52 to 8.53. - [Release notes](https://github.com/Alfresco/alfresco-data-model/releases) - [Commits](https://github.com/Alfresco/alfresco-data-model/compare/8.52...8.53) Signed-off-by: dependabot-preview[bot] --- 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 729d1bb30..ef23d4dc4 100644 --- a/search-services/alfresco-solrclient-lib/pom.xml +++ b/search-services/alfresco-solrclient-lib/pom.xml @@ -22,7 +22,7 @@ - 8.52 + 8.53 2.10.0 From a51984f57b11f352052b73a03a04d7d51d462a87 Mon Sep 17 00:00:00 2001 From: agazzarini Date: Wed, 16 Oct 2019 14:25:17 +0200 Subject: [PATCH 04/42] [ SEARCH-1606 ] First chunk of unit tests --- .../solr/lifecycle/SolrCoreLoadListener.java | 277 +++++++++++++++++- .../lifecycle/SolrCoreLoadRegistration.java | 258 ---------------- .../lifecycle/SolrCoreLoadListenerTest.java | 118 ++++++++ 3 files changed, 387 insertions(+), 266 deletions(-) delete mode 100644 search-services/alfresco-search/src/main/java/org/alfresco/solr/lifecycle/SolrCoreLoadRegistration.java create mode 100644 search-services/alfresco-search/src/test/java/org/alfresco/solr/lifecycle/SolrCoreLoadListenerTest.java diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/lifecycle/SolrCoreLoadListener.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/lifecycle/SolrCoreLoadListener.java index 5f4e6db5f..7f6c44490 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/lifecycle/SolrCoreLoadListener.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/lifecycle/SolrCoreLoadListener.java @@ -16,31 +16,292 @@ * You should have received a copy of the GNU Lesser General Public License * along with Alfresco. If not, see . */ - package org.alfresco.solr.lifecycle; +import static java.util.Optional.ofNullable; + +import org.alfresco.opencmis.dictionary.CMISStrictDictionaryService; import org.alfresco.solr.AlfrescoCoreAdminHandler; +import org.alfresco.solr.AlfrescoSolrDataModel; +import org.alfresco.solr.SolrInformationServer; +import org.alfresco.solr.SolrKeyResourceLoader; +import org.alfresco.solr.client.SOLRAPIClient; +import org.alfresco.solr.client.SOLRAPIClientFactory; +import org.alfresco.solr.content.SolrContentStore; +import org.alfresco.solr.tracker.AclTracker; +import org.alfresco.solr.tracker.CascadeTracker; +import org.alfresco.solr.tracker.CommitTracker; +import org.alfresco.solr.tracker.ContentTracker; +import org.alfresco.solr.tracker.MetadataTracker; +import org.alfresco.solr.tracker.ModelTracker; +import org.alfresco.solr.tracker.SolrTrackerScheduler; +import org.alfresco.solr.tracker.Tracker; +import org.alfresco.solr.tracker.TrackerRegistry; +import org.apache.solr.common.util.NamedList; +import org.apache.solr.common.util.StrUtils; import org.apache.solr.core.AbstractSolrEventListener; +import org.apache.solr.core.CloseHook; import org.apache.solr.core.CoreContainer; +import org.apache.solr.core.CoreDescriptorDecorator; +import org.apache.solr.core.PluginInfo; import org.apache.solr.core.SolrCore; +import org.apache.solr.core.SolrResourceLoader; +import org.apache.solr.handler.ReplicationHandler; +import org.apache.solr.request.SolrRequestHandler; import org.apache.solr.search.SolrIndexSearcher; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.lang.invoke.MethodHandles; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Properties; +import java.util.function.Function; +import java.util.function.Predicate; /** - * Listens for the first searcher to be created for a core and registers the trackers + * Listeners for *FIRST SEARCHER* events in order to prepare and register the SolrContentStore and the Tracking Subsystem. * * @author Gethin James + * @author Andrea Gazzarini */ -public class SolrCoreLoadListener extends AbstractSolrEventListener { +public class SolrCoreLoadListener extends AbstractSolrEventListener +{ + private static final Logger LOGGER = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); - public SolrCoreLoadListener(SolrCore core) { + /** + * Builds a new listener instance with the given {@link SolrCore} (event source). + * + * @param core the {@link SolrCore} instance representing the event source of this listener. + */ + public SolrCoreLoadListener(SolrCore core) + { super(core); } @Override - public void newSearcher(SolrIndexSearcher newSearcher, SolrIndexSearcher currentSearcher) { + public void newSearcher(SolrIndexSearcher newSearcher, SolrIndexSearcher currentSearcher) + { CoreContainer coreContainer = getCore().getCoreContainer(); - AlfrescoCoreAdminHandler coreAdminHandler = (AlfrescoCoreAdminHandler) coreContainer.getMultiCoreHandler(); + AlfrescoCoreAdminHandler admin = (AlfrescoCoreAdminHandler) coreContainer.getMultiCoreHandler(); + SolrCore core = getCore(); + + TrackerRegistry trackerRegistry = admin.getTrackerRegistry(); + Properties coreProperties = new CoreDescriptorDecorator(core.getCoreDescriptor()).getProperties(); + + SolrResourceLoader loader = core.getLatestSchema().getResourceLoader(); + SolrKeyResourceLoader keyResourceLoader = new SolrKeyResourceLoader(loader); + SOLRAPIClientFactory clientFactory = new SOLRAPIClientFactory(); + SOLRAPIClient repositoryClient = + clientFactory.getSOLRAPIClient(coreProperties, keyResourceLoader, + AlfrescoSolrDataModel.getInstance().getDictionaryService(CMISStrictDictionaryService.DEFAULT), + AlfrescoSolrDataModel.getInstance().getNamespaceDAO()); + + SolrContentStore contentStore = new SolrContentStore(coreContainer.getSolrHome()); + SolrInformationServer informationServer = new SolrInformationServer(admin, core, repositoryClient, contentStore); + coreProperties.putAll(informationServer.getProps()); + admin.getInformationServers().put(core.getName(), informationServer); + + final SolrTrackerScheduler scheduler = admin.getScheduler(); + + // Prevents other threads from registering the ModelTracker at the same time + // Create model tracker and load all the persisted models + synchronized(SolrCoreLoadListener.class) + { + createModelTracker(core.getName(), + trackerRegistry, + coreProperties, + coreContainer.getSolrHome(), + repositoryClient, + informationServer, + scheduler); + } + + boolean trackersHaveBeenExplicitlyDisabled = Boolean.parseBoolean(coreProperties.getProperty("enable.alfresco.tracking", "false")); + boolean owningCoreIsSlave = isSlaveModeEnabledFor(core); + + // Guard conditions: if trackers must be disabled then immediately return, we've done here. + // Case #1: trackers have been explicitly disabled. + if (trackersHaveBeenExplicitlyDisabled) + { + LOGGER.info("SearchServices Core Trackers have been explicitly disabled on core \"{}\" through \"enable.alfresco.tracking\" configuration property.", core.getName()); + return; + } + + // Case #2: we are on a slave node. + if (owningCoreIsSlave) + { + LOGGER.info("SearchServices Core Trackers have been disabled on core \"{}\" because it is a slave core.", core.getName()); + return; + } + + LOGGER.info("SearchServices Core Tracking Subsystem starts on core {}", core.getName()); + if (trackerRegistry.hasTrackersForCore(core.getName())) + { + LOGGER.info("Trackers for " + core.getName()+ " is already registered, shutting them down."); + shutdownTrackers(core.getName(), trackerRegistry.getTrackersForCore(core.getName()), scheduler); + trackerRegistry.removeTrackersForCore(core.getName()); + admin.getInformationServers().remove(core.getName()); + } + + final List trackers = createCoreTrackers(core.getName(), trackerRegistry, coreProperties, scheduler, repositoryClient, informationServer); + + CommitTracker commitTracker = new CommitTracker(coreProperties, repositoryClient, core.getName(), informationServer, trackers); + trackerRegistry.register(core.getName(), commitTracker); + scheduler.schedule(commitTracker, core.getName(), coreProperties); + + LOGGER.info("SearchServices Core Trackers have been correctly registered and scheduled."); + + //Add the commitTracker to the list of scheduled trackers that can be shutdown + trackers.add(commitTracker); + + core.addCloseHook(new CloseHook() + { + @Override + public void preClose(SolrCore core) + { + LOGGER.info("Tracking Subsystem shutdown procedure for core {} has been started.", core.getName()); + shutdownTrackers(core.getName(), trackers, scheduler); + } + + @Override + public void postClose(SolrCore core) + { + LOGGER.info("Shutdown procedure for core {} has been completed.", core.getName()); + } + }); - SolrCoreLoadRegistration.registerForCore(coreAdminHandler, coreContainer, getCore(), getCore().getName()); } -} + + List createCoreTrackers(String coreName, + TrackerRegistry trackerRegistry, + Properties props, + SolrTrackerScheduler scheduler, + SOLRAPIClient repositoryClient, + SolrInformationServer srv) + { + List trackers = new ArrayList<>(); + + AclTracker aclTracker = new AclTracker(props, repositoryClient, coreName, srv); + trackerRegistry.register(coreName, aclTracker); + scheduler.schedule(aclTracker, coreName, props); + + ContentTracker contentTrkr = new ContentTracker(props, repositoryClient, coreName, srv); + trackerRegistry.register(coreName, contentTrkr); + scheduler.schedule(contentTrkr, coreName, props); + + MetadataTracker metaTrkr = new MetadataTracker(props, repositoryClient, coreName, srv); + trackerRegistry.register(coreName, metaTrkr); + scheduler.schedule(metaTrkr, coreName, props); + + CascadeTracker cascadeTrkr = new CascadeTracker(props, repositoryClient, coreName, srv); + trackerRegistry.register(coreName, cascadeTrkr); + scheduler.schedule(cascadeTrkr, coreName, props); + + //The CommitTracker will acquire these locks in order + //The ContentTracker will likely have the longest runs so put it first to ensure the MetadataTracker is not paused while + //waiting for the ContentTracker to release it's lock. + //The aclTracker will likely have the shortest runs so put it last. + trackers.add(cascadeTrkr); + trackers.add(contentTrkr); + trackers.add(metaTrkr); + trackers.add(aclTracker); + return trackers; + } + + private void createModelTracker(String coreName, + TrackerRegistry trackerRegistry, + Properties props, + String solrHome, + SOLRAPIClient repositoryClient, + SolrInformationServer srv, + SolrTrackerScheduler scheduler) + { + ModelTracker mTracker = trackerRegistry.getModelTracker(); + if (mTracker == null) + { + LOGGER.debug("Creating a new Model Tracker instance."); + mTracker = new ModelTracker(solrHome, props, repositoryClient, coreName, srv); + trackerRegistry.setModelTracker(mTracker); + + LOGGER.info("Model Tracker: ensuring first model sync."); + mTracker.ensureFirstModelSync(); + + scheduler.schedule(mTracker, coreName, props); + + LOGGER.info("Model Tracker has been correctly initialised, registered and scheduled."); + } + } + + /** + * Shuts down the trackers for a core. + * + * The trackers are only deleted from the scheduler if they are the exact same instance of the Tracker class + * passed into this method. + * For example, you could have 2 cores of the same name and have the trackers registered with the scheduler BUT + * the scheduler only keys by core name. The Collections passed into this method are only removed + * from the scheduler if the instances are == (equal). See scheduler.deleteJobForTrackerInstance() + * + * Trackers are not removed from the registry because the registry only keys by core name; its possible to + * have multiple cores of the same name running. Left over trackers in the registry are cleaned up by the CoreContainer + * shutdown, that happens in the the AlfrescoCoreAdminHandler.shutdown(). + * + * @param coreName The name of the core + * @param coreTrackers A collection of trackers + * @param scheduler The scheduler + */ + void shutdownTrackers(String coreName, Collection coreTrackers, SolrTrackerScheduler scheduler) + { + try + { + LOGGER.info("Shutting down Trackers Subsystem for core \"{}\" which contains {} core trackers.", coreName, coreTrackers.size()); + + // Sets the shutdown flag on the trackers to stop them from doing any more work + coreTrackers.forEach(tracker -> tracker.setShutdown(true)); + + if (!scheduler.isShutdown()) + { + coreTrackers.forEach(tracker -> scheduler.deleteJobForTrackerInstance(coreName, tracker) ); + } + + coreTrackers.forEach(Tracker::shutdown); + } + catch (Exception e) + { + LOGGER.error("Tracking Subsystem shutdown procedure failed to shutdown trackers for core {}. See the stacktrace below for further details.", coreName, e); + } + } + + /** + * Checks if the content store belonging to the hosting Solr node must be set in read only mode. + * + * @param core the hosting {@link SolrCore} instance. + * @return true if the content store must be set in read only mode, false otherwise. + */ + private boolean isSlaveModeEnabledFor(SolrCore core) + { + Predicate onlyReplicationHandler = + plugin -> "/replication".equals(plugin.name) + || plugin.className.endsWith(ReplicationHandler.class.getSimpleName()); + + Function isSlaveModeEnabled = + params -> ofNullable(params) + .map(configuration -> { + Object enable = configuration.get("enable"); + return enable == null || + (enable instanceof String ? StrUtils.parseBool((String)enable) : Boolean.TRUE.equals(enable));}) + .orElse(false); + + return core.getSolrConfig().getPluginInfos(SolrRequestHandler.class.getName()) + .stream() + .filter(PluginInfo::isEnabled) + .filter(onlyReplicationHandler) + .findFirst() + .map(plugin -> plugin.initArgs) + .map(params -> params.get("slave")) + .map(NamedList.class::cast) + .map(isSlaveModeEnabled) + .orElse(false); + } +} \ No newline at end of file diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/lifecycle/SolrCoreLoadRegistration.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/lifecycle/SolrCoreLoadRegistration.java deleted file mode 100644 index c7f46f770..000000000 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/lifecycle/SolrCoreLoadRegistration.java +++ /dev/null @@ -1,258 +0,0 @@ -/* - * Copyright (C) 2005-2016 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.solr.lifecycle; - -import java.lang.invoke.MethodHandles; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Properties; - -import org.alfresco.opencmis.dictionary.CMISStrictDictionaryService; -import org.alfresco.solr.AlfrescoCoreAdminHandler; -import org.alfresco.solr.AlfrescoSolrDataModel; -import org.alfresco.solr.SolrInformationServer; -import org.alfresco.solr.SolrKeyResourceLoader; -import org.alfresco.solr.client.SOLRAPIClient; -import org.alfresco.solr.client.SOLRAPIClientFactory; -import org.alfresco.solr.content.SolrContentStore; -import org.alfresco.solr.tracker.AclTracker; -import org.alfresco.solr.tracker.CascadeTracker; -import org.alfresco.solr.tracker.CommitTracker; -import org.alfresco.solr.tracker.ContentTracker; -import org.alfresco.solr.tracker.MetadataTracker; -import org.alfresco.solr.tracker.ModelTracker; -import org.alfresco.solr.tracker.SolrTrackerScheduler; -import org.alfresco.solr.tracker.Tracker; -import org.alfresco.solr.tracker.TrackerRegistry; -import org.apache.solr.core.CloseHook; -import org.apache.solr.core.CoreContainer; -import org.apache.solr.core.CoreDescriptorDecorator; -import org.apache.solr.core.SolrCore; -import org.apache.solr.core.SolrResourceLoader; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Deals with core registration when the core is loaded. - * - * @author Gethin James - */ -public class SolrCoreLoadRegistration { - - private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); - - /** - * Registers with the admin handler the information server and the trackers. - */ - public static void registerForCore(AlfrescoCoreAdminHandler adminHandler, CoreContainer coreContainer, SolrCore core, - String coreName) - { - - - TrackerRegistry trackerRegistry = adminHandler.getTrackerRegistry(); - Properties props = new CoreDescriptorDecorator(core.getCoreDescriptor()).getProperties(); - //Prepare cores - SolrResourceLoader loader = core.getLatestSchema().getResourceLoader(); - SolrKeyResourceLoader keyResourceLoader = new SolrKeyResourceLoader(loader); - SOLRAPIClientFactory clientFactory = new SOLRAPIClientFactory(); - SOLRAPIClient repositoryClient = clientFactory.getSOLRAPIClient(props, keyResourceLoader, - AlfrescoSolrDataModel.getInstance().getDictionaryService(CMISStrictDictionaryService.DEFAULT), - AlfrescoSolrDataModel.getInstance().getNamespaceDAO()); - //Start content store - SolrContentStore contentStore = new SolrContentStore(coreContainer.getSolrHome()); - SolrInformationServer srv = new SolrInformationServer(adminHandler, core, repositoryClient, contentStore); - props.putAll(srv.getProps()); - adminHandler.getInformationServers().put(coreName, srv); - - SolrTrackerScheduler scheduler = adminHandler.getScheduler(); - - // Prevents other threads from registering the ModelTracker at the same time - // Create model tracker and load all the persisted models - createModelTracker(coreName, - trackerRegistry, - props, - coreContainer.getSolrHome(), - repositoryClient, - srv, - scheduler); - - - log.info("Starting to track " + coreName); - if (Boolean.parseBoolean(props.getProperty("enable.alfresco.tracking", "false"))) - { - - if (trackerRegistry.hasTrackersForCore(coreName)) - { - log.info("Trackers for " + coreName+ " is already registered, shutting them down."); - shutdownTrackers(coreName, trackerRegistry.getTrackersForCore(coreName),scheduler); - trackerRegistry.removeTrackersForCore(coreName); - adminHandler.getInformationServers().remove(coreName); - } - - List trackers = createCoreTrackers(coreName, trackerRegistry, props, scheduler, repositoryClient, srv); - - CommitTracker commitTracker = new CommitTracker(props, repositoryClient, coreName, srv, trackers); - trackerRegistry.register(coreName, commitTracker); - scheduler.schedule(commitTracker, coreName, props); - log.info("The Trackers are now scheduled to run"); - trackers.add(commitTracker); //Add the commitTracker to the list of scheduled trackers that can be shutdown - - core.addCloseHook(new CloseHook() - { - @Override - public void preClose(SolrCore core) - { - log.info("Shutting down " + core.getName()); - SolrCoreLoadRegistration.shutdownTrackers(core.getName(), trackers, scheduler); - } - - @Override - public void postClose(SolrCore core) - { - // Nothing to be done here - } - }); - } - } - - /** - * Creates the trackers - * - * @param coreName - * @param trackerRegistry - * @param props - * @param scheduler - * @param repositoryClient - * @param srv - * @return A list of trackers - */ - private static List createCoreTrackers(String coreName, - TrackerRegistry trackerRegistry, - Properties props, - SolrTrackerScheduler scheduler, - SOLRAPIClient repositoryClient, - SolrInformationServer srv) { - List trackers = new ArrayList(); - - AclTracker aclTracker = new AclTracker(props, repositoryClient, coreName, srv); - trackerRegistry.register(coreName, aclTracker); - scheduler.schedule(aclTracker, coreName, props); - - ContentTracker contentTrkr = new ContentTracker(props, repositoryClient, coreName, srv); - trackerRegistry.register(coreName, contentTrkr); - scheduler.schedule(contentTrkr, coreName, props); - - MetadataTracker metaTrkr = new MetadataTracker(props, repositoryClient, coreName, srv); - trackerRegistry.register(coreName, metaTrkr); - scheduler.schedule(metaTrkr, coreName, props); - - CascadeTracker cascadeTrkr = new CascadeTracker(props, repositoryClient, coreName, srv); - trackerRegistry.register(coreName, cascadeTrkr); - scheduler.schedule(cascadeTrkr, coreName, props); - - //The CommitTracker will acquire these locks in order - //The ContentTracker will likely have the longest runs so put it first to ensure the MetadataTracker is not paused while - //waiting for the ContentTracker to release it's lock. - //The aclTracker will likely have the shortest runs so put it last. - trackers.add(cascadeTrkr); - trackers.add(contentTrkr); - trackers.add(metaTrkr); - trackers.add(aclTracker); - return trackers; - } - - - /** - * Create model tracker and load persisted models. - * - * @param coreName - * @param trackerRegistry - * @param props - * @param solrHome - * @param repositoryClient - * @param srv - * @param scheduler - * @return true if model tracker has been created, false if it already exists. - */ - private synchronized static void createModelTracker(String coreName, - TrackerRegistry trackerRegistry, - Properties props, - String solrHome, - SOLRAPIClient repositoryClient, - SolrInformationServer srv, - SolrTrackerScheduler scheduler) - { - ModelTracker mTracker = trackerRegistry.getModelTracker(); - if (mTracker == null) - { - log.debug("Creating ModelTracker"); - mTracker = new ModelTracker(solrHome, props, repositoryClient, - coreName, srv); - - trackerRegistry.setModelTracker(mTracker); - log.info("Ensuring first model sync."); - mTracker.ensureFirstModelSync(); - log.info("Done ensuring first model sync."); - - //Scheduling the ModelTracker. - scheduler.schedule(mTracker, coreName, props); - } - - } - - /** - * Shuts down the trackers for a core. - * - * The trackers are only deleted from the scheduler if they are the exact same instance of the Tracker class - * passed into this method. - * For example, you could have 2 cores of the same name and have the trackers registered with the scheduler BUT - * the scheduler only keys by core name. The Collections passed into this method are only removed - * from the scheduler if the instances are == (equal). See scheduler.deleteJobForTrackerInstance() - * - * Trackers are not removed from the registry because the registry only keys by core name; its possible to - * have multiple cores of the same name running. Left over trackers in the registry are cleaned up by the CoreContainer - * shutdown, that happens in the the AlfrescoCoreAdminHandler.shutdown(). - * - * @param coreName The name of the core - * @param coreTrackers A collection of trackers - * @param scheduler The scheduler - */ - public static void shutdownTrackers(String coreName, Collection coreTrackers, SolrTrackerScheduler scheduler) - { - try - { - log.info("Shutting down " + coreName + " with " + coreTrackers.size() + " trackers."); - - // Sets the shutdown flag on the trackers to stop them from doing any more work - coreTrackers.forEach(tracker -> tracker.setShutdown(true)); - - if (!scheduler.isShutdown()) - { - coreTrackers.forEach(tracker -> scheduler.deleteJobForTrackerInstance(coreName,tracker) ); - } - - coreTrackers.forEach(tracker -> tracker.shutdown()); - } - catch (Exception e) - { - log.error("Failed to shutdown trackers for core "+coreName, e); - } - } -} diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/lifecycle/SolrCoreLoadListenerTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/lifecycle/SolrCoreLoadListenerTest.java new file mode 100644 index 000000000..ec54cfd91 --- /dev/null +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/lifecycle/SolrCoreLoadListenerTest.java @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2005-2013 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.solr.lifecycle; + +import org.alfresco.solr.SolrInformationServer; +import org.alfresco.solr.client.SOLRAPIClient; +import org.alfresco.solr.tracker.AclTracker; +import org.alfresco.solr.tracker.CascadeTracker; +import org.alfresco.solr.tracker.ContentTracker; +import org.alfresco.solr.tracker.MetadataTracker; +import org.alfresco.solr.tracker.SolrTrackerScheduler; +import org.alfresco.solr.tracker.Tracker; +import org.alfresco.solr.tracker.TrackerRegistry; +import org.apache.solr.core.SolrCore; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +import java.util.List; +import java.util.Properties; + +import static java.util.Arrays.asList; +import static org.junit.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.same; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +/** + * Unit tests for the {@link SolrCoreLoadListener}. + * + * @author Andrea Gazzarini + * @since 1.5 + */ +@RunWith(MockitoJUnitRunner.class) +public class SolrCoreLoadListenerTest +{ + private SolrCoreLoadListener listener; + + @Mock + private SolrCore core; + + @Mock + private SolrTrackerScheduler scheduler; + + @Mock + private SOLRAPIClient api; + + @Mock + private SolrInformationServer informationServer; + + @Mock + private TrackerRegistry registry; + + private Properties coreProperties; + + private String coreName = "XYZ"; + + @Before + public void setUp() + { + listener = new SolrCoreLoadListener(core); + when(core.getName()).thenReturn(coreName); + + coreProperties = new Properties(); + } + + @Test + public void coreTrackersRegistrationAndScheduling() + { + List coreTrackers = listener.createCoreTrackers(core.getName(), registry, coreProperties, scheduler, api, informationServer); + + verify(registry).register(eq(coreName), any(AclTracker.class)); + verify(registry).register(eq(coreName), any(ContentTracker.class)); + verify(registry).register(eq(coreName), any(MetadataTracker.class)); + verify(registry).register(eq(coreName), any(CascadeTracker.class)); + + verify(scheduler).schedule(any(AclTracker.class), eq(coreName), same(coreProperties)); + verify(scheduler).schedule(any(ContentTracker.class), eq(coreName), same(coreProperties)); + verify(scheduler).schedule(any(MetadataTracker.class), eq(coreName), same(coreProperties)); + verify(scheduler).schedule(any(CascadeTracker.class), eq(coreName), same(coreProperties)); + + assertEquals(4, coreTrackers.size()); + } + + @Test + public void trackersShutDownProcedure() + { + List coreTrackers = + asList(mock(AclTracker.class), mock(ContentTracker.class), mock(MetadataTracker.class), mock(CascadeTracker.class)); + + listener.shutdownTrackers(coreName, coreTrackers, scheduler); + + coreTrackers.forEach(tracker -> verify(tracker).setShutdown(true)); + coreTrackers.forEach(tracker -> verify(scheduler).deleteJobForTrackerInstance(core.getName(), tracker)); + coreTrackers.forEach(tracker -> verify(tracker).shutdown()); + } +} From 064d6281396b7339468d9206d2eedee9bf7a2392 Mon Sep 17 00:00:00 2001 From: agazzarini Date: Wed, 16 Oct 2019 14:38:59 +0200 Subject: [PATCH 05/42] [ SEARCH-1606 ] Unit tests for master/slave role detection --- .../solr/lifecycle/SolrCoreLoadListener.java | 2 +- .../lifecycle/SolrCoreLoadListenerTest.java | 56 ++++++++++++++++++- .../solrconfig_empty_replication_handler.xml | 36 ++++++++++++ ...ig_master_disabled_replication_handler.xml | 37 ++++++++++++ .../solrconfig_master_replication_handler.xml | 36 ++++++++++++ ...rconfig_no_replication_handler_defined.xml | 29 ++++++++++ ...fig_slave_disabled_replication_handler.xml | 37 ++++++++++++ .../solrconfig_slave_replication_handler.xml | 36 ++++++++++++ 8 files changed, 266 insertions(+), 3 deletions(-) create mode 100644 search-services/alfresco-search/src/test/resources/test-files/solrconfig_empty_replication_handler.xml create mode 100644 search-services/alfresco-search/src/test/resources/test-files/solrconfig_master_disabled_replication_handler.xml create mode 100644 search-services/alfresco-search/src/test/resources/test-files/solrconfig_master_replication_handler.xml create mode 100644 search-services/alfresco-search/src/test/resources/test-files/solrconfig_no_replication_handler_defined.xml create mode 100644 search-services/alfresco-search/src/test/resources/test-files/solrconfig_slave_disabled_replication_handler.xml create mode 100644 search-services/alfresco-search/src/test/resources/test-files/solrconfig_slave_replication_handler.xml diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/lifecycle/SolrCoreLoadListener.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/lifecycle/SolrCoreLoadListener.java index 7f6c44490..700bc7632 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/lifecycle/SolrCoreLoadListener.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/lifecycle/SolrCoreLoadListener.java @@ -279,7 +279,7 @@ public class SolrCoreLoadListener extends AbstractSolrEventListener * @param core the hosting {@link SolrCore} instance. * @return true if the content store must be set in read only mode, false otherwise. */ - private boolean isSlaveModeEnabledFor(SolrCore core) + boolean isSlaveModeEnabledFor(SolrCore core) { Predicate onlyReplicationHandler = plugin -> "/replication".equals(plugin.name) diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/lifecycle/SolrCoreLoadListenerTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/lifecycle/SolrCoreLoadListenerTest.java index ec54cfd91..8462aefc0 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/lifecycle/SolrCoreLoadListenerTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/lifecycle/SolrCoreLoadListenerTest.java @@ -27,18 +27,22 @@ import org.alfresco.solr.tracker.MetadataTracker; import org.alfresco.solr.tracker.SolrTrackerScheduler; import org.alfresco.solr.tracker.Tracker; import org.alfresco.solr.tracker.TrackerRegistry; +import org.apache.solr.core.SolrConfig; import org.apache.solr.core.SolrCore; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; +import org.xml.sax.InputSource; import java.util.List; import java.util.Properties; import static java.util.Arrays.asList; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.same; @@ -82,7 +86,7 @@ public class SolrCoreLoadListenerTest listener = new SolrCoreLoadListener(core); when(core.getName()).thenReturn(coreName); - coreProperties = new Properties(); + coreProperties = new Properties(); } @Test @@ -115,4 +119,52 @@ public class SolrCoreLoadListenerTest coreTrackers.forEach(tracker -> verify(scheduler).deleteJobForTrackerInstance(core.getName(), tracker)); coreTrackers.forEach(tracker -> verify(tracker).shutdown()); } -} + + @Test + public void noReplicationHandlerDefined_thenContentStoreIsInReadWriteMode() throws Exception + { + prepare("solrconfig_no_replication_handler_defined.xml"); + assertFalse("If no replication handler is defined, then we expect to run a RW content store.", listener.isSlaveModeEnabledFor(core)); + } + + @Test + public void emptyReplicationHandlerDefined_thenContentStoreIsInReadWriteMode() throws Exception + { + prepare("solrconfig_empty_replication_handler.xml"); + assertFalse("If an empty replication handler is defined, then we expect to run a RW content store.", listener.isSlaveModeEnabledFor(core)); + } + + @Test + public void slaveReplicationHandlerDefinedButDisabled_thenContentStoreIsInReadWriteMode() throws Exception + { + prepare("solrconfig_slave_disabled_replication_handler.xml"); + assertFalse("If a slave replication handler is defined but disabled, then we expect to run a RW content store.", listener.isSlaveModeEnabledFor(core)); + } + + @Test + public void masterReplicationHandlerDefined_thenContentStoreIsInReadWriteMode() throws Exception + { + prepare("solrconfig_master_replication_handler.xml"); + assertFalse("If a master replication handler is defined but disabled, then we expect to run a RW content store.", listener.isSlaveModeEnabledFor(core)); + } + + @Test + public void masterReplicationHandlerDefinedButDisabled_thenContentStoreIsInReadWriteMode() throws Exception + { + prepare("solrconfig_master_disabled_replication_handler.xml"); + assertFalse("If a master replication handler is defined but disabled, then we expect to run a RW content store.", listener.isSlaveModeEnabledFor(core)); + } + + @Test + public void slaveReplicationHandlerDefined_thenContentStoreIsInReadOnlyMode() throws Exception + { + prepare("solrconfig_slave_replication_handler.xml"); + assertTrue("If a slave replication handler is defined, then we expect to run a RO content store.", listener.isSlaveModeEnabledFor(core)); + } + + private void prepare(String configName) throws Exception + { + SolrConfig solrConfig = new SolrConfig(configName, new InputSource(getClass().getResourceAsStream("/test-files/" + configName))); + when(core.getSolrConfig()).thenReturn(solrConfig); + } +} \ No newline at end of file diff --git a/search-services/alfresco-search/src/test/resources/test-files/solrconfig_empty_replication_handler.xml b/search-services/alfresco-search/src/test/resources/test-files/solrconfig_empty_replication_handler.xml new file mode 100644 index 000000000..e05ab0538 --- /dev/null +++ b/search-services/alfresco-search/src/test/resources/test-files/solrconfig_empty_replication_handler.xml @@ -0,0 +1,36 @@ + + + 6.6.5 + /tmp/test + + + ${solr.lock.type:native} + + + + + + + + + + commit + schema.xml + + + + + + false + id + lucene + + + + + Query me! + + \ No newline at end of file diff --git a/search-services/alfresco-search/src/test/resources/test-files/solrconfig_master_disabled_replication_handler.xml b/search-services/alfresco-search/src/test/resources/test-files/solrconfig_master_disabled_replication_handler.xml new file mode 100644 index 000000000..0ed005b25 --- /dev/null +++ b/search-services/alfresco-search/src/test/resources/test-files/solrconfig_master_disabled_replication_handler.xml @@ -0,0 +1,37 @@ + + + 6.6.5 + /tmp/test + + + ${solr.lock.type:native} + + + + + + + + + + false + commit + schema.xml + + + + + + false + id + lucene + + + + + Query me! + + \ No newline at end of file diff --git a/search-services/alfresco-search/src/test/resources/test-files/solrconfig_master_replication_handler.xml b/search-services/alfresco-search/src/test/resources/test-files/solrconfig_master_replication_handler.xml new file mode 100644 index 000000000..e05ab0538 --- /dev/null +++ b/search-services/alfresco-search/src/test/resources/test-files/solrconfig_master_replication_handler.xml @@ -0,0 +1,36 @@ + + + 6.6.5 + /tmp/test + + + ${solr.lock.type:native} + + + + + + + + + + commit + schema.xml + + + + + + false + id + lucene + + + + + Query me! + + \ No newline at end of file diff --git a/search-services/alfresco-search/src/test/resources/test-files/solrconfig_no_replication_handler_defined.xml b/search-services/alfresco-search/src/test/resources/test-files/solrconfig_no_replication_handler_defined.xml new file mode 100644 index 000000000..0025cb3ca --- /dev/null +++ b/search-services/alfresco-search/src/test/resources/test-files/solrconfig_no_replication_handler_defined.xml @@ -0,0 +1,29 @@ + + + 6.6.5 + /tmp/test + + + ${solr.lock.type:native} + + + + + + + + + + false + id + lucene + + + + + Query me! + + \ No newline at end of file diff --git a/search-services/alfresco-search/src/test/resources/test-files/solrconfig_slave_disabled_replication_handler.xml b/search-services/alfresco-search/src/test/resources/test-files/solrconfig_slave_disabled_replication_handler.xml new file mode 100644 index 000000000..76192edf1 --- /dev/null +++ b/search-services/alfresco-search/src/test/resources/test-files/solrconfig_slave_disabled_replication_handler.xml @@ -0,0 +1,37 @@ + + + 6.6.5 + /tmp/test + + + ${solr.lock.type:native} + + + + + + + + + + false + http://localhost:8983/solr/alfresco + 00:00:20 + + + + + + false + id + lucene + + + + + Query me! + + \ No newline at end of file diff --git a/search-services/alfresco-search/src/test/resources/test-files/solrconfig_slave_replication_handler.xml b/search-services/alfresco-search/src/test/resources/test-files/solrconfig_slave_replication_handler.xml new file mode 100644 index 000000000..650bfe467 --- /dev/null +++ b/search-services/alfresco-search/src/test/resources/test-files/solrconfig_slave_replication_handler.xml @@ -0,0 +1,36 @@ + + + 6.6.5 + /tmp/test + + + ${solr.lock.type:native} + + + + + + + + + + http://localhost:8983/solr/alfresco + 00:00:20 + + + + + + false + id + lucene + + + + + Query me! + + \ No newline at end of file From 4eebda2eccc1c2abba35930e929d5d82c2858578 Mon Sep 17 00:00:00 2001 From: agazzarini Date: Wed, 16 Oct 2019 16:46:10 +0200 Subject: [PATCH 06/42] [ SEARCH-1606 ] Minor fix on trackers disable/enable property --- .../org/alfresco/solr/lifecycle/SolrCoreLoadListener.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/lifecycle/SolrCoreLoadListener.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/lifecycle/SolrCoreLoadListener.java index 700bc7632..6d6a79793 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/lifecycle/SolrCoreLoadListener.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/lifecycle/SolrCoreLoadListener.java @@ -118,12 +118,12 @@ public class SolrCoreLoadListener extends AbstractSolrEventListener scheduler); } - boolean trackersHaveBeenExplicitlyDisabled = Boolean.parseBoolean(coreProperties.getProperty("enable.alfresco.tracking", "false")); + boolean trackersHaveBeenEnabled = Boolean.parseBoolean(coreProperties.getProperty("enable.alfresco.tracking", "false")); boolean owningCoreIsSlave = isSlaveModeEnabledFor(core); // Guard conditions: if trackers must be disabled then immediately return, we've done here. // Case #1: trackers have been explicitly disabled. - if (trackersHaveBeenExplicitlyDisabled) + if (!trackersHaveBeenEnabled) { LOGGER.info("SearchServices Core Trackers have been explicitly disabled on core \"{}\" through \"enable.alfresco.tracking\" configuration property.", core.getName()); return; From b5634ee7b874e235f27f984c0f04d5a9f267a81d Mon Sep 17 00:00:00 2001 From: agazzarini Date: Thu, 17 Oct 2019 08:11:58 +0200 Subject: [PATCH 07/42] [ SEARCH-1606 ] Minor fix on a log message --- .../java/org/alfresco/solr/lifecycle/SolrCoreLoadListener.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/lifecycle/SolrCoreLoadListener.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/lifecycle/SolrCoreLoadListener.java index 6d6a79793..4e858480e 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/lifecycle/SolrCoreLoadListener.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/lifecycle/SolrCoreLoadListener.java @@ -136,7 +136,7 @@ public class SolrCoreLoadListener extends AbstractSolrEventListener return; } - LOGGER.info("SearchServices Core Tracking Subsystem starts on core {}", core.getName()); + LOGGER.info("SearchServices Tracking Subsystem starts on core {}", core.getName()); if (trackerRegistry.hasTrackersForCore(core.getName())) { LOGGER.info("Trackers for " + core.getName()+ " is already registered, shutting them down."); From 404a9e0624ed78bbabba11ad6662f13c76d33a13 Mon Sep 17 00:00:00 2001 From: agazzarini Date: Thu, 17 Oct 2019 08:31:53 +0200 Subject: [PATCH 08/42] [ SEARCH-1606 ] alfresco.enable.tracking set to true by default --- .../java/org/alfresco/solr/lifecycle/SolrCoreLoadListener.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/lifecycle/SolrCoreLoadListener.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/lifecycle/SolrCoreLoadListener.java index 4e858480e..d65ce1a43 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/lifecycle/SolrCoreLoadListener.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/lifecycle/SolrCoreLoadListener.java @@ -118,7 +118,7 @@ public class SolrCoreLoadListener extends AbstractSolrEventListener scheduler); } - boolean trackersHaveBeenEnabled = Boolean.parseBoolean(coreProperties.getProperty("enable.alfresco.tracking", "false")); + boolean trackersHaveBeenEnabled = Boolean.parseBoolean(coreProperties.getProperty("enable.alfresco.tracking", "true")); boolean owningCoreIsSlave = isSlaveModeEnabledFor(core); // Guard conditions: if trackers must be disabled then immediately return, we've done here. From f463b470879c0320b750ba39e2ea42c59ce971b4 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 18 Oct 2019 00:13:02 +0000 Subject: [PATCH 09/42] Bump utility from 3.0.11 to 3.0.12 in /e2e-test Bumps [utility](https://github.com/Alfresco/alfresco-tas-utility) from 3.0.11 to 3.0.12. - [Release notes](https://github.com/Alfresco/alfresco-tas-utility/releases) - [Changelog](https://github.com/Alfresco/alfresco-tas-utility/blob/master/docs/CHANGELOG.md) - [Commits](https://github.com/Alfresco/alfresco-tas-utility/compare/utility-3.0.11...utility-3.0.12) Signed-off-by: dependabot-preview[bot] --- e2e-test/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e-test/pom.xml b/e2e-test/pom.xml index 4016219ff..456a86403 100644 --- a/e2e-test/pom.xml +++ b/e2e-test/pom.xml @@ -13,7 +13,7 @@ 6.0.1.2 6.0.0.4 - 3.0.11 + 3.0.12 3.2.0-SNAPSHOT From c981a204d1697bc439d7ef8a67799f01266d4698 Mon Sep 17 00:00:00 2001 From: agazzarini Date: Fri, 18 Oct 2019 07:00:35 +0200 Subject: [PATCH 10/42] [ SEARCH-1752 ] NodeStateProvider and SlaveNodeStateProvider --- .../solr/tracker/MetadataTracker.java | 198 +--------------- .../solr/tracker/NodeStateProvider.java | 222 ++++++++++++++++++ .../solr/tracker/SlaveNodeStateProvider.java | 65 +++++ 3 files changed, 299 insertions(+), 186 deletions(-) create mode 100644 search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/NodeStateProvider.java create mode 100644 search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/SlaveNodeStateProvider.java diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/MetadataTracker.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/MetadataTracker.java index 58778d865..27439ea82 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/MetadataTracker.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/MetadataTracker.java @@ -20,27 +20,15 @@ package org.alfresco.solr.tracker; import java.io.IOException; import java.util.ArrayList; -import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; -import java.util.Optional; import java.util.Properties; import java.util.concurrent.ConcurrentLinkedQueue; import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.httpclient.AuthenticationException; -import org.alfresco.opencmis.dictionary.CMISStrictDictionaryService; -import org.alfresco.repo.dictionary.NamespaceDAO; -import org.alfresco.repo.index.shard.ShardMethodEnum; import org.alfresco.repo.index.shard.ShardState; -import org.alfresco.repo.index.shard.ShardStateBuilder; -import org.alfresco.repo.search.impl.QueryParserUtils; -import org.alfresco.service.cmr.dictionary.DictionaryService; -import org.alfresco.service.cmr.dictionary.PropertyDefinition; -import org.alfresco.service.namespace.QName; -import org.alfresco.solr.AlfrescoCoreAdminHandler; -import org.alfresco.solr.AlfrescoSolrDataModel; import org.alfresco.solr.BoundedDeque; import org.alfresco.solr.InformationServer; import org.alfresco.solr.NodeReport; @@ -53,97 +41,43 @@ import org.alfresco.solr.client.SOLRAPIClient; import org.alfresco.solr.client.Transaction; import org.alfresco.solr.client.Transactions; import org.apache.commons.codec.EncoderException; -import org.apache.commons.lang3.StringUtils; import org.json.JSONException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import static java.util.Optional.of; - -import static java.util.Optional.ofNullable; -import static org.alfresco.solr.tracker.DocRouterFactory.SHARD_KEY_KEY; - /* * This tracks two things: transactions and metadata nodes * @author Ahmed Owian */ -public class MetadataTracker extends AbstractTracker implements Tracker +public class MetadataTracker extends NodeStateProvider implements Tracker { - protected final static Logger log = LoggerFactory.getLogger(MetadataTracker.class); private static final int DEFAULT_TRANSACTION_DOCS_BATCH_SIZE = 100; private static final int DEFAULT_NODE_BATCH_SIZE = 10; private int transactionDocsBatchSize = DEFAULT_TRANSACTION_DOCS_BATCH_SIZE; private int nodeBatchSize = DEFAULT_NODE_BATCH_SIZE; - private ConcurrentLinkedQueue transactionsToReindex = new ConcurrentLinkedQueue(); - private ConcurrentLinkedQueue transactionsToIndex = new ConcurrentLinkedQueue(); - private ConcurrentLinkedQueue transactionsToPurge = new ConcurrentLinkedQueue(); - private ConcurrentLinkedQueue nodesToReindex = new ConcurrentLinkedQueue(); - private ConcurrentLinkedQueue nodesToIndex = new ConcurrentLinkedQueue(); - private ConcurrentLinkedQueue nodesToPurge = new ConcurrentLinkedQueue(); - private ConcurrentLinkedQueue queriesToReindex = new ConcurrentLinkedQueue(); - private DocRouter docRouter; - /** The string representation of the shard key. */ - private Optional shardKey; - /** The property to use for determining the shard. */ - private Optional shardProperty = Optional.empty(); + private ConcurrentLinkedQueue transactionsToReindex = new ConcurrentLinkedQueue<>(); + private ConcurrentLinkedQueue transactionsToIndex = new ConcurrentLinkedQueue<>(); + private ConcurrentLinkedQueue transactionsToPurge = new ConcurrentLinkedQueue<>(); + private ConcurrentLinkedQueue nodesToReindex = new ConcurrentLinkedQueue<>(); + private ConcurrentLinkedQueue nodesToIndex = new ConcurrentLinkedQueue<>(); + private ConcurrentLinkedQueue nodesToPurge = new ConcurrentLinkedQueue<>(); + private ConcurrentLinkedQueue queriesToReindex = new ConcurrentLinkedQueue<>(); public MetadataTracker(Properties p, SOLRAPIClient client, String coreName, InformationServer informationServer) { super(p, client, coreName, informationServer, Tracker.Type.MetaData); transactionDocsBatchSize = Integer.parseInt(p.getProperty("alfresco.transactionDocsBatchSize", "100")); - shardMethod = p.getProperty("shard.method", SHARD_METHOD_DBID); - shardKey = ofNullable(p.getProperty(SHARD_KEY_KEY)); - firstUpdateShardProperty(); - docRouter = DocRouterFactory.getRouter(p, ShardMethodEnum.getShardMethod(shardMethod)); nodeBatchSize = Integer.parseInt(p.getProperty("alfresco.nodeBatchSize", "10")); threadHandler = new ThreadHandler(p, coreName, "MetadataTracker"); } - /** - * Set the shard property using the shard key. - */ - private void updateShardProperty() - { - shardKey.ifPresent(shardKeyName -> { - Optional updatedShardProperty = getShardProperty(shardKeyName); - if (!shardProperty.equals(updatedShardProperty)) - { - if (updatedShardProperty.isEmpty()) - { - log.warn("The model defining " + shardKeyName + " property has been disabled"); - } - else - { - log.info("New " + SHARD_KEY_KEY + " property found for " + shardKeyName); - } - } - shardProperty = updatedShardProperty; - }); - } - - private void firstUpdateShardProperty() - { - shardKey.ifPresent( shardKeyName -> { - updateShardProperty(); - if (shardProperty.isEmpty()) - { - log.warn("Sharding property " + SHARD_KEY_KEY + " was set to " + shardKeyName + ", but no such property was found."); - } - }); - } - - MetadataTracker() { super(Tracker.Type.MetaData); } - public DocRouter getDocRouter() { - return this.docRouter; - } - @Override protected void doTrack() throws AuthenticationException, IOException, JSONException, EncoderException { @@ -160,7 +94,8 @@ public class MetadataTracker extends AbstractTracker implements Tracker } } - public void maintenance() throws Exception { + public void maintenance() throws Exception + { purgeTransactions(); purgeNodes(); reindexTransactions(); @@ -170,7 +105,8 @@ public class MetadataTracker extends AbstractTracker implements Tracker indexNodes(); } - public boolean hasMaintenance() throws Exception { + public boolean hasMaintenance() + { return transactionsToReindex.size() > 0 || transactionsToIndex.size() > 0 || transactionsToPurge.size() > 0 || @@ -180,30 +116,11 @@ public class MetadataTracker extends AbstractTracker implements Tracker queriesToReindex.size() > 0; } - - private void trackRepository() throws IOException, AuthenticationException, JSONException, EncoderException { log.debug("####### MetadataTracker trackRepository Start #######"); checkShutdown(); - if(!isMaster && isSlave) - { - // Dynamic registration - /* - * This section allows Solr's master/slave setup to be used with dynamic shard registration. - * In this scenario the slave is polling a "tracking" Solr node. The code below calls - * the repo to register the state of the node without pulling any real transactions from the repo. - * - * This allows the repo to register the replica so that it will be included in queries. But the slave Solr node - * will pull its data from a "tracking" Solr node using Solr's master/slave replication, rather then tracking the repository. - * - */ - ShardState shardstate = getShardState(); - client.getTransactions(0L, null, 0L, null, 0, shardstate); - return; - } - // Check we are tracking the correct repository TrackerState state = super.getTrackerState(); log.debug("####### MetadataTracker check CYCLE #######"); @@ -233,67 +150,6 @@ public class MetadataTracker extends AbstractTracker implements Tracker trackTransactions(); } - /** - * The {@link ShardState}, as the name suggests, encapsulates/stores the state of the shard which hosts this - * {@link MetadataTracker} instance. - * - * The {@link ShardState} is primarily used in two places: - * - *
    - *
  • Transaction tracking: (see {@link #trackTransactions()}): for pulling/tracking transactions from Alfresco
  • - *
  • - * DynamicSharding: when the {@link MetadataTracker} is running on a slave instance it doesn't actually act - * as a tracker, it calls Alfresco to register the state of the node (the shard) without pulling any transactions. - * As consequence of that, Alfresco will be aware about the shard which will be included in subsequent queries. - *
  • - *
- * - * @return the {@link ShardState} instance which stores the current state of the hosting shard. - */ - ShardState getShardState() - { - TrackerState transactionsTrackerState = super.getTrackerState(); - TrackerState changeSetsTrackerState = - of(infoSrv.getAdminHandler()) - .map(AlfrescoCoreAdminHandler::getTrackerRegistry) - .map(registry -> registry.getTrackerForCore(coreName, AclTracker.class)) - .map(Tracker::getTrackerState) - .orElse(transactionsTrackerState); - - HashMap propertyBag = new HashMap<>(); - propertyBag.put("coreName", coreName); - HashMap extendedPropertyBag = new HashMap<>(propertyBag); - updateShardProperty(); - - shardProperty.ifPresent(p -> extendedPropertyBag.putAll(docRouter.getProperties(p))); - - return ShardStateBuilder.shardState() - .withMaster(isMaster) - .withLastUpdated(System.currentTimeMillis()) - .withLastIndexedChangeSetCommitTime(changeSetsTrackerState.getLastIndexedChangeSetCommitTime()) - .withLastIndexedChangeSetId(changeSetsTrackerState.getLastIndexedChangeSetId()) - .withLastIndexedTxCommitTime(transactionsTrackerState.getLastIndexedTxCommitTime()) - .withLastIndexedTxId(transactionsTrackerState.getLastIndexedTxId()) - .withPropertyBag(extendedPropertyBag) - .withShardInstance() - .withBaseUrl(infoSrv.getBaseUrl()) - .withPort(infoSrv.getPort()) - .withHostName(infoSrv.getHostName()) - .withShard() - .withInstance(shardInstance) - .withFloc() - .withNumberOfShards(shardCount) - .withAddedStoreRef(storeRef) - .withTemplate(shardTemplate) - .withHasContent(transformContent) - .withShardMethod(ShardMethodEnum.getShardMethod(shardMethod)) - .withPropertyBag(propertyBag) - .endFloc() - .endShard() - .endShardInstance() - .build(); - } - /** * Checks the first and last TX time * @param state the state of this tracker @@ -1230,34 +1086,4 @@ public class MetadataTracker extends AbstractTracker implements Tracker { this.queriesToReindex.offer(query); } - - - /** - * Given the field name, returns the name of the property definition. - * If the property definition is not found, Empty optional is returned. - * - * @param field - * - * @return the name of the associated property definition if present, Optional.Empty() otherwise - * - */ - public static Optional getShardProperty(String field) - { - if (StringUtils.isBlank(field)) - { - throw new IllegalArgumentException("Sharding property " + SHARD_KEY_KEY + " has not been set."); - } - AlfrescoSolrDataModel dataModel = AlfrescoSolrDataModel.getInstance(); - NamespaceDAO namespaceDAO = dataModel.getNamespaceDAO(); - DictionaryService dictionaryService = dataModel.getDictionaryService(CMISStrictDictionaryService.DEFAULT); - PropertyDefinition propertyDef = QueryParserUtils.matchPropertyDefinition("http://www.alfresco.org/model/content/1.0", - namespaceDAO, - dictionaryService, - field); - if (propertyDef == null) - { - return Optional.empty(); - } - return of(propertyDef.getName()); - } } diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/NodeStateProvider.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/NodeStateProvider.java new file mode 100644 index 000000000..6b3c7fa30 --- /dev/null +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/NodeStateProvider.java @@ -0,0 +1,222 @@ +/* + * #%L + * Alfresco Solr Client + * %% + * 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.tracker; + +import org.alfresco.opencmis.dictionary.CMISStrictDictionaryService; +import org.alfresco.repo.dictionary.NamespaceDAO; +import org.alfresco.repo.index.shard.ShardMethodEnum; +import org.alfresco.repo.index.shard.ShardState; +import org.alfresco.repo.index.shard.ShardStateBuilder; +import org.alfresco.repo.search.impl.QueryParserUtils; +import org.alfresco.service.cmr.dictionary.DictionaryService; +import org.alfresco.service.cmr.dictionary.PropertyDefinition; +import org.alfresco.service.namespace.QName; +import org.alfresco.solr.AlfrescoCoreAdminHandler; +import org.alfresco.solr.AlfrescoSolrDataModel; +import org.alfresco.solr.InformationServer; +import org.alfresco.solr.TrackerState; +import org.alfresco.solr.client.SOLRAPIClient; +import org.apache.commons.lang3.StringUtils; + +import java.util.HashMap; +import java.util.Optional; +import java.util.Properties; + +import static java.util.Optional.of; +import static java.util.Optional.ofNullable; +import static org.alfresco.solr.tracker.DocRouterFactory.SHARD_KEY_KEY; + +/** + * Superclass for all components which are able to inform Alfresco about the hosting node state. + * This has been introduced in SEARCH-1752 for splitting the dual responsibility of the {@link MetadataTracker}. + * As consequence of that, this class contains all the members needed for obtaining a valid + * {@link org.alfresco.repo.index.shard.ShardState} that can be periodically communicated to Alfresco. + * + * @author Andrea Gazzarini + * @since 1.5 + * @see SEARCH-1752 + */ +public abstract class NodeStateProvider extends AbstractTracker +{ + DocRouter docRouter; + + /** The string representation of the shard key. */ + private Optional shardKey; + + /** The property to use for determining the shard. */ + protected Optional shardProperty = Optional.empty(); + + NodeStateProvider( + Properties p, + SOLRAPIClient client, + String coreName, + InformationServer informationServer, + Type type) + { + super(p, client, coreName, informationServer, type); + shardMethod = p.getProperty("shard.method", SHARD_METHOD_DBID); + shardKey = ofNullable(p.getProperty(SHARD_KEY_KEY)); + firstUpdateShardProperty(); + docRouter = DocRouterFactory.getRouter(p, ShardMethodEnum.getShardMethod(shardMethod)); + } + + NodeStateProvider(Type type) + { + super(type); + } + + private void firstUpdateShardProperty() + { + shardKey.ifPresent( shardKeyName -> { + updateShardProperty(); + if (shardProperty.isEmpty()) + { + log.warn("Sharding property " + SHARD_KEY_KEY + " was set to " + shardKeyName + ", but no such property was found."); + } + }); + } + + /** + * Set the shard property using the shard key. + */ + void updateShardProperty() + { + shardKey.ifPresent(shardKeyName -> { + Optional updatedShardProperty = getShardProperty(shardKeyName); + if (!shardProperty.equals(updatedShardProperty)) + { + if (updatedShardProperty.isEmpty()) + { + log.warn("The model defining " + shardKeyName + " property has been disabled"); + } + else + { + log.info("New " + SHARD_KEY_KEY + " property found for " + shardKeyName); + } + } + shardProperty = updatedShardProperty; + }); + } + + /** + * Given the field name, returns the name of the property definition. + * If the property definition is not found, Empty optional is returned. + * + * @param field the field name. + * @return the name of the associated property definition if present, Optional.Empty() otherwise + */ + static Optional getShardProperty(String field) + { + if (StringUtils.isBlank(field)) + { + throw new IllegalArgumentException("Sharding property " + SHARD_KEY_KEY + " has not been set."); + } + + AlfrescoSolrDataModel dataModel = AlfrescoSolrDataModel.getInstance(); + NamespaceDAO namespaceDAO = dataModel.getNamespaceDAO(); + DictionaryService dictionaryService = dataModel.getDictionaryService(CMISStrictDictionaryService.DEFAULT); + PropertyDefinition propertyDef = QueryParserUtils.matchPropertyDefinition("http://www.alfresco.org/model/content/1.0", + namespaceDAO, + dictionaryService, + field); + if (propertyDef == null) + { + return Optional.empty(); + } + return of(propertyDef.getName()); + } + + /** + * The {@link ShardState}, as the name suggests, encapsulates/stores the state of the shard which hosts this + * {@link MetadataTracker} instance. + * + * The {@link ShardState} is primarily used in two places: + * + *
    + *
  • Transaction tracking: (see {@link MetadataTracker#trackTransactions()}): for pulling/tracking transactions from Alfresco
  • + *
  • + * DynamicSharding: when the {@link MetadataTracker} is running on a slave instance it doesn't actually act + * as a tracker, it calls Alfresco to register the state of the node (the shard) without pulling any transactions. + * As consequence of that, Alfresco will be aware about the shard which will be included in subsequent queries. + *
  • + *
+ * + * @return the {@link ShardState} instance which stores the current state of the hosting shard. + */ + ShardState getShardState() + { + TrackerState transactionsTrackerState = super.getTrackerState(); + TrackerState changeSetsTrackerState = + of(infoSrv.getAdminHandler()) + .map(AlfrescoCoreAdminHandler::getTrackerRegistry) + .map(registry -> registry.getTrackerForCore(coreName, AclTracker.class)) + .map(Tracker::getTrackerState) + .orElse(transactionsTrackerState); + + HashMap propertyBag = new HashMap<>(); + propertyBag.put("coreName", coreName); + HashMap extendedPropertyBag = new HashMap<>(propertyBag); + updateShardProperty(); + + shardProperty.ifPresent(p -> extendedPropertyBag.putAll(docRouter.getProperties(p))); + + return ShardStateBuilder.shardState() + .withMaster(isMaster) + .withLastUpdated(System.currentTimeMillis()) + .withLastIndexedChangeSetCommitTime(changeSetsTrackerState.getLastIndexedChangeSetCommitTime()) + .withLastIndexedChangeSetId(changeSetsTrackerState.getLastIndexedChangeSetId()) + .withLastIndexedTxCommitTime(transactionsTrackerState.getLastIndexedTxCommitTime()) + .withLastIndexedTxId(transactionsTrackerState.getLastIndexedTxId()) + .withPropertyBag(extendedPropertyBag) + .withShardInstance() + .withBaseUrl(infoSrv.getBaseUrl()) + .withPort(infoSrv.getPort()) + .withHostName(infoSrv.getHostName()) + .withShard() + .withInstance(shardInstance) + .withFloc() + .withNumberOfShards(shardCount) + .withAddedStoreRef(storeRef) + .withTemplate(shardTemplate) + .withHasContent(transformContent) + .withShardMethod(ShardMethodEnum.getShardMethod(shardMethod)) + .withPropertyBag(propertyBag) + .endFloc() + .endShard() + .endShardInstance() + .build(); + } + + /** + * Returns the {@link DocRouter} instance in use on this node. + * + * @return the {@link DocRouter} instance in use on this node. + */ + public DocRouter getDocRouter() + { + return this.docRouter; + } +} diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/SlaveNodeStateProvider.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/SlaveNodeStateProvider.java new file mode 100644 index 000000000..c9ac8567a --- /dev/null +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/SlaveNodeStateProvider.java @@ -0,0 +1,65 @@ +package org.alfresco.solr.tracker; + +import org.alfresco.httpclient.AuthenticationException; +import org.alfresco.repo.index.shard.ShardState; +import org.apache.commons.codec.EncoderException; + +import java.io.IOException; + +/** + * Despite belonging to the Tracker ecosystem, this component is actually a publisher, which periodically informs + * Alfresco about the state of the hosting slave node. + * As the name suggests, this worker is scheduled only when the hosting node acts as a slave. + * It allows Solr's master/slave setup to be used with dynamic shard registration. + * + * In this scenario the slave is polling a "tracking" Solr node. The tracker below calls + * the repo to register the state of the node without pulling any real transactions from the repo. + * + * This allows the repo to register the replica so that it will be included in queries. But the slave Solr node + * will pull its data from a "tracking" Solr node using Solr's master/slave replication, rather then tracking the repository. + * + * @author Andrea Gazzarini + * @since 1.5 + */ +public class SlaveNodeStateProvider extends MetadataTracker +{ + @Override + protected void doTrack() + { + try + { + ShardState shardstate = getShardState(); + client.getTransactions(0L, null, 0L, null, 0, shardstate); + } + catch (EncoderException exception ) + { + log.error("Unable to publish this node state. " + + "A failure condition has been met during the outbound subscription message encoding process. " + + "See the stacktrace below for further details.", exception); + } + catch (IOException exception ) + { + log.error("Unable to publish this node state. " + + "Detected an I/O failure while sending the subscription state message. " + + "See the stacktrace below for further details.", exception); + } + catch (AuthenticationException exception) + { + log.error("Unable to publish this node state. " + + "Authentication failure detected while sending the subscription state message. " + + "See the stacktrace below for further details.", exception); + } + } + + @Override + public void maintenance() + { + // Do nothing here + } + + @Override + public boolean hasMaintenance() + { + return false; + } +} \ No newline at end of file From e360b63d6768380690fca42710f46259a5163ed0 Mon Sep 17 00:00:00 2001 From: agazzarini Date: Fri, 18 Oct 2019 11:06:06 +0200 Subject: [PATCH 11/42] [ SEARCH-1606 ] Review comments addressed --- .../org/alfresco/solr/lifecycle/SolrCoreLoadListener.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/lifecycle/SolrCoreLoadListener.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/lifecycle/SolrCoreLoadListener.java index d65ce1a43..c1ec3719d 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/lifecycle/SolrCoreLoadListener.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/lifecycle/SolrCoreLoadListener.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2016 Alfresco Software Limited. + * Copyright (C) 2005-2019 Alfresco Software Limited. * * This file is part of Alfresco * @@ -52,7 +52,6 @@ import org.apache.solr.search.SolrIndexSearcher; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.lang.invoke.MethodHandles; import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -68,7 +67,7 @@ import java.util.function.Predicate; */ public class SolrCoreLoadListener extends AbstractSolrEventListener { - private static final Logger LOGGER = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); + private static final Logger LOGGER = LoggerFactory.getLogger(SolrCoreLoadListener.class); /** * Builds a new listener instance with the given {@link SolrCore} (event source). From 1ed1c1c41358fed4576b71f4985083bda0861ab4 Mon Sep 17 00:00:00 2001 From: agazzarini Date: Sat, 19 Oct 2019 07:40:54 +0200 Subject: [PATCH 12/42] [ SEARCH-1752 ] Formatting and comments on affected classes --- .../org/alfresco/solr/tracker/CascadeTracker.java | 4 ++-- .../org/alfresco/solr/tracker/CommitTracker.java | 4 ++-- .../org/alfresco/solr/tracker/ContentTracker.java | 4 ++-- .../java/org/alfresco/solr/tracker/Tracker.java | 14 ++++++++------ .../alfresco/solr/tracker/ContentTrackerTest.java | 2 +- 5 files changed, 15 insertions(+), 13 deletions(-) diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/CascadeTracker.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/CascadeTracker.java index 363206404..56f0f6b3f 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/CascadeTracker.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/CascadeTracker.java @@ -50,14 +50,14 @@ public class CascadeTracker extends AbstractTracker implements Tracker public CascadeTracker(Properties p, SOLRAPIClient client, String coreName, InformationServer informationServer) { - super(p, client, coreName, informationServer, Tracker.Type.Cascade); + super(p, client, coreName, informationServer, Tracker.Type.CASCADE); threadHandler = new ThreadHandler(p, coreName, "CascadeTracker"); } CascadeTracker() { - super(Tracker.Type.Cascade); + super(Tracker.Type.CASCADE); } @Override diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/CommitTracker.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/CommitTracker.java index 3acbd4a51..d8a301cf9 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/CommitTracker.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/CommitTracker.java @@ -51,7 +51,7 @@ public class CommitTracker extends AbstractTracker **/ CommitTracker() { - super(Tracker.Type.Commit); + super(Tracker.Type.COMMIT); } public CommitTracker(Properties p, @@ -60,7 +60,7 @@ public class CommitTracker extends AbstractTracker InformationServer informationServer, List trackers) { - super(p, client, coreName, informationServer, Tracker.Type.Commit); + super(p, client, coreName, informationServer, Tracker.Type.COMMIT); //Set the trackers for(Tracker tracker : trackers) { diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/ContentTracker.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/ContentTracker.java index 28b4fc698..4c3ed15a8 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/ContentTracker.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/ContentTracker.java @@ -45,7 +45,7 @@ public class ContentTracker extends AbstractTracker implements Tracker public ContentTracker(Properties p, SOLRAPIClient client, String coreName, InformationServer informationServer) { - super(p, client, coreName, informationServer, Tracker.Type.Content); + super(p, client, coreName, informationServer, Tracker.Type.CONTENT); contentReadBatchSize = Integer.parseInt(p.getProperty("alfresco.contentReadBatchSize", "100")); contentUpdateBatchSize = Integer.parseInt(p.getProperty("alfresco.contentUpdateBatchSize", "1000")); threadHandler = new ThreadHandler(p, coreName, "ContentTracker"); @@ -53,7 +53,7 @@ public class ContentTracker extends AbstractTracker implements Tracker ContentTracker() { - super(Tracker.Type.Content); + super(Tracker.Type.CONTENT); } @Override diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/Tracker.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/Tracker.java index 9f6654121..ef7a3a3f5 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/Tracker.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/Tracker.java @@ -51,12 +51,14 @@ public interface Tracker Type getType(); - enum Type{ - Model, - Content, + enum Type + { + MODEL, + CONTENT, ACL, - Cascade, - Commit, - MetaData + CASCADE, + COMMIT, + METADATA, + NODE_STATE_PUBLISHER } } diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/ContentTrackerTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/ContentTrackerTest.java index a2e74acfb..e3d6112da 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/ContentTrackerTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/ContentTrackerTest.java @@ -137,7 +137,7 @@ public class ContentTrackerTest @Test public void typeCheck() { - Assert.assertTrue(contentTracker.getType().equals(Tracker.Type.Content)); + Assert.assertTrue(contentTracker.getType().equals(Tracker.Type.CONTENT)); } } From 200e71ce73e37562e06e24ee53e24362cd5fea08 Mon Sep 17 00:00:00 2001 From: agazzarini Date: Sat, 19 Oct 2019 07:41:22 +0200 Subject: [PATCH 13/42] [ SEARCH-1752 ] First working draft --- .../solr/lifecycle/SolrCoreLoadListener.java | 52 ++++++++++++------- .../solr/tracker/MetadataTracker.java | 4 +- .../alfresco/solr/tracker/ModelTracker.java | 4 +- .../solr/tracker/NodeStateProvider.java | 8 +-- .../solr/tracker/SlaveNodeStateProvider.java | 12 ++++- .../solr/tracker/SolrTrackerScheduler.java | 27 ++++++---- 6 files changed, 69 insertions(+), 38 deletions(-) diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/lifecycle/SolrCoreLoadListener.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/lifecycle/SolrCoreLoadListener.java index c1ec3719d..eacac1570 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/lifecycle/SolrCoreLoadListener.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/lifecycle/SolrCoreLoadListener.java @@ -34,6 +34,7 @@ import org.alfresco.solr.tracker.CommitTracker; import org.alfresco.solr.tracker.ContentTracker; import org.alfresco.solr.tracker.MetadataTracker; import org.alfresco.solr.tracker.ModelTracker; +import org.alfresco.solr.tracker.SlaveNodeStateProvider; import org.alfresco.solr.tracker.SolrTrackerScheduler; import org.alfresco.solr.tracker.Tracker; import org.alfresco.solr.tracker.TrackerRegistry; @@ -117,6 +118,31 @@ public class SolrCoreLoadListener extends AbstractSolrEventListener scheduler); } + /* + * The shutdown hook needs to be registered regardless we are slave or masters. + * This because if we are master all trackers will be scheduled, if we are slave the node state publisher + * will be scheduled. + * + * As consequence of that, regardless the node role, we will always have something to shutdown in the tracker + * registry. + */ + final List trackers = new ArrayList<>(); + core.addCloseHook(new CloseHook() + { + @Override + public void preClose(SolrCore core) + { + LOGGER.info("Tracking Subsystem shutdown procedure for core {} has been started.", core.getName()); + shutdownTrackers(core.getName(), trackers, scheduler); + } + + @Override + public void postClose(SolrCore core) + { + LOGGER.info("Tracking Subsystem shutdown procedure for core {} has been completed.", core.getName()); + } + }); + boolean trackersHaveBeenEnabled = Boolean.parseBoolean(coreProperties.getProperty("enable.alfresco.tracking", "true")); boolean owningCoreIsSlave = isSlaveModeEnabledFor(core); @@ -132,6 +158,13 @@ public class SolrCoreLoadListener extends AbstractSolrEventListener if (owningCoreIsSlave) { LOGGER.info("SearchServices Core Trackers have been disabled on core \"{}\" because it is a slave core.", core.getName()); + + SlaveNodeStateProvider stateProvider = new SlaveNodeStateProvider(coreProperties, repositoryClient, core.getName(), informationServer); + trackerRegistry.register(core.getName(), stateProvider); + scheduler.schedule(stateProvider, core.getName(), coreProperties); + + LOGGER.info("SearchServices Slave Node Provider have been created and scheduled for core \"{}\".", core.getName()); + return; } @@ -144,7 +177,7 @@ public class SolrCoreLoadListener extends AbstractSolrEventListener admin.getInformationServers().remove(core.getName()); } - final List trackers = createCoreTrackers(core.getName(), trackerRegistry, coreProperties, scheduler, repositoryClient, informationServer); + trackers.addAll(createCoreTrackers(core.getName(), trackerRegistry, coreProperties, scheduler, repositoryClient, informationServer)); CommitTracker commitTracker = new CommitTracker(coreProperties, repositoryClient, core.getName(), informationServer, trackers); trackerRegistry.register(core.getName(), commitTracker); @@ -154,23 +187,6 @@ public class SolrCoreLoadListener extends AbstractSolrEventListener //Add the commitTracker to the list of scheduled trackers that can be shutdown trackers.add(commitTracker); - - core.addCloseHook(new CloseHook() - { - @Override - public void preClose(SolrCore core) - { - LOGGER.info("Tracking Subsystem shutdown procedure for core {} has been started.", core.getName()); - shutdownTrackers(core.getName(), trackers, scheduler); - } - - @Override - public void postClose(SolrCore core) - { - LOGGER.info("Shutdown procedure for core {} has been completed.", core.getName()); - } - }); - } List createCoreTrackers(String coreName, diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/MetadataTracker.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/MetadataTracker.java index 27439ea82..39d251b03 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/MetadataTracker.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/MetadataTracker.java @@ -67,7 +67,7 @@ public class MetadataTracker extends NodeStateProvider implements Tracker public MetadataTracker(Properties p, SOLRAPIClient client, String coreName, InformationServer informationServer) { - super(p, client, coreName, informationServer, Tracker.Type.MetaData); + super(p, client, coreName, informationServer, Tracker.Type.METADATA); transactionDocsBatchSize = Integer.parseInt(p.getProperty("alfresco.transactionDocsBatchSize", "100")); nodeBatchSize = Integer.parseInt(p.getProperty("alfresco.nodeBatchSize", "10")); threadHandler = new ThreadHandler(p, coreName, "MetadataTracker"); @@ -75,7 +75,7 @@ public class MetadataTracker extends NodeStateProvider implements Tracker MetadataTracker() { - super(Tracker.Type.MetaData); + super(Tracker.Type.METADATA); } @Override diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/ModelTracker.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/ModelTracker.java index c19c31eaa..b3f3cd26b 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/ModelTracker.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/ModelTracker.java @@ -103,7 +103,7 @@ public class ModelTracker extends AbstractTracker implements Tracker public ModelTracker(String solrHome, Properties p, SOLRAPIClient client, String coreName, InformationServer informationServer) { - super(p, client, coreName, informationServer, Tracker.Type.Model); + super(p, client, coreName, informationServer, Tracker.Type.MODEL); String normalSolrHome = SolrResourceLoader.normalizeDir(solrHome); alfrescoModelDir = new File(ConfigUtil.locateProperty("solr.model.dir", normalSolrHome+"alfrescoModels")); log.info("Alfresco Model dir " + alfrescoModelDir); @@ -187,7 +187,7 @@ public class ModelTracker extends AbstractTracker implements Tracker */ ModelTracker() { - super(Tracker.Type.Model); + super(Tracker.Type.MODEL); } @Override diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/NodeStateProvider.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/NodeStateProvider.java index 6b3c7fa30..ad0cbaebf 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/NodeStateProvider.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/NodeStateProvider.java @@ -25,6 +25,10 @@ */ package org.alfresco.solr.tracker; +import static java.util.Optional.of; +import static java.util.Optional.ofNullable; +import static org.alfresco.solr.tracker.DocRouterFactory.SHARD_KEY_KEY; + import org.alfresco.opencmis.dictionary.CMISStrictDictionaryService; import org.alfresco.repo.dictionary.NamespaceDAO; import org.alfresco.repo.index.shard.ShardMethodEnum; @@ -45,10 +49,6 @@ import java.util.HashMap; import java.util.Optional; import java.util.Properties; -import static java.util.Optional.of; -import static java.util.Optional.ofNullable; -import static org.alfresco.solr.tracker.DocRouterFactory.SHARD_KEY_KEY; - /** * Superclass for all components which are able to inform Alfresco about the hosting node state. * This has been introduced in SEARCH-1752 for splitting the dual responsibility of the {@link MetadataTracker}. diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/SlaveNodeStateProvider.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/SlaveNodeStateProvider.java index c9ac8567a..2b9d24272 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/SlaveNodeStateProvider.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/SlaveNodeStateProvider.java @@ -1,10 +1,15 @@ package org.alfresco.solr.tracker; +import static org.alfresco.solr.tracker.Tracker.Type.NODE_STATE_PUBLISHER; + import org.alfresco.httpclient.AuthenticationException; import org.alfresco.repo.index.shard.ShardState; +import org.alfresco.solr.SolrInformationServer; +import org.alfresco.solr.client.SOLRAPIClient; import org.apache.commons.codec.EncoderException; import java.io.IOException; +import java.util.Properties; /** * Despite belonging to the Tracker ecosystem, this component is actually a publisher, which periodically informs @@ -21,8 +26,13 @@ import java.io.IOException; * @author Andrea Gazzarini * @since 1.5 */ -public class SlaveNodeStateProvider extends MetadataTracker +public class SlaveNodeStateProvider extends NodeStateProvider { + public SlaveNodeStateProvider(Properties coreProperties, SOLRAPIClient repositoryClient, String name, SolrInformationServer informationServer) + { + super(coreProperties, repositoryClient, name, informationServer, NODE_STATE_PUBLISHER); + } + @Override protected void doTrack() { diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/SolrTrackerScheduler.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/SolrTrackerScheduler.java index 78d2683ab..2038091c5 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/SolrTrackerScheduler.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/SolrTrackerScheduler.java @@ -76,18 +76,20 @@ public class SolrTrackerScheduler { log.error("Failed to schedule " + jobType + " Job.", e); } + private String getCron(Properties props, String cronType) { String cron = props.getProperty(cronType); - return cron == null ? props.getProperty("alfresco.cron",DEFAULT_CRON) : cron; + return cron == null ? props.getProperty("alfresco.cron", DEFAULT_CRON) : cron; } + /** * Schedules individual trackers based on the solrcore properties. * * @author Michael Suzuki - * @param tracker - * @param coreName - * @param props + * @param tracker the tracker to bo scheduled. + * @param coreName the owning core name. + * @param props the core properties. */ public void schedule(Tracker tracker, String coreName, Properties props) { @@ -98,27 +100,30 @@ public class SolrTrackerScheduler Trigger trigger; try { - String cron = null; + String cron; switch (tracker.getType()) { case ACL: cron = getCron(props,"alfresco.acl.tracker.cron"); break; - case Model: + case MODEL: cron = getCron(props,"alfresco.model.tracker.cron"); break; - case Content: + case CONTENT: cron = getCron(props,"alfresco.content.tracker.cron"); break; - case MetaData: + case METADATA: cron = getCron(props,"alfresco.metadata.tracker.cron"); break; - case Cascade: + case CASCADE: cron = getCron(props,"alfresco.cascade.tracker.cron"); break; - case Commit: + case COMMIT: cron = getCron(props,"alfresco.commit.tracker.cron"); break; + case NODE_STATE_PUBLISHER: + cron = getCron(props,"alfresco.nodestate.tracker.cron"); + break; default: cron = props.getProperty("alfresco.cron",DEFAULT_CRON); break; @@ -161,7 +166,7 @@ public class SolrTrackerScheduler * identical to the instance that is passed in. If they are identical then the job is deleted. * Otherwise, another core (of the same name) scheduled this job, so its left alone. * - * @param coreName + * @param coreName the core name. * @param tracker Specific instance of a tracker */ public void deleteJobForTrackerInstance(String coreName, Tracker tracker) From 843dc10987792da2876e78fb664d327b6fbca627 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 21 Oct 2019 00:20:48 +0000 Subject: [PATCH 14/42] Bump utility from 3.0.12 to 3.0.13 in /e2e-test Bumps [utility](https://github.com/Alfresco/alfresco-tas-utility) from 3.0.12 to 3.0.13. - [Release notes](https://github.com/Alfresco/alfresco-tas-utility/releases) - [Changelog](https://github.com/Alfresco/alfresco-tas-utility/blob/master/docs/CHANGELOG.md) - [Commits](https://github.com/Alfresco/alfresco-tas-utility/compare/utility-3.0.12...utility-3.0.13) Signed-off-by: dependabot-preview[bot] --- e2e-test/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e-test/pom.xml b/e2e-test/pom.xml index 456a86403..e1d9aed00 100644 --- a/e2e-test/pom.xml +++ b/e2e-test/pom.xml @@ -13,7 +13,7 @@ 6.0.1.2 6.0.0.4 - 3.0.12 + 3.0.13 3.2.0-SNAPSHOT From 091afab426eac5a555afd567625490c9b476cdd8 Mon Sep 17 00:00:00 2001 From: agazzarini Date: Tue, 22 Oct 2019 16:25:30 +0100 Subject: [PATCH 15/42] [ SEARCH-1752 ] TrackerState got updated on slaves + remove unused configuration properties --- .../app/templates/images/search/Dockerfile | 4 +--- .../trackers/00001-content-tracker.md | 2 -- .../solr/lifecycle/SolrCoreLoadListener.java | 6 ++--- .../solr/tracker/AbstractTracker.java | 20 ++++------------ .../org/alfresco/solr/tracker/AclTracker.java | 5 ---- .../solr/tracker/MetadataTracker.java | 4 ++-- .../solr/tracker/NodeStateProvider.java | 8 ++++++- .../solr/tracker/SlaveNodeStateProvider.java | 23 +++++++++++++++++-- .../solr/tracker/MetadataTrackerTest.java | 13 ++++++----- .../solr/tracker/ModelTrackerTest.java | 2 -- .../tracker/SolrTrackerSchedulerTest.java | 4 +--- 11 files changed, 47 insertions(+), 44 deletions(-) diff --git a/e2e-test/generator-alfresco-docker-compose/generators/app/templates/images/search/Dockerfile b/e2e-test/generator-alfresco-docker-compose/generators/app/templates/images/search/Dockerfile index d43b4f910..163f75682 100755 --- a/e2e-test/generator-alfresco-docker-compose/generators/app/templates/images/search/Dockerfile +++ b/e2e-test/generator-alfresco-docker-compose/generators/app/templates/images/search/Dockerfile @@ -54,7 +54,6 @@ ENV MASTER_HOST $MASTER_HOST # Set Master / Slave configuration for this Node RUN if [ "$ENABLE_MASTER" == "true" ] ; then \ - sed -i '/^bash.*/i echo "\nenable.master=${ENABLE_MASTER}\nenable.slave=${ENABLE_SLAVE}" >> ${DIST_DIR}/solrhome/templates/rerank/conf/solrcore.properties\n' \ ${DIST_DIR}/solr/bin/search_config_setup.sh; \ sed -i "/^bash.*/i sed -i '/^\\\\\s*\ @@ -64,7 +63,6 @@ RUN if [ "$ENABLE_MASTER" == "true" ] ; then \ ' ${DIST_DIR}/solrhome/templates/rerank/conf/solrconfig.xml\n" ${DIST_DIR}/solr/bin/search_config_setup.sh; \ fi RUN if [ "$ENABLE_SLAVE" == "true" ] ; then \ - sed -i '/^bash.*/i echo "\nenable.master=${ENABLE_MASTER}\nenable.slave=${ENABLE_SLAVE}" >> ${DIST_DIR}/solrhome/templates/rerank/conf/solrcore.properties\n' \ ${DIST_DIR}/solr/bin/search_config_setup.sh; \ sed -i "/^bash.*/i sed -i '/^\\\\\s*\ @@ -131,4 +129,4 @@ fi RUN mkdir ${DIST_DIR}/keystore \ && chown -R solr:solr ${DIST_DIR}/keystore -VOLUME ["${DIST_DIR}/keystore"] \ No newline at end of file +VOLUME ["${DIST_DIR}/keystore"] diff --git a/search-services/alfresco-search/doc/architecture/trackers/00001-content-tracker.md b/search-services/alfresco-search/doc/architecture/trackers/00001-content-tracker.md index 77c0159cb..e267a79a9 100644 --- a/search-services/alfresco-search/doc/architecture/trackers/00001-content-tracker.md +++ b/search-services/alfresco-search/doc/architecture/trackers/00001-content-tracker.md @@ -150,8 +150,6 @@ The following table illustrates the configuration properties used by the Tracker |alfresco.stores|workspace://SpacesStore|The reference to a node store| | |Y|Y| | | |batch.count|5000|UpSert batch size (e.g. metadata docs, acls)| | |Y|Y| | | |alfresco.maxLiveSearchers|2|Max allowed number of active searchers|Y| |Y|Y| | | -|enable.slave|false|Indicates if the hosting instance is a slave| | |Y|Y| | | -|enable.master|true|Indicates if the hosting instance is a master| | |Y|Y| | | |shard.count|1|The total number of shards that compose the Solr infrastructure|| |Y|Y| | | |shard.instance|0|The unique shard identifier assigned to this instance|| |Y|Y| | | |shard.method|"DB_ID"|Data (Documents, ACLs) Routing criteria among shards| | |Y|Y| | | diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/lifecycle/SolrCoreLoadListener.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/lifecycle/SolrCoreLoadListener.java index eacac1570..53f0cf131 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/lifecycle/SolrCoreLoadListener.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/lifecycle/SolrCoreLoadListener.java @@ -159,7 +159,7 @@ public class SolrCoreLoadListener extends AbstractSolrEventListener { LOGGER.info("SearchServices Core Trackers have been disabled on core \"{}\" because it is a slave core.", core.getName()); - SlaveNodeStateProvider stateProvider = new SlaveNodeStateProvider(coreProperties, repositoryClient, core.getName(), informationServer); + SlaveNodeStateProvider stateProvider = new SlaveNodeStateProvider(false, coreProperties, repositoryClient, core.getName(), informationServer); trackerRegistry.register(core.getName(), stateProvider); scheduler.schedule(stateProvider, core.getName(), coreProperties); @@ -206,7 +206,7 @@ public class SolrCoreLoadListener extends AbstractSolrEventListener trackerRegistry.register(coreName, contentTrkr); scheduler.schedule(contentTrkr, coreName, props); - MetadataTracker metaTrkr = new MetadataTracker(props, repositoryClient, coreName, srv); + MetadataTracker metaTrkr = new MetadataTracker(true, props, repositoryClient, coreName, srv); trackerRegistry.register(coreName, metaTrkr); scheduler.schedule(metaTrkr, coreName, props); @@ -289,7 +289,7 @@ public class SolrCoreLoadListener extends AbstractSolrEventListener } /** - * Checks if the content store belonging to the hosting Solr node must be set in read only mode. + * Checks if the configuration declares this node as a slave. * * @param core the hosting {@link SolrCore} instance. * @return true if the content store must be set in read only mode, false otherwise. diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/AbstractTracker.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/AbstractTracker.java index ae944dd4b..a4bb8c8e0 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/AbstractTracker.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/AbstractTracker.java @@ -31,7 +31,6 @@ import org.alfresco.solr.client.SOLRAPIClient; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - /** * Abstract base class that provides common {@link Tracker} behaviour. * @@ -39,20 +38,17 @@ import org.slf4j.LoggerFactory; */ public abstract class AbstractTracker implements Tracker { - public static final long TIME_STEP_32_DAYS_IN_MS = 1000 * 60 * 60 * 24 * 32L; - public static final long TIME_STEP_1_HR_IN_MS = 60 * 60 * 1000L; - public static final String SHARD_METHOD_ACLID = "ACL_ID"; - public static final String SHARD_METHOD_DBID = "DB_ID"; + static final long TIME_STEP_32_DAYS_IN_MS = 1000 * 60 * 60 * 24 * 32L; + static final long TIME_STEP_1_HR_IN_MS = 60 * 60 * 1000L; + static final String SHARD_METHOD_DBID = "DB_ID"; protected final static Logger log = LoggerFactory.getLogger(AbstractTracker.class); protected Properties props; protected SOLRAPIClient client; - protected InformationServer infoSrv; + InformationServer infoSrv; protected String coreName; protected StoreRef storeRef; protected long batchCount; - protected boolean isSlave = false; - protected boolean isMaster = true; protected String alfrescoVersion; protected TrackerStats trackerStats; protected boolean runPostModelLoadInit = true; @@ -71,14 +67,10 @@ public abstract class AbstractTracker implements Tracker protected volatile boolean rollback; protected final Type type; - /* * A thread handler can be used by subclasses, but they have to intentionally instantiate it. */ - protected ThreadHandler threadHandler; - - - + ThreadHandler threadHandler; /** * Default constructor, strictly for testing. @@ -98,8 +90,6 @@ public abstract class AbstractTracker implements Tracker storeRef = new StoreRef(p.getProperty("alfresco.stores", "workspace://SpacesStore")); batchCount = Integer.parseInt(p.getProperty("alfresco.batch.count", "5000")); maxLiveSearchers = Integer.parseInt(p.getProperty("alfresco.maxLiveSearchers", "2")); - isSlave = Boolean.parseBoolean(p.getProperty("enable.slave", "false")); - isMaster = Boolean.parseBoolean(p.getProperty("enable.master", "true")); shardCount = Integer.parseInt(p.getProperty("shard.count", "1")); shardInstance = Integer.parseInt(p.getProperty("shard.instance", "0")); diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/AclTracker.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/AclTracker.java index f21ef9085..7851920cd 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/AclTracker.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/AclTracker.java @@ -288,11 +288,6 @@ public class AclTracker extends AbstractTracker protected void trackRepository() throws IOException, AuthenticationException, JSONException { checkShutdown(); - - if(!isMaster && isSlave) - { - return; - } TrackerState state = super.getTrackerState(); diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/MetadataTracker.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/MetadataTracker.java index 39d251b03..36d092d7a 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/MetadataTracker.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/MetadataTracker.java @@ -64,10 +64,10 @@ public class MetadataTracker extends NodeStateProvider implements Tracker private ConcurrentLinkedQueue nodesToPurge = new ConcurrentLinkedQueue<>(); private ConcurrentLinkedQueue queriesToReindex = new ConcurrentLinkedQueue<>(); - public MetadataTracker(Properties p, SOLRAPIClient client, String coreName, + public MetadataTracker(final boolean isMaster, Properties p, SOLRAPIClient client, String coreName, InformationServer informationServer) { - super(p, client, coreName, informationServer, Tracker.Type.METADATA); + super(isMaster, p, client, coreName, informationServer, Tracker.Type.METADATA); transactionDocsBatchSize = Integer.parseInt(p.getProperty("alfresco.transactionDocsBatchSize", "100")); nodeBatchSize = Integer.parseInt(p.getProperty("alfresco.nodeBatchSize", "10")); threadHandler = new ThreadHandler(p, coreName, "MetadataTracker"); diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/NodeStateProvider.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/NodeStateProvider.java index ad0cbaebf..c64e03d17 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/NodeStateProvider.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/NodeStateProvider.java @@ -62,6 +62,7 @@ import java.util.Properties; public abstract class NodeStateProvider extends AbstractTracker { DocRouter docRouter; + private final boolean isMaster; /** The string representation of the shard key. */ private Optional shardKey; @@ -70,6 +71,7 @@ public abstract class NodeStateProvider extends AbstractTracker protected Optional shardProperty = Optional.empty(); NodeStateProvider( + boolean isMaster, Properties p, SOLRAPIClient client, String coreName, @@ -77,15 +79,19 @@ public abstract class NodeStateProvider extends AbstractTracker Type type) { super(p, client, coreName, informationServer, type); + this.isMaster = isMaster; shardMethod = p.getProperty("shard.method", SHARD_METHOD_DBID); shardKey = ofNullable(p.getProperty(SHARD_KEY_KEY)); + firstUpdateShardProperty(); + docRouter = DocRouterFactory.getRouter(p, ShardMethodEnum.getShardMethod(shardMethod)); } NodeStateProvider(Type type) { super(type); + this.isMaster = false; } private void firstUpdateShardProperty() @@ -168,7 +174,7 @@ public abstract class NodeStateProvider extends AbstractTracker */ ShardState getShardState() { - TrackerState transactionsTrackerState = super.getTrackerState(); + TrackerState transactionsTrackerState = getTrackerState(); TrackerState changeSetsTrackerState = of(infoSrv.getAdminHandler()) .map(AlfrescoCoreAdminHandler::getTrackerRegistry) diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/SlaveNodeStateProvider.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/SlaveNodeStateProvider.java index 2b9d24272..0650aef40 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/SlaveNodeStateProvider.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/SlaveNodeStateProvider.java @@ -5,6 +5,7 @@ import static org.alfresco.solr.tracker.Tracker.Type.NODE_STATE_PUBLISHER; import org.alfresco.httpclient.AuthenticationException; import org.alfresco.repo.index.shard.ShardState; import org.alfresco.solr.SolrInformationServer; +import org.alfresco.solr.TrackerState; import org.alfresco.solr.client.SOLRAPIClient; import org.apache.commons.codec.EncoderException; @@ -28,9 +29,14 @@ import java.util.Properties; */ public class SlaveNodeStateProvider extends NodeStateProvider { - public SlaveNodeStateProvider(Properties coreProperties, SOLRAPIClient repositoryClient, String name, SolrInformationServer informationServer) + public SlaveNodeStateProvider( + boolean isMaster, + Properties coreProperties, + SOLRAPIClient repositoryClient, + String name, + SolrInformationServer informationServer) { - super(coreProperties, repositoryClient, name, informationServer, NODE_STATE_PUBLISHER); + super(isMaster, coreProperties, repositoryClient, name, informationServer, NODE_STATE_PUBLISHER); } @Override @@ -72,4 +78,17 @@ public class SlaveNodeStateProvider extends NodeStateProvider { return false; } + + /** + * When running in a slave mode, we need to recreate the tracker state every time. + * This because in that context we don't have any tracker updating the state (e.g. lastIndexedChangeSetCommitTime, + * lastIndexedChangeSetId) + * + * @return a new, fresh and up to date instance of {@link TrackerState}. + */ + @Override + public TrackerState getTrackerState() + { + return infoSrv.getTrackerInitialState(); + } } \ No newline at end of file diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/MetadataTrackerTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/MetadataTrackerTest.java index 56f444a9d..5c68f5974 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/MetadataTrackerTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/MetadataTrackerTest.java @@ -47,7 +47,7 @@ import org.junit.runner.RunWith; import org.mockito.InOrder; import org.mockito.Mock; import org.mockito.Spy; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; @RunWith(MockitoJUnitRunner.class) public class MetadataTrackerTest @@ -58,20 +58,23 @@ public class MetadataTrackerTest @Mock private SOLRAPIClient repositoryClient; - private String coreName = "theCoreName"; + @Mock private InformationServer srv; + @Spy private Properties props; + @Mock private TrackerStats trackerStats; @Before - public void setUp() throws Exception + public void setUp() { doReturn("workspace://SpacesStore").when(props).getProperty("alfresco.stores"); when(srv.getTrackerStats()).thenReturn(trackerStats); - this.metadataTracker = spy(new MetadataTracker(props, repositoryClient, coreName, srv)); + String coreName = "theCoreName"; + this.metadataTracker = spy(new MetadataTracker(true, props, repositoryClient, coreName, srv)); ModelTracker modelTracker = mock(ModelTracker.class); when(modelTracker.hasModels()).thenReturn(true); @@ -197,6 +200,4 @@ public class MetadataTrackerTest assertSame(nodes4Tx, nodes); } - - } diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/ModelTrackerTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/ModelTrackerTest.java index 318eb27f5..71ee93280 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/ModelTrackerTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/ModelTrackerTest.java @@ -102,8 +102,6 @@ public class ModelTrackerTest when(props.getProperty("alfresco.stores", "workspace://SpacesStore")).thenReturn("workspace://SpacesStore"); when(props.getProperty("alfresco.batch.count", "5000")).thenReturn("5000"); when(props.getProperty("alfresco.maxLiveSearchers", "2")).thenReturn("2"); - when(props.getProperty("enable.slave", "false")).thenReturn("false"); - when(props.getProperty("enable.master", "true")).thenReturn("true"); when(props.getProperty("shard.count", "1")).thenReturn("1"); when(props.getProperty("shard.instance", "0")).thenReturn("0"); when(this.srv.getTrackerStats()).thenReturn(trackerStats); diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/SolrTrackerSchedulerTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/SolrTrackerSchedulerTest.java index 822b01a32..e685b14be 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/SolrTrackerSchedulerTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/SolrTrackerSchedulerTest.java @@ -73,8 +73,6 @@ public class SolrTrackerSchedulerTest props.put("alfresco.stores", "workspace://SpacesStore"); props.put("alfresco.batch.count", "5000"); props.put("alfresco.maxLiveSearchers", "2"); - props.put("enable.slave", "false"); - props.put("enable.master", "true"); props.put("shard.count", "1"); props.put("shard.instance", "0"); props.put("shard.method", "SHARD_METHOD_DBID"); @@ -128,7 +126,7 @@ public class SolrTrackerSchedulerTest { String exp = "0/4 * * * * ? *"; props.put("alfresco.metadata.tracker.cron", exp); - MetadataTracker metadataTracker = new MetadataTracker(props, client, exp, informationServer); + MetadataTracker metadataTracker = new MetadataTracker(true, props, client, exp, informationServer); this.trackerScheduler.schedule(metadataTracker, CORE_NAME, props); verify(spiedQuartzScheduler).scheduleJob(any(JobDetail.class), any(Trigger.class)); checkCronExpression(exp); From da023e9335f92b6d4331491c8dd45c690e1c1ce2 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 23 Oct 2019 21:12:24 +0000 Subject: [PATCH 16/42] Bump randomizedtesting-runner from 2.7.3 to 2.7.4 in /search-services Bumps randomizedtesting-runner from 2.7.3 to 2.7.4. Signed-off-by: dependabot-preview[bot] --- search-services/alfresco-search/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/search-services/alfresco-search/pom.xml b/search-services/alfresco-search/pom.xml index c2ad31797..1a041e2f9 100644 --- a/search-services/alfresco-search/pom.xml +++ b/search-services/alfresco-search/pom.xml @@ -120,7 +120,7 @@ com.carrotsearch.randomizedtesting randomizedtesting-runner - 2.7.3 + 2.7.4 test From c829993e835b515a7095cf197c32e4d2e243eae2 Mon Sep 17 00:00:00 2001 From: agazzarini Date: Tue, 29 Oct 2019 10:26:59 +0100 Subject: [PATCH 17/42] [ SEARCH-1606 ] Fix on core close hook + more logging about the trackers lifecycle. --- .../solr/AlfrescoCoreAdminHandler.java | 5 +- .../solr/lifecycle/SolrCoreLoadListener.java | 183 +++++++++++++++--- .../solr/tracker/AbstractTracker.java | 7 +- .../org/alfresco/solr/tracker/Tracker.java | 4 +- .../lifecycle/SolrCoreLoadListenerTest.java | 4 +- 5 files changed, 170 insertions(+), 33 deletions(-) diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/AlfrescoCoreAdminHandler.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/AlfrescoCoreAdminHandler.java index 9255db2a0..f714307dc 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/AlfrescoCoreAdminHandler.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/AlfrescoCoreAdminHandler.java @@ -224,10 +224,7 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler MultiThreadedHttpConnectionManager.shutdownAll(); //Remove any core trackers still hanging around - trackerRegistry.getCoreNames().forEach(coreName -> - { - trackerRegistry.removeTrackersForCore(coreName); - }); + trackerRegistry.getCoreNames().forEach(coreName -> trackerRegistry.removeTrackersForCore(coreName)); //Remove any information servers informationServers.clear(); diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/lifecycle/SolrCoreLoadListener.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/lifecycle/SolrCoreLoadListener.java index c1ec3719d..26eb0776d 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/lifecycle/SolrCoreLoadListener.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/lifecycle/SolrCoreLoadListener.java @@ -82,6 +82,21 @@ public class SolrCoreLoadListener extends AbstractSolrEventListener @Override public void newSearcher(SolrIndexSearcher newSearcher, SolrIndexSearcher currentSearcher) { + if (getCore().isReloaded()) + { + LOGGER.info("Solr Core {}, instance {} has been reloaded. " + + "The previous tracking subsystem will be stopped and another set of trackers will be registered on this new instance.", + getCore().getName(), + getCore().hashCode()); + } + else + { + LOGGER.info("Solr Core {}, instance {}, has been registered for the first time. " + + "Tracking subsystem will be registered on this new instance.", + getCore().getName(), + getCore().hashCode()); + } + CoreContainer coreContainer = getCore().getCoreContainer(); AlfrescoCoreAdminHandler admin = (AlfrescoCoreAdminHandler) coreContainer.getMultiCoreHandler(); SolrCore core = getCore(); @@ -135,22 +150,34 @@ public class SolrCoreLoadListener extends AbstractSolrEventListener return; } - LOGGER.info("SearchServices Tracking Subsystem starts on core {}", core.getName()); if (trackerRegistry.hasTrackersForCore(core.getName())) { - LOGGER.info("Trackers for " + core.getName()+ " is already registered, shutting them down."); - shutdownTrackers(core.getName(), trackerRegistry.getTrackersForCore(core.getName()), scheduler); + LOGGER.info("Trackers for " + core.getName() + " are already registered, shutting them down."); + Collection alreadyRegisteredTrackers = trackerRegistry.getTrackersForCore(core.getName()); trackerRegistry.removeTrackersForCore(core.getName()); + + shutdownTrackers(core, alreadyRegisteredTrackers, scheduler, core.isReloaded()); admin.getInformationServers().remove(core.getName()); } - final List trackers = createCoreTrackers(core.getName(), trackerRegistry, coreProperties, scheduler, repositoryClient, informationServer); + LOGGER.info("SearchServices Tracking Subsystem starts on Solr Core instance {} with name {}", core.hashCode(), core.getName()); + + // Re-put the information server in the map because a Core reload (see above) could have removed the reference. + admin.getInformationServers().put(core.getName(), informationServer); + + final List trackers = createAndScheduleCoreTrackers(core, trackerRegistry, coreProperties, scheduler, repositoryClient, informationServer); CommitTracker commitTracker = new CommitTracker(coreProperties, repositoryClient, core.getName(), informationServer, trackers); trackerRegistry.register(core.getName(), commitTracker); scheduler.schedule(commitTracker, core.getName(), coreProperties); - LOGGER.info("SearchServices Core Trackers have been correctly registered and scheduled."); + LOGGER.info("Tracker {}, instance {}, belonging to Core {}, instance {} has been registered and scheduled.", + commitTracker.getClass().getSimpleName(), + commitTracker.hashCode(), + core.getName(), + core.hashCode()); + + LOGGER.info("SearchServices Core Trackers have been correctly registered and scheduled on Solr Core instance {} with name {}", core.hashCode(), core.getName()); //Add the commitTracker to the list of scheduled trackers that can be shutdown trackers.add(commitTracker); @@ -160,44 +187,70 @@ public class SolrCoreLoadListener extends AbstractSolrEventListener @Override public void preClose(SolrCore core) { - LOGGER.info("Tracking Subsystem shutdown procedure for core {} has been started.", core.getName()); - shutdownTrackers(core.getName(), trackers, scheduler); + LOGGER.info("Solr Core instance {} with name {} is going to be closed. Tracking Subsystem shutdown callback procedure has been started.", core.hashCode(), core.getName()); + + // IMPORTANT: the closure needs to be created with the trackers created in this method + shutdownTrackers(core, trackers, scheduler, false); } @Override public void postClose(SolrCore core) { - LOGGER.info("Shutdown procedure for core {} has been completed.", core.getName()); + LOGGER.info("Solr Core instance {} with name {} has been closed. Tracking Subsystem shutdown callback procedure has been completed.", core.hashCode(), core.getName()); } }); - } - List createCoreTrackers(String coreName, - TrackerRegistry trackerRegistry, - Properties props, - SolrTrackerScheduler scheduler, - SOLRAPIClient repositoryClient, - SolrInformationServer srv) + List createAndScheduleCoreTrackers(SolrCore core, + TrackerRegistry trackerRegistry, + Properties props, + SolrTrackerScheduler scheduler, + SOLRAPIClient repositoryClient, + SolrInformationServer srv) { List trackers = new ArrayList<>(); + String coreName = core.getName(); AclTracker aclTracker = new AclTracker(props, repositoryClient, coreName, srv); trackerRegistry.register(coreName, aclTracker); scheduler.schedule(aclTracker, coreName, props); + LOGGER.info("Tracker {}, instance {}, belonging to Core {}, instance {} has been registered and scheduled.", + aclTracker.getClass().getSimpleName(), + aclTracker.hashCode(), + core.getName(), + core.hashCode()); + ContentTracker contentTrkr = new ContentTracker(props, repositoryClient, coreName, srv); trackerRegistry.register(coreName, contentTrkr); scheduler.schedule(contentTrkr, coreName, props); + LOGGER.info("Tracker {}, instance {}, belonging to Core {}, instance {} has been registered and scheduled.", + contentTrkr.getClass().getSimpleName(), + contentTrkr.hashCode(), + core.getName(), + core.hashCode()); + MetadataTracker metaTrkr = new MetadataTracker(props, repositoryClient, coreName, srv); trackerRegistry.register(coreName, metaTrkr); scheduler.schedule(metaTrkr, coreName, props); + LOGGER.info("Tracker {}, instance {}, belonging to Core {}, instance {} has been registered and scheduled.", + metaTrkr.getClass().getSimpleName(), + metaTrkr.hashCode(), + core.getName(), + core.hashCode()); + CascadeTracker cascadeTrkr = new CascadeTracker(props, repositoryClient, coreName, srv); trackerRegistry.register(coreName, cascadeTrkr); scheduler.schedule(cascadeTrkr, coreName, props); + LOGGER.info("Tracker {}, instance {}, belonging to Core {}, instance {} has been registered and scheduled.", + cascadeTrkr.getClass().getSimpleName(), + cascadeTrkr.hashCode(), + core.getName(), + core.hashCode()); + //The CommitTracker will acquire these locks in order //The ContentTracker will likely have the longest runs so put it first to ensure the MetadataTracker is not paused while //waiting for the ContentTracker to release it's lock. @@ -246,32 +299,112 @@ public class SolrCoreLoadListener extends AbstractSolrEventListener * have multiple cores of the same name running. Left over trackers in the registry are cleaned up by the CoreContainer * shutdown, that happens in the the AlfrescoCoreAdminHandler.shutdown(). * - * @param coreName The name of the core + * The coreHasBeenReloaded flag is used just for logging out meaningful messages about the owning core instance. + * If we are in a RELOAD scenario (coreHasBeenReloaded = true) we no longer have the reference of the closed core + * so we print only its name. Instead in case we are here because a core has been closed, we can print out the core + * reference in order to add meaningful information in the log. + * + * @param core The owning core name. * @param coreTrackers A collection of trackers * @param scheduler The scheduler + * @param coreHasBeenReloaded a flag indicating if we are on a Core RELOAD scenario. */ - void shutdownTrackers(String coreName, Collection coreTrackers, SolrTrackerScheduler scheduler) + void shutdownTrackers(SolrCore core, Collection coreTrackers, SolrTrackerScheduler scheduler, boolean coreHasBeenReloaded) { + coreTrackers.forEach(tracker -> shutdownTracker(core, tracker, scheduler, coreHasBeenReloaded)); + } + + /** + * Shutdown procedure for a single tracker. + * The coreHasBeenReloaded flag is used just for logging out meaningful messages about the owning core instance. + * If we are in a RELOAD scenario (coreHasBeenReloaded = true) we no longer have the reference of the closed core + * so we print only its name. Instead in case we are here because a core has been closed, we can print out the core + * reference in order to add meaningful information in the log. + * + * @param core the owning {@link SolrCore} + * @param tracker the {@link Tracker} instance we want to stop. + * @param scheduler the scheduler. + * @param coreHasBeenReloaded a flag indicating if we are on a Core RELOAD scenario. + */ + private void shutdownTracker(SolrCore core, Tracker tracker, SolrTrackerScheduler scheduler, boolean coreHasBeenReloaded) + { + if (tracker.isAlreadyInShutDownMode()) + { + LOGGER.info("Tracker {}, instance {} belonging to core {}, instance {}, is already in shutdown mode.", + tracker.getClass().getSimpleName(), + tracker.hashCode(), + core.getName(), + core.hashCode()); + return; + } + + // Just differentiate the log message: in case of reload the input core is not the owner: the owner + // is instead the previous (closed) core and we don't have its reference here. + if (coreHasBeenReloaded) + { + LOGGER.info("Tracker {}, instance {} belonging to core {} shutdown procedure initiated." + + " If you reloaded the core that is probably the reason you're seeing this message.", + tracker.getClass().getSimpleName(), + tracker.hashCode(), + core.getName()); + } + else + { + LOGGER.info("Tracker {}, instance {} belonging to core {}, instance {}, shutdown procedure initiated.", + tracker.getClass().getSimpleName(), + tracker.hashCode(), + core.getName(), + core.hashCode()); + } + try { - LOGGER.info("Shutting down Trackers Subsystem for core \"{}\" which contains {} core trackers.", coreName, coreTrackers.size()); - - // Sets the shutdown flag on the trackers to stop them from doing any more work - coreTrackers.forEach(tracker -> tracker.setShutdown(true)); - + tracker.setShutdown(true); if (!scheduler.isShutdown()) { - coreTrackers.forEach(tracker -> scheduler.deleteJobForTrackerInstance(coreName, tracker) ); + scheduler.deleteJobForTrackerInstance(core.getName(), tracker); } - coreTrackers.forEach(Tracker::shutdown); + tracker.shutdown(); + + if (coreHasBeenReloaded) + { + LOGGER.info("Tracker {}, instance {}, belonging to core {} shutdown procedure correctly terminated.", + tracker.getClass().getSimpleName(), + tracker.hashCode(), + core.getName()); + } + else + { + LOGGER.info("Tracker {}, instance {} belonging to core {}, instance {}, shutdown procedure correctly terminated.", + tracker.getClass().getSimpleName(), + tracker.hashCode(), + core.getName(), + core.hashCode()); + } } catch (Exception e) { - LOGGER.error("Tracking Subsystem shutdown procedure failed to shutdown trackers for core {}. See the stacktrace below for further details.", coreName, e); + if (coreHasBeenReloaded) + { + LOGGER.info("Tracker {}, instance {} belonging to core {} shutdown procedure correctly terminated.", + tracker.getClass().getSimpleName(), + tracker.hashCode(), + core.getName()); + } + else + { + LOGGER.error("Tracker {}, instance {} belonging to core {}, instance {}, shutdown procedure failed. " + + "See the stacktrace below for further details.", + tracker.getClass().getSimpleName(), + tracker.hashCode(), + core.getName(), + core.hashCode(), e); + } } } + /** * Checks if the content store belonging to the hosting Solr node must be set in read only mode. * diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/AbstractTracker.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/AbstractTracker.java index ae944dd4b..d4de08a72 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/AbstractTracker.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/AbstractTracker.java @@ -328,6 +328,12 @@ public abstract class AbstractTracker implements Tracker } } + @Override + public boolean isAlreadyInShutDownMode() + { + return shutdown; + } + @Override public void setShutdown(boolean shutdown) { @@ -337,7 +343,6 @@ public abstract class AbstractTracker implements Tracker @Override public void shutdown() { - log.warn("Core " + coreName + " shutdown called on tracker. " + getClass().getSimpleName() + " " + hashCode()); setShutdown(true); if(this.threadHandler != null) { diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/Tracker.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/Tracker.java index 9f6654121..3c10af6c6 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/Tracker.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/Tracker.java @@ -36,7 +36,9 @@ public interface Tracker String getAlfrescoVersion(); void setShutdown(boolean shutdown); - + + boolean isAlreadyInShutDownMode(); + void shutdown(); boolean getRollback(); diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/lifecycle/SolrCoreLoadListenerTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/lifecycle/SolrCoreLoadListenerTest.java index 8462aefc0..e1ec88140 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/lifecycle/SolrCoreLoadListenerTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/lifecycle/SolrCoreLoadListenerTest.java @@ -92,7 +92,7 @@ public class SolrCoreLoadListenerTest @Test public void coreTrackersRegistrationAndScheduling() { - List coreTrackers = listener.createCoreTrackers(core.getName(), registry, coreProperties, scheduler, api, informationServer); + List coreTrackers = listener.createAndScheduleCoreTrackers(core, registry, coreProperties, scheduler, api, informationServer); verify(registry).register(eq(coreName), any(AclTracker.class)); verify(registry).register(eq(coreName), any(ContentTracker.class)); @@ -113,7 +113,7 @@ public class SolrCoreLoadListenerTest List coreTrackers = asList(mock(AclTracker.class), mock(ContentTracker.class), mock(MetadataTracker.class), mock(CascadeTracker.class)); - listener.shutdownTrackers(coreName, coreTrackers, scheduler); + listener.shutdownTrackers(core, coreTrackers, scheduler, false); coreTrackers.forEach(tracker -> verify(tracker).setShutdown(true)); coreTrackers.forEach(tracker -> verify(scheduler).deleteJobForTrackerInstance(core.getName(), tracker)); From b450dce5d604491c95ae682f86c4fba2e0a193ee Mon Sep 17 00:00:00 2001 From: Tom Page Date: Tue, 29 Oct 2019 10:05:35 +0000 Subject: [PATCH 18/42] Update to use released AGS 3.2.0. --- e2e-test/pom.xml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/e2e-test/pom.xml b/e2e-test/pom.xml index e1d9aed00..aa7f12854 100644 --- a/e2e-test/pom.xml +++ b/e2e-test/pom.xml @@ -14,9 +14,7 @@ 6.0.1.2 6.0.0.4 3.0.13 - - 3.2.0-SNAPSHOT + 3.2.0 src/test/resources/SearchSuite.xml From 5894812fd590d1175d791f8a6c5e8ef9ed63b8a7 Mon Sep 17 00:00:00 2001 From: agazzarini Date: Tue, 29 Oct 2019 11:57:43 +0100 Subject: [PATCH 19/42] [ SEARCH-1752 ] Manage core reload (publisher registration and re-registration) --- .../solr/lifecycle/SolrCoreLoadListener.java | 50 +++++++++++-------- ...ider.java => SlaveNodeStatePublisher.java} | 4 +- 2 files changed, 31 insertions(+), 23 deletions(-) rename search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/{SlaveNodeStateProvider.java => SlaveNodeStatePublisher.java} (97%) diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/lifecycle/SolrCoreLoadListener.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/lifecycle/SolrCoreLoadListener.java index b45682434..666255ec5 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/lifecycle/SolrCoreLoadListener.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/lifecycle/SolrCoreLoadListener.java @@ -34,7 +34,7 @@ import org.alfresco.solr.tracker.CommitTracker; import org.alfresco.solr.tracker.ContentTracker; import org.alfresco.solr.tracker.MetadataTracker; import org.alfresco.solr.tracker.ModelTracker; -import org.alfresco.solr.tracker.SlaveNodeStateProvider; +import org.alfresco.solr.tracker.SlaveNodeStatePublisher; import org.alfresco.solr.tracker.SolrTrackerScheduler; import org.alfresco.solr.tracker.Tracker; import org.alfresco.solr.tracker.TrackerRegistry; @@ -92,8 +92,7 @@ public class SolrCoreLoadListener extends AbstractSolrEventListener } else { - LOGGER.info("Solr Core {}, instance {}, has been registered for the first time. " + - "Tracking subsystem will be registered on this new instance.", + LOGGER.info("Solr Core {}, instance {}, has been registered for the first time.", getCore().getName(), getCore().hashCode()); } @@ -163,11 +162,32 @@ public class SolrCoreLoadListener extends AbstractSolrEventListener boolean trackersHaveBeenEnabled = Boolean.parseBoolean(coreProperties.getProperty("enable.alfresco.tracking", "true")); boolean owningCoreIsSlave = isSlaveModeEnabledFor(core); + if (trackerRegistry.hasTrackersForCore(core.getName())) + { + LOGGER.info("Trackers (it could be only the node state publisher in case this node is a slave) for " + core.getName() + " are already registered, shutting them down."); + Collection alreadyRegisteredTrackers = trackerRegistry.getTrackersForCore(core.getName()); + trackerRegistry.removeTrackersForCore(core.getName()); + + shutdownTrackers(core, alreadyRegisteredTrackers, scheduler, core.isReloaded()); + admin.getInformationServers().remove(core.getName()); + } + + // Re-put the information server in the map because a Core reload (see above) could have removed the reference. + admin.getInformationServers().put(core.getName(), informationServer); + // Guard conditions: if trackers must be disabled then immediately return, we've done here. // Case #1: trackers have been explicitly disabled. if (!trackersHaveBeenEnabled) { LOGGER.info("SearchServices Core Trackers have been explicitly disabled on core \"{}\" through \"enable.alfresco.tracking\" configuration property.", core.getName()); + + SlaveNodeStatePublisher statePublisher = new SlaveNodeStatePublisher(false, coreProperties, repositoryClient, core.getName(), informationServer); + trackerRegistry.register(core.getName(), statePublisher); + scheduler.schedule(statePublisher, core.getName(), coreProperties); + trackers.add(statePublisher); + + LOGGER.info("SearchServices Slave Node Provider have been created and scheduled for core \"{}\".", core.getName()); + return; } @@ -176,31 +196,19 @@ public class SolrCoreLoadListener extends AbstractSolrEventListener { LOGGER.info("SearchServices Core Trackers have been disabled on core \"{}\" because it is a slave core.", core.getName()); - SlaveNodeStateProvider stateProvider = new SlaveNodeStateProvider(false, coreProperties, repositoryClient, core.getName(), informationServer); - trackerRegistry.register(core.getName(), stateProvider); - scheduler.schedule(stateProvider, core.getName(), coreProperties); + SlaveNodeStatePublisher statePublisher = new SlaveNodeStatePublisher(false, coreProperties, repositoryClient, core.getName(), informationServer); + trackerRegistry.register(core.getName(), statePublisher); + scheduler.schedule(statePublisher, core.getName(), coreProperties); + trackers.add(statePublisher); - LOGGER.info("SearchServices Slave Node Provider have been created and scheduled for core \"{}\".", core.getName()); + LOGGER.info("SearchServices Slave Node Provider have been created and scheduled for Core instance {} with name {}.", core.hashCode(), core.getName()); return; } - if (trackerRegistry.hasTrackersForCore(core.getName())) - { - LOGGER.info("Trackers for " + core.getName() + " are already registered, shutting them down."); - Collection alreadyRegisteredTrackers = trackerRegistry.getTrackersForCore(core.getName()); - trackerRegistry.removeTrackersForCore(core.getName()); - - shutdownTrackers(core, alreadyRegisteredTrackers, scheduler, core.isReloaded()); - admin.getInformationServers().remove(core.getName()); - } - LOGGER.info("SearchServices Tracking Subsystem starts on Solr Core instance {} with name {}", core.hashCode(), core.getName()); - // Re-put the information server in the map because a Core reload (see above) could have removed the reference. - admin.getInformationServers().put(core.getName(), informationServer); - - final List trackers = createAndScheduleCoreTrackers(core, trackerRegistry, coreProperties, scheduler, repositoryClient, informationServer); + trackers.addAll(createAndScheduleCoreTrackers(core, trackerRegistry, coreProperties, scheduler, repositoryClient, informationServer)); CommitTracker commitTracker = new CommitTracker(coreProperties, repositoryClient, core.getName(), informationServer, trackers); trackerRegistry.register(core.getName(), commitTracker); diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/SlaveNodeStateProvider.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/SlaveNodeStatePublisher.java similarity index 97% rename from search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/SlaveNodeStateProvider.java rename to search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/SlaveNodeStatePublisher.java index 0650aef40..b013328d8 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/SlaveNodeStateProvider.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/SlaveNodeStatePublisher.java @@ -27,9 +27,9 @@ import java.util.Properties; * @author Andrea Gazzarini * @since 1.5 */ -public class SlaveNodeStateProvider extends NodeStateProvider +public class SlaveNodeStatePublisher extends NodeStateProvider { - public SlaveNodeStateProvider( + public SlaveNodeStatePublisher( boolean isMaster, Properties coreProperties, SOLRAPIClient repositoryClient, From a52ecfa6ff12ca97fc9b9ef47385406d7285e95f Mon Sep 17 00:00:00 2001 From: Alessandro Benedetti Date: Tue, 29 Oct 2019 16:24:05 +0100 Subject: [PATCH 20/42] [MNT-21015] improved approach in purpose bits checking --- .../solr/component/RewriteFacetParametersComponent.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/component/RewriteFacetParametersComponent.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/component/RewriteFacetParametersComponent.java index 33de8a9fb..2288f8931 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/component/RewriteFacetParametersComponent.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/component/RewriteFacetParametersComponent.java @@ -439,7 +439,11 @@ public class RewriteFacetParametersComponent extends SearchComponent Map fieldMappings, SolrQueryRequest req) { String shardPurpose = req.getParams().get(ShardParams.SHARDS_PURPOSE); - boolean isRefinementRequest = (shardPurpose!=null)?(shardPurpose.equals(String.valueOf(ShardRequest.PURPOSE_REFINE_FACETS))) || (shardPurpose.equals(String.valueOf(ShardRequest.PURPOSE_REFINE_PIVOT_FACETS))):false; + boolean isRefinementRequest = false; + if(shardPurpose!=null){ + int shardPurposeCode = Integer.parseInt(shardPurpose); + isRefinementRequest = ((shardPurposeCode & ShardRequest.PURPOSE_REFINE_FACETS) != 0) || ((shardPurposeCode & ShardRequest.PURPOSE_REFINE_PIVOT_FACETS) != 0); + } String[] facetFieldsOrig = params.getParams(paramName); List facetFieldList = new ArrayList<>(); if(facetFieldsOrig != null) From 3be68b06a0e52e42682bf17c7da59f3ad00ab8aa Mon Sep 17 00:00:00 2001 From: Alessandro Benedetti Date: Wed, 30 Oct 2019 09:04:52 +0100 Subject: [PATCH 21/42] [MNT-21015] log addition --- .../solr/component/RewriteFacetParametersComponent.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/component/RewriteFacetParametersComponent.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/component/RewriteFacetParametersComponent.java index 2288f8931..9f80b7dcb 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/component/RewriteFacetParametersComponent.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/component/RewriteFacetParametersComponent.java @@ -40,6 +40,8 @@ import org.apache.solr.handler.component.ResponseBuilder; import org.apache.solr.handler.component.SearchComponent; import org.apache.solr.handler.component.ShardRequest; import org.apache.solr.request.SolrQueryRequest; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** @@ -49,6 +51,8 @@ import org.apache.solr.request.SolrQueryRequest; */ public class RewriteFacetParametersComponent extends SearchComponent { + private static final Logger log = LoggerFactory.getLogger(RewriteFacetParametersComponent.class); + /* (non-Javadoc) * @see org.apache.solr.handler.component.SearchComponent#prepare(org.apache.solr.handler.component.ResponseBuilder) */ @@ -440,8 +444,10 @@ public class RewriteFacetParametersComponent extends SearchComponent { String shardPurpose = req.getParams().get(ShardParams.SHARDS_PURPOSE); boolean isRefinementRequest = false; - if(shardPurpose!=null){ + //Fix for https://issues.alfresco.com/jira/browse/MNT-21015 + if (shardPurpose != null) { int shardPurposeCode = Integer.parseInt(shardPurpose); + log.debug("ShardPurpose: " + shardPurpose); isRefinementRequest = ((shardPurposeCode & ShardRequest.PURPOSE_REFINE_FACETS) != 0) || ((shardPurposeCode & ShardRequest.PURPOSE_REFINE_PIVOT_FACETS) != 0); } String[] facetFieldsOrig = params.getParams(paramName); From 25bf4a69c2f3950859c9a805ca4335467aae038c Mon Sep 17 00:00:00 2001 From: agazzarini Date: Wed, 30 Oct 2019 17:32:06 +0100 Subject: [PATCH 22/42] [ SEARCH-1752 ] Review comments addressed --- .../solr/lifecycle/SolrCoreLoadListener.java | 175 ++++++++---------- .../solr/tracker/AbstractTracker.java | 26 +-- .../solr/tracker/MetadataTracker.java | 2 +- .../alfresco/solr/tracker/ModelTracker.java | 8 +- ...eProvider.java => NodeStatePublisher.java} | 19 +- .../solr/tracker/SlaveNodeStatePublisher.java | 18 +- .../solr/tracker/SolrTrackerScheduler.java | 2 +- 7 files changed, 106 insertions(+), 144 deletions(-) rename search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/{NodeStateProvider.java => NodeStatePublisher.java} (93%) diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/lifecycle/SolrCoreLoadListener.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/lifecycle/SolrCoreLoadListener.java index 666255ec5..0b41cba15 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/lifecycle/SolrCoreLoadListener.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/lifecycle/SolrCoreLoadListener.java @@ -18,6 +18,7 @@ */ package org.alfresco.solr.lifecycle; +import static java.util.Arrays.asList; import static java.util.Optional.ofNullable; import org.alfresco.opencmis.dictionary.CMISStrictDictionaryService; @@ -220,8 +221,6 @@ public class SolrCoreLoadListener extends AbstractSolrEventListener core.getName(), core.hashCode()); - LOGGER.info("SearchServices Core Trackers have been correctly registered and scheduled on Solr Core instance {} with name {}", core.hashCode(), core.getName()); - //Add the commitTracker to the list of scheduled trackers that can be shutdown trackers.add(commitTracker); } @@ -233,58 +232,68 @@ public class SolrCoreLoadListener extends AbstractSolrEventListener SOLRAPIClient repositoryClient, SolrInformationServer srv) { - List trackers = new ArrayList<>(); - String coreName = core.getName(); + AclTracker aclTracker = + registerAndSchedule( + new AclTracker(props, repositoryClient, core.getName(), srv), + core, + props, + trackerRegistry, + scheduler); - AclTracker aclTracker = new AclTracker(props, repositoryClient, coreName, srv); - trackerRegistry.register(coreName, aclTracker); - scheduler.schedule(aclTracker, coreName, props); + ContentTracker contentTracker = + registerAndSchedule( + new ContentTracker(props, repositoryClient, core.getName(), srv), + core, + props, + trackerRegistry, + scheduler); - LOGGER.info("Tracker {}, instance {}, belonging to Core {}, instance {} has been registered and scheduled.", - aclTracker.getClass().getSimpleName(), - aclTracker.hashCode(), - core.getName(), - core.hashCode()); + MetadataTracker metadataTracker = + registerAndSchedule( + new MetadataTracker(true, props, repositoryClient, core.getName(), srv), + core, + props, + trackerRegistry, + scheduler); - ContentTracker contentTrkr = new ContentTracker(props, repositoryClient, coreName, srv); - trackerRegistry.register(coreName, contentTrkr); - scheduler.schedule(contentTrkr, coreName, props); - - LOGGER.info("Tracker {}, instance {}, belonging to Core {}, instance {} has been registered and scheduled.", - contentTrkr.getClass().getSimpleName(), - contentTrkr.hashCode(), - core.getName(), - core.hashCode()); - - MetadataTracker metaTrkr = new MetadataTracker(true, props, repositoryClient, coreName, srv); - trackerRegistry.register(coreName, metaTrkr); - scheduler.schedule(metaTrkr, coreName, props); - - LOGGER.info("Tracker {}, instance {}, belonging to Core {}, instance {} has been registered and scheduled.", - metaTrkr.getClass().getSimpleName(), - metaTrkr.hashCode(), - core.getName(), - core.hashCode()); - - CascadeTracker cascadeTrkr = new CascadeTracker(props, repositoryClient, coreName, srv); - trackerRegistry.register(coreName, cascadeTrkr); - scheduler.schedule(cascadeTrkr, coreName, props); - - LOGGER.info("Tracker {}, instance {}, belonging to Core {}, instance {} has been registered and scheduled.", - cascadeTrkr.getClass().getSimpleName(), - cascadeTrkr.hashCode(), - core.getName(), - core.hashCode()); + CascadeTracker cascadeTracker = + registerAndSchedule( + new CascadeTracker(props, repositoryClient, core.getName(), srv), + core, + props, + trackerRegistry, + scheduler); //The CommitTracker will acquire these locks in order //The ContentTracker will likely have the longest runs so put it first to ensure the MetadataTracker is not paused while //waiting for the ContentTracker to release it's lock. //The aclTracker will likely have the shortest runs so put it last. - trackers.add(cascadeTrkr); - trackers.add(contentTrkr); - trackers.add(metaTrkr); - trackers.add(aclTracker); - return trackers; + return asList(cascadeTracker, contentTracker, metadataTracker, aclTracker); + } + + /** + * Accepts a {@link Tracker} instance, registers and schedules it. + * + * @param tracker the tracker that will be scheduled and registered. + * @param core the owning core. + * @param properties configuration properties. + * @param registry the tracker registry instance. + * @param scheduler the tracker schedule instance. + * @param the tracker instance. + * @return the registered and scheduled tracker instance. + */ + private T registerAndSchedule(T tracker, SolrCore core, Properties properties, TrackerRegistry registry, SolrTrackerScheduler scheduler) + { + registry.register(core.getName(), tracker); + scheduler.schedule(tracker, core.getName(), properties); + + LOGGER.info("Tracker {}, instance {}, belonging to Core {}, instance {} has been registered and scheduled.", + tracker.getClass().getSimpleName(), + tracker.hashCode(), + core.getName(), + core.hashCode()); + + return tracker; } private void createModelTracker(String coreName, @@ -353,35 +362,22 @@ public class SolrCoreLoadListener extends AbstractSolrEventListener */ private void shutdownTracker(SolrCore core, Tracker tracker, SolrTrackerScheduler scheduler, boolean coreHasBeenReloaded) { + // In case of reload the input core is not the owner: the owner is instead the previous (closed) core and we don't have its reference here. + String coreReference = core.getName() + (coreHasBeenReloaded ? "" : ", instance " + core.hashCode()); + if (tracker.isAlreadyInShutDownMode()) { - LOGGER.info("Tracker {}, instance {} belonging to core {}, instance {}, is already in shutdown mode.", + LOGGER.info("Tracker {}, instance {} belonging to core {}, is already in shutdown mode.", tracker.getClass().getSimpleName(), tracker.hashCode(), - core.getName(), - core.hashCode()); + coreReference); return; } - // Just differentiate the log message: in case of reload the input core is not the owner: the owner - // is instead the previous (closed) core and we don't have its reference here. - if (coreHasBeenReloaded) - { - LOGGER.info("Tracker {}, instance {} belonging to core {} shutdown procedure initiated." + - " If you reloaded the core that is probably the reason you're seeing this message.", - tracker.getClass().getSimpleName(), - tracker.hashCode(), - core.getName()); - } - else - { - LOGGER.info("Tracker {}, instance {} belonging to core {}, instance {}, shutdown procedure initiated.", - tracker.getClass().getSimpleName(), - tracker.hashCode(), - core.getName(), - core.hashCode()); - } - + LOGGER.info("Tracker {}, instance {} belonging to core {} shutdown procedure initiated.", + tracker.getClass().getSimpleName(), + tracker.hashCode(), + coreReference); try { tracker.setShutdown(true); @@ -392,40 +388,19 @@ public class SolrCoreLoadListener extends AbstractSolrEventListener tracker.shutdown(); - if (coreHasBeenReloaded) - { - LOGGER.info("Tracker {}, instance {}, belonging to core {} shutdown procedure correctly terminated.", - tracker.getClass().getSimpleName(), - tracker.hashCode(), - core.getName()); - } - else - { - LOGGER.info("Tracker {}, instance {} belonging to core {}, instance {}, shutdown procedure correctly terminated.", - tracker.getClass().getSimpleName(), - tracker.hashCode(), - core.getName(), - core.hashCode()); - } + LOGGER.info("Tracker {}, instance {}, belonging to core {} shutdown procedure correctly terminated.", + tracker.getClass().getSimpleName(), + tracker.hashCode(), + coreReference); } - catch (Exception e) + catch (Exception exception) { - if (coreHasBeenReloaded) - { - LOGGER.info("Tracker {}, instance {} belonging to core {} shutdown procedure correctly terminated.", - tracker.getClass().getSimpleName(), - tracker.hashCode(), - core.getName()); - } - else - { - LOGGER.error("Tracker {}, instance {} belonging to core {}, instance {}, shutdown procedure failed. " + - "See the stacktrace below for further details.", - tracker.getClass().getSimpleName(), - tracker.hashCode(), - core.getName(), - core.hashCode(), e); - } + LOGGER.error("Tracker {}, instance {} belonging to core {}, shutdown procedure failed. " + + "See the stacktrace below for further details.", + tracker.getClass().getSimpleName(), + tracker.hashCode(), + coreReference, + exception); } } diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/AbstractTracker.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/AbstractTracker.java index 116408cfe..e32e64636 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/AbstractTracker.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/AbstractTracker.java @@ -18,6 +18,7 @@ */ package org.alfresco.solr.tracker; +import java.lang.invoke.MethodHandles; import java.net.ConnectException; import java.net.SocketTimeoutException; import java.util.Properties; @@ -41,7 +42,8 @@ public abstract class AbstractTracker implements Tracker static final long TIME_STEP_32_DAYS_IN_MS = 1000 * 60 * 60 * 24 * 32L; static final long TIME_STEP_1_HR_IN_MS = 60 * 60 * 1000L; static final String SHARD_METHOD_DBID = "DB_ID"; - protected final static Logger log = LoggerFactory.getLogger(AbstractTracker.class); + + protected final static Logger LOGGER = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); protected Properties props; protected SOLRAPIClient client; @@ -105,7 +107,7 @@ public abstract class AbstractTracker implements Tracker this.type = type; - log.info("Solr built for Alfresco version: " + alfrescoVersion); + LOGGER.info("Solr built for Alfresco version: " + alfrescoVersion); } @@ -164,7 +166,7 @@ public abstract class AbstractTracker implements Tracker public void track() { if(runLock.availablePermits() == 0) { - log.info("... " + this.getClass().getSimpleName() + " for core [" + coreName + "] is already in use "+ this.getClass()); + LOGGER.info("... " + this.getClass().getSimpleName() + " for core [" + coreName + "] is already in use "+ this.getClass()); return; } @@ -182,7 +184,7 @@ public abstract class AbstractTracker implements Tracker assert(assertTrackerStateRemainsNull()); } - log.info("... Running " + this.getClass().getSimpleName() + " for core [" + coreName + "]."); + LOGGER.info("... Running " + this.getClass().getSimpleName() + " for core [" + coreName + "]."); if(this.state == null) { @@ -190,8 +192,8 @@ public abstract class AbstractTracker implements Tracker * Set the global state for the tracker here. */ this.state = getTrackerState(); - log.debug("##### Setting tracker global state."); - log.debug("State set: " + this.state.toString()); + LOGGER.debug("##### Setting tracker global state."); + LOGGER.debug("State set: " + this.state.toString()); this.state.setRunning(true); } else @@ -209,33 +211,33 @@ public abstract class AbstractTracker implements Tracker catch(IndexTrackingShutdownException t) { setRollback(true); - log.info("Stopping index tracking for " + getClass().getSimpleName() + " - " + coreName); + LOGGER.info("Stopping index tracking for " + getClass().getSimpleName() + " - " + coreName); } catch(Throwable t) { setRollback(true); if (t instanceof SocketTimeoutException || t instanceof ConnectException) { - if (log.isDebugEnabled()) + if (LOGGER.isDebugEnabled()) { // DEBUG, so give the whole stack trace - log.warn("Tracking communication timed out for " + getClass().getSimpleName() + " - " + coreName, t); + LOGGER.warn("Tracking communication timed out for " + getClass().getSimpleName() + " - " + coreName, t); } else { // We don't need the stack trace. It timed out. - log.warn("Tracking communication timed out for " + getClass().getSimpleName() + " - " + coreName); + LOGGER.warn("Tracking communication timed out for " + getClass().getSimpleName() + " - " + coreName); } } else { - log.error("Tracking failed for " + getClass().getSimpleName() + " - " + coreName, t); + LOGGER.error("Tracking failed for " + getClass().getSimpleName() + " - " + coreName, t); } } } catch (InterruptedException e) { - log.error("Semaphore interrupted for " + getClass().getSimpleName() + " - " + coreName, e); + LOGGER.error("Semaphore interrupted for " + getClass().getSimpleName() + " - " + coreName, e); } finally { diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/MetadataTracker.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/MetadataTracker.java index 36d092d7a..f118c523b 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/MetadataTracker.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/MetadataTracker.java @@ -49,7 +49,7 @@ import org.slf4j.LoggerFactory; * This tracks two things: transactions and metadata nodes * @author Ahmed Owian */ -public class MetadataTracker extends NodeStateProvider implements Tracker +public class MetadataTracker extends NodeStatePublisher implements Tracker { protected final static Logger log = LoggerFactory.getLogger(MetadataTracker.class); private static final int DEFAULT_TRANSACTION_DOCS_BATCH_SIZE = 100; diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/ModelTracker.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/ModelTracker.java index b3f3cd26b..034d14228 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/ModelTracker.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/ModelTracker.java @@ -106,7 +106,7 @@ public class ModelTracker extends AbstractTracker implements Tracker super(p, client, coreName, informationServer, Tracker.Type.MODEL); String normalSolrHome = SolrResourceLoader.normalizeDir(solrHome); alfrescoModelDir = new File(ConfigUtil.locateProperty("solr.model.dir", normalSolrHome+"alfrescoModels")); - log.info("Alfresco Model dir " + alfrescoModelDir); + LOGGER.info("Alfresco Model dir " + alfrescoModelDir); if (!alfrescoModelDir.exists()) { alfrescoModelDir.mkdir(); @@ -197,7 +197,7 @@ public class ModelTracker extends AbstractTracker implements Tracker int registeredSearcherCount = this.infoSrv.getRegisteredSearcherCount(); if (registeredSearcherCount >= getMaxLiveSearchers()) { - log.info(".... skipping tracking registered searcher count = " + registeredSearcherCount); + LOGGER.info(".... skipping tracking registered searcher count = " + registeredSearcherCount); return; } @@ -268,7 +268,7 @@ public class ModelTracker extends AbstractTracker implements Tracker } catch (Throwable t) { - log.error("Model tracking failed for core: "+ coreName, t); + LOGGER.error("Model tracking failed for core: "+ coreName, t); } } @@ -534,7 +534,7 @@ public class ModelTracker extends AbstractTracker implements Tracker { loadedModels.add(modelName); } - log.info("Loading model " + model.getName()); + LOGGER.info("Loading model " + model.getName()); } } diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/NodeStateProvider.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/NodeStatePublisher.java similarity index 93% rename from search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/NodeStateProvider.java rename to search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/NodeStatePublisher.java index c64e03d17..d6fd2d78a 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/NodeStateProvider.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/NodeStatePublisher.java @@ -59,7 +59,7 @@ import java.util.Properties; * @since 1.5 * @see SEARCH-1752 */ -public abstract class NodeStateProvider extends AbstractTracker +public abstract class NodeStatePublisher extends AbstractTracker { DocRouter docRouter; private final boolean isMaster; @@ -70,7 +70,7 @@ public abstract class NodeStateProvider extends AbstractTracker /** The property to use for determining the shard. */ protected Optional shardProperty = Optional.empty(); - NodeStateProvider( + NodeStatePublisher( boolean isMaster, Properties p, SOLRAPIClient client, @@ -88,7 +88,7 @@ public abstract class NodeStateProvider extends AbstractTracker docRouter = DocRouterFactory.getRouter(p, ShardMethodEnum.getShardMethod(shardMethod)); } - NodeStateProvider(Type type) + NodeStatePublisher(Type type) { super(type); this.isMaster = false; @@ -100,7 +100,7 @@ public abstract class NodeStateProvider extends AbstractTracker updateShardProperty(); if (shardProperty.isEmpty()) { - log.warn("Sharding property " + SHARD_KEY_KEY + " was set to " + shardKeyName + ", but no such property was found."); + LOGGER.warn("Sharding property {} was set to {}, but no such property was found.", SHARD_KEY_KEY, shardKeyName); } }); } @@ -116,11 +116,11 @@ public abstract class NodeStateProvider extends AbstractTracker { if (updatedShardProperty.isEmpty()) { - log.warn("The model defining " + shardKeyName + " property has been disabled"); + LOGGER.warn("The model defining {} property has been disabled", shardKeyName); } else { - log.info("New " + SHARD_KEY_KEY + " property found for " + shardKeyName); + LOGGER.info("New {} property found for {} ", SHARD_KEY_KEY, shardKeyName); } } shardProperty = updatedShardProperty; @@ -148,11 +148,8 @@ public abstract class NodeStateProvider extends AbstractTracker namespaceDAO, dictionaryService, field); - if (propertyDef == null) - { - return Optional.empty(); - } - return of(propertyDef.getName()); + + return ofNullable(propertyDef).map(PropertyDefinition::getName); } /** diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/SlaveNodeStatePublisher.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/SlaveNodeStatePublisher.java index b013328d8..4e7ccf709 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/SlaveNodeStatePublisher.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/SlaveNodeStatePublisher.java @@ -27,7 +27,7 @@ import java.util.Properties; * @author Andrea Gazzarini * @since 1.5 */ -public class SlaveNodeStatePublisher extends NodeStateProvider +public class SlaveNodeStatePublisher extends NodeStatePublisher { public SlaveNodeStatePublisher( boolean isMaster, @@ -47,24 +47,12 @@ public class SlaveNodeStatePublisher extends NodeStateProvider ShardState shardstate = getShardState(); client.getTransactions(0L, null, 0L, null, 0, shardstate); } - catch (EncoderException exception ) + catch (EncoderException | IOException | AuthenticationException exception ) { - log.error("Unable to publish this node state. " + + LOGGER.error("Unable to publish this node state. " + "A failure condition has been met during the outbound subscription message encoding process. " + "See the stacktrace below for further details.", exception); } - catch (IOException exception ) - { - log.error("Unable to publish this node state. " + - "Detected an I/O failure while sending the subscription state message. " + - "See the stacktrace below for further details.", exception); - } - catch (AuthenticationException exception) - { - log.error("Unable to publish this node state. " + - "Authentication failure detected while sending the subscription state message. " + - "See the stacktrace below for further details.", exception); - } } @Override diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/SolrTrackerScheduler.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/SolrTrackerScheduler.java index 2038091c5..c584d80fb 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/SolrTrackerScheduler.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/SolrTrackerScheduler.java @@ -121,7 +121,7 @@ public class SolrTrackerScheduler case COMMIT: cron = getCron(props,"alfresco.commit.tracker.cron"); break; - case NODE_STATE_PUBLISHER: + case NODE_STATE_PUBLISHER: cron = getCron(props,"alfresco.nodestate.tracker.cron"); break; default: From ea691cba2709e993a679b88f0776d941e9bab2dd Mon Sep 17 00:00:00 2001 From: agazzarini Date: Wed, 30 Oct 2019 17:52:05 +0100 Subject: [PATCH 23/42] [ SEARCH-1752 ] Proper usage of placeholders in logging messages. --- .../solr/tracker/AbstractTracker.java | 61 +++++++++---------- 1 file changed, 29 insertions(+), 32 deletions(-) diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/AbstractTracker.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/AbstractTracker.java index e32e64636..d4429f92b 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/AbstractTracker.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/AbstractTracker.java @@ -107,19 +107,19 @@ public abstract class AbstractTracker implements Tracker this.type = type; - LOGGER.info("Solr built for Alfresco version: " + alfrescoVersion); + LOGGER.info("Solr built for Alfresco version: {}", alfrescoVersion); } /** * Subclasses must implement behaviour that completes the following steps, in order: + * *
    *
  1. Purge
  2. *
  3. Reindex
  4. *
  5. Index
  6. *
  7. Track repository
  8. *
- * @throws Throwable */ protected abstract void doTrack() throws Throwable; @@ -138,7 +138,7 @@ public abstract class AbstractTracker implements Tracker } catch(Exception e) { - + // Ignore } @@ -150,12 +150,7 @@ public abstract class AbstractTracker implements Tracker getTrackerState(); - - if(state == null) { - return true; - } else { - return false; - } + return state == null; } /** @@ -165,8 +160,9 @@ public abstract class AbstractTracker implements Tracker @Override public void track() { - if(runLock.availablePermits() == 0) { - LOGGER.info("... " + this.getClass().getSimpleName() + " for core [" + coreName + "] is already in use "+ this.getClass()); + if(runLock.availablePermits() == 0) + { + LOGGER.info("... {} for core [{}] is already in use {}", this.getClass().getSimpleName(), coreName, getClass()); return; } @@ -176,15 +172,14 @@ public abstract class AbstractTracker implements Tracker * The runLock ensures that for each tracker type (metadata, content, commit, cascade) only one tracker will * be running at a time. */ - runLock.acquire(); - if(state==null && Boolean.parseBoolean(System.getProperty("alfresco.test", "false"))) + if (state==null && Boolean.parseBoolean(System.getProperty("alfresco.test", "false"))) { assert(assertTrackerStateRemainsNull()); } - LOGGER.info("... Running " + this.getClass().getSimpleName() + " for core [" + coreName + "]."); + LOGGER.info("... Running {} for core [{}]", this.getClass().getSimpleName(), coreName); if(this.state == null) { @@ -193,7 +188,7 @@ public abstract class AbstractTracker implements Tracker */ this.state = getTrackerState(); LOGGER.debug("##### Setting tracker global state."); - LOGGER.debug("State set: " + this.state.toString()); + LOGGER.debug("State set: {}", this.state.toString()); this.state.setRunning(true); } else @@ -211,7 +206,7 @@ public abstract class AbstractTracker implements Tracker catch(IndexTrackingShutdownException t) { setRollback(true); - LOGGER.info("Stopping index tracking for " + getClass().getSimpleName() + " - " + coreName); + LOGGER.info("Stopping index tracking for {} - {}", getClass().getSimpleName(), coreName); } catch(Throwable t) { @@ -221,28 +216,29 @@ public abstract class AbstractTracker implements Tracker if (LOGGER.isDebugEnabled()) { // DEBUG, so give the whole stack trace - LOGGER.warn("Tracking communication timed out for " + getClass().getSimpleName() + " - " + coreName, t); + LOGGER.warn("Tracking communication timed out for {} - {}", getClass().getSimpleName(), coreName, t); } else { // We don't need the stack trace. It timed out. - LOGGER.warn("Tracking communication timed out for " + getClass().getSimpleName() + " - " + coreName); + LOGGER.warn("Tracking communication timed out for for {} - {}", getClass().getSimpleName(), coreName); } } else { - LOGGER.error("Tracking failed for " + getClass().getSimpleName() + " - " + coreName, t); + LOGGER.error("Tracking failed for for {} - {}", getClass().getSimpleName(), coreName, t); } } } catch (InterruptedException e) { - LOGGER.error("Semaphore interrupted for " + getClass().getSimpleName() + " - " + coreName, e); + LOGGER.error("Semaphore interrupted for for {} - {}", getClass().getSimpleName(), coreName, e); } finally { infoSrv.unregisterTrackerThread(); - if(state != null) { + if(state != null) + { //During a rollback state is set to null. state.setRunning(false); state.setCheck(false); @@ -251,15 +247,18 @@ public abstract class AbstractTracker implements Tracker } } - public boolean getRollback() { + public boolean getRollback() + { return this.rollback; } - public void setRollback(boolean rollback) { + public void setRollback(boolean rollback) + { this.rollback = rollback; } - private void continueState() { + private void continueState() + { infoSrv.continueState(state); state.incrementTrackerCycles(); } @@ -281,8 +280,6 @@ public abstract class AbstractTracker implements Tracker return this.infoSrv.getTrackerInitialState(); } } - - /** * Allows time for the scheduled asynchronous tasks to complete @@ -301,6 +298,7 @@ public abstract class AbstractTracker implements Tracker } catch (InterruptedException e) { + // Nothing to be done here } } currentRunnable = this.threadHandler.peekHeadReindexWorker(); @@ -342,15 +340,16 @@ public abstract class AbstractTracker implements Tracker } } - public Semaphore getWriteLock() { + public Semaphore getWriteLock() + { return this.writeLock; } - public Semaphore getRunLock() { + public Semaphore getRunLock() + { return this.runLock; } - /** * @return Alfresco version Solr was built for */ @@ -369,6 +368,4 @@ public abstract class AbstractTracker implements Tracker { return type; } - - -} +} \ No newline at end of file From c6e56dee7c23d528ee886077e79b47f29342e986 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 31 Oct 2019 22:13:17 +0000 Subject: [PATCH 24/42] Bump slf4j.version from 1.7.28 to 1.7.29 in /search-services Bumps `slf4j.version` from 1.7.28 to 1.7.29. Updates `slf4j-log4j12` from 1.7.28 to 1.7.29 - [Release notes](https://github.com/qos-ch/slf4j/releases) - [Commits](https://github.com/qos-ch/slf4j/commits) Updates `slf4j-api` from 1.7.28 to 1.7.29 - [Release notes](https://github.com/qos-ch/slf4j/releases) - [Commits](https://github.com/qos-ch/slf4j/commits) Signed-off-by: dependabot-preview[bot] --- search-services/alfresco-solrclient-lib/pom.xml | 2 +- search-services/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/search-services/alfresco-solrclient-lib/pom.xml b/search-services/alfresco-solrclient-lib/pom.xml index ef23d4dc4..a70bf5fcc 100644 --- a/search-services/alfresco-solrclient-lib/pom.xml +++ b/search-services/alfresco-solrclient-lib/pom.xml @@ -73,7 +73,7 @@ org.slf4j slf4j-log4j12 - 1.7.28 + 1.7.29 diff --git a/search-services/pom.xml b/search-services/pom.xml index 833207db8..8af1e3219 100644 --- a/search-services/pom.xml +++ b/search-services/pom.xml @@ -14,7 +14,7 @@ pom Alfresco Solr Search parent - 1.7.28 + 1.7.29 alfresco-solrclient-lib From 3b27d37b8e25fe1c8079ff8a6423a0f97c7a6f03 Mon Sep 17 00:00:00 2001 From: Tom Page Date: Fri, 1 Nov 2019 09:54:04 +0000 Subject: [PATCH 25/42] SEARCH-1763 Rename long running tests to end in IT. --- ...ava => AbstractAlfrescoDistributedIT.java} | 2 +- ...Tests.java => AbstractAlfrescoSolrIT.java} | 7 +++--- ...st.java => AdminHandlerDistributedIT.java} | 2 +- ...inHandlerTest.java => AdminHandlerIT.java} | 3 ++- ...t.java => AlfrescoCoreAdminHandlerIT.java} | 2 +- ...oadTest.java => AlfrescoSolrReloadIT.java} | 5 ++-- .../org/alfresco/solr/AlfrescoSolrUtils.java | 2 +- ...ava => AlfrescoTrackerRegistrationIT.java} | 2 +- ...va => CoresCreateUpdateDistributedIT.java} | 2 +- ...est.java => CoresCreateViaPropertyIT.java} | 2 +- ...nitializer.java => SolrITInitializer.java} | 2 +- ...dTest.java => TemplatesDistributedIT.java} | 2 +- ...a => AlfrescoHighligherDistributedIT.java} | 6 ++--- ...erTest.java => AlfrescoHighlighterIT.java} | 24 ++++--------------- ...er.java => PostingsSolrHighlighterIT.java} | 6 ++--- ...ava => AlfrescoReRankQParserPluginIT.java} | 4 ++-- ...st.java => AlfrescoSolrFingerprintIT.java} | 4 ++-- ...t.java => AlfrescoSolrSpellcheckerIT.java} | 18 ++------------ .../org/alfresco/solr/query/AuthDataLoad.java | 4 ++-- .../{AuthQueryTest.java => AuthQueryIT.java} | 2 +- ...=> DistributedAlfrescoSolrFacetingIT.java} | 6 ++--- ...DistributedAlfrescoSolrFingerPrintIT.java} | 4 ++-- ...istributedAlfrescoSolrSpellcheckerIT.java} | 4 ++-- .../{SolrAuthTest.java => SolrAuthIT.java} | 5 ++-- ...FieldTest.java => UntokenisedFieldIT.java} | 6 ++--- ...Test.java => AbstractQParserPluginIT.java} | 13 ++-------- ...pingTest.java => FieldNameEscapingIT.java} | 2 +- ...erPluginTest.java => QParserPluginIT.java} | 2 +- ...yTest.java => AFTSDefaultTextQueryIT.java} | 2 +- ...nctionTest.java => AFTSDisjunctionIT.java} | 2 +- ...sTest.java => AFTSIdentifierFieldsIT.java} | 2 +- ...geQueryTest.java => AFTSRangeQueryIT.java} | 2 +- ...lerTest.java => AFTSRequestHandlerIT.java} | 2 +- ...est.java => AbstractRequestHandlerIT.java} | 4 ++-- .../{MNTTest.java => MNTIT.java} | 2 +- .../query/cmis/{CmisTest.java => CmisIT.java} | 2 +- .../solr/query/cmis/LoadCMISData.java | 4 ++-- ...uterTest.java => AclModCountRouterIT.java} | 2 +- ...va => AlfrescoSolrTrackerExceptionIT.java} | 6 ++--- ...erTest.java => AlfrescoSolrTrackerIT.java} | 6 ++--- ...ava => AlfrescoSolrTrackerRollbackIT.java} | 6 ++--- ...t.java => AlfrescoSolrTrackerStateIT.java} | 4 ++-- ...TrackerTest.java => CascadeTrackerIT.java} | 4 ++-- ...TrackerTest.java => ContentTrackerIT.java} | 2 +- ...RouterTest.java => DateMonthRouterIT.java} | 2 +- ...istributedAclIdAlfrescoSolrTrackerIT.java} | 4 ++-- ...ava => DistributedAlfrescoSolrJsonIT.java} | 4 ++-- ... => DistributedAlfrescoSolrTrackerIT.java} | 4 ++-- ...DistributedAlfrescoSolrTrackerRaceIT.java} | 4 ++-- ...istributedAlfrescoSolrTrackerStateIT.java} | 4 ++-- ....java => DistributedCascadeTrackerIT.java} | 4 ++-- ...DistributedDateAbstractSolrTrackerIT.java} | 4 ++-- ...ibutedDateMonthAlfrescoSolrTrackerIT.java} | 6 ++--- ...utedDateQuarterAlfrescoSolrTrackerIT.java} | 2 +- ...edDateSplitYearAlfrescoSolrTrackerIT.java} | 4 ++-- ...ibutedDbidRangeAlfrescoSolrTrackerIT.java} | 6 ++--- ...ExpandDbidRangeAlfrescoSolrTrackerIT.java} | 6 ++--- ...citShardIdWithStaticPropertyRouterIT.java} | 4 ++-- ...ributedExplicitShardRoutingTrackerIT.java} | 6 ++--- ...edPropertyBasedAlfrescoSolrTrackerIT.java} | 6 ++--- ...outerTest.java => ExplicitIDRouterIT.java} | 2 +- ...t.java => ExplicitIDWithLRISRouterIT.java} | 2 +- ...elTrackerTest.java => ModelTrackerIT.java} | 2 +- ...yRouterTest.java => PropertyRouterIT.java} | 2 +- ...rTest.java => CachedDocTransformerIT.java} | 6 ++--- ...shFilterTest.java => MinHashFilterIT.java} | 2 +- ...java => AlfrescoLukeRequestHandlerIT.java} | 2 +- 67 files changed, 120 insertions(+), 163 deletions(-) rename search-services/alfresco-search/src/test/java/org/alfresco/solr/{AbstractAlfrescoDistributedTest.java => AbstractAlfrescoDistributedIT.java} (99%) rename search-services/alfresco-search/src/test/java/org/alfresco/solr/{AbstractAlfrescoSolrTests.java => AbstractAlfrescoSolrIT.java} (99%) rename search-services/alfresco-search/src/test/java/org/alfresco/solr/{AdminHandlerDistributedTest.java => AdminHandlerDistributedIT.java} (97%) rename search-services/alfresco-search/src/test/java/org/alfresco/solr/{AdminHandlerTest.java => AdminHandlerIT.java} (96%) rename search-services/alfresco-search/src/test/java/org/alfresco/solr/{AlfrescoCoreAdminHandlerTest.java => AlfrescoCoreAdminHandlerIT.java} (99%) rename search-services/alfresco-search/src/test/java/org/alfresco/solr/{AlfrescoSolrReloadTest.java => AlfrescoSolrReloadIT.java} (97%) rename search-services/alfresco-search/src/test/java/org/alfresco/solr/{AlfrescoTrackerRegistrationTest.java => AlfrescoTrackerRegistrationIT.java} (96%) rename search-services/alfresco-search/src/test/java/org/alfresco/solr/{CoresCreateUpdateDistributedTest.java => CoresCreateUpdateDistributedIT.java} (99%) rename search-services/alfresco-search/src/test/java/org/alfresco/solr/{CoresCreateViaPropertyTest.java => CoresCreateViaPropertyIT.java} (97%) rename search-services/alfresco-search/src/test/java/org/alfresco/solr/{SolrTestInitializer.java => SolrITInitializer.java} (99%) rename search-services/alfresco-search/src/test/java/org/alfresco/solr/{TemplatesDistributedTest.java => TemplatesDistributedIT.java} (97%) rename search-services/alfresco-search/src/test/java/org/alfresco/solr/highlight/{AlfrescoHighligherDistributedTest.java => AlfrescoHighligherDistributedIT.java} (96%) rename search-services/alfresco-search/src/test/java/org/alfresco/solr/highlight/{AlfrescoHighlighterTest.java => AlfrescoHighlighterIT.java} (95%) rename search-services/alfresco-search/src/test/java/org/alfresco/solr/highlight/{TestPostingsSolrHighlighter.java => PostingsSolrHighlighterIT.java} (97%) rename search-services/alfresco-search/src/test/java/org/alfresco/solr/query/{AlfrescoReRankQParserPluginTest.java => AlfrescoReRankQParserPluginIT.java} (97%) rename search-services/alfresco-search/src/test/java/org/alfresco/solr/query/{AlfrescoSolrFingerprintTest.java => AlfrescoSolrFingerprintIT.java} (99%) rename search-services/alfresco-search/src/test/java/org/alfresco/solr/query/{AlfrescoSolrSpellcheckerTest.java => AlfrescoSolrSpellcheckerIT.java} (88%) rename search-services/alfresco-search/src/test/java/org/alfresco/solr/query/{AuthQueryTest.java => AuthQueryIT.java} (99%) rename search-services/alfresco-search/src/test/java/org/alfresco/solr/query/{DistributedAlfrescoSolrFacetingTest.java => DistributedAlfrescoSolrFacetingIT.java} (99%) rename search-services/alfresco-search/src/test/java/org/alfresco/solr/query/{DistributedAlfrescoSolrFingerPrintTest.java => DistributedAlfrescoSolrFingerPrintIT.java} (99%) rename search-services/alfresco-search/src/test/java/org/alfresco/solr/query/{DistributedAlfrescoSolrSpellcheckerTest.java => DistributedAlfrescoSolrSpellcheckerIT.java} (96%) rename search-services/alfresco-search/src/test/java/org/alfresco/solr/query/{SolrAuthTest.java => SolrAuthIT.java} (95%) rename search-services/alfresco-search/src/test/java/org/alfresco/solr/query/{UntokenisedFieldTest.java => UntokenisedFieldIT.java} (94%) rename search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/qparser/{AbstractQParserPluginTest.java => AbstractQParserPluginIT.java} (74%) rename search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/qparser/{FieldNameEscapingTest.java => FieldNameEscapingIT.java} (94%) rename search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/qparser/{QParserPluginTest.java => QParserPluginIT.java} (99%) rename search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/{AFTSDefaultTextQueryTest.java => AFTSDefaultTextQueryIT.java} (99%) rename search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/{AFTSDisjunctionTest.java => AFTSDisjunctionIT.java} (97%) rename search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/{AFTSIdentifierFieldsTest.java => AFTSIdentifierFieldsIT.java} (97%) rename search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/{AFTSRangeQueryTest.java => AFTSRangeQueryIT.java} (98%) rename search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/{AFTSRequestHandlerTest.java => AFTSRequestHandlerIT.java} (99%) rename search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/{AbstractRequestHandlerTest.java => AbstractRequestHandlerIT.java} (95%) rename search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/{MNTTest.java => MNTIT.java} (97%) rename search-services/alfresco-search/src/test/java/org/alfresco/solr/query/cmis/{CmisTest.java => CmisIT.java} (99%) rename search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/{AclModCountRouterTest.java => AclModCountRouterIT.java} (99%) rename search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/{AlfrescoSolrTrackerExceptionTest.java => AlfrescoSolrTrackerExceptionIT.java} (99%) rename search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/{AlfrescoSolrTrackerTest.java => AlfrescoSolrTrackerIT.java} (99%) rename search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/{AlfrescoSolrTrackerRollbackTest.java => AlfrescoSolrTrackerRollbackIT.java} (98%) rename search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/{AlfrescoSolrTrackerStateTest.java => AlfrescoSolrTrackerStateIT.java} (98%) rename search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/{CascadeTrackerTest.java => CascadeTrackerIT.java} (98%) rename search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/{ContentTrackerTest.java => ContentTrackerIT.java} (99%) rename search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/{DateMonthRouterTest.java => DateMonthRouterIT.java} (99%) rename search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/{DistributedAclIdAlfrescoSolrTrackerTest.java => DistributedAclIdAlfrescoSolrTrackerIT.java} (97%) rename search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/{DistributedAlfrescoSolrJsonTest.java => DistributedAlfrescoSolrJsonIT.java} (97%) rename search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/{DistributedAlfrescoSolrTrackerTest.java => DistributedAlfrescoSolrTrackerIT.java} (98%) rename search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/{DistributedAlfrescoSolrTrackerRaceTest.java => DistributedAlfrescoSolrTrackerRaceIT.java} (97%) rename search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/{DistributedAlfrescoSolrTrackerStateTest.java => DistributedAlfrescoSolrTrackerStateIT.java} (98%) rename search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/{DistributedCascadeTrackerTest.java => DistributedCascadeTrackerIT.java} (98%) rename search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/{DistributedDateAbstractSolrTrackerTest.java => DistributedDateAbstractSolrTrackerIT.java} (97%) rename search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/{DistributedDateMonthAlfrescoSolrTrackerTest.java => DistributedDateMonthAlfrescoSolrTrackerIT.java} (97%) rename search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/{DistributedDateQuarterAlfrescoSolrTrackerTest.java => DistributedDateQuarterAlfrescoSolrTrackerIT.java} (95%) rename search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/{DistributedDateSplitYearAlfrescoSolrTrackerTest.java => DistributedDateSplitYearAlfrescoSolrTrackerIT.java} (93%) rename search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/{DistributedDbidRangeAlfrescoSolrTrackerTest.java => DistributedDbidRangeAlfrescoSolrTrackerIT.java} (96%) rename search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/{DistributedExpandDbidRangeAlfrescoSolrTrackerTest.java => DistributedExpandDbidRangeAlfrescoSolrTrackerIT.java} (98%) rename search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/{DistributedExplicitShardIdWithStaticPropertyRouterTest.java => DistributedExplicitShardIdWithStaticPropertyRouterIT.java} (97%) rename search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/{DistributedExplicitShardRoutingTrackerTest.java => DistributedExplicitShardRoutingTrackerIT.java} (97%) rename search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/{DistributedPropertyBasedAlfrescoSolrTrackerTest.java => DistributedPropertyBasedAlfrescoSolrTrackerIT.java} (97%) rename search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/{ExplicitIDRouterTest.java => ExplicitIDRouterIT.java} (99%) rename search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/{ExplicitIDWithLRISRouterTest.java => ExplicitIDWithLRISRouterIT.java} (99%) rename search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/{ModelTrackerTest.java => ModelTrackerIT.java} (96%) rename search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/{PropertyRouterTest.java => PropertyRouterIT.java} (99%) rename search-services/alfresco-search/src/test/java/org/alfresco/solr/transformer/{CachedDocTransformerTest.java => CachedDocTransformerIT.java} (98%) rename search-services/alfresco-search/src/test/java/org/apache/lucene/analysis/minhash/{MinHashFilterTest.java => MinHashFilterIT.java} (99%) rename search-services/alfresco-search/src/test/java/org/apache/solr/handler/component/{AlfrescoLukeRequestHandlerTest.java => AlfrescoLukeRequestHandlerIT.java} (99%) diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/AbstractAlfrescoDistributedTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/AbstractAlfrescoDistributedIT.java similarity index 99% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/AbstractAlfrescoDistributedTest.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/AbstractAlfrescoDistributedIT.java index 7fcef7193..14a9a805d 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/AbstractAlfrescoDistributedTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/AbstractAlfrescoDistributedIT.java @@ -87,7 +87,7 @@ import static org.alfresco.repo.search.adaptor.lucene.QueryConstants.FIELD_VERSI * @author Michael Suzuki */ @ThreadLeakLingering(linger = 5000) -public abstract class AbstractAlfrescoDistributedTest extends SolrTestInitializer +public abstract class AbstractAlfrescoDistributedIT extends SolrITInitializer { protected static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/AbstractAlfrescoSolrTests.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/AbstractAlfrescoSolrIT.java similarity index 99% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/AbstractAlfrescoSolrTests.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/AbstractAlfrescoSolrIT.java index a7647a399..d9ee37eaa 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/AbstractAlfrescoSolrTests.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/AbstractAlfrescoSolrIT.java @@ -27,7 +27,6 @@ import org.alfresco.solr.client.NodeMetaData; import org.alfresco.solr.client.SOLRAPIQueueClient; import org.alfresco.solr.client.Transaction; import org.alfresco.solr.tracker.Tracker; -import org.alfresco.util.SearchLanguageConversion; import org.apache.chemistry.opencmis.commons.impl.json.JSONArray; import org.apache.chemistry.opencmis.commons.impl.json.JSONObject; import org.apache.chemistry.opencmis.commons.impl.json.JSONValue; @@ -84,17 +83,17 @@ import static org.junit.Assert.assertEquals; /** * Base class that provides the solr test harness. - * This is used to manage the embedded solr used for unit and integration testing. + * This is used to manage the embedded solr used for integration testing. * The abstract also provides helper method that interacts with the * embedded solr. * * @author Michael Suzuki * */ -public abstract class AbstractAlfrescoSolrTests implements SolrTestFiles, AlfrescoSolrConstants +public abstract class AbstractAlfrescoSolrIT implements SolrTestFiles, AlfrescoSolrConstants { static AlfrescoCoreAdminHandler admin; - private static Log LOG = LogFactory.getLog(AbstractAlfrescoSolrTests.class); + private static Log LOG = LogFactory.getLog(AbstractAlfrescoSolrIT.class); private static boolean CORE_NOT_YET_CREATED = true; /** diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/AdminHandlerDistributedTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/AdminHandlerDistributedIT.java similarity index 97% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/AdminHandlerDistributedTest.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/AdminHandlerDistributedIT.java index 95b98db09..1f6255b13 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/AdminHandlerDistributedTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/AdminHandlerDistributedIT.java @@ -43,7 +43,7 @@ import static org.alfresco.solr.AlfrescoSolrUtils.*; */ @SolrTestCaseJ4.SuppressSSL @LuceneTestCase.SuppressCodecs({"Appending","Lucene3x","Lucene40","Lucene41","Lucene42","Lucene43", "Lucene44", "Lucene45","Lucene46","Lucene47","Lucene48","Lucene49"}) -public class AdminHandlerDistributedTest extends AbstractAlfrescoDistributedTest +public class AdminHandlerDistributedIT extends AbstractAlfrescoDistributedIT { private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); final String JETTY_SERVER_ID = this.getClass().getSimpleName(); diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/AdminHandlerTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/AdminHandlerIT.java similarity index 96% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/AdminHandlerTest.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/AdminHandlerIT.java index 872fea72c..140b6b1db 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/AdminHandlerTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/AdminHandlerIT.java @@ -11,7 +11,8 @@ import org.junit.Test; @LuceneTestCase.SuppressCodecs({"Appending","Lucene3x","Lucene40","Lucene41","Lucene42","Lucene43", "Lucene44", "Lucene45","Lucene46","Lucene47","Lucene48","Lucene49"}) @SolrTestCaseJ4.SuppressSSL -public class AdminHandlerTest extends AbstractAlfrescoSolrTests { +public class AdminHandlerIT extends AbstractAlfrescoSolrIT +{ static CoreAdminHandler admin; diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/AlfrescoCoreAdminHandlerTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/AlfrescoCoreAdminHandlerIT.java similarity index 99% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/AlfrescoCoreAdminHandlerTest.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/AlfrescoCoreAdminHandlerIT.java index 955f365b5..5e264adb3 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/AlfrescoCoreAdminHandlerTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/AlfrescoCoreAdminHandlerIT.java @@ -60,7 +60,7 @@ import org.mockito.junit.MockitoJUnitRunner; /** Unit tests for {@link org.alfresco.solr.AlfrescoCoreAdminHandler}. */ @RunWith(MockitoJUnitRunner.class) -public class AlfrescoCoreAdminHandlerTest +public class AlfrescoCoreAdminHandlerIT { /** The string representing a transaction report. */ private static final String TXREPORT = "TXREPORT"; diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/AlfrescoSolrReloadTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/AlfrescoSolrReloadIT.java similarity index 97% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/AlfrescoSolrReloadTest.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/AlfrescoSolrReloadIT.java index c56138ed0..70500adf6 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/AlfrescoSolrReloadTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/AlfrescoSolrReloadIT.java @@ -37,8 +37,9 @@ import org.quartz.SchedulerException; @LuceneTestCase.SuppressCodecs({"Appending","Lucene3x","Lucene40","Lucene41","Lucene42","Lucene43", "Lucene44", "Lucene45","Lucene46","Lucene47","Lucene48","Lucene49"}) @SolrTestCaseJ4.SuppressSSL -public class AlfrescoSolrReloadTest extends AbstractAlfrescoSolrTests { - private static Log logger = LogFactory.getLog(org.alfresco.solr.tracker.AlfrescoSolrTrackerTest.class); +public class AlfrescoSolrReloadIT extends AbstractAlfrescoSolrIT +{ + private static Log logger = LogFactory.getLog(org.alfresco.solr.tracker.AlfrescoSolrTrackerIT.class); @BeforeClass public static void beforeClass() throws Exception { diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/AlfrescoSolrUtils.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/AlfrescoSolrUtils.java index 174939124..03f55926f 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/AlfrescoSolrUtils.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/AlfrescoSolrUtils.java @@ -77,7 +77,7 @@ import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.namespace.QName; -import org.alfresco.solr.AbstractAlfrescoSolrTests.SolrServletRequest; +import org.alfresco.solr.AbstractAlfrescoSolrIT.SolrServletRequest; import org.alfresco.solr.client.Acl; import org.alfresco.solr.client.AclChangeSet; import org.alfresco.solr.client.AclReaders; diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/AlfrescoTrackerRegistrationTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/AlfrescoTrackerRegistrationIT.java similarity index 96% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/AlfrescoTrackerRegistrationTest.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/AlfrescoTrackerRegistrationIT.java index cbb1c1e36..b679ec5fe 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/AlfrescoTrackerRegistrationTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/AlfrescoTrackerRegistrationIT.java @@ -30,7 +30,7 @@ import org.junit.BeforeClass; import org.junit.Test; @SolrTestCaseJ4.SuppressSSL -public class AlfrescoTrackerRegistrationTest extends AbstractAlfrescoSolrTests +public class AlfrescoTrackerRegistrationIT extends AbstractAlfrescoSolrIT { @BeforeClass public static void beforeClass() throws Exception { diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/CoresCreateUpdateDistributedTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/CoresCreateUpdateDistributedIT.java similarity index 99% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/CoresCreateUpdateDistributedTest.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/CoresCreateUpdateDistributedIT.java index 2081c770f..feb54a648 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/CoresCreateUpdateDistributedTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/CoresCreateUpdateDistributedIT.java @@ -51,7 +51,7 @@ import static org.alfresco.solr.AlfrescoSolrUtils.getCore; */ @SolrTestCaseJ4.SuppressSSL @LuceneTestCase.SuppressCodecs({"Appending","Lucene3x","Lucene40","Lucene41","Lucene42","Lucene43", "Lucene44", "Lucene45","Lucene46","Lucene47","Lucene48","Lucene49"}) -public class CoresCreateUpdateDistributedTest extends AbstractAlfrescoDistributedTest +public class CoresCreateUpdateDistributedIT extends AbstractAlfrescoDistributedIT { private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); final static String JETTY_SERVER_ID = "CoresCreateUpdateDistributedTest"; diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/CoresCreateViaPropertyTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/CoresCreateViaPropertyIT.java similarity index 97% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/CoresCreateViaPropertyTest.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/CoresCreateViaPropertyIT.java index 2bc699dd5..82d128394 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/CoresCreateViaPropertyTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/CoresCreateViaPropertyIT.java @@ -40,7 +40,7 @@ import static org.alfresco.solr.AlfrescoSolrUtils.getCore; */ @SolrTestCaseJ4.SuppressSSL @LuceneTestCase.SuppressCodecs({"Appending","Lucene3x","Lucene40","Lucene41","Lucene42","Lucene43", "Lucene44", "Lucene45","Lucene46","Lucene47","Lucene48","Lucene49"}) -public class CoresCreateViaPropertyTest extends AbstractAlfrescoDistributedTest +public class CoresCreateViaPropertyIT extends AbstractAlfrescoDistributedIT { private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); final static String JETTY_SERVER_ID = "CoresCreateViaPropertyTest"; diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/SolrTestInitializer.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/SolrITInitializer.java similarity index 99% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/SolrTestInitializer.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/SolrITInitializer.java index e9019df77..08be29603 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/SolrTestInitializer.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/SolrITInitializer.java @@ -69,7 +69,7 @@ import static org.alfresco.solr.AlfrescoSolrUtils.createCoreUsingTemplate; * @author Michael Suzuki */ @ThreadLeakLingering(linger = 5000) -public abstract class SolrTestInitializer extends SolrTestCaseJ4 +public abstract class SolrITInitializer extends SolrTestCaseJ4 { private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/TemplatesDistributedTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/TemplatesDistributedIT.java similarity index 97% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/TemplatesDistributedTest.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/TemplatesDistributedIT.java index 6ed551911..b7db5c77a 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/TemplatesDistributedTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/TemplatesDistributedIT.java @@ -40,7 +40,7 @@ import static org.alfresco.solr.AlfrescoSolrUtils.*; */ @SolrTestCaseJ4.SuppressSSL @LuceneTestCase.SuppressCodecs({"Appending","Lucene3x","Lucene40","Lucene41","Lucene42","Lucene43", "Lucene44", "Lucene45","Lucene46","Lucene47","Lucene48","Lucene49"}) -public class TemplatesDistributedTest extends AbstractAlfrescoDistributedTest +public class TemplatesDistributedIT extends AbstractAlfrescoDistributedIT { private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); final static String JETTY_SERVER_ID = "TemplatesDistributedTest"; diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/highlight/AlfrescoHighligherDistributedTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/highlight/AlfrescoHighligherDistributedIT.java similarity index 96% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/highlight/AlfrescoHighligherDistributedTest.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/highlight/AlfrescoHighligherDistributedIT.java index 62c0397d8..4eb9cae4c 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/highlight/AlfrescoHighligherDistributedTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/highlight/AlfrescoHighligherDistributedIT.java @@ -18,7 +18,7 @@ */ package org.alfresco.solr.highlight; -import org.alfresco.solr.AbstractAlfrescoDistributedTest; +import org.alfresco.solr.AbstractAlfrescoDistributedIT; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.lucene.util.LuceneTestCase; @@ -35,9 +35,9 @@ import org.junit.Test; */ @SolrTestCaseJ4.SuppressSSL @LuceneTestCase.SuppressCodecs({"Appending","Lucene3x","Lucene40","Lucene41","Lucene42","Lucene43", "Lucene44", "Lucene45","Lucene46","Lucene47","Lucene48","Lucene49"}) -public class AlfrescoHighligherDistributedTest extends AbstractAlfrescoDistributedTest +public class AlfrescoHighligherDistributedIT extends AbstractAlfrescoDistributedIT { - private static Log logger = LogFactory.getLog(AlfrescoHighligherDistributedTest.class); + private static Log logger = LogFactory.getLog(AlfrescoHighligherDistributedIT.class); @BeforeClass private static void initData() throws Throwable diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/highlight/AlfrescoHighlighterTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/highlight/AlfrescoHighlighterIT.java similarity index 95% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/highlight/AlfrescoHighlighterTest.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/highlight/AlfrescoHighlighterIT.java index b63746f64..c19a8ee68 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/highlight/AlfrescoHighlighterTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/highlight/AlfrescoHighlighterIT.java @@ -22,13 +22,9 @@ package org.alfresco.solr.highlight; import java.util.Map; import org.alfresco.model.ContentModel; import org.alfresco.repo.search.adaptor.lucene.QueryConstants; -import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.namespace.QName; -import org.alfresco.solr.AbstractAlfrescoSolrTests; -import org.alfresco.solr.AlfrescoCoreAdminHandler; +import org.alfresco.solr.AbstractAlfrescoSolrIT; import org.alfresco.solr.client.*; -import org.alfresco.solr.dataload.TestDataProvider; -import org.alfresco.util.Pair; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.lucene.index.Term; @@ -37,39 +33,27 @@ import org.apache.lucene.search.BooleanQuery; import org.apache.lucene.search.LegacyNumericRangeQuery; import org.apache.lucene.search.TermQuery; import org.apache.lucene.util.LuceneTestCase; -import org.apache.solr.client.solrj.response.QueryResponse; import org.apache.solr.common.params.HighlightParams; -import org.apache.solr.common.params.ModifiableSolrParams; -import org.apache.solr.response.BasicResultContext; -import org.apache.solr.response.SolrQueryResponse; -import org.junit.After; import org.junit.AfterClass; -import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import java.util.ArrayList; -import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Locale; -import java.util.Random; import static com.google.common.collect.ImmutableMap.of; import static java.util.Arrays.asList; -import static java.util.stream.IntStream.range; + import static junit.framework.TestCase.assertTrue; -import static org.alfresco.model.ContentModel.PROP_CREATOR; -import static org.alfresco.model.ContentModel.PROP_RATING_SCHEME; -import static org.alfresco.model.ContentModel.TYPE_CONTENT; import static org.alfresco.solr.AlfrescoSolrUtils.*; -import static org.apache.solr.SolrJettyTestBase.jetty; import static org.junit.Assert.assertNotNull; @LuceneTestCase.SuppressCodecs({"Appending","Lucene3x","Lucene40","Lucene41","Lucene42","Lucene43", "Lucene44", "Lucene45","Lucene46","Lucene47","Lucene48","Lucene49"}) -public class AlfrescoHighlighterTest extends AbstractAlfrescoSolrTests +public class AlfrescoHighlighterIT extends AbstractAlfrescoSolrIT { - private static Log logger = LogFactory.getLog(AlfrescoHighlighterTest.class); + private static Log logger = LogFactory.getLog(AlfrescoHighlighterIT.class); private static long MAX_WAIT_TIME = 80000; @BeforeClass diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/highlight/TestPostingsSolrHighlighter.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/highlight/PostingsSolrHighlighterIT.java similarity index 97% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/highlight/TestPostingsSolrHighlighter.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/highlight/PostingsSolrHighlighterIT.java index bc50a73c1..2b54f3af2 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/highlight/TestPostingsSolrHighlighter.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/highlight/PostingsSolrHighlighterIT.java @@ -16,12 +16,10 @@ */ package org.alfresco.solr.highlight; -import org.alfresco.solr.AbstractAlfrescoSolrTests; +import org.alfresco.solr.AbstractAlfrescoSolrIT; import org.apache.lucene.util.LuceneTestCase; -import org.apache.solr.SolrTestCaseJ4; import org.apache.solr.handler.component.AlfrescoSolrHighlighter; import org.apache.solr.handler.component.HighlightComponent; -import org.apache.solr.highlight.PostingsSolrHighlighter; import org.apache.solr.highlight.SolrHighlighter; import org.apache.solr.schema.IndexSchema; import org.junit.Before; @@ -31,7 +29,7 @@ import org.junit.Test; import static junit.framework.TestCase.*; @LuceneTestCase.SuppressCodecs({"Appending","Lucene3x","Lucene40","Lucene41","Lucene42","Lucene43", "Lucene44", "Lucene45","Lucene46","Lucene47","Lucene48","Lucene49"}) -public class TestPostingsSolrHighlighter extends AbstractAlfrescoSolrTests +public class PostingsSolrHighlighterIT extends AbstractAlfrescoSolrIT { @BeforeClass public static void beforeClass() throws Exception diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/AlfrescoReRankQParserPluginTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/AlfrescoReRankQParserPluginIT.java similarity index 97% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/query/AlfrescoReRankQParserPluginTest.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/query/AlfrescoReRankQParserPluginIT.java index 34d1a2d6b..1797a5c17 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/AlfrescoReRankQParserPluginTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/AlfrescoReRankQParserPluginIT.java @@ -22,7 +22,7 @@ package org.alfresco.solr.query; import java.util.ArrayList; import java.util.List; import java.util.Random; -import org.alfresco.solr.AbstractAlfrescoSolrTests; +import org.alfresco.solr.AbstractAlfrescoSolrIT; import org.apache.lucene.util.LuceneTestCase; import org.apache.solr.common.params.ModifiableSolrParams; import org.apache.solr.common.util.NamedList; @@ -38,7 +38,7 @@ import org.junit.Test; @LuceneTestCase.SuppressCodecs({"Appending","Lucene3x","Lucene40","Lucene41","Lucene42","Lucene43", "Lucene44", "Lucene45","Lucene46","Lucene47","Lucene48","Lucene49"}) -public class AlfrescoReRankQParserPluginTest extends AbstractAlfrescoSolrTests +public class AlfrescoReRankQParserPluginIT extends AbstractAlfrescoSolrIT { @BeforeClass public static void beforeClass() throws Exception diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/AlfrescoSolrFingerprintTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/AlfrescoSolrFingerprintIT.java similarity index 99% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/query/AlfrescoSolrFingerprintTest.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/query/AlfrescoSolrFingerprintIT.java index 96e1285c0..d9f0694e2 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/AlfrescoSolrFingerprintTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/AlfrescoSolrFingerprintIT.java @@ -21,7 +21,7 @@ package org.alfresco.solr.query; import org.alfresco.model.ContentModel; import org.alfresco.repo.search.adaptor.lucene.QueryConstants; -import org.alfresco.solr.AbstractAlfrescoSolrTests; +import org.alfresco.solr.AbstractAlfrescoSolrIT; import org.alfresco.solr.client.Acl; import org.alfresco.solr.client.AclChangeSet; import org.alfresco.solr.client.AclReaders; @@ -51,7 +51,7 @@ import static java.util.Collections.singletonList; import static java.util.stream.IntStream.range; import static org.alfresco.solr.AlfrescoSolrUtils.*; -public class AlfrescoSolrFingerprintTest extends AbstractAlfrescoSolrTests +public class AlfrescoSolrFingerprintIT extends AbstractAlfrescoSolrIT { private static long MAX_WAIT_TIME = 80000; diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/AlfrescoSolrSpellcheckerTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/AlfrescoSolrSpellcheckerIT.java similarity index 88% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/query/AlfrescoSolrSpellcheckerTest.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/query/AlfrescoSolrSpellcheckerIT.java index 98a723d2a..4d6ad4257 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/AlfrescoSolrSpellcheckerTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/AlfrescoSolrSpellcheckerIT.java @@ -19,31 +19,17 @@ package org.alfresco.solr.query; -import static org.junit.Assert.*; - -import java.util.ArrayList; -import java.util.List; -import java.util.Random; - -import org.alfresco.solr.AbstractAlfrescoSolrTests; +import org.alfresco.solr.AbstractAlfrescoSolrIT; import org.apache.lucene.util.LuceneTestCase; -import org.apache.lucene.util.RefCount; import org.apache.solr.common.params.ModifiableSolrParams; -import org.apache.solr.common.util.NamedList; import org.apache.solr.request.SolrQueryRequest; -import org.apache.solr.response.ResultContext; -import org.apache.solr.response.SolrQueryResponse; -import org.apache.solr.search.DocIterator; -import org.apache.solr.search.DocList; -import org.apache.solr.search.SolrIndexSearcher; -import org.apache.solr.util.RefCounted; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; @LuceneTestCase.SuppressCodecs({"Appending","Lucene3x","Lucene40","Lucene41","Lucene42","Lucene43", "Lucene44", "Lucene45","Lucene46","Lucene47","Lucene48","Lucene49"}) -public class AlfrescoSolrSpellcheckerTest extends AbstractAlfrescoSolrTests +public class AlfrescoSolrSpellcheckerIT extends AbstractAlfrescoSolrIT { @BeforeClass public static void beforeClass() throws Exception diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/AuthDataLoad.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/AuthDataLoad.java index 3a201b545..0b86af558 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/AuthDataLoad.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/AuthDataLoad.java @@ -34,7 +34,7 @@ import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter; import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.QName; -import org.alfresco.solr.AbstractAlfrescoSolrTests; +import org.alfresco.solr.AbstractAlfrescoSolrIT; import org.alfresco.solr.client.ContentPropertyValue; import org.alfresco.solr.client.MLTextPropertyValue; import org.alfresco.solr.client.PropertyValue; @@ -46,7 +46,7 @@ import org.junit.BeforeClass; * @author Michael Suzuki * */ -public class AuthDataLoad extends AbstractAlfrescoSolrTests +public class AuthDataLoad extends AbstractAlfrescoSolrIT { static int count = 100; static long maxReader = 1000; diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/AuthQueryTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/AuthQueryIT.java similarity index 99% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/query/AuthQueryTest.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/query/AuthQueryIT.java index 00cc9c06a..55a93e309 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/AuthQueryTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/AuthQueryIT.java @@ -39,7 +39,7 @@ import org.junit.Test; * @author Michael Suzuki * */ -public class AuthQueryTest extends AuthDataLoad +public class AuthQueryIT extends AuthDataLoad { @Test public void checkAuth() diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/DistributedAlfrescoSolrFacetingTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/DistributedAlfrescoSolrFacetingIT.java similarity index 99% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/query/DistributedAlfrescoSolrFacetingTest.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/query/DistributedAlfrescoSolrFacetingIT.java index 457497cd1..13f28d874 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/DistributedAlfrescoSolrFacetingTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/DistributedAlfrescoSolrFacetingIT.java @@ -18,7 +18,7 @@ */ package org.alfresco.solr.query; -import org.alfresco.solr.AbstractAlfrescoDistributedTest; +import org.alfresco.solr.AbstractAlfrescoDistributedIT; import org.apache.lucene.util.LuceneTestCase; import org.apache.solr.SolrTestCaseJ4; import org.apache.solr.client.solrj.response.FacetField; @@ -37,12 +37,12 @@ import static org.hamcrest.core.Is.is; @SolrTestCaseJ4.SuppressSSL @LuceneTestCase.SuppressCodecs({ "Appending", "Lucene3x", "Lucene40", "Lucene41", "Lucene42", "Lucene43", "Lucene44", "Lucene45", "Lucene46", "Lucene47", "Lucene48", - "Lucene49" }) public class DistributedAlfrescoSolrFacetingTest extends AbstractAlfrescoDistributedTest + "Lucene49" }) public class DistributedAlfrescoSolrFacetingIT extends AbstractAlfrescoDistributedIT { @BeforeClass private static void initData() throws Throwable { - initSolrServers(2, "DistributedAlfrescoSolrFacetingTest", null); + initSolrServers(2, "DistributedAlfrescoSolrFacetingIT", null); indexSampleDocumentsForFacetingMincount(); } diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/DistributedAlfrescoSolrFingerPrintTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/DistributedAlfrescoSolrFingerPrintIT.java similarity index 99% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/query/DistributedAlfrescoSolrFingerPrintTest.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/query/DistributedAlfrescoSolrFingerPrintIT.java index 980ad45db..dfd4326c8 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/DistributedAlfrescoSolrFingerPrintTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/DistributedAlfrescoSolrFingerPrintIT.java @@ -34,7 +34,7 @@ import java.util.Random; import org.alfresco.model.ContentModel; import org.alfresco.repo.search.adaptor.lucene.QueryConstants; -import org.alfresco.solr.AbstractAlfrescoDistributedTest; +import org.alfresco.solr.AbstractAlfrescoDistributedIT; import org.alfresco.solr.client.Acl; import org.alfresco.solr.client.AclChangeSet; import org.alfresco.solr.client.AclReaders; @@ -61,7 +61,7 @@ import org.junit.Test; */ @SolrTestCaseJ4.SuppressSSL @LuceneTestCase.SuppressCodecs({"Appending","Lucene3x","Lucene40","Lucene41","Lucene42","Lucene43", "Lucene44", "Lucene45","Lucene46","Lucene47","Lucene48","Lucene49"}) -public class DistributedAlfrescoSolrFingerPrintTest extends AbstractAlfrescoDistributedTest +public class DistributedAlfrescoSolrFingerPrintIT extends AbstractAlfrescoDistributedIT { private static long MAX_WAIT_TIME = 80000; diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/DistributedAlfrescoSolrSpellcheckerTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/DistributedAlfrescoSolrSpellcheckerIT.java similarity index 96% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/query/DistributedAlfrescoSolrSpellcheckerTest.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/query/DistributedAlfrescoSolrSpellcheckerIT.java index ea05e052a..1561564ed 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/DistributedAlfrescoSolrSpellcheckerTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/DistributedAlfrescoSolrSpellcheckerIT.java @@ -18,7 +18,7 @@ */ package org.alfresco.solr.query; -import org.alfresco.solr.AbstractAlfrescoDistributedTest; +import org.alfresco.solr.AbstractAlfrescoDistributedIT; import org.apache.lucene.util.LuceneTestCase; import org.apache.solr.SolrTestCaseJ4; import org.apache.solr.client.solrj.response.QueryResponse; @@ -32,7 +32,7 @@ import org.junit.Test; */ @SolrTestCaseJ4.SuppressSSL @LuceneTestCase.SuppressCodecs({"Appending","Lucene3x","Lucene40","Lucene41","Lucene42","Lucene43", "Lucene44", "Lucene45","Lucene46","Lucene47","Lucene48","Lucene49"}) -public class DistributedAlfrescoSolrSpellcheckerTest extends AbstractAlfrescoDistributedTest +public class DistributedAlfrescoSolrSpellcheckerIT extends AbstractAlfrescoDistributedIT { @BeforeClass private static void initData() throws Throwable diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/SolrAuthTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/SolrAuthIT.java similarity index 95% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/query/SolrAuthTest.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/query/SolrAuthIT.java index 2b4b28fe1..0491c2f4a 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/SolrAuthTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/SolrAuthIT.java @@ -20,19 +20,18 @@ package org.alfresco.solr.query; import org.alfresco.repo.search.adaptor.lucene.QueryConstants; -import org.alfresco.solr.AbstractAlfrescoSolrTests; +import org.alfresco.solr.AbstractAlfrescoSolrIT; import org.apache.lucene.util.LuceneTestCase; import org.apache.solr.SolrTestCaseJ4; import org.apache.solr.common.params.ModifiableSolrParams; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; -import org.junit.runners.Parameterized.Parameters; @LuceneTestCase.SuppressCodecs({"Appending","Lucene3x","Lucene40","Lucene41","Lucene42","Lucene43", "Lucene44", "Lucene45","Lucene46","Lucene47","Lucene48","Lucene49"}) @SolrTestCaseJ4.SuppressSSL -public class SolrAuthTest extends AbstractAlfrescoSolrTests +public class SolrAuthIT extends AbstractAlfrescoSolrIT { @BeforeClass diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/UntokenisedFieldTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/UntokenisedFieldIT.java similarity index 94% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/query/UntokenisedFieldTest.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/query/UntokenisedFieldIT.java index 0bfbf3614..694364efd 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/UntokenisedFieldTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/UntokenisedFieldIT.java @@ -18,9 +18,7 @@ */ package org.alfresco.solr.query; -import org.alfresco.model.ContentModel; -import org.alfresco.service.cmr.search.GeneralHighlightParameters; -import org.alfresco.solr.AbstractAlfrescoSolrTests; +import org.alfresco.solr.AbstractAlfrescoSolrIT; import org.junit.Before; import org.junit.Test; @@ -32,7 +30,7 @@ import org.junit.Test; * @author Michael Suzuki * */ -public class UntokenisedFieldTest extends AbstractAlfrescoSolrTests +public class UntokenisedFieldIT extends AbstractAlfrescoSolrIT { String nodeRef = "workspace://SpacesStore/00000000-0000-1-4731-76966678"; String nodeRefS = "noderef@s_@mytest" ; diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/qparser/AbstractQParserPluginTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/qparser/AbstractQParserPluginIT.java similarity index 74% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/qparser/AbstractQParserPluginTest.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/qparser/AbstractQParserPluginIT.java index 177760071..35520530a 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/qparser/AbstractQParserPluginTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/qparser/AbstractQParserPluginIT.java @@ -18,25 +18,16 @@ */ package org.alfresco.solr.query.afts.qparser; -import static java.util.Arrays.asList; -import static java.util.stream.IntStream.range; - -import org.alfresco.solr.AbstractAlfrescoSolrTests; +import org.alfresco.solr.AbstractAlfrescoSolrIT; import org.junit.BeforeClass; -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; -import java.util.stream.Collectors; -import java.util.stream.Stream; - /** * Supertype layer for all AFTS QParser tests. * * @author Andrea Gazzarini */ -public abstract class AbstractQParserPluginTest extends AbstractAlfrescoSolrTests +public abstract class AbstractQParserPluginIT extends AbstractAlfrescoSolrIT { @BeforeClass public static void spinUpSolr() throws Exception diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/qparser/FieldNameEscapingTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/qparser/FieldNameEscapingIT.java similarity index 94% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/qparser/FieldNameEscapingTest.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/qparser/FieldNameEscapingIT.java index 6485fd022..f2d103787 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/qparser/FieldNameEscapingTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/qparser/FieldNameEscapingIT.java @@ -24,7 +24,7 @@ import org.alfresco.util.ISO9075; import org.junit.BeforeClass; import org.junit.Test; -public class FieldNameEscapingTest extends AbstractQParserPluginTest implements QueryConstants +public class FieldNameEscapingIT extends AbstractQParserPluginIT implements QueryConstants { private static TestDataProvider DATASETS_PROVIDER; diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/qparser/QParserPluginTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/qparser/QParserPluginIT.java similarity index 99% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/qparser/QParserPluginTest.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/qparser/QParserPluginIT.java index 32c889d30..9a15161c8 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/qparser/QParserPluginTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/qparser/QParserPluginIT.java @@ -43,7 +43,7 @@ import org.junit.BeforeClass; import org.junit.Test; @SolrTestCaseJ4.SuppressSSL -public class QParserPluginTest extends AbstractQParserPluginTest implements QueryConstants +public class QParserPluginIT extends AbstractQParserPluginIT implements QueryConstants { /** The UTC time zone. */ private static final TimeZone UTC = TimeZone.getTimeZone("UTC"); diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/AFTSDefaultTextQueryTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/AFTSDefaultTextQueryIT.java similarity index 99% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/AFTSDefaultTextQueryTest.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/AFTSDefaultTextQueryIT.java index 6791bbf32..e4d3ad755 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/AFTSDefaultTextQueryTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/AFTSDefaultTextQueryIT.java @@ -49,7 +49,7 @@ import static com.google.common.collect.ImmutableMap.of; * This test set checks that in all these query types the default fields are involved in the search. * */ -public class AFTSDefaultTextQueryTest extends AbstractRequestHandlerTest +public class AFTSDefaultTextQueryIT extends AbstractRequestHandlerIT { @BeforeClass diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/AFTSDisjunctionTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/AFTSDisjunctionIT.java similarity index 97% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/AFTSDisjunctionTest.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/AFTSDisjunctionIT.java index 8462d00e3..3037a3e2d 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/AFTSDisjunctionTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/AFTSDisjunctionIT.java @@ -39,7 +39,7 @@ import org.junit.Test; * * @author msuzuki */ -public class AFTSDisjunctionTest extends AbstractRequestHandlerTest +public class AFTSDisjunctionIT extends AbstractRequestHandlerIT { @BeforeClass public static void beforeClass() throws Exception diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/AFTSIdentifierFieldsTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/AFTSIdentifierFieldsIT.java similarity index 97% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/AFTSIdentifierFieldsTest.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/AFTSIdentifierFieldsIT.java index 2dc910b8c..e4eac23b2 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/AFTSIdentifierFieldsTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/AFTSIdentifierFieldsIT.java @@ -43,7 +43,7 @@ import java.util.Map; * @author eporciani * @author agazzarini */ -public class AFTSIdentifierFieldsTest extends AbstractRequestHandlerTest +public class AFTSIdentifierFieldsIT extends AbstractRequestHandlerIT { @BeforeClass public static void beforeClass() throws Exception diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/AFTSRangeQueryTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/AFTSRangeQueryIT.java similarity index 98% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/AFTSRangeQueryTest.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/AFTSRangeQueryIT.java index ed38a5006..ba7dc7f13 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/AFTSRangeQueryTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/AFTSRangeQueryIT.java @@ -41,7 +41,7 @@ import java.util.Map; * * @author elia */ -public class AFTSRangeQueryTest extends AbstractRequestHandlerTest +public class AFTSRangeQueryIT extends AbstractRequestHandlerIT { @BeforeClass public static void beforeClass() throws Exception diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/AFTSRequestHandlerTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/AFTSRequestHandlerIT.java similarity index 99% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/AFTSRequestHandlerTest.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/AFTSRequestHandlerIT.java index b6f818791..131bd8dce 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/AFTSRequestHandlerTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/AFTSRequestHandlerIT.java @@ -20,7 +20,7 @@ import java.util.Locale; @LuceneTestCase.SuppressCodecs({"Appending","Lucene3x","Lucene40","Lucene41","Lucene42","Lucene43", "Lucene44", "Lucene45","Lucene46","Lucene47","Lucene48","Lucene49"}) @SolrTestCaseJ4.SuppressSSL -public class AFTSRequestHandlerTest extends AbstractRequestHandlerTest implements QueryConstants +public class AFTSRequestHandlerIT extends AbstractRequestHandlerIT implements QueryConstants { private static TestDataProvider DATASETS_PROVIDER; diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/AbstractRequestHandlerTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/AbstractRequestHandlerIT.java similarity index 95% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/AbstractRequestHandlerTest.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/AbstractRequestHandlerIT.java index 3a4bf2681..929b0d30e 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/AbstractRequestHandlerTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/AbstractRequestHandlerIT.java @@ -1,6 +1,6 @@ package org.alfresco.solr.query.afts.requestHandler; -import org.alfresco.solr.AbstractAlfrescoSolrTests; +import org.alfresco.solr.AbstractAlfrescoSolrIT; import org.junit.BeforeClass; import java.util.ArrayList; @@ -12,7 +12,7 @@ import java.util.stream.Stream; import static java.util.Arrays.asList; import static java.util.stream.IntStream.range; -public abstract class AbstractRequestHandlerTest extends AbstractAlfrescoSolrTests +public abstract class AbstractRequestHandlerIT extends AbstractAlfrescoSolrIT { @BeforeClass public static void spinUpSolr() throws Exception diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/MNTTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/MNTIT.java similarity index 97% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/MNTTest.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/MNTIT.java index a7b0dd5df..613e2da1e 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/MNTTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/MNTIT.java @@ -9,7 +9,7 @@ import org.junit.Test; * * @author Andrea Gazzarini */ -public class MNTTest extends AbstractRequestHandlerTest +public class MNTIT extends AbstractRequestHandlerIT { @BeforeClass public static void loadData() throws Exception diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/cmis/CmisTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/cmis/CmisIT.java similarity index 99% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/query/cmis/CmisTest.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/query/cmis/CmisIT.java index 570a88cc9..6b05203f2 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/cmis/CmisTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/cmis/CmisIT.java @@ -31,7 +31,7 @@ import org.junit.Test; * @author Michael Suzuki * */ -public class CmisTest extends LoadCMISData +public class CmisIT extends LoadCMISData { @Before public void setup() throws Exception diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/cmis/LoadCMISData.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/cmis/LoadCMISData.java index 46082dac9..f64efe0a5 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/cmis/LoadCMISData.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/cmis/LoadCMISData.java @@ -37,7 +37,7 @@ import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter; import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.QName; -import org.alfresco.solr.AbstractAlfrescoSolrTests; +import org.alfresco.solr.AbstractAlfrescoSolrIT; import org.alfresco.solr.AlfrescoSolrDataModel; import org.alfresco.solr.client.ContentPropertyValue; import org.alfresco.solr.client.MLTextPropertyValue; @@ -51,7 +51,7 @@ import org.junit.BeforeClass; * @author Michael Suzuki * */ -public class LoadCMISData extends AbstractAlfrescoSolrTests +public class LoadCMISData extends AbstractAlfrescoSolrIT { protected static NodeRef testCMISContent00NodeRef; protected static NodeRef testCMISRootNodeRef; diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/AclModCountRouterTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/AclModCountRouterIT.java similarity index 99% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/AclModCountRouterTest.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/AclModCountRouterIT.java index c903cd8f3..451b29ed6 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/AclModCountRouterTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/AclModCountRouterIT.java @@ -39,7 +39,7 @@ import java.util.Map; import java.util.Properties; @RunWith(MockitoJUnitRunner.class) -public class AclModCountRouterTest +public class AclModCountRouterIT { private DocRouter router; diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/AlfrescoSolrTrackerExceptionTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/AlfrescoSolrTrackerExceptionIT.java similarity index 99% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/AlfrescoSolrTrackerExceptionTest.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/AlfrescoSolrTrackerExceptionIT.java index 8a728a519..43d779f8f 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/AlfrescoSolrTrackerExceptionTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/AlfrescoSolrTrackerExceptionIT.java @@ -36,7 +36,7 @@ import org.alfresco.model.ContentModel; import org.alfresco.repo.search.adaptor.lucene.QueryConstants; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.StoreRef; -import org.alfresco.solr.AbstractAlfrescoSolrTests; +import org.alfresco.solr.AbstractAlfrescoSolrIT; import org.alfresco.solr.client.Acl; import org.alfresco.solr.client.AclChangeSet; import org.alfresco.solr.client.AclReaders; @@ -62,9 +62,9 @@ import org.junit.Test; @LuceneTestCase.SuppressCodecs({"Appending","Lucene3x","Lucene40","Lucene41","Lucene42","Lucene43", "Lucene44", "Lucene45","Lucene46","Lucene47","Lucene48","Lucene49"}) @SolrTestCaseJ4.SuppressSSL -public class AlfrescoSolrTrackerExceptionTest extends AbstractAlfrescoSolrTests +public class AlfrescoSolrTrackerExceptionIT extends AbstractAlfrescoSolrIT { - private static Log logger = LogFactory.getLog(AlfrescoSolrTrackerTest.class); + private static Log logger = LogFactory.getLog(AlfrescoSolrTrackerExceptionIT.class); private static long MAX_WAIT_TIME = 80000; @BeforeClass public static void beforeClass() throws Exception diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/AlfrescoSolrTrackerTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/AlfrescoSolrTrackerIT.java similarity index 99% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/AlfrescoSolrTrackerTest.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/AlfrescoSolrTrackerIT.java index c1e8c70fb..749e82c03 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/AlfrescoSolrTrackerTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/AlfrescoSolrTrackerIT.java @@ -37,7 +37,7 @@ import org.alfresco.model.ContentModel; import org.alfresco.repo.search.adaptor.lucene.QueryConstants; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.StoreRef; -import org.alfresco.solr.AbstractAlfrescoSolrTests; +import org.alfresco.solr.AbstractAlfrescoSolrIT; import org.alfresco.solr.client.Acl; import org.alfresco.solr.client.AclChangeSet; import org.alfresco.solr.client.AclReaders; @@ -64,9 +64,9 @@ import org.junit.Test; @LuceneTestCase.SuppressCodecs({"Appending","Lucene3x","Lucene40","Lucene41","Lucene42","Lucene43", "Lucene44", "Lucene45","Lucene46","Lucene47","Lucene48","Lucene49"}) @SolrTestCaseJ4.SuppressSSL -public class AlfrescoSolrTrackerTest extends AbstractAlfrescoSolrTests +public class AlfrescoSolrTrackerIT extends AbstractAlfrescoSolrIT { - private static Log logger = LogFactory.getLog(AlfrescoSolrTrackerTest.class); + private static Log logger = LogFactory.getLog(AlfrescoSolrTrackerIT.class); private static long MAX_WAIT_TIME = 80000; @BeforeClass public static void beforeClass() throws Exception diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/AlfrescoSolrTrackerRollbackTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/AlfrescoSolrTrackerRollbackIT.java similarity index 98% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/AlfrescoSolrTrackerRollbackTest.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/AlfrescoSolrTrackerRollbackIT.java index d2ea46e05..2313586ac 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/AlfrescoSolrTrackerRollbackTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/AlfrescoSolrTrackerRollbackIT.java @@ -32,7 +32,7 @@ import java.util.Collection; import org.alfresco.repo.search.adaptor.lucene.QueryConstants; -import org.alfresco.solr.AbstractAlfrescoSolrTests; +import org.alfresco.solr.AbstractAlfrescoSolrIT; import org.alfresco.solr.AlfrescoCoreAdminHandler; import org.alfresco.solr.client.Acl; @@ -58,9 +58,9 @@ import org.junit.Test; @LuceneTestCase.SuppressCodecs({"Appending","Lucene3x","Lucene40","Lucene41","Lucene42","Lucene43", "Lucene44", "Lucene45","Lucene46","Lucene47","Lucene48","Lucene49"}) @SolrTestCaseJ4.SuppressSSL -public class AlfrescoSolrTrackerRollbackTest extends AbstractAlfrescoSolrTests +public class AlfrescoSolrTrackerRollbackIT extends AbstractAlfrescoSolrIT { - private static Log logger = LogFactory.getLog(AlfrescoSolrTrackerTest.class); + private static Log logger = LogFactory.getLog(AlfrescoSolrTrackerIT.class); private static long MAX_WAIT_TIME = 80000; @BeforeClass public static void beforeClass() throws Exception diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/AlfrescoSolrTrackerStateTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/AlfrescoSolrTrackerStateIT.java similarity index 98% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/AlfrescoSolrTrackerStateTest.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/AlfrescoSolrTrackerStateIT.java index d37d8ab99..119aab737 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/AlfrescoSolrTrackerStateTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/AlfrescoSolrTrackerStateIT.java @@ -36,7 +36,7 @@ import static org.junit.Assert.assertNotEquals; import org.alfresco.repo.index.shard.ShardState; import org.alfresco.repo.search.adaptor.lucene.QueryConstants; -import org.alfresco.solr.AbstractAlfrescoSolrTests; +import org.alfresco.solr.AbstractAlfrescoSolrIT; import org.alfresco.solr.AlfrescoCoreAdminHandler; import org.alfresco.solr.client.Acl; import org.alfresco.solr.client.AclChangeSet; @@ -70,7 +70,7 @@ import java.util.stream.Collectors; * * @author agazzarini */ -public class AlfrescoSolrTrackerStateTest extends AbstractAlfrescoSolrTests +public class AlfrescoSolrTrackerStateIT extends AbstractAlfrescoSolrIT { @BeforeClass public static void beforeClass() throws Exception diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/CascadeTrackerTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/CascadeTrackerIT.java similarity index 98% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/CascadeTrackerTest.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/CascadeTrackerIT.java index 16f1b0c56..00c34cfa4 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/CascadeTrackerTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/CascadeTrackerIT.java @@ -35,7 +35,7 @@ import org.alfresco.model.ContentModel; import org.alfresco.repo.search.adaptor.lucene.QueryConstants; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.StoreRef; -import org.alfresco.solr.AbstractAlfrescoSolrTests; +import org.alfresco.solr.AbstractAlfrescoSolrIT; import org.alfresco.solr.client.*; import org.apache.lucene.index.Term; import org.apache.lucene.search.*; @@ -52,7 +52,7 @@ import java.util.List; @LuceneTestCase.SuppressCodecs({"Appending","Lucene3x","Lucene40","Lucene41","Lucene42","Lucene43", "Lucene44", "Lucene45","Lucene46","Lucene47","Lucene48","Lucene49"}) @SolrTestCaseJ4.SuppressSSL -public class CascadeTrackerTest extends AbstractAlfrescoSolrTests +public class CascadeTrackerIT extends AbstractAlfrescoSolrIT { private static long MAX_WAIT_TIME = 80000; diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/ContentTrackerTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/ContentTrackerIT.java similarity index 99% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/ContentTrackerTest.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/ContentTrackerIT.java index e3d6112da..517a5f241 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/ContentTrackerTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/ContentTrackerIT.java @@ -38,7 +38,7 @@ import org.mockito.Spy; import org.mockito.runners.MockitoJUnitRunner; @RunWith(MockitoJUnitRunner.class) -public class ContentTrackerTest +public class ContentTrackerIT { private ContentTracker contentTracker; diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DateMonthRouterTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DateMonthRouterIT.java similarity index 99% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DateMonthRouterTest.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DateMonthRouterIT.java index 2432966d5..03cf95823 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DateMonthRouterTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DateMonthRouterIT.java @@ -46,7 +46,7 @@ import java.util.Properties; import java.util.Random; @RunWith(MockitoJUnitRunner.class) -public class DateMonthRouterTest +public class DateMonthRouterIT { private Random randomizer = new Random(); diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedAclIdAlfrescoSolrTrackerTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedAclIdAlfrescoSolrTrackerIT.java similarity index 97% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedAclIdAlfrescoSolrTrackerTest.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedAclIdAlfrescoSolrTrackerIT.java index f177f915d..8c268e01a 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedAclIdAlfrescoSolrTrackerTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedAclIdAlfrescoSolrTrackerIT.java @@ -19,7 +19,7 @@ package org.alfresco.solr.tracker; import org.alfresco.repo.index.shard.ShardMethodEnum; -import org.alfresco.solr.AbstractAlfrescoDistributedTest; +import org.alfresco.solr.AbstractAlfrescoDistributedIT; import org.alfresco.solr.SolrInformationServer; import org.alfresco.solr.client.Acl; import org.alfresco.solr.client.AclChangeSet; @@ -57,7 +57,7 @@ import static org.alfresco.solr.AlfrescoSolrUtils.list; */ @SolrTestCaseJ4.SuppressSSL @LuceneTestCase.SuppressCodecs({"Appending","Lucene3x","Lucene40","Lucene41","Lucene42","Lucene43", "Lucene44", "Lucene45","Lucene46","Lucene47","Lucene48","Lucene49"}) -public class DistributedAclIdAlfrescoSolrTrackerTest extends AbstractAlfrescoDistributedTest +public class DistributedAclIdAlfrescoSolrTrackerIT extends AbstractAlfrescoDistributedIT { @BeforeClass diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedAlfrescoSolrJsonTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedAlfrescoSolrJsonIT.java similarity index 97% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedAlfrescoSolrJsonTest.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedAlfrescoSolrJsonIT.java index 1a86633e2..c0d0c14ec 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedAlfrescoSolrJsonTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedAlfrescoSolrJsonIT.java @@ -19,7 +19,7 @@ package org.alfresco.solr.tracker; import org.alfresco.repo.search.adaptor.lucene.QueryConstants; -import org.alfresco.solr.AbstractAlfrescoDistributedTest; +import org.alfresco.solr.AbstractAlfrescoDistributedIT; import org.alfresco.solr.client.Acl; import org.alfresco.solr.client.AclChangeSet; import org.alfresco.solr.client.Node; @@ -50,7 +50,7 @@ import static org.alfresco.solr.AlfrescoSolrUtils.getTransaction; */ @SolrTestCaseJ4.SuppressSSL @LuceneTestCase.SuppressCodecs({"Appending","Lucene3x","Lucene40","Lucene41","Lucene42","Lucene43", "Lucene44", "Lucene45","Lucene46","Lucene47","Lucene48","Lucene49"}) -public class DistributedAlfrescoSolrJsonTest extends AbstractAlfrescoDistributedTest +public class DistributedAlfrescoSolrJsonIT extends AbstractAlfrescoDistributedIT { @BeforeClass private static void initData() throws Throwable diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedAlfrescoSolrTrackerTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedAlfrescoSolrTrackerIT.java similarity index 98% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedAlfrescoSolrTrackerTest.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedAlfrescoSolrTrackerIT.java index b80d8793e..8b0f610f9 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedAlfrescoSolrTrackerTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedAlfrescoSolrTrackerIT.java @@ -19,7 +19,7 @@ package org.alfresco.solr.tracker; import org.alfresco.repo.search.adaptor.lucene.QueryConstants; -import org.alfresco.solr.AbstractAlfrescoDistributedTest; +import org.alfresco.solr.AbstractAlfrescoDistributedIT; import org.alfresco.solr.client.Acl; import org.alfresco.solr.client.AclChangeSet; import org.alfresco.solr.client.AclReaders; @@ -56,7 +56,7 @@ import static org.alfresco.solr.AlfrescoSolrUtils.list; */ @SolrTestCaseJ4.SuppressSSL @LuceneTestCase.SuppressCodecs({"Appending","Lucene3x","Lucene40","Lucene41","Lucene42","Lucene43", "Lucene44", "Lucene45","Lucene46","Lucene47","Lucene48","Lucene49"}) -public class DistributedAlfrescoSolrTrackerTest extends AbstractAlfrescoDistributedTest +public class DistributedAlfrescoSolrTrackerIT extends AbstractAlfrescoDistributedIT { @BeforeClass diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedAlfrescoSolrTrackerRaceTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedAlfrescoSolrTrackerRaceIT.java similarity index 97% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedAlfrescoSolrTrackerRaceTest.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedAlfrescoSolrTrackerRaceIT.java index 65bab2295..01290fcc7 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedAlfrescoSolrTrackerRaceTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedAlfrescoSolrTrackerRaceIT.java @@ -19,7 +19,7 @@ package org.alfresco.solr.tracker; import org.alfresco.repo.search.adaptor.lucene.QueryConstants; -import org.alfresco.solr.AbstractAlfrescoDistributedTest; +import org.alfresco.solr.AbstractAlfrescoDistributedIT; import org.alfresco.solr.client.Acl; import org.alfresco.solr.client.AclChangeSet; import org.alfresco.solr.client.AclReaders; @@ -54,7 +54,7 @@ import static org.alfresco.solr.AlfrescoSolrUtils.indexAclChangeSet; */ @SolrTestCaseJ4.SuppressSSL @LuceneTestCase.SuppressCodecs({"Appending","Lucene3x","Lucene40","Lucene41","Lucene42","Lucene43", "Lucene44", "Lucene45","Lucene46","Lucene47","Lucene48","Lucene49"}) -public class DistributedAlfrescoSolrTrackerRaceTest extends AbstractAlfrescoDistributedTest +public class DistributedAlfrescoSolrTrackerRaceIT extends AbstractAlfrescoDistributedIT { @BeforeClass diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedAlfrescoSolrTrackerStateTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedAlfrescoSolrTrackerStateIT.java similarity index 98% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedAlfrescoSolrTrackerStateTest.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedAlfrescoSolrTrackerStateIT.java index 58e697c9d..e33447951 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedAlfrescoSolrTrackerStateTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedAlfrescoSolrTrackerStateIT.java @@ -33,7 +33,7 @@ import static org.alfresco.solr.AlfrescoSolrUtils.indexAclChangeSet; import org.alfresco.repo.index.shard.ShardState; import org.alfresco.repo.search.adaptor.lucene.QueryConstants; -import org.alfresco.solr.AbstractAlfrescoDistributedTest; +import org.alfresco.solr.AbstractAlfrescoDistributedIT; import org.alfresco.solr.AlfrescoCoreAdminHandler; import org.alfresco.solr.client.Acl; import org.alfresco.solr.client.AclChangeSet; @@ -68,7 +68,7 @@ import java.util.stream.Collectors; * @author agazzarini */ @SolrTestCaseJ4.SuppressSSL -public class DistributedAlfrescoSolrTrackerStateTest extends AbstractAlfrescoDistributedTest +public class DistributedAlfrescoSolrTrackerStateIT extends AbstractAlfrescoDistributedIT { @BeforeClass private static void initData() throws Throwable diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedCascadeTrackerTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedCascadeTrackerIT.java similarity index 98% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedCascadeTrackerTest.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedCascadeTrackerIT.java index cba592b86..6e5fbe39f 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedCascadeTrackerTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedCascadeTrackerIT.java @@ -30,7 +30,7 @@ import static org.alfresco.solr.AlfrescoSolrUtils.indexAclChangeSet; import static org.carrot2.shaded.guava.common.collect.ImmutableList.of; import org.alfresco.model.ContentModel; -import org.alfresco.solr.AbstractAlfrescoDistributedTest; +import org.alfresco.solr.AbstractAlfrescoDistributedIT; import org.alfresco.solr.client.Acl; import org.alfresco.solr.client.AclChangeSet; import org.alfresco.solr.client.AclReaders; @@ -55,7 +55,7 @@ import java.util.Properties; */ @SolrTestCaseJ4.SuppressSSL @LuceneTestCase.SuppressCodecs({"Appending","Lucene3x","Lucene40","Lucene41","Lucene42","Lucene43", "Lucene44", "Lucene45","Lucene46","Lucene47","Lucene48","Lucene49"}) -public class DistributedCascadeTrackerTest extends AbstractAlfrescoDistributedTest +public class DistributedCascadeTrackerIT extends AbstractAlfrescoDistributedIT { private Node parentFolder; private NodeMetaData parentFolderMetadata; diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedDateAbstractSolrTrackerTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedDateAbstractSolrTrackerIT.java similarity index 97% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedDateAbstractSolrTrackerTest.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedDateAbstractSolrTrackerIT.java index 6aacd0282..1cdaa1cc2 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedDateAbstractSolrTrackerTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedDateAbstractSolrTrackerIT.java @@ -21,7 +21,7 @@ package org.alfresco.solr.tracker; import org.alfresco.model.ContentModel; import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter; import org.alfresco.service.namespace.QName; -import org.alfresco.solr.AbstractAlfrescoDistributedTest; +import org.alfresco.solr.AbstractAlfrescoDistributedIT; import org.alfresco.solr.AlfrescoSolrDataModel; import org.alfresco.solr.client.Acl; import org.alfresco.solr.client.AclChangeSet; @@ -63,7 +63,7 @@ import static org.alfresco.solr.AlfrescoSolrUtils.indexAclChangeSet; */ @SolrTestCaseJ4.SuppressSSL @LuceneTestCase.SuppressCodecs({"Appending","Lucene3x","Lucene40","Lucene41","Lucene42","Lucene43", "Lucene44", "Lucene45","Lucene46","Lucene47","Lucene48","Lucene49"}) -public abstract class DistributedDateAbstractSolrTrackerTest extends AbstractAlfrescoDistributedTest +public abstract class DistributedDateAbstractSolrTrackerIT extends AbstractAlfrescoDistributedIT { @Test public void testDateMonth() throws Exception diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedDateMonthAlfrescoSolrTrackerTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedDateMonthAlfrescoSolrTrackerIT.java similarity index 97% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedDateMonthAlfrescoSolrTrackerTest.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedDateMonthAlfrescoSolrTrackerIT.java index e0a569b4a..8dcbf6e5e 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedDateMonthAlfrescoSolrTrackerTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedDateMonthAlfrescoSolrTrackerIT.java @@ -33,7 +33,7 @@ import org.alfresco.model.ContentModel; import org.alfresco.repo.index.shard.ShardMethodEnum; import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter; import org.alfresco.service.namespace.QName; -import org.alfresco.solr.AbstractAlfrescoDistributedTest; +import org.alfresco.solr.AbstractAlfrescoDistributedIT; import org.alfresco.solr.AlfrescoSolrDataModel; import org.alfresco.solr.SolrInformationServer; import org.alfresco.solr.client.Acl; @@ -63,13 +63,13 @@ import java.util.Properties; import java.util.TimeZone; @SolrTestCaseJ4.SuppressSSL -public class DistributedDateMonthAlfrescoSolrTrackerTest extends AbstractAlfrescoDistributedTest +public class DistributedDateMonthAlfrescoSolrTrackerIT extends AbstractAlfrescoDistributedIT { @BeforeClass @SuppressWarnings("unused") public static void initData() throws Throwable { - initSolrServers(5, DistributedDateMonthAlfrescoSolrTrackerTest.class.getSimpleName(), getShardMethod()); + initSolrServers(5, DistributedDateMonthAlfrescoSolrTrackerIT.class.getSimpleName(), getShardMethod()); } @AfterClass diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedDateQuarterAlfrescoSolrTrackerTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedDateQuarterAlfrescoSolrTrackerIT.java similarity index 95% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedDateQuarterAlfrescoSolrTrackerTest.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedDateQuarterAlfrescoSolrTrackerIT.java index 0c8c061f3..f2dc207c6 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedDateQuarterAlfrescoSolrTrackerTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedDateQuarterAlfrescoSolrTrackerIT.java @@ -33,7 +33,7 @@ import java.util.Properties; @SolrTestCaseJ4.SuppressSSL @LuceneTestCase.SuppressCodecs({"Appending","Lucene3x","Lucene40","Lucene41","Lucene42","Lucene43", "Lucene44", "Lucene45","Lucene46","Lucene47","Lucene48","Lucene49"}) -public class DistributedDateQuarterAlfrescoSolrTrackerTest extends DistributedDateAbstractSolrTrackerTest +public class DistributedDateQuarterAlfrescoSolrTrackerIT extends DistributedDateAbstractSolrTrackerIT { @BeforeClass diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedDateSplitYearAlfrescoSolrTrackerTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedDateSplitYearAlfrescoSolrTrackerIT.java similarity index 93% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedDateSplitYearAlfrescoSolrTrackerTest.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedDateSplitYearAlfrescoSolrTrackerIT.java index faa7618c0..ff488c138 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedDateSplitYearAlfrescoSolrTrackerTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedDateSplitYearAlfrescoSolrTrackerIT.java @@ -33,12 +33,12 @@ import java.util.Properties; @SolrTestCaseJ4.SuppressSSL @LuceneTestCase.SuppressCodecs({"Appending","Lucene3x","Lucene40","Lucene41","Lucene42","Lucene43", "Lucene44", "Lucene45","Lucene46","Lucene47","Lucene48","Lucene49"}) -public class DistributedDateSplitYearAlfrescoSolrTrackerTest extends DistributedDateAbstractSolrTrackerTest +public class DistributedDateSplitYearAlfrescoSolrTrackerIT extends DistributedDateAbstractSolrTrackerIT { @BeforeClass private static void initData() throws Throwable { - initSolrServers(3, "DistributedDateSplitYearAlfrescoSolrTrackerTest", getShardMethod()); + initSolrServers(3, "DistributedDateSplitYearAlfrescoSolrTrackerIT", getShardMethod()); } @AfterClass diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedDbidRangeAlfrescoSolrTrackerTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedDbidRangeAlfrescoSolrTrackerIT.java similarity index 96% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedDbidRangeAlfrescoSolrTrackerTest.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedDbidRangeAlfrescoSolrTrackerIT.java index 8d8655728..f683c0ce1 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedDbidRangeAlfrescoSolrTrackerTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedDbidRangeAlfrescoSolrTrackerIT.java @@ -18,7 +18,7 @@ */ package org.alfresco.solr.tracker; -import org.alfresco.solr.AbstractAlfrescoDistributedTest; +import org.alfresco.solr.AbstractAlfrescoDistributedIT; import org.alfresco.solr.SolrInformationServer; import org.alfresco.solr.client.Acl; import org.alfresco.solr.client.AclChangeSet; @@ -53,12 +53,12 @@ import static org.alfresco.solr.AlfrescoSolrUtils.list; */ @SolrTestCaseJ4.SuppressSSL @LuceneTestCase.SuppressCodecs({"Appending","Lucene3x","Lucene40","Lucene41","Lucene42","Lucene43", "Lucene44", "Lucene45","Lucene46","Lucene47","Lucene48","Lucene49"}) -public class DistributedDbidRangeAlfrescoSolrTrackerTest extends AbstractAlfrescoDistributedTest +public class DistributedDbidRangeAlfrescoSolrTrackerIT extends AbstractAlfrescoDistributedIT { @BeforeClass private static void initData() throws Throwable { - initSolrServers(2, "DistributedDbidRangeAlfrescoSolrTrackerTest", getShardMethod()); + initSolrServers(2, "DistributedDbidRangeAlfrescoSolrTrackerIT", getShardMethod()); } @AfterClass diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedExpandDbidRangeAlfrescoSolrTrackerTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedExpandDbidRangeAlfrescoSolrTrackerIT.java similarity index 98% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedExpandDbidRangeAlfrescoSolrTrackerTest.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedExpandDbidRangeAlfrescoSolrTrackerIT.java index cf6ca9dbd..07c07f0b7 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedExpandDbidRangeAlfrescoSolrTrackerTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedExpandDbidRangeAlfrescoSolrTrackerIT.java @@ -18,7 +18,7 @@ */ package org.alfresco.solr.tracker; -import org.alfresco.solr.AbstractAlfrescoDistributedTest; +import org.alfresco.solr.AbstractAlfrescoDistributedIT; import org.alfresco.solr.SolrInformationServer; import org.alfresco.solr.client.Acl; import org.alfresco.solr.client.AclChangeSet; @@ -56,12 +56,12 @@ import static org.alfresco.solr.AlfrescoSolrUtils.list; */ @SolrTestCaseJ4.SuppressSSL @LuceneTestCase.SuppressCodecs({"Appending","Lucene3x","Lucene40","Lucene41","Lucene42","Lucene43", "Lucene44", "Lucene45","Lucene46","Lucene47","Lucene48","Lucene49"}) -public class DistributedExpandDbidRangeAlfrescoSolrTrackerTest extends AbstractAlfrescoDistributedTest +public class DistributedExpandDbidRangeAlfrescoSolrTrackerIT extends AbstractAlfrescoDistributedIT { @BeforeClass private static void initData() throws Throwable { - initSolrServers(2, "DistributedExpandDbidRangeAlfrescoSolrTrackerTest", getShardMethod()); + initSolrServers(2, "DistributedExpandDbidRangeAlfrescoSolrTrackerIT", getShardMethod()); } @AfterClass diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedExplicitShardIdWithStaticPropertyRouterTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedExplicitShardIdWithStaticPropertyRouterIT.java similarity index 97% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedExplicitShardIdWithStaticPropertyRouterTest.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedExplicitShardIdWithStaticPropertyRouterIT.java index 115d81029..7ccf1792e 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedExplicitShardIdWithStaticPropertyRouterTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedExplicitShardIdWithStaticPropertyRouterIT.java @@ -21,7 +21,7 @@ package org.alfresco.solr.tracker; import java.util.Properties; import org.alfresco.model.ContentModel; import org.alfresco.repo.index.shard.ShardMethodEnum; -import org.alfresco.solr.AbstractAlfrescoDistributedTest; +import org.alfresco.solr.AbstractAlfrescoDistributedIT; import org.alfresco.solr.client.Acl; import org.alfresco.solr.client.AclChangeSet; import org.alfresco.solr.client.AclReaders; @@ -53,7 +53,7 @@ import static org.carrot2.shaded.guava.common.collect.ImmutableList.of; @SolrTestCaseJ4.SuppressSSL @SolrTestCaseJ4.SuppressObjectReleaseTracker (bugUrl = "RAMDirectory") @LuceneTestCase.SuppressCodecs({"Appending","Lucene3x","Lucene40","Lucene41","Lucene42","Lucene43", "Lucene44", "Lucene45","Lucene46","Lucene47","Lucene48","Lucene49"}) -public class DistributedExplicitShardIdWithStaticPropertyRouterTest extends AbstractAlfrescoDistributedTest +public class DistributedExplicitShardIdWithStaticPropertyRouterIT extends AbstractAlfrescoDistributedIT { private static long MAX_WAIT_TIME = 80000; private final int timeout = 100000; diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedExplicitShardRoutingTrackerTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedExplicitShardRoutingTrackerIT.java similarity index 97% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedExplicitShardRoutingTrackerTest.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedExplicitShardRoutingTrackerIT.java index b10bdc275..bd7c5f325 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedExplicitShardRoutingTrackerTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedExplicitShardRoutingTrackerIT.java @@ -20,7 +20,7 @@ package org.alfresco.solr.tracker; import org.alfresco.model.ContentModel; import org.alfresco.repo.index.shard.ShardMethodEnum; -import org.alfresco.solr.AbstractAlfrescoDistributedTest; +import org.alfresco.solr.AbstractAlfrescoDistributedIT; import org.alfresco.solr.SolrInformationServer; import org.alfresco.solr.client.Acl; import org.alfresco.solr.client.AclChangeSet; @@ -62,12 +62,12 @@ import static org.alfresco.solr.tracker.DocRouterFactory.SHARD_KEY_KEY; @SolrTestCaseJ4.SuppressSSL @SolrTestCaseJ4.SuppressObjectReleaseTracker (bugUrl = "RAMDirectory") @LuceneTestCase.SuppressCodecs({"Appending","Lucene3x","Lucene40","Lucene41","Lucene42","Lucene43", "Lucene44", "Lucene45","Lucene46","Lucene47","Lucene48","Lucene49"}) -public class DistributedExplicitShardRoutingTrackerTest extends AbstractAlfrescoDistributedTest +public class DistributedExplicitShardRoutingTrackerIT extends AbstractAlfrescoDistributedIT { @BeforeClass private static void initData() throws Throwable { - initSolrServers(3, "DistributedExplicitShardRoutingTrackerTest", getProperties()); + initSolrServers(3, "DistributedExplicitShardRoutingTrackerIT", getProperties()); } @AfterClass diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedPropertyBasedAlfrescoSolrTrackerTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedPropertyBasedAlfrescoSolrTrackerIT.java similarity index 97% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedPropertyBasedAlfrescoSolrTrackerTest.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedPropertyBasedAlfrescoSolrTrackerIT.java index ac01034b2..1e7c8b8f4 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedPropertyBasedAlfrescoSolrTrackerTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedPropertyBasedAlfrescoSolrTrackerIT.java @@ -41,7 +41,7 @@ import com.carrotsearch.randomizedtesting.RandomizedContext; import org.alfresco.model.ContentModel; import org.alfresco.repo.index.shard.ShardMethodEnum; -import org.alfresco.solr.AbstractAlfrescoDistributedTest; +import org.alfresco.solr.AbstractAlfrescoDistributedIT; import org.alfresco.solr.SolrInformationServer; import org.alfresco.solr.client.Acl; import org.alfresco.solr.client.AclChangeSet; @@ -66,7 +66,7 @@ import org.junit.Test; @SolrTestCaseJ4.SuppressSSL @SolrTestCaseJ4.SuppressObjectReleaseTracker (bugUrl = "RAMDirectory") @LuceneTestCase.SuppressCodecs({"Appending","Lucene3x","Lucene40","Lucene41","Lucene42","Lucene43", "Lucene44", "Lucene45","Lucene46","Lucene47","Lucene48","Lucene49"}) -public class DistributedPropertyBasedAlfrescoSolrTrackerTest extends AbstractAlfrescoDistributedTest +public class DistributedPropertyBasedAlfrescoSolrTrackerIT extends AbstractAlfrescoDistributedIT { private static final String[] DOMAINS = {"alfresco.com", "king.com", "gmail.com", "yahoo.com", "cookie.es"}; private static final Map domainsCount = new HashMap<>(); @@ -78,7 +78,7 @@ public class DistributedPropertyBasedAlfrescoSolrTrackerTest extends AbstractAlf { domainsCount.put(domain,0); } - initSolrServers(4, "DistributedPropertyBasedAlfrescoSolrTrackerTest", getProperties()); + initSolrServers(4, "DistributedPropertyBasedAlfrescoSolrTrackerIT", getProperties()); } @AfterClass diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/ExplicitIDRouterTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/ExplicitIDRouterIT.java similarity index 99% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/ExplicitIDRouterTest.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/ExplicitIDRouterIT.java index dd9a04333..0800301f8 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/ExplicitIDRouterTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/ExplicitIDRouterIT.java @@ -41,7 +41,7 @@ import java.util.Map; import java.util.Properties; @RunWith(MockitoJUnitRunner.class) -public class ExplicitIDRouterTest +public class ExplicitIDRouterIT { private DocRouter router; diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/ExplicitIDWithLRISRouterTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/ExplicitIDWithLRISRouterIT.java similarity index 99% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/ExplicitIDWithLRISRouterTest.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/ExplicitIDWithLRISRouterIT.java index 2cbdd138c..0cebbbac3 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/ExplicitIDWithLRISRouterTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/ExplicitIDWithLRISRouterIT.java @@ -42,7 +42,7 @@ import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.when; @RunWith(MockitoJUnitRunner.class) -public class ExplicitIDWithLRISRouterTest +public class ExplicitIDWithLRISRouterIT { private DocRouter router; diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/ModelTrackerTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/ModelTrackerIT.java similarity index 96% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/ModelTrackerTest.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/ModelTrackerIT.java index 71ee93280..b0a64fe97 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/ModelTrackerTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/ModelTrackerIT.java @@ -56,7 +56,7 @@ import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; @RunWith(MockitoJUnitRunner.class) -public class ModelTrackerTest +public class ModelTrackerIT { private ModelTracker modelTracker; diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/PropertyRouterTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/PropertyRouterIT.java similarity index 99% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/PropertyRouterTest.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/PropertyRouterIT.java index 67fbdd076..ac233df7a 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/PropertyRouterTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/PropertyRouterIT.java @@ -42,7 +42,7 @@ import java.util.HashMap; import java.util.Map; @RunWith(MockitoJUnitRunner.class) -public class PropertyRouterTest +public class PropertyRouterIT { private PropertyRouter router; diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/transformer/CachedDocTransformerTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/transformer/CachedDocTransformerIT.java similarity index 98% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/transformer/CachedDocTransformerTest.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/transformer/CachedDocTransformerIT.java index ce8889489..4d0314e3c 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/transformer/CachedDocTransformerTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/transformer/CachedDocTransformerIT.java @@ -21,7 +21,7 @@ package org.alfresco.solr.transformer; import org.alfresco.model.ContentModel; import org.alfresco.repo.search.adaptor.lucene.QueryConstants; import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter; -import org.alfresco.solr.AbstractAlfrescoDistributedTest; +import org.alfresco.solr.AbstractAlfrescoDistributedIT; import org.alfresco.solr.client.Acl; import org.alfresco.solr.client.AclChangeSet; import org.alfresco.solr.client.AclReaders; @@ -58,14 +58,14 @@ import static org.alfresco.solr.AlfrescoSolrUtils.list; @LuceneTestCase.SuppressCodecs({"Appending","Lucene3x","Lucene40","Lucene41","Lucene42","Lucene43", "Lucene44", "Lucene45","Lucene46","Lucene47","Lucene48","Lucene49"}) @SolrTestCaseJ4.SuppressSSL -public class CachedDocTransformerTest extends AbstractAlfrescoDistributedTest +public class CachedDocTransformerIT extends AbstractAlfrescoDistributedIT { public static final String ALFRESCO_JSON = "{\"locales\":[\"en\"], \"templates\": [{\"name\":\"t1\", \"template\":\"%cm:content\"}]}"; @BeforeClass private static void initData() throws Throwable { - initSolrServers(1, "CachedDocTransformerTest", null); + initSolrServers(1, "CachedDocTransformerIT", null); populateAlfrescoData(); } diff --git a/search-services/alfresco-search/src/test/java/org/apache/lucene/analysis/minhash/MinHashFilterTest.java b/search-services/alfresco-search/src/test/java/org/apache/lucene/analysis/minhash/MinHashFilterIT.java similarity index 99% rename from search-services/alfresco-search/src/test/java/org/apache/lucene/analysis/minhash/MinHashFilterTest.java rename to search-services/alfresco-search/src/test/java/org/apache/lucene/analysis/minhash/MinHashFilterIT.java index be21a6d53..c936e639d 100644 --- a/search-services/alfresco-search/src/test/java/org/apache/lucene/analysis/minhash/MinHashFilterTest.java +++ b/search-services/alfresco-search/src/test/java/org/apache/lucene/analysis/minhash/MinHashFilterIT.java @@ -56,7 +56,7 @@ import org.apache.lucene.util.automaton.CharacterRunAutomaton; import org.apache.lucene.util.automaton.RegExp; import org.junit.Test; -public class MinHashFilterTest extends BaseTokenStreamTestCase +public class MinHashFilterIT extends BaseTokenStreamTestCase { @Test public void testIntHash() { diff --git a/search-services/alfresco-search/src/test/java/org/apache/solr/handler/component/AlfrescoLukeRequestHandlerTest.java b/search-services/alfresco-search/src/test/java/org/apache/solr/handler/component/AlfrescoLukeRequestHandlerIT.java similarity index 99% rename from search-services/alfresco-search/src/test/java/org/apache/solr/handler/component/AlfrescoLukeRequestHandlerTest.java rename to search-services/alfresco-search/src/test/java/org/apache/solr/handler/component/AlfrescoLukeRequestHandlerIT.java index 7236adddb..9c2a2dfe4 100644 --- a/search-services/alfresco-search/src/test/java/org/apache/solr/handler/component/AlfrescoLukeRequestHandlerTest.java +++ b/search-services/alfresco-search/src/test/java/org/apache/solr/handler/component/AlfrescoLukeRequestHandlerIT.java @@ -43,7 +43,7 @@ import org.mockito.Mock; /** * Unit tests for the {@link AlfrescoLukeRequestHandler}. */ -public class AlfrescoLukeRequestHandlerTest +public class AlfrescoLukeRequestHandlerIT { /** The reference to text for a search term. */ private static final BytesRef TERM_TEXT = new BytesRef("TermText"); From be9f75ab16f7d83dd0dfce75a2e41f0d92054480 Mon Sep 17 00:00:00 2001 From: Tom Page Date: Fri, 1 Nov 2019 10:20:34 +0000 Subject: [PATCH 26/42] SEARCH-1913 Delete failing test. This test does not appear to be very valuable. It is currently only passing due to interaction with other tests. Whenever it starts failing then the numbers in it are updated so that it passes again. --- .../org/alfresco/solr/SolrDataModelTest.java | 75 ------------------- 1 file changed, 75 deletions(-) diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/SolrDataModelTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/SolrDataModelTest.java index 17bc9ee73..0f46bbed4 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/SolrDataModelTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/SolrDataModelTest.java @@ -72,79 +72,4 @@ public class SolrDataModelTest Long actualId = AlfrescoSolrDataModel.parseTransactionId(id); assertEquals(expectedId, actualId); } - - @Test - public void smokeTestCMISModel() - { - AlfrescoSolrDataModel dataModel = new AlfrescoSolrDataModel(); - - // load test model containing content properties multiple - ClassLoader cl = SolrDataModelTest.class.getClassLoader(); - InputStream modelStream = cl.getResourceAsStream("alfresco/model/dictionaryModel.xml"); - - assertNotNull(modelStream); - M2Model model = M2Model.createModel(modelStream); - dataModel.putModel(model); - - modelStream = cl.getResourceAsStream("alfresco/model/cmisModel.xml"); - assertNotNull(modelStream); - model = M2Model.createModel(modelStream); - dataModel.putModel(model); - - assertEquals(2, dataModel.getAlfrescoModels().size()); - - assertEquals(1, dataModel.getIndexedFieldNamesForProperty(OBJECT_ID).getFields().size()); - assertEquals(4, dataModel.getIndexedFieldNamesForProperty(NAME).getFields().size()); - assertEquals(1, dataModel.getIndexedFieldNamesForProperty(CREATION_DATE).getFields().size()); - assertEquals(0, dataModel.getIndexedFieldNamesForProperty(IS_IMMUTABLE).getFields().size()); - assertEquals(0, dataModel.getIndexedFieldNamesForProperty(IS_PRIVATE_WOKING_COPY).getFields().size()); - assertEquals(1, dataModel.getIndexedFieldNamesForProperty(CONTENT_STREAM_LENGTH).getFields().size()); - - assertEquals(1, dataModel .getQueryableFields(OBJECT_ID, null, FieldUse.FACET).getFields().size()); - assertEquals(1, dataModel .getQueryableFields(OBJECT_ID, null, FieldUse.COMPLETION).getFields().size()); - assertEquals(1, dataModel .getQueryableFields(OBJECT_ID, null, FieldUse.FTS).getFields().size()); - assertEquals(1, dataModel .getQueryableFields(OBJECT_ID, null, FieldUse.ID).getFields().size()); - assertEquals(1, dataModel .getQueryableFields(OBJECT_ID, null, FieldUse.MULTI_FACET).getFields().size()); - assertEquals(1, dataModel .getQueryableFields(OBJECT_ID, null, FieldUse.SORT).getFields().size()); - assertEquals(1, dataModel .getQueryableFields(OBJECT_ID, null, FieldUse.STATS).getFields().size()); - assertEquals(1, dataModel .getQueryableFields(OBJECT_ID, null, FieldUse.SUGGESTION).getFields().size()); - - assertEquals(1, dataModel .getQueryableFields(NAME, null, FieldUse.FACET).getFields().size()); - assertEquals(1, dataModel .getQueryableFields(NAME, null, FieldUse.COMPLETION).getFields().size()); - assertEquals(1, dataModel .getQueryableFields(NAME, null, FieldUse.FTS).getFields().size()); - assertEquals(2, dataModel .getQueryableFields(NAME, null, FieldUse.ID).getFields().size()); - assertEquals(1, dataModel .getQueryableFields(NAME, null, FieldUse.MULTI_FACET).getFields().size()); - assertEquals(1, dataModel .getQueryableFields(NAME, null, FieldUse.SORT).getFields().size()); - assertEquals(1, dataModel .getQueryableFields(NAME, null, FieldUse.STATS).getFields().size()); - assertEquals(1, dataModel .getQueryableFields(NAME, null, FieldUse.SUGGESTION).getFields().size()); - - assertEquals(1, dataModel .getQueryableFields(CREATION_DATE, null, FieldUse.FACET).getFields().size()); - assertEquals(1, dataModel .getQueryableFields(CREATION_DATE, null, FieldUse.COMPLETION).getFields().size()); - assertEquals(1, dataModel .getQueryableFields(CREATION_DATE, null, FieldUse.FTS).getFields().size()); - assertEquals(1, dataModel .getQueryableFields(CREATION_DATE, null, FieldUse.ID).getFields().size()); - assertEquals(1, dataModel .getQueryableFields(CREATION_DATE, null, FieldUse.MULTI_FACET).getFields().size()); - assertEquals(1, dataModel .getQueryableFields(CREATION_DATE, null, FieldUse.SORT).getFields().size()); - assertEquals(1, dataModel .getQueryableFields(CREATION_DATE, null, FieldUse.STATS).getFields().size()); - assertEquals(1, dataModel .getQueryableFields(CREATION_DATE, null, FieldUse.SUGGESTION).getFields().size()); - - assertEquals(1, dataModel .getQueryableFields(IS_PRIVATE_WOKING_COPY, null, FieldUse.FACET).getFields().size()); - assertEquals(1, dataModel .getQueryableFields(IS_PRIVATE_WOKING_COPY, null, FieldUse.COMPLETION).getFields().size()); - assertEquals(1, dataModel .getQueryableFields(IS_PRIVATE_WOKING_COPY, null, FieldUse.FTS).getFields().size()); - assertEquals(1, dataModel .getQueryableFields(IS_PRIVATE_WOKING_COPY, null, FieldUse.ID).getFields().size()); - assertEquals(1, dataModel .getQueryableFields(IS_PRIVATE_WOKING_COPY, null, FieldUse.MULTI_FACET).getFields().size()); - assertEquals(1, dataModel .getQueryableFields(IS_PRIVATE_WOKING_COPY, null, FieldUse.SORT).getFields().size()); - assertEquals(1, dataModel .getQueryableFields(IS_PRIVATE_WOKING_COPY, null, FieldUse.STATS).getFields().size()); - assertEquals(1, dataModel .getQueryableFields(IS_PRIVATE_WOKING_COPY, null, FieldUse.SUGGESTION).getFields().size()); - - assertEquals(1, dataModel .getQueryableFields(CONTENT_STREAM_LENGTH, null, FieldUse.FACET).getFields().size()); - assertEquals(1, dataModel .getQueryableFields(CONTENT_STREAM_LENGTH, null, FieldUse.COMPLETION).getFields().size()); - assertEquals(1, dataModel .getQueryableFields(CONTENT_STREAM_LENGTH, null, FieldUse.FTS).getFields().size()); - assertEquals(1, dataModel .getQueryableFields(CONTENT_STREAM_LENGTH, null, FieldUse.ID).getFields().size()); - assertEquals(1, dataModel .getQueryableFields(CONTENT_STREAM_LENGTH, null, FieldUse.MULTI_FACET).getFields().size()); - assertEquals(1, dataModel .getQueryableFields(CONTENT_STREAM_LENGTH, null, FieldUse.SORT).getFields().size()); - assertEquals(1, dataModel .getQueryableFields(CONTENT_STREAM_LENGTH, null, FieldUse.STATS).getFields().size()); - assertEquals(1, dataModel .getQueryableFields(CONTENT_STREAM_LENGTH, null, FieldUse.SUGGESTION).getFields().size()); - - - } } From 9c5201c6bbcceab0423413060cf444af16f37577 Mon Sep 17 00:00:00 2001 From: Tom Page Date: Fri, 1 Nov 2019 11:11:38 +0000 Subject: [PATCH 27/42] SEARCH-1763 Ignore all third party libraries with Jacoco. --- search-services/alfresco-search/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/search-services/alfresco-search/pom.xml b/search-services/alfresco-search/pom.xml index 1a041e2f9..f5285a7cf 100644 --- a/search-services/alfresco-search/pom.xml +++ b/search-services/alfresco-search/pom.xml @@ -292,7 +292,7 @@ - **/AnnotationWriter.* + **/libs/* ${project.build.directory}/coverage-reports/jacoco-ut.exec From 5a0e9a66eeece388d26b5adeb0990cd89900c8ea Mon Sep 17 00:00:00 2001 From: Tom Page Date: Fri, 1 Nov 2019 11:18:14 +0000 Subject: [PATCH 28/42] SEARCH-1763 Ensure we run renamed integration tests during integration-test phase. --- pom.xml | 13 +++++++++++++ search-services/packaging/pom.xml | 13 ------------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/pom.xml b/pom.xml index 5731b13fe..2cc03f504 100644 --- a/pom.xml +++ b/pom.xml @@ -54,6 +54,19 @@ true + + org.apache.maven.plugins + maven-failsafe-plugin + 2.22.2 + + + + integration-test + verify + + + + diff --git a/search-services/packaging/pom.xml b/search-services/packaging/pom.xml index 3417b6e2e..8c17b9e40 100644 --- a/search-services/packaging/pom.xml +++ b/search-services/packaging/pom.xml @@ -40,19 +40,6 @@ alfresco-search-services-${project.version} - - org.apache.maven.plugins - maven-failsafe-plugin - 2.22.2 - - - - integration-test - verify - - - - org.codehaus.mojo properties-maven-plugin From 34324db13e7fc6a10ae5522b71916deb78a1749f Mon Sep 17 00:00:00 2001 From: Tom Page Date: Fri, 1 Nov 2019 11:38:44 +0000 Subject: [PATCH 29/42] SEARCH-1763 Remove over a megabyte of output from the integration tests. --- .../src/test/java/org/alfresco/solr/query/AuthQueryIT.java | 1 - 1 file changed, 1 deletion(-) diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/AuthQueryIT.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/AuthQueryIT.java index 55a93e309..82d9d70a6 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/AuthQueryIT.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/AuthQueryIT.java @@ -109,7 +109,6 @@ public class AuthQueryIT extends AuthDataLoad searchParameters.setQuery(queryString); Query query = dataModel.getFTSQuery(new Pair(searchParameters, Boolean.FALSE), solrQueryRequest, FTSQueryParser.RerankPhase.SINGLE_PASS); - System.out.println("##################### Query:"+query); TopDocs docs = solrIndexSearcher.search(query, count * 2 + 10); Assert.assertEquals(count, docs.totalHits); From 7821da2d21479240cad0754d7feea5d685f17ad0 Mon Sep 17 00:00:00 2001 From: Tom Page Date: Fri, 1 Nov 2019 11:48:55 +0000 Subject: [PATCH 30/42] SEARCH-1763 Remove a load more output from the integration tests. --- .../java/org/alfresco/solr/AbstractAlfrescoDistributedIT.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/AbstractAlfrescoDistributedIT.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/AbstractAlfrescoDistributedIT.java index 14a9a805d..33a0761e4 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/AbstractAlfrescoDistributedIT.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/AbstractAlfrescoDistributedIT.java @@ -760,8 +760,6 @@ public abstract class AbstractAlfrescoDistributedIT extends SolrITInitializer params.remove("distrib"); setDistributedParams(params); QueryResponse rsp = queryRandomShard(json, params); - System.out.println("Cluster Response:"+rsp); - System.out.println("Control Response:"+controlRsp); solrComparator.compareResponses(rsp, controlRsp); return rsp; } From 7e9d53a55ca85e05ab88137b523d6f72ce9dfb17 Mon Sep 17 00:00:00 2001 From: Tom Page Date: Fri, 1 Nov 2019 13:35:57 +0000 Subject: [PATCH 31/42] SEARCH-1763 Convert AlfrescoCMISQParserPluginTest to an integration test. --- ...SQParserPluginTest.java => AlfrescoCMISQParserPluginIT.java} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename search-services/alfresco-search/src/test/java/org/alfresco/solr/query/cmis/{AlfrescoCMISQParserPluginTest.java => AlfrescoCMISQParserPluginIT.java} (99%) diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/cmis/AlfrescoCMISQParserPluginTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/cmis/AlfrescoCMISQParserPluginIT.java similarity index 99% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/query/cmis/AlfrescoCMISQParserPluginTest.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/query/cmis/AlfrescoCMISQParserPluginIT.java index b98fe72b0..e5803fe88 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/cmis/AlfrescoCMISQParserPluginTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/cmis/AlfrescoCMISQParserPluginIT.java @@ -27,7 +27,7 @@ import org.junit.Test; @LuceneTestCase.SuppressCodecs({"Appending","Lucene3x","Lucene40","Lucene41","Lucene42","Lucene43", "Lucene44", "Lucene45","Lucene46","Lucene47","Lucene48","Lucene49"}) @SolrTestCaseJ4.SuppressSSL -public class AlfrescoCMISQParserPluginTest extends LoadCMISData implements QueryConstants +public class AlfrescoCMISQParserPluginIT extends LoadCMISData implements QueryConstants { @Test public void cmisBasic() throws Exception From c67371fe754898dea7506684456f1c38440bd74c Mon Sep 17 00:00:00 2001 From: Tom Page Date: Fri, 1 Nov 2019 13:51:30 +0000 Subject: [PATCH 32/42] SEARCH-1914 Remove unused failing test. --- .../highlight/PostingsSolrHighlighterIT.java | 174 ------------------ 1 file changed, 174 deletions(-) delete mode 100644 search-services/alfresco-search/src/test/java/org/alfresco/solr/highlight/PostingsSolrHighlighterIT.java diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/highlight/PostingsSolrHighlighterIT.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/highlight/PostingsSolrHighlighterIT.java deleted file mode 100644 index 2b54f3af2..000000000 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/highlight/PostingsSolrHighlighterIT.java +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.alfresco.solr.highlight; - -import org.alfresco.solr.AbstractAlfrescoSolrIT; -import org.apache.lucene.util.LuceneTestCase; -import org.apache.solr.handler.component.AlfrescoSolrHighlighter; -import org.apache.solr.handler.component.HighlightComponent; -import org.apache.solr.highlight.SolrHighlighter; -import org.apache.solr.schema.IndexSchema; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; - -import static junit.framework.TestCase.*; - -@LuceneTestCase.SuppressCodecs({"Appending","Lucene3x","Lucene40","Lucene41","Lucene42","Lucene43", "Lucene44", "Lucene45","Lucene46","Lucene47","Lucene48","Lucene49"}) -public class PostingsSolrHighlighterIT extends AbstractAlfrescoSolrIT -{ - @BeforeClass - public static void beforeClass() throws Exception - { - initAlfrescoCore("schema.xml"); - // test our config is sane, just to be sure: - - // postingshighlighter should be used - SolrHighlighter highlighter = HighlightComponent.getHighlighter(getCore()); - assertTrue("wrong highlighter: " + highlighter.getClass(), highlighter instanceof AlfrescoSolrHighlighter); - - // 'text' and 'text3' should have offsets, 'text2' should not - IndexSchema schema = getCore().getLatestSchema(); - assertTrue(schema.getField("text").storeOffsetsWithPositions()); - assertTrue(schema.getField("text3").storeOffsetsWithPositions()); - assertFalse(schema.getField("text2").storeOffsetsWithPositions()); - } - - @Before - public void setUp() throws Exception - { - - // if you override setUp or tearDown, you better call - // the super classes version - clearIndex(); - assertU(adoc("text", "document one", "text2", "document one", "text3", "crappy document", "id", "101")); - assertU(adoc("text", "second document", "text2", "second document", "text3", "crappier document", "id", "102")); - assertU(commit()); - } - - @Test - public void testSimple() { - assertQ("simplest test", - req("q", "text:document", "sort", "id asc", "hl", "true"), - "count(//lst[@name='highlighting']/*)=2", - "//lst[@name='highlighting']/lst[@name='101']/arr[@name='text']/str='document one'", - "//lst[@name='highlighting']/lst[@name='102']/arr[@name='text']/str='second document'"); - } - - public void testPagination() { - assertQ("pagination test", - req("q", "text:document", "sort", "id asc", "hl", "true", "rows", "1", "start", "1"), - "count(//lst[@name='highlighting']/*)=1", - "//lst[@name='highlighting']/lst[@name='102']/arr[@name='text']/str='second document'"); - } - - public void testEmptySnippet() { - assertQ("null snippet test", - req("q", "text:one OR *:*", "sort", "id asc", "hl", "true"), - "count(//lst[@name='highlighting']/*)=2", - "//lst[@name='highlighting']/lst[@name='101']/arr[@name='text']/str='document one'", - "count(//lst[@name='highlighting']/lst[@name='102']/arr[@name='text']/*)=0"); - } - - public void testDefaultSummary() { - assertQ("null snippet test", - req("q", "text:one OR *:*", "sort", "id asc", "hl", "true", "hl.defaultSummary", "true"), - "count(//lst[@name='highlighting']/*)=2", - "//lst[@name='highlighting']/lst[@name='101']/arr[@name='text']/str='document one'", - "//lst[@name='highlighting']/lst[@name='102']/arr[@name='text']/str='second document'"); - } - - public void testDifferentField() { - assertQ("highlighting text3", - req("q", "text3:document", "sort", "id asc", "hl", "true", "hl.fl", "text3"), - "count(//lst[@name='highlighting']/*)=2", - "//lst[@name='highlighting']/lst[@name='101']/arr[@name='text3']/str='crappy document'", - "//lst[@name='highlighting']/lst[@name='102']/arr[@name='text3']/str='crappier document'"); - } - - public void testTwoFields() { - assertQ("highlighting text and text3", - req("q", "text:document text3:document", "sort", "id asc", "hl", "true", "hl.fl", "text,text3"), - "count(//lst[@name='highlighting']/*)=2", - "//lst[@name='highlighting']/lst[@name='101']/arr[@name='text']/str='document one'", - "//lst[@name='highlighting']/lst[@name='101']/arr[@name='text3']/str='crappy document'", - "//lst[@name='highlighting']/lst[@name='102']/arr[@name='text']/str='second document'", - "//lst[@name='highlighting']/lst[@name='102']/arr[@name='text3']/str='crappier document'"); - } - /** - public void testMisconfiguredField() { - ignoreException("was indexed without offsets"); - try { - assertQ("should fail, has no offsets", - req("q", "text2:document", "sort", "id asc", "hl", "true", "hl.fl", "text2")); - fail(); - } catch (Exception expected) { - // expected - } - resetExceptionIgnores(); - } - **/ - public void testTags() { - assertQ("different pre/post tags", - req("q", "text:document", "sort", "id asc", "hl", "true", "hl.tag.pre", "[", "hl.tag.post", "]"), - "count(//lst[@name='highlighting']/*)=2", - "//lst[@name='highlighting']/lst[@name='101']/arr[@name='text']/str='[document] one'", - "//lst[@name='highlighting']/lst[@name='102']/arr[@name='text']/str='second [document]'"); - } - - public void testTagsPerField() { - assertQ("highlighting text and text3", - req("q", "text:document text3:document", "sort", "id asc", "hl", "true", "hl.fl", "text,text3", "f.text3.hl.tag.pre", "[", "f.text3.hl.tag.post", "]"), - "count(//lst[@name='highlighting']/*)=2", - "//lst[@name='highlighting']/lst[@name='101']/arr[@name='text']/str='document one'", - "//lst[@name='highlighting']/lst[@name='101']/arr[@name='text3']/str='crappy [document]'", - "//lst[@name='highlighting']/lst[@name='102']/arr[@name='text']/str='second document'", - "//lst[@name='highlighting']/lst[@name='102']/arr[@name='text3']/str='crappier [document]'"); - } - - public void testBreakIterator() { - assertQ("different breakiterator", - req("q", "text:document", "sort", "id asc", "hl", "true", "hl.bs.type", "WORD"), - "count(//lst[@name='highlighting']/*)=2", - "//lst[@name='highlighting']/lst[@name='101']/arr[@name='text']/str='document'", - "//lst[@name='highlighting']/lst[@name='102']/arr[@name='text']/str='document'"); - } - - public void testBreakIterator2() { - assertU(adoc("text", "Document one has a first sentence. Document two has a second sentence.", "id", "103")); - assertU(commit()); - assertQ("different breakiterator", - req("q", "text:document", "sort", "id asc", "hl", "true", "hl.bs.type", "WHOLE"), - "//lst[@name='highlighting']/lst[@name='103']/arr[@name='text']/str='Document one has a first sentence. Document two has a second sentence.'"); - } - - public void testEncoder() { - assertU(adoc("text", "Document one has a first sentence.", "id", "103")); - assertU(commit()); - assertQ("html escaped", - req("q", "text:document", "sort", "id asc", "hl", "true", "hl.encoder", "html"), - "//lst[@name='highlighting']/lst[@name='103']/arr[@name='text']/str='Document one has a first <i>sentence</i>.'"); - } - - public void testWildcard() { - assertQ("simplest test", - req("q", "text:doc*ment", "sort", "id asc", "hl", "true", "hl.highlightMultiTerm", "true"), - "count(//lst[@name='highlighting']/*)=2", - "//lst[@name='highlighting']/lst[@name='101']/arr[@name='text']/str='document one'", - "//lst[@name='highlighting']/lst[@name='102']/arr[@name='text']/str='second document'"); - } -} From 8e0b555199b5a3c0ff1f9e8f7ff46ec9c78ada29 Mon Sep 17 00:00:00 2001 From: Tom Page Date: Fri, 1 Nov 2019 13:56:39 +0000 Subject: [PATCH 33/42] SEARCH-1763 Fix server name in AdminHandlerDistributedIT. --- .../test/java/org/alfresco/solr/AdminHandlerDistributedIT.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/AdminHandlerDistributedIT.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/AdminHandlerDistributedIT.java index 1f6255b13..2a9fe6aca 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/AdminHandlerDistributedIT.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/AdminHandlerDistributedIT.java @@ -52,7 +52,7 @@ public class AdminHandlerDistributedIT extends AbstractAlfrescoDistributedIT @BeforeClass private static void initData() throws Throwable { - initSolrServers(2, "AdminHandlerDistributedTest", null); + initSolrServers(2, "AdminHandlerDistributedIT", null); } @AfterClass From e450152807866b590e170ccf0dbb7f0f83298e2b Mon Sep 17 00:00:00 2001 From: Tom Page Date: Mon, 4 Nov 2019 16:29:17 +0000 Subject: [PATCH 34/42] SEARCH-1906 Upgrade to solr 6.6.5-patched.1. This contains the upgrade to Jetty 9.3.27.v20190418. --- pom.xml | 2 +- search-services/packaging/pom.xml | 14 ++-- .../src/main/resources/licenses/notice.txt | 80 +++++++++---------- 3 files changed, 48 insertions(+), 48 deletions(-) diff --git a/pom.xml b/pom.xml index 5731b13fe..a729d72ee 100644 --- a/pom.xml +++ b/pom.xml @@ -29,7 +29,7 @@ 11 6.6.5 - ${solr.base.version}-patched + ${solr.base.version}-patched.1 diff --git a/search-services/packaging/pom.xml b/search-services/packaging/pom.xml index 3417b6e2e..ed5fca082 100644 --- a/search-services/packaging/pom.xml +++ b/search-services/packaging/pom.xml @@ -163,13 +163,13 @@ - - - - - - - + + + + + + + diff --git a/search-services/packaging/src/main/resources/licenses/notice.txt b/search-services/packaging/src/main/resources/licenses/notice.txt index 6faa2cd2d..c29663f5e 100644 --- a/search-services/packaging/src/main/resources/licenses/notice.txt +++ b/search-services/packaging/src/main/resources/licenses/notice.txt @@ -74,6 +74,19 @@ guessencoding-1.4.jar http://docs.codehaus.org/display/GUESSENC/ xml-apis-1.4.01.jar https://github.com/FasterXML/jackson jug-2.0.0-asl.jar http://jug.safehaus.org/ acegi-security-0.8.2_patched.jar http://sourceforge.net/projects/acegisecurity/ +jetty-continuation-9.3.27.v20190418.jar +jetty-deploy-9.3.27.v20190418.jar +jetty-http-9.3.27.v20190418.jar +jetty-io-9.3.27.v20190418.jar +jetty-jmx-9.3.27.v20190418.jar +jetty-rewrite-9.3.27.v20190418.jar +jetty-security-9.3.27.v20190418.jar +jetty-server-9.3.27.v20190418.jar +jetty-servlet-9.3.27.v20190418.jar +jetty-servlets-9.3.27.v20190418.jar +jetty-util-9.3.27.v20190418.jar +jetty-webapp-9.3.27.v20190418.jar +jetty-xml-9.3.27.v20190418.jar === CDDL 1.0 === @@ -148,19 +161,6 @@ javax.servlet-api-3.1.0.jar jcl-over-slf4j-1.7.7.jar jdom-1.0.jar jempbox-1.8.13.jar -jetty-continuation-9.3.14.v20161028.jar -jetty-deploy-9.3.14.v20161028.jar -jetty-http-9.3.14.v20161028.jar -jetty-io-9.3.14.v20161028.jar -jetty-jmx-9.3.14.v20161028.jar -jetty-rewrite-9.3.14.v20161028.jar -jetty-security-9.3.14.v20161028.jar -jetty-server-9.3.14.v20161028.jar -jetty-servlet-9.3.14.v20161028.jar -jetty-servlets-9.3.14.v20161028.jar -jetty-util-9.3.14.v20161028.jar -jetty-webapp-9.3.14.v20161028.jar -jetty-xml-9.3.14.v20161028.jar jmatio-1.2.jar joda-time-2.2.jar jsonic-1.2.7.jar @@ -168,28 +168,28 @@ jul-to-slf4j-1.7.7.jar juniversalchardet-1.0.3.jar langdetect-1.1-20120112.jar log4j-1.2.17.jar -lucene-analyzers-common-6.6.5-patched.jar -lucene-analyzers-icu-6.6.5-patched.jar -lucene-analyzers-kuromoji-6.6.5-patched.jar -lucene-analyzers-morfologik-6.6.5-patched.jar -lucene-analyzers-phonetic-6.6.5-patched.jar -lucene-analyzers-smartcn-6.6.5-patched.jar -lucene-analyzers-stempel-6.6.5-patched.jar -lucene-backward-codecs-6.6.5-patched.jar -lucene-classification-6.6.5-patched.jar -lucene-codecs-6.6.5-patched.jar -lucene-core-6.6.5-patched.jar -lucene-expressions-6.6.5-patched.jar -lucene-grouping-6.6.5-patched.jar -lucene-highlighter-6.6.5-patched.jar -lucene-join-6.6.5-patched.jar -lucene-memory-6.6.5-patched.jar -lucene-misc-6.6.5-patched.jar -lucene-queries-6.6.5-patched.jar -lucene-queryparser-6.6.5-patched.jar -lucene-sandbox-6.6.5-patched.jar -lucene-spatial-extras-6.6.5-patched.jar -lucene-suggest-6.6.5-patched.jar +lucene-analyzers-common-6.6.5-patched.1.jar +lucene-analyzers-icu-6.6.5-patched.1.jar +lucene-analyzers-kuromoji-6.6.5-patched.1.jar +lucene-analyzers-morfologik-6.6.5-patched.1.jar +lucene-analyzers-phonetic-6.6.5-patched.1.jar +lucene-analyzers-smartcn-6.6.5-patched.1.jar +lucene-analyzers-stempel-6.6.5-patched.1.jar +lucene-backward-codecs-6.6.5-patched.1.jar +lucene-classification-6.6.5-patched.1.jar +lucene-codecs-6.6.5-patched.1.jar +lucene-core-6.6.5-patched.1.jar +lucene-expressions-6.6.5-patched.1.jar +lucene-grouping-6.6.5-patched.1.jar +lucene-highlighter-6.6.5-patched.1.jar +lucene-join-6.6.5-patched.1.jar +lucene-memory-6.6.5-patched.1.jar +lucene-misc-6.6.5-patched.1.jar +lucene-queries-6.6.5-patched.1.jar +lucene-queryparser-6.6.5-patched.1.jar +lucene-sandbox-6.6.5-patched.1.jar +lucene-spatial-extras-6.6.5-patched.1.jar +lucene-suggest-6.6.5-patched.1.jar metadata-extractor-2.9.1.jar metrics-core-3.2.2.jar metrics-ganglia-3.2.2.jar @@ -213,11 +213,11 @@ rome-1.5.1.jar simple-xml-2.7.1.jar slf4j-api-1.7.7.jar slf4j-log4j12-1.7.7.jar -solr-analysis-extras-6.6.5-patched.jar -solr-clustering-6.6.5-patched.jar -solr-core-6.6.5-patched.jar -solr-langid-6.6.5-patched.jar -solr-solrj-6.6.5-patched.jar +solr-analysis-extras-6.6.5-patched.1.jar +solr-clustering-6.6.5-patched.1.jar +solr-core-6.6.5-patched.1.jar +solr-langid-6.6.5-patched.1.jar +solr-solrj-6.6.5-patched.1.jar spatial4j-0.6.jar start.jar stax2-api-3.1.4.jar From c32ff1a922a878457abee6e66c20c294512e3390 Mon Sep 17 00:00:00 2001 From: Tom Page Date: Mon, 4 Nov 2019 16:37:14 +0000 Subject: [PATCH 35/42] SEARCH-1906 Add license reference for Jetty. --- .../src/main/resources/licenses/notice.txt | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/search-services/packaging/src/main/resources/licenses/notice.txt b/search-services/packaging/src/main/resources/licenses/notice.txt index c29663f5e..12e46175c 100644 --- a/search-services/packaging/src/main/resources/licenses/notice.txt +++ b/search-services/packaging/src/main/resources/licenses/notice.txt @@ -74,19 +74,19 @@ guessencoding-1.4.jar http://docs.codehaus.org/display/GUESSENC/ xml-apis-1.4.01.jar https://github.com/FasterXML/jackson jug-2.0.0-asl.jar http://jug.safehaus.org/ acegi-security-0.8.2_patched.jar http://sourceforge.net/projects/acegisecurity/ -jetty-continuation-9.3.27.v20190418.jar -jetty-deploy-9.3.27.v20190418.jar -jetty-http-9.3.27.v20190418.jar -jetty-io-9.3.27.v20190418.jar -jetty-jmx-9.3.27.v20190418.jar -jetty-rewrite-9.3.27.v20190418.jar -jetty-security-9.3.27.v20190418.jar -jetty-server-9.3.27.v20190418.jar -jetty-servlet-9.3.27.v20190418.jar -jetty-servlets-9.3.27.v20190418.jar -jetty-util-9.3.27.v20190418.jar -jetty-webapp-9.3.27.v20190418.jar -jetty-xml-9.3.27.v20190418.jar +jetty-continuation-9.3.27.v20190418.jar https://www.eclipse.org/jetty/licenses.html +jetty-deploy-9.3.27.v20190418.jar https://www.eclipse.org/jetty/licenses.html +jetty-http-9.3.27.v20190418.jar https://www.eclipse.org/jetty/licenses.html +jetty-io-9.3.27.v20190418.jar https://www.eclipse.org/jetty/licenses.html +jetty-jmx-9.3.27.v20190418.jar https://www.eclipse.org/jetty/licenses.html +jetty-rewrite-9.3.27.v20190418.jar https://www.eclipse.org/jetty/licenses.html +jetty-security-9.3.27.v20190418.jar https://www.eclipse.org/jetty/licenses.html +jetty-server-9.3.27.v20190418.jar https://www.eclipse.org/jetty/licenses.html +jetty-servlet-9.3.27.v20190418.jar https://www.eclipse.org/jetty/licenses.html +jetty-servlets-9.3.27.v20190418.jar https://www.eclipse.org/jetty/licenses.html +jetty-util-9.3.27.v20190418.jar https://www.eclipse.org/jetty/licenses.html +jetty-webapp-9.3.27.v20190418.jar https://www.eclipse.org/jetty/licenses.html +jetty-xml-9.3.27.v20190418.jar https://www.eclipse.org/jetty/licenses.html === CDDL 1.0 === From 9cf970f60a3943ed7280199fa38bdec66809c54e Mon Sep 17 00:00:00 2001 From: agazzarini Date: Tue, 5 Nov 2019 19:27:49 +0100 Subject: [PATCH 36/42] [ SEARCH-1917 ] First working draft --- .../solr/AlfrescoCoreAdminHandler.java | 786 +++++++++--------- .../alfresco/solr/HandlerReportBuilder.java | 502 ++++++----- .../solr/lifecycle/SolrCoreLoadListener.java | 6 +- ...Publisher.java => CoreStatePublisher.java} | 33 +- .../solr/tracker/MetadataTracker.java | 34 +- ...sher.java => SlaveCoreStatePublisher.java} | 14 +- 6 files changed, 741 insertions(+), 634 deletions(-) rename search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/{NodeStatePublisher.java => CoreStatePublisher.java} (91%) rename search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/{SlaveNodeStatePublisher.java => SlaveCoreStatePublisher.java} (90%) diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/AlfrescoCoreAdminHandler.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/AlfrescoCoreAdminHandler.java index f714307dc..9badb9506 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/AlfrescoCoreAdminHandler.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/AlfrescoCoreAdminHandler.java @@ -27,7 +27,8 @@ import static org.alfresco.solr.HandlerOfResources.getSafeLong; import static org.alfresco.solr.HandlerOfResources.openResource; import static org.alfresco.solr.HandlerOfResources.updatePropertiesFile; import static org.alfresco.solr.HandlerOfResources.updateSharedProperties; -import static org.alfresco.solr.HandlerReportBuilder.addCoreSummary; +import static org.alfresco.solr.HandlerReportBuilder.addMasterOrStandaloneCoreSummary; +import static org.alfresco.solr.HandlerReportBuilder.addSlaveCoreSummary; import static org.alfresco.solr.HandlerReportBuilder.buildAclReport; import static org.alfresco.solr.HandlerReportBuilder.buildAclTxReport; import static org.alfresco.solr.HandlerReportBuilder.buildNodeReport; @@ -36,7 +37,6 @@ import static org.alfresco.solr.HandlerReportBuilder.buildTxReport; import java.io.File; import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; @@ -66,6 +66,8 @@ import org.alfresco.solr.tracker.DBIDRangeRouter; import org.alfresco.solr.tracker.DocRouter; import org.alfresco.solr.tracker.IndexHealthReport; import org.alfresco.solr.tracker.MetadataTracker; +import org.alfresco.solr.tracker.CoreStatePublisher; +import org.alfresco.solr.tracker.SlaveCoreStatePublisher; import org.alfresco.solr.tracker.SolrTrackerScheduler; import org.alfresco.solr.tracker.Tracker; import org.alfresco.solr.tracker.TrackerRegistry; @@ -92,15 +94,15 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler protected static final Logger LOGGER = LoggerFactory.getLogger(AlfrescoCoreAdminHandler.class); private static final String ARG_ACLTXID = "acltxid"; - protected static final String ARG_TXID = "txid"; + static final String ARG_TXID = "txid"; private static final String ARG_ACLID = "aclid"; private static final String ARG_NODEID = "nodeid"; private static final String ARG_QUERY = "query"; - public static final String DATA_DIR_ROOT = "data.dir.root"; + private static final String DATA_DIR_ROOT = "data.dir.root"; public static final String ALFRESCO_DEFAULTS = "create.alfresco.defaults"; - public static final String NUM_SHARDS = "num.shards"; - public static final String SHARD_IDS = "shard.ids"; - public static final String DEFAULT_TEMPLATE = "rerank"; + private static final String NUM_SHARDS = "num.shards"; + private static final String SHARD_IDS = "shard.ids"; + static final String DEFAULT_TEMPLATE = "rerank"; static final String ALFRESCO_CORE_NAME = "alfresco"; static final String ARCHIVE_CORE_NAME = "archive"; @@ -130,31 +132,22 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler */ public void startup(CoreContainer coreContainer) { - LOGGER.info("Starting Alfresco core container services"); + LOGGER.info("Starting Alfresco Core Administration Services"); trackerRegistry = new TrackerRegistry(); informationServers = new ConcurrentHashMap<>(); this.scheduler = new SolrTrackerScheduler(this); String createDefaultCores = ConfigUtil.locateProperty(ALFRESCO_DEFAULTS, ""); - int numShards = Integer.valueOf(ConfigUtil.locateProperty(NUM_SHARDS, "1")); + int numShards = Integer.parseInt(ConfigUtil.locateProperty(NUM_SHARDS, "1")); String shardIds = ConfigUtil.locateProperty(SHARD_IDS, null); if (createDefaultCores != null && !createDefaultCores.isEmpty()) { - Runnable runnable = () -> + Thread thread = new Thread(() -> { - try - { - TimeUnit.SECONDS.sleep(10); //Wait a little for the container to start up - } - catch (InterruptedException e) - { - //Don't care - } + waitForTenSeconds(); setupNewDefaultCores(createDefaultCores, numShards, 1, 1, 1, shardIds); - }; - - Thread thread = new Thread(runnable); + }); thread.start(); } } @@ -179,7 +172,7 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler * @param numNodes - Not sure why the core needs to know this. * @param shardIds A comma separated list of shard ids for this core (or null). */ - void setupNewDefaultCores(String names, int numShards, int replicationFactor, int nodeInstance, int numNodes, String shardIds) + private void setupNewDefaultCores(String names, int numShards, int replicationFactor, int nodeInstance, int numNodes, String shardIds) { try { @@ -195,7 +188,7 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler .filter(coreName -> !coreName.isEmpty()) .forEach(coreName -> { LOGGER.info("Attempting to create default alfresco core: {}", coreName); - if (!STORE_REF_MAP.keySet().contains(coreName)) + if (!STORE_REF_MAP.containsKey(coreName)) { throw new AlfrescoRuntimeException("Invalid '" + ALFRESCO_DEFAULTS + "' permitted values are " + STORE_REF_MAP.keySet()); } @@ -257,7 +250,7 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler } catch (ClassNotFoundException e) { - return; + // Do nothing here } catch (Exception e) { @@ -267,25 +260,25 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler protected void handleCustomAction(SolrQueryRequest req, SolrQueryResponse rsp) { - LOGGER.info("######## Handle Custom Action ###########"); SolrParams params = req.getParams(); String cname = params.get(CoreAdminParams.CORE); String action = params.get(CoreAdminParams.ACTION); action = action==null?"":action.toUpperCase(); try { - switch (action) { + switch (action) + { case "NEWCORE": newCore(req, rsp); break; case "UPDATECORE": - updateCore(req, rsp); + updateCore(req); break; case "UPDATESHARED": - updateShared(req, rsp); + updateShared(req); break; case "REMOVECORE": - removeCore(req, rsp); + removeCore(req); break; case "NEWDEFAULTINDEX": newDefaultCore(req, rsp); @@ -315,58 +308,82 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler actionREPORT(rsp, params, cname); break; case "PURGE": - if (cname != null) { + if (cname != null) + { actionPURGE(params, cname); - } else { - for (String coreName : getTrackerRegistry().getCoreNames()) { + } + else + { + for (String coreName : getTrackerRegistry().getCoreNames()) + { actionPURGE(params, coreName); } } break; case "REINDEX": - if (cname != null) { + if (cname != null) + { actionREINDEX(params, cname); - } else { - for (String coreName : getTrackerRegistry().getCoreNames()) { + } + else + { + for (String coreName : getTrackerRegistry().getCoreNames()) + { actionREINDEX(params, coreName); } } break; case "RETRY": - if (cname != null) { + if (cname != null) + { actionRETRY(rsp, cname); - } else { - for (String coreName : getTrackerRegistry().getCoreNames()) { + } + else + { + for (String coreName : getTrackerRegistry().getCoreNames()) + { actionRETRY(rsp, coreName); } } break; case "INDEX": - if (cname != null) { + if (cname != null) + { actionINDEX(params, cname); - } else { - for (String coreName : getTrackerRegistry().getCoreNames()) { + } + else + { + for (String coreName : getTrackerRegistry().getCoreNames()) + { actionINDEX(params, coreName); } } break; case "FIX": - if (cname != null) { + if (cname != null) + { actionFIX(cname); - } else { - for (String coreName : getTrackerRegistry().getCoreNames()) { + } + else + { + for (String coreName : getTrackerRegistry().getCoreNames()) + { actionFIX(coreName); } } break; case "SUMMARY": - if (cname != null) { - NamedList report = new SimpleOrderedMap(); + if (cname != null) + { + NamedList report = new SimpleOrderedMap<>(); actionSUMMARY(params, report, cname); rsp.add("Summary", report); - } else { - NamedList report = new SimpleOrderedMap(); - for (String coreName : getTrackerRegistry().getCoreNames()) { + } + else + { + NamedList report = new SimpleOrderedMap<>(); + for (String coreName : getTrackerRegistry().getCoreNames()) + { actionSUMMARY(params, report, coreName); } rsp.add("Summary", report); @@ -374,7 +391,8 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler break; case "LOG4J": String resource = "log4j-solr.properties"; - if (params.get("resource") != null) { + if (params.get("resource") != null) + { resource = params.get("resource"); } initResourceBasedLogging(resource); @@ -391,26 +409,23 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler } } - private boolean newCore(SolrQueryRequest req, SolrQueryResponse rsp) { + private boolean newCore(SolrQueryRequest req, SolrQueryResponse rsp) + { SolrParams params = req.getParams(); req.getContext(); - // If numCore > 1 we are createing a collection of cores for a sole node in a cluster + // If numCore > 1 we are creating a collection of cores for a sole node in a cluster int numShards = params.getInt("numShards", 1); - String store = ""; - if (params.get("storeRef") != null) { - store = params.get("storeRef"); - } - if ((store == null) || (store.length() == 0)) { + String store = params.get("storeRef"); + if (store == null || store.trim().length() == 0) + { return false; } + StoreRef storeRef = new StoreRef(store); - String templateName = "vanilla"; - if (params.get("template") != null) { - templateName = params.get("template"); - } + String templateName = ofNullable(params.get("template")).orElse("vanilla"); int replicationFactor = params.getInt("replicationFactor", 1); int nodeInstance = params.getInt("nodeInstance", -1); @@ -423,23 +438,25 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler return newCore(coreName, numShards, storeRef, templateName, replicationFactor, nodeInstance, numNodes, shardIds, properties, rsp); } - private boolean newDefaultCore(SolrQueryRequest req, SolrQueryResponse rsp) { - + private boolean newDefaultCore(SolrQueryRequest req, SolrQueryResponse response) + { SolrParams params = req.getParams(); String coreName = params.get("coreName") != null?params.get("coreName"):"alfresco"; - StoreRef storeRef = StoreRef.STORE_REF_WORKSPACE_SPACESSTORE; String templateName = params.get("template") != null?params.get("template"): DEFAULT_TEMPLATE; + Properties extraProperties = extractCustomProperties(params); - if (params.get("storeRef") != null) { - String store = params.get("storeRef"); - storeRef = new StoreRef(store); - } - - return newDefaultCore(coreName, storeRef, templateName, extraProperties, rsp); + return newDefaultCore( + coreName, + ofNullable(params.get("storeRef")) + .map(StoreRef::new) + .orElse(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE), + templateName, + extraProperties, + response); } - protected boolean newDefaultCore(String coreName, StoreRef storeRef, String templateName, Properties extraProperties, SolrQueryResponse rsp) + private boolean newDefaultCore(String coreName, StoreRef storeRef, String templateName, Properties extraProperties, SolrQueryResponse rsp) { return newCore(coreName, 1, storeRef, templateName, 1, 1, 1, null, extraProperties, rsp); } @@ -453,9 +470,8 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler File templates = new File(solrHome, "templates"); File template = new File(templates, templateName); - if(numShards > 1 ) + if(numShards > 1) { - String collectionName = templateName + "--" + storeRef.getProtocol() + "-" + storeRef.getIdentifier() + "--shards--"+numShards + "-x-"+replicationFactor+"--node--"+nodeInstance+"-of-"+numNodes; String coreBase = storeRef.getProtocol() + "-" + storeRef.getIdentifier() + "-"; if (coreName != null) @@ -488,18 +504,18 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler for(Integer shard : shards) { - coreName = coreBase+shard; + coreName = coreBase + shard; File newCore = new File(baseDirectory, coreName); String solrCoreName = coreName; if (coreName == null) { if(storeRef.equals(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE)) { - solrCoreName = "alfresco-"+shard; + solrCoreName = "alfresco-" + shard; } else if(storeRef.equals(StoreRef.STORE_REF_ARCHIVE_SPACESSTORE)) { - solrCoreName = "archive-"+shard; + solrCoreName = "archive-" + shard; } } createAndRegisterNewCore(rsp, extraProperties, storeRef, template, solrCoreName, newCore, numShards, shard, templateName); @@ -527,19 +543,15 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler } } - /** - * @param shardIds - * @return - */ private List extractShards(String shardIds, int numShards) { - ArrayList shards = new ArrayList(); + List shards = new ArrayList<>(); for(String shardId : shardIds.split(",")) { try { - Integer shard = Integer.valueOf(shardId); - if(shard.intValue() < numShards) + int shard = Integer.parseInt(shardId); + if(shard < numShards) { shards.add(shard); } @@ -552,17 +564,7 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler return shards; } - /** - * @param rsp - * @param storeRef - * @param template - * @param coreName - * @param newCore - * @throws IOException - * @throws FileNotFoundException - */ - private void createAndRegisterNewCore(SolrQueryResponse rsp, Properties extraProperties, StoreRef storeRef, File template, String coreName, File newCore, int shardCount, int shardInstance, String templateName) throws IOException, - FileNotFoundException + private void createAndRegisterNewCore(SolrQueryResponse rsp, Properties extraProperties, StoreRef storeRef, File template, String coreName, File newCore, int shardCount, int shardInstance, String templateName) throws IOException { if (coreContainer.getLoadedCoreNames().contains(coreName)) { @@ -613,16 +615,11 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler properties.store(fileOutputStream, null); } - SolrCore core = coreContainer.create(coreName, newCore.toPath(), new HashMap(), false); + SolrCore core = coreContainer.create(coreName, newCore.toPath(), new HashMap<>(), false); rsp.add("core", core.getName()); } - /** - * Tests to see if one of the cores is an Alfresco special core! - * @param cores - * @return - */ - public boolean hasAlfrescoCore(Collection cores) + private boolean hasAlfrescoCore(Collection cores) { if (cores == null || cores.isEmpty()) return false; for (SolrCore core:cores) @@ -632,26 +629,24 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler return false; } - private boolean updateShared(SolrQueryRequest req, SolrQueryResponse rsp) + private void updateShared(SolrQueryRequest req) { SolrParams params = req.getParams(); - try { - + try + { File config = new File(AlfrescoSolrDataModel.getResourceDirectory(), AlfrescoSolrDataModel.SHARED_PROPERTIES); updateSharedProperties(params, config, hasAlfrescoCore(coreContainer.getCores())); coreContainer.getCores().forEach(aCore -> coreContainer.reload(aCore.getName())); - - return true; - } catch (IOException e) + } + catch (IOException e) { LOGGER.error("Failed to update Shared properties ", e); } - return false; } - private boolean updateCore(SolrQueryRequest req, SolrQueryResponse rsp) + private void updateCore(SolrQueryRequest req) { String coreName = null; SolrParams params = req.getParams(); @@ -661,36 +656,28 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler coreName = params.get("coreName"); } - if ((coreName == null) || (coreName.length() == 0)) { return false; } - - SolrCore core = null; - try { - core = coreContainer.getCore(coreName); - - if(core == null) - { - return false; - } - - String configLocaltion = core.getResourceLoader().getConfigDir(); - File config = new File(configLocaltion, "solrcore.properties"); - updatePropertiesFile(params, config, null); - - coreContainer.reload(coreName); - - return true; - } - finally + if ((coreName == null) || (coreName.length() == 0)) { - //Decrement core open count - if(core != null) - { - core.close(); - } + return; } + + try (SolrCore core = coreContainer.getCore(coreName)) + { + + if (core == null) + { + return; + } + + String configLocaltion = core.getResourceLoader().getConfigDir(); + File config = new File(configLocaltion, "solrcore.properties"); + updatePropertiesFile(params, config, null); + + coreContainer.reload(coreName); + } } - private boolean removeCore(SolrQueryRequest req, SolrQueryResponse rsp) + private void removeCore(SolrQueryRequest req) { String store = ""; SolrParams params = req.getParams(); @@ -699,7 +686,7 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler store = params.get("storeRef"); } - if ((store == null) || (store.length() == 0)) { return false; } + if ((store == null) || (store.length() == 0)) { return; } StoreRef storeRef = new StoreRef(store); String coreName = storeRef.getProtocol() + "-" + storeRef.getIdentifier(); @@ -710,142 +697,146 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler // remove core coreContainer.unload(coreName, true, true, true); - - return true; } - - private void actionFIX(String coreName) throws AuthenticationException, IOException, JSONException, EncoderException { - // Gets Metadata health and fixes any problems - MetadataTracker metadataTracker = trackerRegistry.getTrackerForCore(coreName, MetadataTracker.class); - IndexHealthReport indexHealthReport = metadataTracker.checkIndex(null, null, null, null); - IOpenBitSet toReindex = indexHealthReport.getTxInIndexButNotInDb(); - toReindex.or(indexHealthReport.getDuplicatedTxInIndex()); - toReindex.or(indexHealthReport.getMissingTxFromIndex()); - long current = -1; - // Goes through problems in the index - while ((current = toReindex.nextSetBit(current + 1)) != -1) + if (isMasterOrStandalone(coreName)) { - metadataTracker.addTransactionToReindex(current); - } - - // Gets the Acl health and fixes any problems - AclTracker aclTracker = trackerRegistry.getTrackerForCore(coreName, AclTracker.class); - indexHealthReport = aclTracker.checkIndex(null, null, null, null); - toReindex = indexHealthReport.getAclTxInIndexButNotInDb(); - toReindex.or(indexHealthReport.getDuplicatedAclTxInIndex()); - toReindex.or(indexHealthReport.getMissingAclTxFromIndex()); - current = -1; - // Goes through the problems in the index - while ((current = toReindex.nextSetBit(current + 1)) != -1) - { - aclTracker.addAclChangeSetToReindex(current); + // Gets Metadata health and fixes any problems + MetadataTracker metadataTracker = trackerRegistry.getTrackerForCore(coreName, MetadataTracker.class); + IndexHealthReport indexHealthReport = metadataTracker.checkIndex(null, null, null, null); + IOpenBitSet toReindex = indexHealthReport.getTxInIndexButNotInDb(); + toReindex.or(indexHealthReport.getDuplicatedTxInIndex()); + toReindex.or(indexHealthReport.getMissingTxFromIndex()); + long current = -1; + // Goes through problems in the index + while ((current = toReindex.nextSetBit(current + 1)) != -1) + { + metadataTracker.addTransactionToReindex(current); + } + + // Gets the Acl health and fixes any problems + AclTracker aclTracker = trackerRegistry.getTrackerForCore(coreName, AclTracker.class); + indexHealthReport = aclTracker.checkIndex(null, null, null, null); + toReindex = indexHealthReport.getAclTxInIndexButNotInDb(); + toReindex.or(indexHealthReport.getDuplicatedAclTxInIndex()); + toReindex.or(indexHealthReport.getMissingAclTxFromIndex()); + current = -1; + // Goes through the problems in the index + while ((current = toReindex.nextSetBit(current + 1)) != -1) + { + aclTracker.addAclChangeSetToReindex(current); + } } } private void actionCHECK(String cname) { + trackerRegistry.getCoreNames() + .stream() + .filter(coreName -> cname == null || coreName.equals(cname)) + .map(trackerRegistry::getTrackersForCore) + .flatMap(Collection::stream) + .map(Tracker::getTrackerState) + .forEach(state -> state.setCheck(true)); + } + + private void actionACLREPORT(SolrQueryResponse rsp, SolrParams params, String cname) throws JSONException + { + NamedList report = new SimpleOrderedMap<>(); + rsp.add("report", report); + + Long aclid = + ofNullable(params.get(ARG_ACLID)) + .map(Long::valueOf) + .orElseThrow(() -> new AlfrescoRuntimeException("No " + ARG_ACLID + " parameter set.")); + if (cname != null) { - for (Tracker tracker : trackerRegistry.getTrackersForCore(cname)) - { - tracker.getTrackerState().setCheck(true); - } + ofNullable(trackerRegistry.getTrackerForCore(cname, AclTracker.class)) + .ifPresent(tracker -> report.add(cname, buildAclReport(tracker, aclid))); } else { - for (String core : trackerRegistry.getCoreNames()) - { - for (Tracker tracker : trackerRegistry.getTrackersForCore(core)) - { - tracker.getTrackerState().setCheck(true); - } - } + trackerRegistry.getCoreNames() + .forEach(coreName -> + ofNullable(trackerRegistry.getTrackerForCore(coreName, AclTracker.class)) + .ifPresent(tracker -> report.add(coreName, buildAclReport(tracker, aclid)))); + } + + if (report.size() == 0) + { + report.add("WARNING", "This response comes from a slave core. Please consider to ask the same request to its corresponding master core, in order to get more information about the requested Node"); } } - private void actionACLREPORT(SolrQueryResponse rsp, SolrParams params, String cname) throws IOException, - JSONException + private void actionTXREPORT(SolrQueryResponse rsp, SolrParams params, String cname) + throws AuthenticationException, IOException, JSONException, EncoderException { - if (params.get(ARG_ACLID) == null) - { - throw new AlfrescoRuntimeException("No aclid parameter set"); - } - - if (cname != null) - { - Long aclid = Long.valueOf(params.get(ARG_ACLID)); - NamedList report = new SimpleOrderedMap(); - AclTracker tracker = trackerRegistry.getTrackerForCore(cname, AclTracker.class); - report.add(cname, buildAclReport(tracker, aclid)); - rsp.add("report", report); - } - else - { - Long aclid = Long.valueOf(params.get(ARG_ACLID)); - NamedList report = new SimpleOrderedMap(); - for (String coreName : trackerRegistry.getCoreNames()) - { - AclTracker tracker = trackerRegistry.getTrackerForCore(coreName, AclTracker.class); - report.add(coreName, buildAclReport(tracker, aclid)); - } - rsp.add("report", report); - } - } - - private void actionTXREPORT(SolrQueryResponse rsp, SolrParams params, String cname) throws AuthenticationException, - IOException, JSONException, EncoderException - { - if (params.get(ARG_TXID) == null) - { - throw new AlfrescoRuntimeException("No txid parameter set"); - } - if (cname == null) - { - throw new AlfrescoRuntimeException("No cname parameter set"); - } + NamedList report = new SimpleOrderedMap<>(); + rsp.add("report", report); MetadataTracker tracker = trackerRegistry.getTrackerForCore(cname, MetadataTracker.class); - Long txid = Long.valueOf(params.get(ARG_TXID)); - NamedList report = new SimpleOrderedMap(); - report.add(cname, buildTxReport(getTrackerRegistry(), informationServers.get(cname), cname, tracker, txid)); - rsp.add("report", report); + if (tracker != null) + { + Long txid = + ofNullable(params.get(ARG_TXID)) + .map(Long::valueOf) + .orElseThrow(() -> new AlfrescoRuntimeException("No " + ARG_TXID + " parameter set.")); + + if (cname == null) + { + throw new AlfrescoRuntimeException("No cname parameter set"); + } + + report.add(cname, buildTxReport(getTrackerRegistry(), informationServers.get(cname), cname, tracker, txid)); + } + else + { + report.add("WARNING", "This response comes from a slave core. Please consider to ask the same request to its corresponding master core, in order to get more information about the requested Node"); + } } - private void actionACLTXREPORT(SolrQueryResponse rsp, SolrParams params, String cname) - throws AuthenticationException, IOException, JSONException, EncoderException + private void actionACLTXREPORT(SolrQueryResponse rsp, SolrParams params, String cname) throws JSONException { if (params.get(ARG_ACLTXID) == null) { throw new AlfrescoRuntimeException("No acltxid parameter set"); } - + + NamedList report = new SimpleOrderedMap<>(); + rsp.add("report", report); + + Long acltxid = + ofNullable(params.get(ARG_ACLTXID)) + .map(Long::valueOf) + .orElseThrow(() -> new AlfrescoRuntimeException("No " + ARG_ACLTXID + " parameter set.")); + if (cname != null) { - AclTracker tracker = trackerRegistry.getTrackerForCore(cname, AclTracker.class); - Long acltxid = Long.valueOf(params.get(ARG_ACLTXID)); - NamedList report = new SimpleOrderedMap(); - report.add(cname, buildAclTxReport(getTrackerRegistry(), informationServers.get(cname), cname, tracker, acltxid)); - rsp.add("report", report); + ofNullable(trackerRegistry.getTrackerForCore(cname, AclTracker.class)) + .ifPresent(tracker -> report.add(cname, buildAclTxReport(trackerRegistry, informationServers.get(cname), cname, tracker, acltxid))); } else { - Long acltxid = Long.valueOf(params.get(ARG_ACLTXID)); - NamedList report = new SimpleOrderedMap(); - for (String coreName : trackerRegistry.getCoreNames()) - { - AclTracker tracker = trackerRegistry.getTrackerForCore(coreName, AclTracker.class); - report.add(coreName, buildAclTxReport(getTrackerRegistry(), informationServers.get(coreName), coreName, tracker, acltxid)); - } - rsp.add("report", report); + trackerRegistry.getCoreNames() + .forEach(coreName -> + ofNullable(trackerRegistry.getTrackerForCore(coreName, AclTracker.class)) + .ifPresent(tracker -> report.add(cname, buildAclTxReport(trackerRegistry, informationServers.get(cname), cname, tracker, acltxid)))); + } + + if (report.size() == 0) + { + report.add("WARNING", "This response comes from a slave core. Please consider to ask the same request to its corresponding master core, in order to get more information about the requested Node"); } } - private void actionREPORT(SolrQueryResponse rsp, SolrParams params, String cname) throws IOException, - JSONException, AuthenticationException, EncoderException + private void actionREPORT(SolrQueryResponse rsp, SolrParams params, String cname) throws JSONException { + NamedList report = new SimpleOrderedMap<>(); + rsp.add("report", report); + Long fromTime = getSafeLong(params, "fromTime"); Long toTime = getSafeLong(params, "toTime"); Long fromTx = getSafeLong(params, "fromTx"); @@ -855,32 +846,17 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler if (cname != null) { - NamedList report = new SimpleOrderedMap(); - if (trackerRegistry.hasTrackersForCore(cname)) + if (trackerRegistry.hasTrackersForCore(cname) && isMasterOrStandalone(cname)) { - report.add(cname, buildTrackerReport(getTrackerRegistry(), informationServers.get(cname),cname, fromTx, toTx, fromAclTx, toAclTx, fromTime, toTime)); - rsp.add("report", report); - } - else - { - report.add(cname, "Core unknown"); + report.add(cname, buildTrackerReport(trackerRegistry, informationServers.get(cname),cname, fromTx, toTx, fromAclTx, toAclTx, fromTime, toTime)); } } else { - NamedList report = new SimpleOrderedMap(); - for (String coreName : trackerRegistry.getCoreNames()) - { - if (trackerRegistry.hasTrackersForCore(coreName)) - { - report.add(coreName, buildTrackerReport(getTrackerRegistry(), informationServers.get(coreName), coreName, fromTx, toTx, fromAclTx, toAclTx, fromTime, toTime)); - } - else - { - report.add(coreName, "Core unknown"); - } - } - rsp.add("report", report); + trackerRegistry.getCoreNames().stream() + .filter(trackerRegistry::hasTrackersForCore) + .filter(this::isMasterOrStandalone) + .forEach(coreName -> report.add(coreName, buildTrackerReport(trackerRegistry, informationServers.get(coreName), coreName, fromTx, toTx, fromAclTx, toAclTx, fromTime, toTime))); } } @@ -896,8 +872,7 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler } } - DocRouter docRouter = metadataTracker.getDocRouter(); - return docRouter; + return metadataTracker.getDocRouter(); } @@ -907,8 +882,8 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler DocRouter docRouter = getDocRouter(cname); - if(docRouter instanceof DBIDRangeRouter) { - + if(docRouter instanceof DBIDRangeRouter) + { DBIDRangeRouter dbidRangeRouter = (DBIDRangeRouter) docRouter; if(!dbidRangeRouter.getInitialized()) @@ -938,7 +913,8 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler double density = 0; - if(offset > 0) { + if(offset > 0) + { density = ((double)nodeCount) / ((double)offset); // This is how dense we are so far. } @@ -975,15 +951,15 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler rsp.add("density", Math.abs(density)); rsp.add("expand", bestGuess); rsp.add("expanded", dbidRangeRouter.getExpanded()); - } else { + } + else + { rsp.add("expand", -1); rsp.add("exception", "ERROR: Wrong document router type:"+docRouter.getClass().getSimpleName()); - return; } } - private synchronized void expand(SolrQueryResponse rsp, SolrParams params, String cname) - throws IOException + private synchronized void expand(SolrQueryResponse rsp, SolrParams params, String cname) throws IOException { InformationServer informationServer = informationServers.get(cname); DocRouter docRouter = getDocRouter(cname); @@ -1011,7 +987,7 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler long startRange = dbidRangeRouter.getStartRange(); long maxNodeId = informationServer.maxNodeId(); - long range = currentEndRange-startRange; + long range = currentEndRange - startRange; long safe = startRange + ((long) (range * .75)); if(maxNodeId > safe) @@ -1030,65 +1006,38 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler dbidRangeRouter.setExpanded(true); assert newEndRange == dbidRangeRouter.getEndRange(); rsp.add("expand", dbidRangeRouter.getEndRange()); - return; } catch(Throwable t) { rsp.add("expand", -1); rsp.add("exception", t.getMessage()); LOGGER.error("exception expanding", t); - return; } } else { rsp.add("expand", -1); - rsp.add("exception", "Wrong document router type:"+docRouter.getClass().getSimpleName()); - return; + rsp.add("exception", "Wrong document router type:" + docRouter.getClass().getSimpleName()); } } - private void actionNODEREPORTS(SolrQueryResponse rsp, SolrParams params, String cname) throws IOException, - JSONException + private void actionNODEREPORTS(SolrQueryResponse rsp, SolrParams params, String cname) throws JSONException { + Long dbid = + ofNullable(params.get(ARG_NODEID)) + .map(Long::valueOf) + .orElseThrow(() -> new AlfrescoRuntimeException("No dbid parameter set.")); + + NamedList report = new SimpleOrderedMap<>(); + rsp.add("report", report); + if (cname != null) { - MetadataTracker tracker = trackerRegistry.getTrackerForCore(cname, - MetadataTracker.class); - Long dbid = null; - if (params.get(ARG_NODEID) != null) - { - dbid = Long.valueOf(params.get(ARG_NODEID)); - NamedList report = new SimpleOrderedMap(); - report.add(cname, buildNodeReport(tracker, dbid)); - rsp.add("report", report); - - } - else - { - throw new AlfrescoRuntimeException("No dbid parameter set"); - } + report.add(cname, buildNodeReport(nodeStatePublisher(cname), dbid)); } else { - Long dbid = null; - if (params.get(ARG_NODEID) != null) - { - dbid = Long.valueOf(params.get(ARG_NODEID)); - NamedList report = new SimpleOrderedMap(); - for (String coreName : trackerRegistry.getCoreNames()) - { - MetadataTracker tracker = trackerRegistry.getTrackerForCore(coreName, - MetadataTracker.class); - report.add(coreName, buildNodeReport(tracker, dbid)); - } - rsp.add("report", report); - } - else - { - throw new AlfrescoRuntimeException("No dbid parameter set"); - } - + trackerRegistry.getCoreNames().forEach(coreName -> report.add(coreName, buildNodeReport(nodeStatePublisher(coreName), dbid))); } } @@ -1102,11 +1051,18 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler InformationServer srv = informationServers.get(coreName); if (srv != null) { - addCoreSummary(trackerRegistry, coreName, detail, hist, values, srv, report); - - if (reset) + if (isMasterOrStandalone(coreName)) { - srv.getTrackerStats().reset(); + addMasterOrStandaloneCoreSummary(trackerRegistry, coreName, detail, hist, values, srv, report); + + if (reset) + { + srv.getTrackerStats().reset(); + } + } + else + { + addSlaveCoreSummary(trackerRegistry, coreName, detail, hist, values, srv, report); } } else @@ -1115,106 +1071,128 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler } } - private void actionINDEX(SolrParams params, String coreName) { - if (params.get(ARG_TXID) != null) + if (isMasterOrStandalone(coreName)) { - Long txid = Long.valueOf(params.get(ARG_TXID)); - MetadataTracker tracker = trackerRegistry.getTrackerForCore(coreName, MetadataTracker.class); - tracker.addTransactionToIndex(txid); - } - if (params.get(ARG_ACLTXID) != null) - { - Long acltxid = Long.valueOf(params.get(ARG_ACLTXID)); - AclTracker tracker = trackerRegistry.getTrackerForCore(coreName, AclTracker.class); - tracker.addAclChangeSetToIndex(acltxid); - } - if (params.get(ARG_NODEID) != null) - { - Long nodeid = Long.valueOf(params.get(ARG_NODEID)); - MetadataTracker tracker = trackerRegistry.getTrackerForCore(coreName, MetadataTracker.class); - tracker.addNodeToIndex(nodeid); - } - if (params.get(ARG_ACLID) != null) - { - Long aclid = Long.valueOf(params.get(ARG_ACLID)); - AclTracker tracker = trackerRegistry.getTrackerForCore(coreName, AclTracker.class); - tracker.addAclToIndex(aclid); + if (params.get(ARG_TXID) != null) + { + Long txid = Long.valueOf(params.get(ARG_TXID)); + MetadataTracker tracker = trackerRegistry.getTrackerForCore(coreName, MetadataTracker.class); + tracker.addTransactionToIndex(txid); + } + + if (params.get(ARG_ACLTXID) != null) + { + Long acltxid = Long.valueOf(params.get(ARG_ACLTXID)); + AclTracker tracker = trackerRegistry.getTrackerForCore(coreName, AclTracker.class); + tracker.addAclChangeSetToIndex(acltxid); + } + + if (params.get(ARG_NODEID) != null) + { + Long nodeid = Long.valueOf(params.get(ARG_NODEID)); + MetadataTracker tracker = trackerRegistry.getTrackerForCore(coreName, MetadataTracker.class); + tracker.addNodeToIndex(nodeid); + } + + if (params.get(ARG_ACLID) != null) + { + Long aclid = Long.valueOf(params.get(ARG_ACLID)); + AclTracker tracker = trackerRegistry.getTrackerForCore(coreName, AclTracker.class); + tracker.addAclToIndex(aclid); + } } } private void actionRETRY(SolrQueryResponse rsp, String coreName) throws IOException { - MetadataTracker tracker = trackerRegistry.getTrackerForCore(coreName, MetadataTracker.class); - InformationServer srv = informationServers.get(coreName); - Set errorDocIds = srv.getErrorDocIds(); - for (Long nodeid : errorDocIds) + if (isMasterOrStandalone(coreName)) { - tracker.addNodeToReindex(nodeid); + MetadataTracker tracker = trackerRegistry.getTrackerForCore(coreName, MetadataTracker.class); + InformationServer srv = informationServers.get(coreName); + + Set errorDocIds = srv.getErrorDocIds(); + for (Long nodeid : errorDocIds) + { + tracker.addNodeToReindex(nodeid); + } + rsp.add(coreName, errorDocIds); } - rsp.add(coreName, errorDocIds); } private void actionREINDEX(SolrParams params, String coreName) { - if (params.get(ARG_TXID) != null) + if (isMasterOrStandalone(coreName)) { - Long txid = Long.valueOf(params.get(ARG_TXID)); - MetadataTracker tracker = trackerRegistry.getTrackerForCore(coreName, MetadataTracker.class); - tracker.addTransactionToReindex(txid); - } - if (params.get(ARG_ACLTXID) != null) - { - Long acltxid = Long.valueOf(params.get(ARG_ACLTXID)); - AclTracker tracker = trackerRegistry.getTrackerForCore(coreName, AclTracker.class); - tracker.addAclChangeSetToReindex(acltxid); - } - if (params.get(ARG_NODEID) != null) - { - Long nodeid = Long.valueOf(params.get(ARG_NODEID)); - MetadataTracker tracker = trackerRegistry.getTrackerForCore(coreName, MetadataTracker.class); - tracker.addNodeToReindex(nodeid); - } - if (params.get(ARG_ACLID) != null) - { - Long aclid = Long.valueOf(params.get(ARG_ACLID)); - AclTracker tracker = trackerRegistry.getTrackerForCore(coreName, AclTracker.class); - tracker.addAclToReindex(aclid); - } - if (params.get(ARG_QUERY) != null) - { - String query = params.get(ARG_QUERY); - MetadataTracker tracker = trackerRegistry.getTrackerForCore(coreName, MetadataTracker.class); - tracker.addQueryToReindex(query); + if (params.get(ARG_TXID) != null) + { + Long txid = Long.valueOf(params.get(ARG_TXID)); + MetadataTracker tracker = trackerRegistry.getTrackerForCore(coreName, MetadataTracker.class); + tracker.addTransactionToReindex(txid); + } + + if (params.get(ARG_ACLTXID) != null) + { + Long acltxid = Long.valueOf(params.get(ARG_ACLTXID)); + AclTracker tracker = trackerRegistry.getTrackerForCore(coreName, AclTracker.class); + tracker.addAclChangeSetToReindex(acltxid); + } + + if (params.get(ARG_NODEID) != null) + { + Long nodeid = Long.valueOf(params.get(ARG_NODEID)); + MetadataTracker tracker = trackerRegistry.getTrackerForCore(coreName, MetadataTracker.class); + tracker.addNodeToReindex(nodeid); + } + + if (params.get(ARG_ACLID) != null) + { + Long aclid = Long.valueOf(params.get(ARG_ACLID)); + AclTracker tracker = trackerRegistry.getTrackerForCore(coreName, AclTracker.class); + tracker.addAclToReindex(aclid); + } + + if (params.get(ARG_QUERY) != null) + { + String query = params.get(ARG_QUERY); + MetadataTracker tracker = trackerRegistry.getTrackerForCore(coreName, MetadataTracker.class); + tracker.addQueryToReindex(query); + } } } private void actionPURGE(SolrParams params, String coreName) { - if (params.get(ARG_TXID) != null) + if (isMasterOrStandalone(coreName)) { - Long txid = Long.valueOf(params.get(ARG_TXID)); - MetadataTracker tracker = trackerRegistry.getTrackerForCore(coreName, MetadataTracker.class); - tracker.addTransactionToPurge(txid); - } - if (params.get(ARG_ACLTXID) != null) - { - Long acltxid = Long.valueOf(params.get(ARG_ACLTXID)); - AclTracker tracker = trackerRegistry.getTrackerForCore(coreName, AclTracker.class); - tracker.addAclChangeSetToPurge(acltxid); - } - if (params.get(ARG_NODEID) != null) - { - Long nodeid = Long.valueOf(params.get(ARG_NODEID)); - MetadataTracker tracker = trackerRegistry.getTrackerForCore(coreName, MetadataTracker.class); - tracker.addNodeToPurge(nodeid); - } - if (params.get(ARG_ACLID) != null) - { - Long aclid = Long.valueOf(params.get(ARG_ACLID)); - AclTracker tracker = trackerRegistry.getTrackerForCore(coreName, AclTracker.class); - tracker.addAclToPurge(aclid); + if (params.get(ARG_TXID) != null) + { + Long txid = Long.valueOf(params.get(ARG_TXID)); + MetadataTracker tracker = trackerRegistry.getTrackerForCore(coreName, MetadataTracker.class); + tracker.addTransactionToPurge(txid); + } + + if (params.get(ARG_ACLTXID) != null) + { + Long acltxid = Long.valueOf(params.get(ARG_ACLTXID)); + AclTracker tracker = trackerRegistry.getTrackerForCore(coreName, AclTracker.class); + tracker.addAclChangeSetToPurge(acltxid); + } + + if (params.get(ARG_NODEID) != null) + { + Long nodeid = Long.valueOf(params.get(ARG_NODEID)); + MetadataTracker tracker = trackerRegistry.getTrackerForCore(coreName, MetadataTracker.class); + tracker.addNodeToPurge(nodeid); + } + + if (params.get(ARG_ACLID) != null) + { + Long aclid = Long.valueOf(params.get(ARG_ACLID)); + AclTracker tracker = trackerRegistry.getTrackerForCore(coreName, AclTracker.class); + tracker.addAclToPurge(aclid); + } } } @@ -1228,7 +1206,7 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler return trackerRegistry; } - protected void setTrackerRegistry(TrackerRegistry trackerRegistry) + void setTrackerRegistry(TrackerRegistry trackerRegistry) { this.trackerRegistry = trackerRegistry; } @@ -1237,4 +1215,34 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler { return scheduler; } + + private void waitForTenSeconds() + { + try + { + TimeUnit.SECONDS.sleep(10); + } + catch (InterruptedException e) + { + //Don't care + } + } + + /** + * Returns, for the given core, the component which is in charge to publish the core state. + * + * @param coreName the owning core name. + * @return the component which is in charge to publish the core state. + */ + private CoreStatePublisher nodeStatePublisher(String coreName) + { + return ofNullable(trackerRegistry.getTrackerForCore(coreName, MetadataTracker.class)) + .map(CoreStatePublisher.class::cast) + .orElse(trackerRegistry.getTrackerForCore(coreName, SlaveCoreStatePublisher.class)); + } + + private boolean isMasterOrStandalone(String coreName) + { + return trackerRegistry.getTrackerForCore(coreName, MetadataTracker.class) != null; + } } diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/HandlerReportBuilder.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/HandlerReportBuilder.java index 5ccd37ed8..8aca5f99c 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/HandlerReportBuilder.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/HandlerReportBuilder.java @@ -21,6 +21,7 @@ */ package org.alfresco.solr; +import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.httpclient.AuthenticationException; import org.alfresco.service.cmr.repository.datatype.Duration; import org.alfresco.solr.client.Node; @@ -37,24 +38,18 @@ import java.util.List; import java.util.Map; import java.util.Set; +import static java.util.Optional.ofNullable; + /** * Methods taken from AlfrescoCoreAdminHandler that deal with building reports */ -public class HandlerReportBuilder { - - /** - * Builds AclReport - * @param tracker - * @param aclid - * @return - * @throws IOException - * @throws JSONException - */ - public static NamedList buildAclReport(AclTracker tracker, Long aclid) throws IOException, JSONException +class HandlerReportBuilder +{ + static NamedList buildAclReport(AclTracker tracker, Long aclid) throws JSONException { AclReport aclReport = tracker.checkAcl(aclid); - NamedList nr = new SimpleOrderedMap(); + NamedList nr = new SimpleOrderedMap<>(); nr.add("Acl Id", aclReport.getAclId()); nr.add("Acl doc in index", aclReport.getIndexAclDoc()); if (aclReport.getIndexAclDoc() != null) @@ -65,26 +60,14 @@ public class HandlerReportBuilder { return nr; } - /** - * Builds TxReport - * @param trackerRegistry - * @param srv - * @param coreName - * @param tracker - * @param txid - * @return - * @throws AuthenticationException - * @throws IOException - * @throws JSONException - * @throws EncoderException - */ - public static NamedList buildTxReport(TrackerRegistry trackerRegistry, InformationServer srv, String coreName, MetadataTracker tracker, Long txid) + static NamedList buildTxReport(TrackerRegistry trackerRegistry, InformationServer srv, String coreName, MetadataTracker tracker, Long txid) throws AuthenticationException, IOException, JSONException, EncoderException { - NamedList nr = new SimpleOrderedMap(); + NamedList nr = new SimpleOrderedMap<>(); nr.add("TXID", txid); - nr.add("transaction", buildTrackerReport(trackerRegistry, srv, coreName, txid, txid, 0l, 0l, null, null)); - NamedList nodes = new SimpleOrderedMap(); + nr.add("transaction", buildTrackerReport(trackerRegistry, srv, coreName, txid, txid, 0L, 0L, null, null)); + NamedList nodes = new SimpleOrderedMap<>(); + // add node reports .... List dbNodes = tracker.getFullNodesForDbTransaction(txid); for (Node node : dbNodes) @@ -97,50 +80,34 @@ public class HandlerReportBuilder { return nr; } - /** - * Builds AclTxReport - * @param trackerRegistry - * @param srv - * @param coreName - * @param tracker - * @param acltxid - * @return - * @throws AuthenticationException - * @throws IOException - * @throws JSONException - * @throws EncoderException - */ - public static NamedList buildAclTxReport(TrackerRegistry trackerRegistry, InformationServer srv, String coreName, AclTracker tracker, Long acltxid) - throws AuthenticationException, IOException, JSONException, EncoderException + static NamedList buildAclTxReport(TrackerRegistry trackerRegistry, InformationServer srv, String coreName, AclTracker tracker, Long acltxid) throws JSONException { - NamedList nr = new SimpleOrderedMap(); - nr.add("TXID", acltxid); - nr.add("transaction", buildTrackerReport(trackerRegistry, srv, coreName, 0l, 0l, acltxid, acltxid, null, null)); - NamedList nodes = new SimpleOrderedMap(); - // add node reports .... - List dbAclIds = tracker.getAclsForDbAclTransaction(acltxid); - for (Long aclid : dbAclIds) + try { + NamedList nr = new SimpleOrderedMap<>(); + nr.add("TXID", acltxid); + nr.add("transaction", buildTrackerReport(trackerRegistry, srv, coreName, 0L, 0L, acltxid, acltxid, null, null)); + NamedList nodes = new SimpleOrderedMap<>(); + + // add node reports .... + List dbAclIds = tracker.getAclsForDbAclTransaction(acltxid); + for (Long aclid : dbAclIds) { + nodes.add("ACLID " + aclid, buildAclReport(tracker, aclid)); + } + nr.add("aclTxDbAclCount", dbAclIds.size()); + nr.add("nodes", nodes); + return nr; + } + catch (Exception exception) { - nodes.add("ACLID " + aclid, buildAclReport(tracker, aclid)); + throw new AlfrescoRuntimeException("", exception); } - nr.add("aclTxDbAclCount", dbAclIds.size()); - nr.add("nodes", nodes); - return nr; } - /** - * Builds Node report - * @param tracker - * @param node - * @return - * @throws IOException - * @throws JSONException - */ - public static NamedList buildNodeReport(MetadataTracker tracker, Node node) throws IOException, JSONException + static NamedList buildNodeReport(MetadataTracker tracker, Node node) throws JSONException { NodeReport nodeReport = tracker.checkNode(node); - NamedList nr = new SimpleOrderedMap(); + NamedList nr = new SimpleOrderedMap<>(); nr.add("Node DBID", nodeReport.getDbid()); nr.add("DB TX", nodeReport.getDbTx()); nr.add("DB TX status", nodeReport.getDbNodeStatus().toString()); @@ -156,161 +123,258 @@ public class HandlerReportBuilder { return nr; } - /** - * Builds Node Report - * @param tracker - * @param dbid - * @return - * @throws IOException - * @throws JSONException - */ - public static NamedList buildNodeReport(MetadataTracker tracker, Long dbid) throws IOException, JSONException + static NamedList buildNodeReport(CoreStatePublisher publisher, Long dbid) throws JSONException { - NodeReport nodeReport = tracker.checkNode(dbid); + NodeReport nodeReport = publisher.checkNode(dbid); - NamedList nr = new SimpleOrderedMap(); - nr.add("Node DBID", nodeReport.getDbid()); - nr.add("DB TX", nodeReport.getDbTx()); - nr.add("DB TX status", nodeReport.getDbNodeStatus().toString()); - if (nodeReport.getIndexLeafDoc() != null) + NamedList payload = new SimpleOrderedMap<>(); + payload.add("Node DBID", nodeReport.getDbid()); + + if (publisher.isOnMasterOrStandalone()) { - nr.add("Leaf tx in Index", nodeReport.getIndexLeafTx()); + ofNullable(nodeReport.getDbTx()).ifPresent(value -> payload.add("DB TX", value)); + ofNullable(nodeReport.getDbNodeStatus()).map(Object::toString).ifPresent(value -> payload.add("DB TX Status", value)); + ofNullable(nodeReport.getIndexLeafTx()).ifPresent(value -> payload.add("Leaf tx in Index", value)); + ofNullable(nodeReport.getIndexAuxDoc()).ifPresent(value -> payload.add("Aux tx in Index", value)); } - if (nodeReport.getIndexAuxDoc() != null) + else { - nr.add("Aux tx in Index", nodeReport.getIndexAuxTx()); + payload.add("WARNING", "This response comes from a slave core. Please consider to ask the same to its corresponding master core, in order to get more information about the requested Node"); } - nr.add("Indexed Node Doc Count", nodeReport.getIndexedNodeDocCount()); - return nr; + + ofNullable(nodeReport.getIndexedNodeDocCount()).ifPresent(value -> payload.add("Indexed Node Doc Count", value)); + + return payload; } /** * Builds Tracker report - * @param trackerRegistry - * @param srv - * @param coreName - * @param fromTx - * @param toTx - * @param fromAclTx - * @param toAclTx - * @param fromTime - * @param toTime - * @return - * @throws IOException - * @throws JSONException - * @throws AuthenticationException - * @throws EncoderException */ - public static NamedList buildTrackerReport(TrackerRegistry trackerRegistry, InformationServer srv, String coreName, Long fromTx, Long toTx, Long fromAclTx, Long toAclTx, - Long fromTime, Long toTime) throws IOException, JSONException, AuthenticationException, EncoderException + static NamedList buildTrackerReport(TrackerRegistry trackerRegistry, InformationServer srv, String coreName, Long fromTx, Long toTx, Long fromAclTx, Long toAclTx, + Long fromTime, Long toTime) throws JSONException { - // ACL - AclTracker aclTracker = trackerRegistry.getTrackerForCore(coreName, AclTracker.class); - IndexHealthReport aclReport = aclTracker.checkIndex(toTx, toAclTx, fromTime, toTime); - NamedList ihr = new SimpleOrderedMap(); - ihr.add("Alfresco version", aclTracker.getAlfrescoVersion()); - ihr.add("DB acl transaction count", aclReport.getDbAclTransactionCount()); - ihr.add("Count of duplicated acl transactions in the index", aclReport.getDuplicatedAclTxInIndex() - .cardinality()); - if (aclReport.getDuplicatedAclTxInIndex().cardinality() > 0) + try { - ihr.add("First duplicate acl tx", aclReport.getDuplicatedAclTxInIndex().nextSetBit(0L)); - } - ihr.add("Count of acl transactions in the index but not the DB", aclReport.getAclTxInIndexButNotInDb() - .cardinality()); - if (aclReport.getAclTxInIndexButNotInDb().cardinality() > 0) - { - ihr.add("First acl transaction in the index but not the DB", aclReport.getAclTxInIndexButNotInDb() - .nextSetBit(0L)); - } - ihr.add("Count of missing acl transactions from the Index", aclReport.getMissingAclTxFromIndex() - .cardinality()); - if (aclReport.getMissingAclTxFromIndex().cardinality() > 0) - { - ihr.add("First acl transaction missing from the Index", aclReport.getMissingAclTxFromIndex() - .nextSetBit(0L)); - } - ihr.add("Index acl transaction count", aclReport.getAclTransactionDocsInIndex()); - ihr.add("Index unique acl transaction count", aclReport.getAclTransactionDocsInIndex()); - TrackerState aclState = aclTracker.getTrackerState(); - ihr.add("Last indexed change set commit time", aclState.getLastIndexedChangeSetCommitTime()); - Date lastChangeSetDate = new Date(aclState.getLastIndexedChangeSetCommitTime()); - ihr.add("Last indexed change set commit date", CachingDateFormat.getDateFormat().format(lastChangeSetDate)); - ihr.add("Last changeset id before holes", aclState.getLastIndexedChangeSetIdBeforeHoles()); + // ACL + AclTracker aclTracker = trackerRegistry.getTrackerForCore(coreName, AclTracker.class); + IndexHealthReport aclReport = aclTracker.checkIndex(toTx, toAclTx, fromTime, toTime); + NamedList ihr = new SimpleOrderedMap<>(); + ihr.add("Alfresco version", aclTracker.getAlfrescoVersion()); + ihr.add("DB acl transaction count", aclReport.getDbAclTransactionCount()); + ihr.add("Count of duplicated acl transactions in the index", aclReport.getDuplicatedAclTxInIndex() + .cardinality()); + if (aclReport.getDuplicatedAclTxInIndex().cardinality() > 0) { + ihr.add("First duplicate acl tx", aclReport.getDuplicatedAclTxInIndex().nextSetBit(0L)); + } + ihr.add("Count of acl transactions in the index but not the DB", aclReport.getAclTxInIndexButNotInDb() + .cardinality()); + if (aclReport.getAclTxInIndexButNotInDb().cardinality() > 0) { + ihr.add("First acl transaction in the index but not the DB", aclReport.getAclTxInIndexButNotInDb() + .nextSetBit(0L)); + } + ihr.add("Count of missing acl transactions from the Index", aclReport.getMissingAclTxFromIndex() + .cardinality()); + if (aclReport.getMissingAclTxFromIndex().cardinality() > 0) { + ihr.add("First acl transaction missing from the Index", aclReport.getMissingAclTxFromIndex() + .nextSetBit(0L)); + } + ihr.add("Index acl transaction count", aclReport.getAclTransactionDocsInIndex()); + ihr.add("Index unique acl transaction count", aclReport.getAclTransactionDocsInIndex()); + TrackerState aclState = aclTracker.getTrackerState(); + ihr.add("Last indexed change set commit time", aclState.getLastIndexedChangeSetCommitTime()); + Date lastChangeSetDate = new Date(aclState.getLastIndexedChangeSetCommitTime()); + ihr.add("Last indexed change set commit date", CachingDateFormat.getDateFormat().format(lastChangeSetDate)); + ihr.add("Last changeset id before holes", aclState.getLastIndexedChangeSetIdBeforeHoles()); - // Metadata - MetadataTracker metadataTracker = trackerRegistry.getTrackerForCore(coreName, MetadataTracker.class); - IndexHealthReport metaReport = metadataTracker.checkIndex(toTx, toAclTx, fromTime, toTime); - ihr.add("DB transaction count", metaReport.getDbTransactionCount()); - ihr.add("Count of duplicated transactions in the index", metaReport.getDuplicatedTxInIndex() - .cardinality()); - if (metaReport.getDuplicatedTxInIndex().cardinality() > 0) - { - ihr.add("First duplicate", metaReport.getDuplicatedTxInIndex().nextSetBit(0L)); - } - ihr.add("Count of transactions in the index but not the DB", metaReport.getTxInIndexButNotInDb() - .cardinality()); - if (metaReport.getTxInIndexButNotInDb().cardinality() > 0) - { - ihr.add("First transaction in the index but not the DB", metaReport.getTxInIndexButNotInDb() - .nextSetBit(0L)); - } - ihr.add("Count of missing transactions from the Index", metaReport.getMissingTxFromIndex().cardinality()); - if (metaReport.getMissingTxFromIndex().cardinality() > 0) - { - ihr.add("First transaction missing from the Index", metaReport.getMissingTxFromIndex() - .nextSetBit(0L)); - } - ihr.add("Index transaction count", metaReport.getTransactionDocsInIndex()); - ihr.add("Index unique transaction count", metaReport.getTransactionDocsInIndex()); - ihr.add("Index node count", metaReport.getLeafDocCountInIndex()); - ihr.add("Count of duplicate nodes in the index", metaReport.getDuplicatedLeafInIndex().cardinality()); - if (metaReport.getDuplicatedLeafInIndex().cardinality() > 0) - { - ihr.add("First duplicate node id in the index", metaReport.getDuplicatedLeafInIndex().nextSetBit(0L)); - } - ihr.add("Index error count", metaReport.getErrorDocCountInIndex()); - ihr.add("Count of duplicate error docs in the index", metaReport.getDuplicatedErrorInIndex() - .cardinality()); - if (metaReport.getDuplicatedErrorInIndex().cardinality() > 0) - { - ihr.add("First duplicate error in the index", SolrInformationServer.PREFIX_ERROR - + metaReport.getDuplicatedErrorInIndex().nextSetBit(0L)); - } - ihr.add("Index unindexed count", metaReport.getUnindexedDocCountInIndex()); - ihr.add("Count of duplicate unindexed docs in the index", metaReport.getDuplicatedUnindexedInIndex() - .cardinality()); - if (metaReport.getDuplicatedUnindexedInIndex().cardinality() > 0) - { - ihr.add("First duplicate unindexed in the index", - metaReport.getDuplicatedUnindexedInIndex().nextSetBit(0L)); - } - TrackerState metaState = metadataTracker.getTrackerState(); - ihr.add("Last indexed transaction commit time", metaState.getLastIndexedTxCommitTime()); - Date lastTxDate = new Date(metaState.getLastIndexedTxCommitTime()); - ihr.add("Last indexed transaction commit date", CachingDateFormat.getDateFormat().format(lastTxDate)); - ihr.add("Last TX id before holes", metaState.getLastIndexedTxIdBeforeHoles()); + // Metadata + MetadataTracker metadataTracker = trackerRegistry.getTrackerForCore(coreName, MetadataTracker.class); + IndexHealthReport metaReport = metadataTracker.checkIndex(toTx, toAclTx, fromTime, toTime); + ihr.add("DB transaction count", metaReport.getDbTransactionCount()); + ihr.add("Count of duplicated transactions in the index", metaReport.getDuplicatedTxInIndex() + .cardinality()); + if (metaReport.getDuplicatedTxInIndex().cardinality() > 0) { + ihr.add("First duplicate", metaReport.getDuplicatedTxInIndex().nextSetBit(0L)); + } + ihr.add("Count of transactions in the index but not the DB", metaReport.getTxInIndexButNotInDb() + .cardinality()); + if (metaReport.getTxInIndexButNotInDb().cardinality() > 0) { + ihr.add("First transaction in the index but not the DB", metaReport.getTxInIndexButNotInDb() + .nextSetBit(0L)); + } + ihr.add("Count of missing transactions from the Index", metaReport.getMissingTxFromIndex().cardinality()); + if (metaReport.getMissingTxFromIndex().cardinality() > 0) { + ihr.add("First transaction missing from the Index", metaReport.getMissingTxFromIndex() + .nextSetBit(0L)); + } + ihr.add("Index transaction count", metaReport.getTransactionDocsInIndex()); + ihr.add("Index unique transaction count", metaReport.getTransactionDocsInIndex()); + ihr.add("Index node count", metaReport.getLeafDocCountInIndex()); + ihr.add("Count of duplicate nodes in the index", metaReport.getDuplicatedLeafInIndex().cardinality()); + if (metaReport.getDuplicatedLeafInIndex().cardinality() > 0) { + ihr.add("First duplicate node id in the index", metaReport.getDuplicatedLeafInIndex().nextSetBit(0L)); + } + ihr.add("Index error count", metaReport.getErrorDocCountInIndex()); + ihr.add("Count of duplicate error docs in the index", metaReport.getDuplicatedErrorInIndex() + .cardinality()); + if (metaReport.getDuplicatedErrorInIndex().cardinality() > 0) { + ihr.add("First duplicate error in the index", SolrInformationServer.PREFIX_ERROR + + metaReport.getDuplicatedErrorInIndex().nextSetBit(0L)); + } + ihr.add("Index unindexed count", metaReport.getUnindexedDocCountInIndex()); + ihr.add("Count of duplicate unindexed docs in the index", metaReport.getDuplicatedUnindexedInIndex() + .cardinality()); + if (metaReport.getDuplicatedUnindexedInIndex().cardinality() > 0) { + ihr.add("First duplicate unindexed in the index", + metaReport.getDuplicatedUnindexedInIndex().nextSetBit(0L)); + } + TrackerState metaState = metadataTracker.getTrackerState(); + ihr.add("Last indexed transaction commit time", metaState.getLastIndexedTxCommitTime()); + Date lastTxDate = new Date(metaState.getLastIndexedTxCommitTime()); + ihr.add("Last indexed transaction commit date", CachingDateFormat.getDateFormat().format(lastTxDate)); + ihr.add("Last TX id before holes", metaState.getLastIndexedTxIdBeforeHoles()); - srv.addFTSStatusCounts(ihr); + srv.addFTSStatusCounts(ihr); - return ihr; + return ihr; + } + catch (Exception exception) + { + throw new AlfrescoRuntimeException("", exception); + } } - - /** - * Adds a core summary - * @param cname - * @param detail - * @param hist - * @param values - * @param srv - * @param report - * @throws IOException - */ - public static void addCoreSummary(TrackerRegistry trackerRegistry, String cname, boolean detail, boolean hist, boolean values, - InformationServer srv, NamedList report) throws IOException + static void addSlaveCoreSummary(TrackerRegistry trackerRegistry, String cname, boolean detail, boolean hist, boolean values, + InformationServer srv, NamedList report) throws IOException { - NamedList coreSummary = new SimpleOrderedMap(); + NamedList coreSummary = new SimpleOrderedMap<>(); + coreSummary.addAll((SimpleOrderedMap) srv.getCoreStats()); + + SlaveCoreStatePublisher statePublisher = trackerRegistry.getTrackerForCore(cname, SlaveCoreStatePublisher.class); + TrackerState trackerState = statePublisher.getTrackerState(); + long lastIndexTxCommitTime = trackerState.getLastIndexedTxCommitTime(); + + long lastIndexedTxId = trackerState.getLastIndexedTxId(); + long lastTxCommitTimeOnServer = trackerState.getLastTxCommitTimeOnServer(); + long lastTxIdOnServer = trackerState.getLastTxIdOnServer(); + + Date lastIndexTxCommitDate = new Date(lastIndexTxCommitTime); + Date lastTxOnServerDate = new Date(lastTxCommitTimeOnServer); + long transactionsToDo = lastTxIdOnServer - lastIndexedTxId; + if (transactionsToDo < 0) + { + transactionsToDo = 0; + } + + long nodesToDo = 0; + long remainingTxTimeMillis = 0; + if (transactionsToDo > 0) + { + // We now use the elapsed time as seen by the single thread farming out metadata indexing + double meanDocsPerTx = srv.getTrackerStats().getMeanDocsPerTx(); + double meanNodeElaspedIndexTime = srv.getTrackerStats().getMeanNodeElapsedIndexTime(); + nodesToDo = (long)(transactionsToDo * meanDocsPerTx); + remainingTxTimeMillis = (long) (nodesToDo * meanNodeElaspedIndexTime); + } + Date now = new Date(); + Date end = new Date(now.getTime() + remainingTxTimeMillis); + Duration remainingTx = new Duration(now, end); + + long remainingChangeSetTimeMillis = 0; + + now = new Date(); + end = new Date(now.getTime() + remainingChangeSetTimeMillis); + Duration remainingChangeSet = new Duration(now, end); + + NamedList ftsSummary = new SimpleOrderedMap<>(); + long remainingContentTimeMillis = 0; + srv.addFTSStatusCounts(ftsSummary); + long cleanCount = + ofNullable(ftsSummary.get("Node count with FTSStatus Clean")) + .map(Number.class::cast) + .map(Number::longValue) + .orElse(0L); + long dirtyCount = + ofNullable(ftsSummary.get("Node count with FTSStatus Dirty")) + .map(Number.class::cast) + .map(Number::longValue) + .orElse(0L); + long newCount = + ofNullable(ftsSummary.get("Node count with FTSStatus New")) + .map(Number.class::cast) + .map(Number::longValue) + .orElse(0L); + + long nodesInIndex = + ofNullable(coreSummary.get("Alfresco Nodes in Index")) + .map(Number.class::cast) + .map(Number::longValue) + .orElse(0L); + + long contentYetToSee = nodesInIndex > 0 ? nodesToDo * (cleanCount + dirtyCount + newCount)/nodesInIndex : 0; + if (dirtyCount + newCount + contentYetToSee > 0) + { + // We now use the elapsed time as seen by the single thread farming out alc indexing + double meanContentElapsedIndexTime = srv.getTrackerStats().getMeanContentElapsedIndexTime(); + remainingContentTimeMillis = (long) ((dirtyCount + newCount + contentYetToSee) * meanContentElapsedIndexTime); + } + now = new Date(); + end = new Date(now.getTime() + remainingContentTimeMillis); + Duration remainingContent = new Duration(now, end); + coreSummary.add("FTS",ftsSummary); + + Duration txLag = new Duration(lastIndexTxCommitDate, lastTxOnServerDate); + if (lastIndexTxCommitDate.compareTo(lastTxOnServerDate) > 0) + { + txLag = new Duration(); + } + long txLagSeconds = (lastTxCommitTimeOnServer - lastIndexTxCommitTime) / 1000; + if (txLagSeconds < 0) + { + txLagSeconds = 0; + } + + ModelTracker modelTrkr = trackerRegistry.getModelTracker(); + TrackerState modelTrkrState = modelTrkr.getTrackerState(); + coreSummary.add("ModelTracker Active", modelTrkrState.isRunning()); + coreSummary.add("NodeState Publisher Active", trackerState.isRunning()); + + // TX + + coreSummary.add("Last Index TX Commit Time", lastIndexTxCommitTime); + coreSummary.add("Last Index TX Commit Date", lastIndexTxCommitDate); + coreSummary.add("TX Lag", txLagSeconds + " s"); + coreSummary.add("TX Duration", txLag.toString()); + coreSummary.add("Timestamp for last TX on server", lastTxCommitTimeOnServer); + coreSummary.add("Date for last TX on server", lastTxOnServerDate); + coreSummary.add("Id for last TX on server", lastTxIdOnServer); + coreSummary.add("Id for last TX in index", lastIndexedTxId); + coreSummary.add("Approx transactions remaining", transactionsToDo); + coreSummary.add("Approx transaction indexing time remaining", remainingTx.largestComponentformattedString()); + // Stats + + coreSummary.add("Model sync times (ms)", srv.getTrackerStats().getModelTimes().getNamedList(detail, hist, values)); + coreSummary.add("Docs/Tx", srv.getTrackerStats().getTxDocs().getNamedList(detail, hist, values)); + + // Model + + Map> modelErrors = srv.getModelErrors(); + if (modelErrors.size() > 0) + { + NamedList errorList = new SimpleOrderedMap<>(); + for (Map.Entry> modelNameToErrors : modelErrors.entrySet()) + { + errorList.add(modelNameToErrors.getKey(), modelNameToErrors.getValue()); + } + coreSummary.add("Model changes are not compatible with the existing data model and have not been applied", errorList); + } + + report.add(cname, coreSummary); + } + + static void addMasterOrStandaloneCoreSummary(TrackerRegistry trackerRegistry, String cname, boolean detail, boolean hist, boolean values, + InformationServer srv, NamedList report) throws IOException + { + NamedList coreSummary = new SimpleOrderedMap<>(); coreSummary.addAll((SimpleOrderedMap) srv.getCoreStats()); MetadataTracker metaTrkr = trackerRegistry.getTrackerForCore(cname, MetadataTracker.class); @@ -368,14 +432,32 @@ public class HandlerReportBuilder { end = new Date(now.getTime() + remainingChangeSetTimeMillis); Duration remainingChangeSet = new Duration(now, end); - NamedList ftsSummary = new SimpleOrderedMap(); + NamedList ftsSummary = new SimpleOrderedMap<>(); long remainingContentTimeMillis = 0; srv.addFTSStatusCounts(ftsSummary); - long cleanCount = ((Long)ftsSummary.get("Node count with FTSStatus Clean")).longValue(); - long dirtyCount = ((Long)ftsSummary.get("Node count with FTSStatus Dirty")).longValue(); - long newCount = ((Long)ftsSummary.get("Node count with FTSStatus New")).longValue(); - long nodesInIndex = ((Long)coreSummary.get("Alfresco Nodes in Index")); - long contentYetToSee = nodesInIndex > 0 ? nodesToDo * (cleanCount + dirtyCount + newCount)/nodesInIndex : 0;; + long cleanCount = + ofNullable(ftsSummary.get("Node count with FTSStatus Clean")) + .map(Number.class::cast) + .map(Number::longValue) + .orElse(0L); + long dirtyCount = + ofNullable(ftsSummary.get("Node count with FTSStatus Dirty")) + .map(Number.class::cast) + .map(Number::longValue) + .orElse(0L); + long newCount = + ofNullable(ftsSummary.get("Node count with FTSStatus New")) + .map(Number.class::cast) + .map(Number::longValue) + .orElse(0L); + + long nodesInIndex = + ofNullable(coreSummary.get("Alfresco Nodes in Index")) + .map(Number.class::cast) + .map(Number::longValue) + .orElse(0L); + + long contentYetToSee = nodesInIndex > 0 ? nodesToDo * (cleanCount + dirtyCount + newCount)/nodesInIndex : 0; if (dirtyCount + newCount + contentYetToSee > 0) { // We now use the elapsed time as seen by the single thread farming out alc indexing @@ -463,14 +545,14 @@ public class HandlerReportBuilder { srv.getTrackerStats().getNodeTimes().getNamedList(detail, hist, values)); coreSummary.add("Docs/Tx", srv.getTrackerStats().getTxDocs().getNamedList(detail, hist, values)); coreSummary.add("Doc Transformation time (ms)", srv.getTrackerStats().getDocTransformationTimes() - .getNamedList(detail, hist, values)); + .getNamedList(detail, hist, values)); // Model Map> modelErrors = srv.getModelErrors(); if (modelErrors.size() > 0) { - NamedList errorList = new SimpleOrderedMap(); + NamedList errorList = new SimpleOrderedMap<>(); for (Map.Entry> modelNameToErrors : modelErrors.entrySet()) { errorList.add(modelNameToErrors.getKey(), modelNameToErrors.getValue()); @@ -481,4 +563,4 @@ public class HandlerReportBuilder { report.add(cname, coreSummary); } -} +} \ No newline at end of file diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/lifecycle/SolrCoreLoadListener.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/lifecycle/SolrCoreLoadListener.java index 0b41cba15..f8945ef94 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/lifecycle/SolrCoreLoadListener.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/lifecycle/SolrCoreLoadListener.java @@ -35,7 +35,7 @@ import org.alfresco.solr.tracker.CommitTracker; import org.alfresco.solr.tracker.ContentTracker; import org.alfresco.solr.tracker.MetadataTracker; import org.alfresco.solr.tracker.ModelTracker; -import org.alfresco.solr.tracker.SlaveNodeStatePublisher; +import org.alfresco.solr.tracker.SlaveCoreStatePublisher; import org.alfresco.solr.tracker.SolrTrackerScheduler; import org.alfresco.solr.tracker.Tracker; import org.alfresco.solr.tracker.TrackerRegistry; @@ -182,7 +182,7 @@ public class SolrCoreLoadListener extends AbstractSolrEventListener { LOGGER.info("SearchServices Core Trackers have been explicitly disabled on core \"{}\" through \"enable.alfresco.tracking\" configuration property.", core.getName()); - SlaveNodeStatePublisher statePublisher = new SlaveNodeStatePublisher(false, coreProperties, repositoryClient, core.getName(), informationServer); + SlaveCoreStatePublisher statePublisher = new SlaveCoreStatePublisher(false, coreProperties, repositoryClient, core.getName(), informationServer); trackerRegistry.register(core.getName(), statePublisher); scheduler.schedule(statePublisher, core.getName(), coreProperties); trackers.add(statePublisher); @@ -197,7 +197,7 @@ public class SolrCoreLoadListener extends AbstractSolrEventListener { LOGGER.info("SearchServices Core Trackers have been disabled on core \"{}\" because it is a slave core.", core.getName()); - SlaveNodeStatePublisher statePublisher = new SlaveNodeStatePublisher(false, coreProperties, repositoryClient, core.getName(), informationServer); + SlaveCoreStatePublisher statePublisher = new SlaveCoreStatePublisher(false, coreProperties, repositoryClient, core.getName(), informationServer); trackerRegistry.register(core.getName(), statePublisher); scheduler.schedule(statePublisher, core.getName(), coreProperties); trackers.add(statePublisher); diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/NodeStatePublisher.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/CoreStatePublisher.java similarity index 91% rename from search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/NodeStatePublisher.java rename to search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/CoreStatePublisher.java index d6fd2d78a..6c38fb47a 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/NodeStatePublisher.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/CoreStatePublisher.java @@ -41,6 +41,7 @@ import org.alfresco.service.namespace.QName; import org.alfresco.solr.AlfrescoCoreAdminHandler; import org.alfresco.solr.AlfrescoSolrDataModel; import org.alfresco.solr.InformationServer; +import org.alfresco.solr.NodeReport; import org.alfresco.solr.TrackerState; import org.alfresco.solr.client.SOLRAPIClient; import org.apache.commons.lang3.StringUtils; @@ -59,7 +60,7 @@ import java.util.Properties; * @since 1.5 * @see SEARCH-1752 */ -public abstract class NodeStatePublisher extends AbstractTracker +public abstract class CoreStatePublisher extends AbstractTracker { DocRouter docRouter; private final boolean isMaster; @@ -70,7 +71,7 @@ public abstract class NodeStatePublisher extends AbstractTracker /** The property to use for determining the shard. */ protected Optional shardProperty = Optional.empty(); - NodeStatePublisher( + CoreStatePublisher( boolean isMaster, Properties p, SOLRAPIClient client, @@ -88,12 +89,28 @@ public abstract class NodeStatePublisher extends AbstractTracker docRouter = DocRouterFactory.getRouter(p, ShardMethodEnum.getShardMethod(shardMethod)); } - NodeStatePublisher(Type type) + CoreStatePublisher(Type type) { super(type); this.isMaster = false; } + /** + * Returns information about the {@link org.alfresco.solr.client.Node} associated with the given dbid. + * + * @param dbid the node identifier. + * @return the {@link org.alfresco.solr.client.Node} associated with the given dbid. + */ + public NodeReport checkNode(Long dbid) + { + NodeReport nodeReport = new NodeReport(); + nodeReport.setDbid(dbid); + + this.infoSrv.addCommonNodeReportInfo(nodeReport); + + return nodeReport; + } + private void firstUpdateShardProperty() { shardKey.ifPresent( shardKeyName -> { @@ -222,4 +239,14 @@ public abstract class NodeStatePublisher extends AbstractTracker { return this.docRouter; } + + /** + * Returns true if the hosting core is master or standalone. + * + * @return true if the hosting core is master or standalone. + */ + public boolean isOnMasterOrStandalone() + { + return isMaster; + } } diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/MetadataTracker.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/MetadataTracker.java index f118c523b..3862ebd30 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/MetadataTracker.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/MetadataTracker.java @@ -49,7 +49,7 @@ import org.slf4j.LoggerFactory; * This tracks two things: transactions and metadata nodes * @author Ahmed Owian */ -public class MetadataTracker extends NodeStatePublisher implements Tracker +public class MetadataTracker extends CoreStatePublisher implements Tracker { protected final static Logger log = LoggerFactory.getLogger(MetadataTracker.class); private static final int DEFAULT_TRANSACTION_DOCS_BATCH_SIZE = 100; @@ -888,24 +888,18 @@ public class MetadataTracker extends NodeStatePublisher implements Tracker } } - - - - + @Override public NodeReport checkNode(Long dbid) { - NodeReport nodeReport = new NodeReport(); - nodeReport.setDbid(dbid); + NodeReport nodeReport = super.checkNode(dbid); // In DB - GetNodesParameters parameters = new GetNodesParameters(); parameters.setFromNodeId(dbid); parameters.setToNodeId(dbid); - List dbnodes; try { - dbnodes = client.getNodes(parameters, 1); + List dbnodes = client.getNodes(parameters, 1); if (dbnodes.size() == 1) { Node dbnode = dbnodes.get(0); @@ -915,41 +909,31 @@ public class MetadataTracker extends NodeStatePublisher implements Tracker else { nodeReport.setDbNodeStatus(SolrApiNodeStatus.UNKNOWN); - nodeReport.setDbTx(-1l); + nodeReport.setDbTx(-1L); } } catch (IOException e) { nodeReport.setDbNodeStatus(SolrApiNodeStatus.UNKNOWN); - nodeReport.setDbTx(-2l); + nodeReport.setDbTx(-2L); } catch (JSONException e) { nodeReport.setDbNodeStatus(SolrApiNodeStatus.UNKNOWN); - nodeReport.setDbTx(-3l); + nodeReport.setDbTx(-3L); } catch (AuthenticationException e1) { nodeReport.setDbNodeStatus(SolrApiNodeStatus.UNKNOWN); - nodeReport.setDbTx(-4l); + nodeReport.setDbTx(-4L); } - - this.infoSrv.addCommonNodeReportInfo(nodeReport); return nodeReport; } public NodeReport checkNode(Node node) { - NodeReport nodeReport = new NodeReport(); - nodeReport.setDbid(node.getId()); - - nodeReport.setDbNodeStatus(node.getStatus()); - nodeReport.setDbTx(node.getTxnId()); - - this.infoSrv.addCommonNodeReportInfo(nodeReport); - - return nodeReport; + return checkNode(node.getId()); } public List getFullNodesForDbTransaction(Long txid) diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/SlaveNodeStatePublisher.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/SlaveCoreStatePublisher.java similarity index 90% rename from search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/SlaveNodeStatePublisher.java rename to search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/SlaveCoreStatePublisher.java index 4e7ccf709..19a93631c 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/SlaveNodeStatePublisher.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/SlaveCoreStatePublisher.java @@ -14,8 +14,8 @@ import java.util.Properties; /** * Despite belonging to the Tracker ecosystem, this component is actually a publisher, which periodically informs - * Alfresco about the state of the hosting slave node. - * As the name suggests, this worker is scheduled only when the hosting node acts as a slave. + * Alfresco about the state of the hosting slave core. + * As the name suggests, this worker is scheduled only when the owning core acts as a slave. * It allows Solr's master/slave setup to be used with dynamic shard registration. * * In this scenario the slave is polling a "tracking" Solr node. The tracker below calls @@ -27,9 +27,9 @@ import java.util.Properties; * @author Andrea Gazzarini * @since 1.5 */ -public class SlaveNodeStatePublisher extends NodeStatePublisher +public class SlaveCoreStatePublisher extends CoreStatePublisher { - public SlaveNodeStatePublisher( + public SlaveCoreStatePublisher( boolean isMaster, Properties coreProperties, SOLRAPIClient repositoryClient, @@ -61,6 +61,12 @@ public class SlaveNodeStatePublisher extends NodeStatePublisher // Do nothing here } + @Override + public boolean isOnMasterOrStandalone() + { + return false; + } + @Override public boolean hasMaintenance() { From 9d0eae0f5e60248a81ae8cbd9d66057d0c49baf2 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 5 Nov 2019 22:14:16 +0000 Subject: [PATCH 37/42] Bump utility from 3.0.13 to 3.0.14 in /e2e-test Bumps [utility](https://github.com/Alfresco/alfresco-tas-utility) from 3.0.13 to 3.0.14. - [Release notes](https://github.com/Alfresco/alfresco-tas-utility/releases) - [Changelog](https://github.com/Alfresco/alfresco-tas-utility/blob/master/docs/CHANGELOG.md) - [Commits](https://github.com/Alfresco/alfresco-tas-utility/compare/utility-3.0.13...utility-3.0.14) Signed-off-by: dependabot-preview[bot] --- e2e-test/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e-test/pom.xml b/e2e-test/pom.xml index aa7f12854..5cee7b842 100644 --- a/e2e-test/pom.xml +++ b/e2e-test/pom.xml @@ -13,7 +13,7 @@ 6.0.1.2 6.0.0.4 - 3.0.13 + 3.0.14 3.2.0 src/test/resources/SearchSuite.xml From 4f3be9dd06b557aa66977ea56a2f2e24516d44a6 Mon Sep 17 00:00:00 2001 From: agazzarini Date: Wed, 6 Nov 2019 11:43:31 +0100 Subject: [PATCH 38/42] [ SEARCH-1917 ] Class comment --- .../org/alfresco/solr/AlfrescoCoreAdminHandler.java | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/AlfrescoCoreAdminHandler.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/AlfrescoCoreAdminHandler.java index 9badb9506..b8e5c36b2 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/AlfrescoCoreAdminHandler.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/AlfrescoCoreAdminHandler.java @@ -89,6 +89,10 @@ import org.json.JSONException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +/** + * Alfresco Solr administration endpoints provider. + * A customisation of the existing Solr {@link CoreAdminHandler} which offers additional administration endpoints. + */ public class AlfrescoCoreAdminHandler extends CoreAdminHandler { protected static final Logger LOGGER = LoggerFactory.getLogger(AlfrescoCoreAdminHandler.class); @@ -124,14 +128,7 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler public AlfrescoCoreAdminHandler(CoreContainer coreContainer) { super(coreContainer); - startup(coreContainer); - } - /** - * Startup services that exist outside of the core. - */ - public void startup(CoreContainer coreContainer) - { LOGGER.info("Starting Alfresco Core Administration Services"); trackerRegistry = new TrackerRegistry(); From 0b32e93ce57ebcaa5bbaa7b7cf6ba1f36ddbce08 Mon Sep 17 00:00:00 2001 From: agazzarini Date: Fri, 8 Nov 2019 17:21:06 +0100 Subject: [PATCH 39/42] [ SEARCH-1917 ] Working implementation + first 10 Unit tests --- .../solr/AlfrescoCoreAdminHandler.java | 1330 +++++++++-------- ...tBuilder.java => HandlerReportHelper.java} | 10 +- .../java/org/alfresco/solr/utils/Utils.java | 56 + .../solr/AlfrescoCoreAdminHandlerTest.java | 88 +- 4 files changed, 813 insertions(+), 671 deletions(-) rename search-services/alfresco-search/src/main/java/org/alfresco/solr/{HandlerReportBuilder.java => HandlerReportHelper.java} (98%) create mode 100644 search-services/alfresco-search/src/main/java/org/alfresco/solr/utils/Utils.java diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/AlfrescoCoreAdminHandler.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/AlfrescoCoreAdminHandler.java index b8e5c36b2..e43d9b536 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/AlfrescoCoreAdminHandler.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/AlfrescoCoreAdminHandler.java @@ -19,60 +19,25 @@ package org.alfresco.solr; -import static java.util.Optional.ofNullable; - -import static org.alfresco.solr.HandlerOfResources.extractCustomProperties; -import static org.alfresco.solr.HandlerOfResources.getSafeBoolean; -import static org.alfresco.solr.HandlerOfResources.getSafeLong; -import static org.alfresco.solr.HandlerOfResources.openResource; -import static org.alfresco.solr.HandlerOfResources.updatePropertiesFile; -import static org.alfresco.solr.HandlerOfResources.updateSharedProperties; -import static org.alfresco.solr.HandlerReportBuilder.addMasterOrStandaloneCoreSummary; -import static org.alfresco.solr.HandlerReportBuilder.addSlaveCoreSummary; -import static org.alfresco.solr.HandlerReportBuilder.buildAclReport; -import static org.alfresco.solr.HandlerReportBuilder.buildAclTxReport; -import static org.alfresco.solr.HandlerReportBuilder.buildNodeReport; -import static org.alfresco.solr.HandlerReportBuilder.buildTrackerReport; -import static org.alfresco.solr.HandlerReportBuilder.buildTxReport; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.TimeUnit; - import com.google.common.collect.ImmutableMap; - import org.alfresco.error.AlfrescoRuntimeException; -import org.alfresco.httpclient.AuthenticationException; import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.solr.adapters.IOpenBitSet; import org.alfresco.solr.client.SOLRAPIClientFactory; import org.alfresco.solr.config.ConfigUtil; import org.alfresco.solr.tracker.AclTracker; +import org.alfresco.solr.tracker.CoreStatePublisher; import org.alfresco.solr.tracker.DBIDRangeRouter; import org.alfresco.solr.tracker.DocRouter; import org.alfresco.solr.tracker.IndexHealthReport; import org.alfresco.solr.tracker.MetadataTracker; -import org.alfresco.solr.tracker.CoreStatePublisher; import org.alfresco.solr.tracker.SlaveCoreStatePublisher; import org.alfresco.solr.tracker.SolrTrackerScheduler; import org.alfresco.solr.tracker.Tracker; import org.alfresco.solr.tracker.TrackerRegistry; +import org.alfresco.solr.utils.Utils; +import org.alfresco.util.Pair; import org.alfresco.util.shard.ExplicitShardingPolicy; -import org.apache.commons.codec.EncoderException; import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager; import org.apache.commons.io.FileUtils; import org.apache.solr.common.SolrException; @@ -89,14 +54,75 @@ import org.json.JSONException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Properties; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; +import java.util.function.BiConsumer; +import java.util.function.Consumer; +import java.util.stream.Collectors; + +import static java.util.Arrays.asList; +import static java.util.Arrays.stream; +import static java.util.Optional.ofNullable; +import static org.alfresco.solr.HandlerOfResources.extractCustomProperties; +import static org.alfresco.solr.HandlerOfResources.getSafeBoolean; +import static org.alfresco.solr.HandlerOfResources.getSafeLong; +import static org.alfresco.solr.HandlerOfResources.openResource; +import static org.alfresco.solr.HandlerOfResources.updatePropertiesFile; +import static org.alfresco.solr.HandlerOfResources.updateSharedProperties; +import static org.alfresco.solr.HandlerReportHelper.addMasterOrStandaloneCoreSummary; +import static org.alfresco.solr.HandlerReportHelper.addSlaveCoreSummary; +import static org.alfresco.solr.HandlerReportHelper.buildAclReport; +import static org.alfresco.solr.HandlerReportHelper.buildAclTxReport; +import static org.alfresco.solr.HandlerReportHelper.buildNodeReport; +import static org.alfresco.solr.HandlerReportHelper.buildTrackerReport; +import static org.alfresco.solr.HandlerReportHelper.buildTxReport; +import static org.alfresco.solr.utils.Utils.notNullOrEmpty; + /** * Alfresco Solr administration endpoints provider. * A customisation of the existing Solr {@link CoreAdminHandler} which offers additional administration endpoints. + * + * Since 1.5 the behaviour of these endpoints differs a bit depending on the target core. This because a lot of these + * endpoints rely on the information obtained from the trackers, and trackers (see SEARCH-1606) are disabled on slave + * cores. + * + * When a request arrives to this handler, the following are the possible scenarios: + * + *
    + *
  • + * a core is specified in the request: if the target core is a slave then a minimal response or an empty + * response with an informational message is returned. If instead the core is a master (or it is a standalone + * core) the service will return as much information as possible (as it happened before 1.5) + *
  • + *
  • + * a core isn't specified in the request: the request is supposed to target all available cores. However, while + * looping, slave cores are filtered out. In case all cores are slave (i.e. we are running a "pure" slave node) + * the response will be empty, it will include an informational message in order to warn the requestor. + * Sometimes this informative behaviour is not feasible: in those cases an empty response will be returned. + *
  • + *
+ * + * @author Andrea Gazzarini */ public class AlfrescoCoreAdminHandler extends CoreAdminHandler { protected static final Logger LOGGER = LoggerFactory.getLogger(AlfrescoCoreAdminHandler.class); - + + private static final String REPORT = "report"; private static final String ARG_ACLTXID = "acltxid"; static final String ARG_TXID = "txid"; private static final String ARG_ACLID = "aclid"; @@ -118,8 +144,10 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler private SolrTrackerScheduler scheduler; private TrackerRegistry trackerRegistry; - private ConcurrentHashMap informationServers = null; - + private ConcurrentHashMap informationServers; + + private static List CORE_PARAMETER_NAMES = asList(CoreAdminParams.CORE, "coreName", "index"); + public AlfrescoCoreAdminHandler() { super(); @@ -203,34 +231,34 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler /** * Shut down services that exist outside of the core. */ - public void shutdown() + @Override + public void shutdown() { super.shutdown(); - try + try { LOGGER.info("Shutting down Alfresco core container services"); + AlfrescoSolrDataModel.getInstance().close(); SOLRAPIClientFactory.close(); MultiThreadedHttpConnectionManager.shutdownAll(); - //Remove any core trackers still hanging around - trackerRegistry.getCoreNames().forEach(coreName -> trackerRegistry.removeTrackersForCore(coreName)); - - //Remove any information servers + coreNames().forEach(trackerRegistry::removeTrackersForCore); informationServers.clear(); - //Shutdown the scheduler and model tracker. if (!scheduler.isShutdown()) { scheduler.pauseAll(); + if (trackerRegistry.getModelTracker() != null) trackerRegistry.getModelTracker().shutdown(); + trackerRegistry.setModelTracker(null); scheduler.shutdown(); } - } - catch(Exception e) + } + catch(Exception exception) { - LOGGER.error("Problem shutting down", e); + LOGGER.error("Problem shutting down Alfresco core container services", exception); } } @@ -258,17 +286,18 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler protected void handleCustomAction(SolrQueryRequest req, SolrQueryResponse rsp) { SolrParams params = req.getParams(); - String cname = params.get(CoreAdminParams.CORE); String action = params.get(CoreAdminParams.ACTION); - action = action==null?"":action.toUpperCase(); + action = Objects.requireNonNullElse(action.toUpperCase(), ""); try { switch (action) { case "NEWCORE": + case "NEWINDEX": newCore(req, rsp); break; case "UPDATECORE": + case "UPDATEINDEX": updateCore(req); break; case "UPDATESHARED": @@ -278,121 +307,55 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler removeCore(req); break; case "NEWDEFAULTINDEX": + case "NEWDEFAULTCORE": newDefaultCore(req, rsp); break; case "CHECK": - actionCHECK(cname); + actionCHECK(params); break; case "NODEREPORT": - actionNODEREPORTS(rsp, params, cname); + actionNODEREPORTS(rsp, params); break; case "ACLREPORT": - actionACLREPORT(rsp, params, cname); + actionACLREPORT(rsp, params); break; case "TXREPORT": - actionTXREPORT(rsp, params, cname); + actionTXREPORT(rsp, params); break; case "ACLTXREPORT": - actionACLTXREPORT(rsp, params, cname); + actionACLTXREPORT(rsp, params); break; case "RANGECHECK": - rangeCheck(rsp, cname); + rangeCheck(rsp, params); break; case "EXPAND": - expand(rsp, params, cname); + expand(rsp, params); break; case "REPORT": - actionREPORT(rsp, params, cname); + actionREPORT(rsp, params); break; case "PURGE": - if (cname != null) - { - actionPURGE(params, cname); - } - else - { - for (String coreName : getTrackerRegistry().getCoreNames()) - { - actionPURGE(params, coreName); - } - } + actionPURGE(params); break; case "REINDEX": - if (cname != null) - { - actionREINDEX(params, cname); - } - else - { - for (String coreName : getTrackerRegistry().getCoreNames()) - { - actionREINDEX(params, coreName); - } - } + actionREINDEX(params); break; case "RETRY": - if (cname != null) - { - actionRETRY(rsp, cname); - } - else - { - for (String coreName : getTrackerRegistry().getCoreNames()) - { - actionRETRY(rsp, coreName); - } - } + actionRETRY(rsp, params); break; case "INDEX": - if (cname != null) - { - actionINDEX(params, cname); - } - else - { - for (String coreName : getTrackerRegistry().getCoreNames()) - { - actionINDEX(params, coreName); - } - } + actionINDEX(params); break; case "FIX": - if (cname != null) - { - actionFIX(cname); - } - else - { - for (String coreName : getTrackerRegistry().getCoreNames()) - { - actionFIX(coreName); - } - } + actionFIX(params); break; case "SUMMARY": - if (cname != null) - { - NamedList report = new SimpleOrderedMap<>(); - actionSUMMARY(params, report, cname); - rsp.add("Summary", report); - } - else - { - NamedList report = new SimpleOrderedMap<>(); - for (String coreName : getTrackerRegistry().getCoreNames()) - { - actionSUMMARY(params, report, coreName); - } - rsp.add("Summary", report); - } + actionSUMMARY(rsp, params); break; case "LOG4J": - String resource = "log4j-solr.properties"; - if (params.get("resource") != null) - { - resource = params.get("resource"); - } - initResourceBasedLogging(resource); + initResourceBasedLogging( + ofNullable(params.get("resource")) + .orElse("log4j-solr.properties")); break; default: super.handleCustomAction(req, rsp); @@ -406,7 +369,7 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler } } - private boolean newCore(SolrQueryRequest req, SolrQueryResponse rsp) + private void newCore(SolrQueryRequest req, SolrQueryResponse rsp) { SolrParams params = req.getParams(); req.getContext(); @@ -417,7 +380,7 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler String store = params.get("storeRef"); if (store == null || store.trim().length() == 0) { - return false; + return; } StoreRef storeRef = new StoreRef(store); @@ -428,22 +391,24 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler int nodeInstance = params.getInt("nodeInstance", -1); int numNodes = params.getInt("numNodes", 1); - String coreName = params.get("coreName"); + String coreName = coreName(params); String shardIds = params.get("shardIds"); - Properties properties = extractCustomProperties(params); - return newCore(coreName, numShards, storeRef, templateName, replicationFactor, nodeInstance, numNodes, shardIds, properties, rsp); + newCore(coreName, numShards, storeRef, templateName, replicationFactor, nodeInstance, numNodes, shardIds, extractCustomProperties(params), rsp); } - private boolean newDefaultCore(SolrQueryRequest req, SolrQueryResponse response) + private void newDefaultCore(SolrQueryRequest req, SolrQueryResponse response) { SolrParams params = req.getParams(); - String coreName = params.get("coreName") != null?params.get("coreName"):"alfresco"; - String templateName = params.get("template") != null?params.get("template"): DEFAULT_TEMPLATE; + String coreName = ofNullable(coreName(params)).orElse(ALFRESCO_CORE_NAME); + String templateName = + params.get("template") != null + ? params.get("template") + : DEFAULT_TEMPLATE; Properties extraProperties = extractCustomProperties(params); - return newDefaultCore( + newDefaultCore( coreName, ofNullable(params.get("storeRef")) .map(StoreRef::new) @@ -453,12 +418,12 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler response); } - private boolean newDefaultCore(String coreName, StoreRef storeRef, String templateName, Properties extraProperties, SolrQueryResponse rsp) + private void newDefaultCore(String coreName, StoreRef storeRef, String templateName, Properties extraProperties, SolrQueryResponse rsp) { - return newCore(coreName, 1, storeRef, templateName, 1, 1, 1, null, extraProperties, rsp); + newCore(coreName, 1, storeRef, templateName, 1, 1, 1, null, extraProperties, rsp); } - protected boolean newCore(String coreName, int numShards, StoreRef storeRef, String templateName, int replicationFactor, int nodeInstance, int numNodes, String shardIds, Properties extraProperties, SolrQueryResponse rsp) + protected void newCore(String coreName, int numShards, StoreRef storeRef, String templateName, int replicationFactor, int nodeInstance, int numNodes, String shardIds, Properties extraProperties, SolrQueryResponse rsp) { try { @@ -476,14 +441,14 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler collectionName = templateName + "--" + coreName + "--shards--"+numShards + "-x-"+replicationFactor+"--node--"+nodeInstance+"-of-"+numNodes; coreBase = coreName + "-"; } - - File baseDirectory = new File(solrHome, collectionName); - + + File baseDirectory = new File(solrHome, collectionName); + if(nodeInstance == -1) { - return false; + return; } - + List shards; if(shardIds != null) { @@ -494,11 +459,11 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler ExplicitShardingPolicy policy = new ExplicitShardingPolicy(numShards, replicationFactor, numNodes); if(!policy.configurationIsValid()) { - return false; + return; } shards = policy.getShardIdsForNode(nodeInstance); } - + for(Integer shard : shards) { coreName = coreBase + shard; @@ -517,8 +482,6 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler } createAndRegisterNewCore(rsp, extraProperties, storeRef, template, solrCoreName, newCore, numShards, shard, templateName); } - - return true; } else { @@ -528,37 +491,41 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler } File newCore = new File(solrHome, coreName); createAndRegisterNewCore(rsp, extraProperties, storeRef, template, coreName, newCore, 0, 0, templateName); - - return true; } - } - catch (IOException e) + catch (IOException exception) { - e.printStackTrace(); - return false; + LOGGER.error("I/O Failure detected while creating the new core " + + "(name={}, numShard={}, storeRef={}, template={}, replication factor={}, node instance={}, num nodes={}, shard ids={})", + coreName, + numShards, + storeRef, + templateName, + replicationFactor, + nodeInstance, + numNodes, + shardIds, + exception); } } - private List extractShards(String shardIds, int numShards) + /** + * Extracts the list of shard identifiers from the given input string. + * the "excludeFromShardId" parameter is used to filter out those shards whose identifier is equal or greater than + * that parameter. + * + * @param shardIds the shards input string, where shards are separated by comma. + * @param excludeFromShardId filter out those shards whose identifier is equal or greater than this value. + * @return the list of shard identifiers. + */ + List extractShards(String shardIds, int excludeFromShardId) { - List shards = new ArrayList<>(); - for(String shardId : shardIds.split(",")) - { - try - { - int shard = Integer.parseInt(shardId); - if(shard < numShards) - { - shards.add(shard); - } - } - catch(NumberFormatException nfe) - { - // ignore - } - } - return shards; + return stream(Objects.requireNonNullElse(shardIds, "").split(",")) + .map(String::trim) + .map(Utils::toIntOrNull) + .filter(Objects::nonNull) + .filter(shard -> shard < excludeFromShardId) + .collect(Collectors.toList()); } private void createAndRegisterNewCore(SolrQueryResponse rsp, Properties extraProperties, StoreRef storeRef, File template, String coreName, File newCore, int shardCount, int shardInstance, String templateName) throws IOException @@ -616,16 +583,15 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler rsp.add("core", core.getName()); } - private boolean hasAlfrescoCore(Collection cores) + boolean hasAlfrescoCore(Collection cores) { - if (cores == null || cores.isEmpty()) return false; - for (SolrCore core:cores) - { - if (trackerRegistry.hasTrackersForCore(core.getName())) return true; - } - return false; + return notNullOrEmpty(cores).stream() + .map(SolrCore::getName) + .anyMatch(trackerRegistry::hasTrackersForCore); } + // ::::: + private void updateShared(SolrQueryRequest req) { SolrParams params = req.getParams(); @@ -645,33 +611,25 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler private void updateCore(SolrQueryRequest req) { - String coreName = null; - SolrParams params = req.getParams(); + ofNullable(coreName(req.getParams())) + .map(String::trim) + .filter(coreName -> !coreName.isEmpty()) + .ifPresent(coreName -> { + try (SolrCore core = coreContainer.getCore(coreName)) + { - if (params.get("coreName") != null) - { - coreName = params.get("coreName"); - } - - if ((coreName == null) || (coreName.length() == 0)) - { - return; - } + if (core == null) + { + return; + } - try (SolrCore core = coreContainer.getCore(coreName)) - { + String configLocaltion = core.getResourceLoader().getConfigDir(); + File config = new File(configLocaltion, "solrcore.properties"); + updatePropertiesFile(req.getParams(), config, null); - if (core == null) - { - return; - } - - String configLocaltion = core.getResourceLoader().getConfigDir(); - File config = new File(configLocaltion, "solrcore.properties"); - updatePropertiesFile(params, config, null); - - coreContainer.reload(coreName); - } + coreContainer.reload(coreName); + } + }); } private void removeCore(SolrQueryRequest req) @@ -686,19 +644,423 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler if ((store == null) || (store.length() == 0)) { return; } StoreRef storeRef = new StoreRef(store); - String coreName = storeRef.getProtocol() + "-" + storeRef.getIdentifier(); - if (params.get("coreName") != null) - { - coreName = params.get("coreName"); - } - // remove core + String coreName = ofNullable(coreName(req.getParams())).orElse(storeRef.getProtocol() + "-" + storeRef.getIdentifier()); coreContainer.unload(coreName, true, true, true); } - private void actionFIX(String coreName) throws AuthenticationException, IOException, JSONException, EncoderException + private void actionCHECK(SolrParams params) { + String cname = params.get(CoreAdminParams.CORE); + coreNames().stream() + .filter(coreName -> cname == null || coreName.equals(cname)) + .map(trackerRegistry::getTrackersForCore) + .flatMap(Collection::stream) + .map(Tracker::getTrackerState) + .forEach(state -> state.setCheck(true)); + } + + private void actionNODEREPORTS(SolrQueryResponse rsp, SolrParams params) throws JSONException + { + Long dbid = + ofNullable(params.get(ARG_NODEID)) + .map(Long::valueOf) + .orElseThrow(() -> new AlfrescoRuntimeException("No dbid parameter set.")); + + NamedList report = new SimpleOrderedMap<>(); + rsp.add(REPORT, report); + + coreNames().stream() + .filter(coreName -> params.get(CoreAdminParams.CORE) == null || coreName.equals(params.get(CoreAdminParams.CORE))) + .filter(trackerRegistry::hasTrackersForCore) + .map(coreName -> new Pair<>(coreName, nodeStatePublisher(coreName))) + .filter(coreNameAndPublisher -> coreNameAndPublisher.getSecond() != null) + .forEach(coreNameAndPublisher -> + report.add( + coreNameAndPublisher.getFirst(), + buildNodeReport(coreNameAndPublisher.getSecond(), dbid))); + } + + private void actionACLREPORT(SolrQueryResponse rsp, SolrParams params) throws JSONException + { + Long aclid = + ofNullable(params.get(ARG_ACLID)) + .map(Long::valueOf) + .orElseThrow(() -> new AlfrescoRuntimeException("No " + ARG_ACLID + " parameter set.")); + + NamedList report = new SimpleOrderedMap<>(); + rsp.add(REPORT, report); + + coreNames().stream() + .filter(coreName -> params.get(CoreAdminParams.CORE) == null || coreName.equals(params.get(CoreAdminParams.CORE))) + .map(coreName -> new Pair<>(coreName, trackerRegistry.getTrackerForCore(coreName, AclTracker.class))) + .filter(coreNameAndAclTracker -> coreNameAndAclTracker.getSecond() != null) + .forEach(coreNameAndAclTracker -> + report.add( + coreNameAndAclTracker.getFirst(), + buildAclReport(coreNameAndAclTracker.getSecond(), aclid))); + + if (report.size() == 0) + { + addAlertMessage(report); + } + } + + private void actionTXREPORT(SolrQueryResponse rsp, SolrParams params) throws JSONException + { + String coreName = + ofNullable(params.get(CoreAdminParams.CORE)) + .orElseThrow(() -> new AlfrescoRuntimeException("No " + params.get(CoreAdminParams.CORE + " parameter set."))); + + NamedList report = new SimpleOrderedMap<>(); + rsp.add(REPORT, report); + if (isMasterOrStandalone(coreName)) + { + MetadataTracker tracker = trackerRegistry.getTrackerForCore(coreName, MetadataTracker.class); + Long txid = + ofNullable(params.get(ARG_TXID)) + .map(Long::valueOf) + .orElseThrow(() -> new AlfrescoRuntimeException("No " + ARG_TXID + " parameter set.")); + + report.add(coreName, buildTxReport(trackerRegistry, informationServers.get(coreName), coreName, tracker, txid)); + } + else + { + addAlertMessage(report); + } + } + + private void actionACLTXREPORT(SolrQueryResponse rsp, SolrParams params) throws JSONException + { + Long acltxid = + ofNullable(params.get(ARG_ACLTXID)) + .map(Long::valueOf) + .orElseThrow(() -> new AlfrescoRuntimeException("No " + ARG_ACLTXID + " parameter set.")); + + NamedList report = new SimpleOrderedMap<>(); + rsp.add(REPORT, report); + + coreNames().stream() + .filter(coreName -> params.get(CoreAdminParams.CORE) == null || coreName.equals(params.get(CoreAdminParams.CORE))) + .map(coreName -> new Pair<>(coreName, trackerRegistry.getTrackerForCore(coreName, AclTracker.class))) + .filter(coreNameAndAclTracker -> coreNameAndAclTracker.getSecond() != null) + .forEach(coreNameAndAclTracker -> + report.add( + coreNameAndAclTracker.getFirst(), + buildAclTxReport( + trackerRegistry, + informationServers.get(coreNameAndAclTracker.getFirst()), + coreNameAndAclTracker.getFirst(), + coreNameAndAclTracker.getSecond(), + acltxid))); + + if (report.size() == 0) + { + addAlertMessage(report); + } + } + + private void rangeCheck(SolrQueryResponse rsp, SolrParams params) throws IOException + { + String coreName = + ofNullable(params.get(CoreAdminParams.CORE)) + .orElseThrow(() -> new AlfrescoRuntimeException("No " + params.get(CoreAdminParams.CORE + " parameter set."))); + + if (isMasterOrStandalone(coreName)) + { + InformationServer informationServer = informationServers.get(coreName); + + DocRouter docRouter = getDocRouter(coreName); + + if(docRouter instanceof DBIDRangeRouter) + { + DBIDRangeRouter dbidRangeRouter = (DBIDRangeRouter) docRouter; + + if(!dbidRangeRouter.getInitialized()) + { + rsp.add("expand", 0); + rsp.add("exception", "DBIDRangeRouter not initialized yet."); + return; + } + + long startRange = dbidRangeRouter.getStartRange(); + long endRange = dbidRangeRouter.getEndRange(); + + long maxNodeId = informationServer.maxNodeId(); + long minNodeId = informationServer.minNodeId(); + long nodeCount = informationServer.nodeCount(); + + long bestGuess = -1; // -1 means expansion cannot be done. Either because expansion + // has already happened or we're above safe range + + long range = endRange - startRange; // We want this many nodes on the server + + long midpoint = startRange + ((long) (range * .5)); + + long safe = startRange + ((long) (range * .75)); + + long offset = maxNodeId-startRange; + + double density = 0; + + if(offset > 0) + { + density = ((double)nodeCount) / ((double)offset); // This is how dense we are so far. + } + + if (!dbidRangeRouter.getExpanded()) + { + if(maxNodeId <= safe) + { + if (maxNodeId >= midpoint) + { + if(density >= 1 || density == 0) + { + //This is fully dense shard or an empty shard. + // If it does happen, no expand is required. + bestGuess=0; + } + else + { + double multiplier = 1/density; + bestGuess = (long)(range*multiplier)-range; // This is how much to add + } + } + else + { + bestGuess = 0; // We're below the midpoint so it's to early to make a guess. + } + } + } + + rsp.add("start", startRange); + rsp.add("end", endRange); + rsp.add("nodeCount", nodeCount); + rsp.add("minDbid", minNodeId); + rsp.add("maxDbid", maxNodeId); + rsp.add("density", Math.abs(density)); + rsp.add("expand", bestGuess); + rsp.add("expanded", dbidRangeRouter.getExpanded()); + } + else + { + rsp.add("expand", -1); + rsp.add("exception", "ERROR: Wrong document router type:"+docRouter.getClass().getSimpleName()); + } + } + else + { + NamedList report = new SimpleOrderedMap<>(); + rsp.add(REPORT, report); + addAlertMessage(report); + } + } + + private synchronized void expand(SolrQueryResponse rsp, SolrParams params) throws IOException + { + String coreName = + ofNullable(params.get(CoreAdminParams.CORE)) + .orElseThrow(() -> new AlfrescoRuntimeException("No " + params.get(CoreAdminParams.CORE + " parameter set."))); + + if (isMasterOrStandalone(coreName)) + { + InformationServer informationServer = informationServers.get(coreName); + DocRouter docRouter = getDocRouter(coreName); + + if(docRouter instanceof DBIDRangeRouter) + { + long expansion = Long.parseLong(params.get("add")); + DBIDRangeRouter dbidRangeRouter = (DBIDRangeRouter)docRouter; + + if(!dbidRangeRouter.getInitialized()) + { + rsp.add("expand", -1); + rsp.add("exception", "DBIDRangeRouter not initialized yet."); + return; + } + + if(dbidRangeRouter.getExpanded()) + { + rsp.add("expand", -1); + rsp.add("exception", "dbid range has already been expanded."); + return; + } + + long currentEndRange = dbidRangeRouter.getEndRange(); + long startRange = dbidRangeRouter.getStartRange(); + long maxNodeId = informationServer.maxNodeId(); + + long range = currentEndRange - startRange; + long safe = startRange + ((long) (range * .75)); + + if(maxNodeId > safe) + { + rsp.add("expand", -1); + rsp.add("exception", "Expansion cannot occur if max DBID in the index is more then 75% of range."); + return; + } + + long newEndRange = expansion+dbidRangeRouter.getEndRange(); + try + { + informationServer.capIndex(newEndRange); + informationServer.hardCommit(); + dbidRangeRouter.setEndRange(newEndRange); + dbidRangeRouter.setExpanded(true); + assert newEndRange == dbidRangeRouter.getEndRange(); + rsp.add("expand", dbidRangeRouter.getEndRange()); + } + catch(Throwable t) + { + rsp.add("expand", -1); + rsp.add("exception", t.getMessage()); + LOGGER.error("exception expanding", t); + } + } + else + { + rsp.add("expand", -1); + rsp.add("exception", "Wrong document router type:" + docRouter.getClass().getSimpleName()); + } + } + else + { + NamedList report = new SimpleOrderedMap<>(); + rsp.add(REPORT, report); + addAlertMessage(report); + } + } + + private void actionREPORT(SolrQueryResponse rsp, SolrParams params) throws JSONException + { + NamedList report = new SimpleOrderedMap<>(); + rsp.add(REPORT, report); + + Long fromTime = getSafeLong(params, "fromTime"); + Long toTime = getSafeLong(params, "toTime"); + Long fromTx = getSafeLong(params, "fromTx"); + Long toTx = getSafeLong(params, "toTx"); + Long fromAclTx = getSafeLong(params, "fromAclTx"); + Long toAclTx = getSafeLong(params, "toAclTx"); + + coreNames().stream() + .filter(coreName -> params.get(CoreAdminParams.CORE) == null || coreName.equals(params.get(CoreAdminParams.CORE))) + .filter(trackerRegistry::hasTrackersForCore) + .filter(this::isMasterOrStandalone) + .forEach(coreName -> + report.add( + coreName, + buildTrackerReport( + trackerRegistry, + informationServers.get(coreName), + coreName, + fromTx, + toTx, + fromAclTx, + toAclTx, + fromTime, + toTime))); + + if (report.size() == 0) + { + addAlertMessage(report); + } + } + + private void actionPURGE(SolrParams params) + { + Consumer purgeOnSpecificCore = coreName -> { + final MetadataTracker metadataTracker = trackerRegistry.getTrackerForCore(coreName, MetadataTracker.class); + final AclTracker aclTracker = trackerRegistry.getTrackerForCore(coreName, AclTracker.class); + + apply(params, ARG_TXID, metadataTracker::addTransactionToPurge) + .andThen(apply(params, ARG_ACLTXID, aclTracker::addAclChangeSetToPurge)) + .andThen(apply(params, ARG_NODEID, metadataTracker::addNodeToPurge)) + .andThen(apply(params, ARG_ACLID, aclTracker::addAclToPurge)); + }; + + coreNames().stream() + .filter(coreName -> params.get(CoreAdminParams.CORE) == null || coreName.equals(params.get(CoreAdminParams.CORE))) + .filter(this::isMasterOrStandalone) + .forEach(purgeOnSpecificCore); + } + + private void actionREINDEX(SolrParams params) + { + Consumer reindexOnSpecificCore = coreName -> { + final MetadataTracker metadataTracker = trackerRegistry.getTrackerForCore(coreName, MetadataTracker.class); + final AclTracker aclTracker = trackerRegistry.getTrackerForCore(coreName, AclTracker.class); + + apply(params, ARG_TXID, metadataTracker::addTransactionToReindex) + .andThen(apply(params, ARG_ACLTXID, aclTracker::addAclChangeSetToReindex)) + .andThen(apply(params, ARG_NODEID, metadataTracker::addNodeToReindex)) + .andThen(apply(params, ARG_ACLID, aclTracker::addAclToReindex)); + + ofNullable(params.get(ARG_QUERY)).ifPresent(metadataTracker::addQueryToReindex); + }; + + coreNames().stream() + .filter(coreName -> params.get(CoreAdminParams.CORE) == null || coreName.equals(params.get(CoreAdminParams.CORE))) + .filter(this::isMasterOrStandalone) + .forEach(reindexOnSpecificCore); + } + + private void actionRETRY(SolrQueryResponse rsp, SolrParams params) + { + final Consumer retryOnSpecificCore = coreName -> { + MetadataTracker tracker = trackerRegistry.getTrackerForCore(coreName, MetadataTracker.class); + InformationServer srv = informationServers.get(coreName); + + try + { + for (Long nodeid : srv.getErrorDocIds()) + { + tracker.addNodeToReindex(nodeid); + } + rsp.add(coreName, srv.getErrorDocIds()); + } + catch (Exception exception) + { + LOGGER.error("I/O Exception while adding Node to reindex.", exception); + } + }; + + coreNames().stream() + .filter(coreName -> params.get(CoreAdminParams.CORE) == null || coreName.equals(params.get(CoreAdminParams.CORE))) + .filter(this::isMasterOrStandalone) + .forEach(retryOnSpecificCore); + } + + private void actionINDEX(SolrParams params) + { + Consumer indexOnSpecificCore = coreName -> { + final MetadataTracker metadataTracker = trackerRegistry.getTrackerForCore(coreName, MetadataTracker.class); + final AclTracker aclTracker = trackerRegistry.getTrackerForCore(coreName, AclTracker.class); + + apply(params, ARG_TXID, metadataTracker::addTransactionToIndex) + .andThen(apply(params, ARG_ACLTXID, aclTracker::addAclChangeSetToIndex)) + .andThen(apply(params, ARG_NODEID, metadataTracker::addNodeToIndex)) + .andThen(apply(params, ARG_ACLID, aclTracker::addAclToIndex)); + }; + + coreNames().stream() + .filter(coreName -> params.get(CoreAdminParams.CORE) == null || coreName.equals(params.get(CoreAdminParams.CORE))) + .filter(this::isMasterOrStandalone) + .forEach(indexOnSpecificCore); + } + + private void actionFIX(SolrParams params) throws JSONException + { + coreNames().stream() + .filter(coreName -> params.get(CoreAdminParams.CORE) == null || coreName.equals(params.get(CoreAdminParams.CORE))) + .filter(this::isMasterOrStandalone) + .forEach(this::fixOnSpecificCore); + } + + private void fixOnSpecificCore(String coreName) + { + try { // Gets Metadata health and fixes any problems MetadataTracker metadataTracker = trackerRegistry.getTrackerForCore(coreName, MetadataTracker.class); @@ -708,8 +1070,7 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler toReindex.or(indexHealthReport.getMissingTxFromIndex()); long current = -1; // Goes through problems in the index - while ((current = toReindex.nextSetBit(current + 1)) != -1) - { + while ((current = toReindex.nextSetBit(current + 1)) != -1) { metadataTracker.addTransactionToReindex(current); } @@ -721,345 +1082,55 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler toReindex.or(indexHealthReport.getMissingAclTxFromIndex()); current = -1; // Goes through the problems in the index - while ((current = toReindex.nextSetBit(current + 1)) != -1) - { + while ((current = toReindex.nextSetBit(current + 1)) != -1) { aclTracker.addAclChangeSetToReindex(current); } } + catch(Exception exception) + { + throw new AlfrescoRuntimeException("", exception); + } } - private void actionCHECK(String cname) - { - trackerRegistry.getCoreNames() - .stream() - .filter(coreName -> cname == null || coreName.equals(cname)) - .map(trackerRegistry::getTrackersForCore) - .flatMap(Collection::stream) - .map(Tracker::getTrackerState) - .forEach(state -> state.setCheck(true)); - } - - private void actionACLREPORT(SolrQueryResponse rsp, SolrParams params, String cname) throws JSONException + private void actionSUMMARY(SolrQueryResponse rsp, SolrParams params) { NamedList report = new SimpleOrderedMap<>(); - rsp.add("report", report); + rsp.add("Summary", report); - Long aclid = - ofNullable(params.get(ARG_ACLID)) - .map(Long::valueOf) - .orElseThrow(() -> new AlfrescoRuntimeException("No " + ARG_ACLID + " parameter set.")); - - if (cname != null) - { - ofNullable(trackerRegistry.getTrackerForCore(cname, AclTracker.class)) - .ifPresent(tracker -> report.add(cname, buildAclReport(tracker, aclid))); - } - else - { - trackerRegistry.getCoreNames() - .forEach(coreName -> - ofNullable(trackerRegistry.getTrackerForCore(coreName, AclTracker.class)) - .ifPresent(tracker -> report.add(coreName, buildAclReport(tracker, aclid)))); - } - - if (report.size() == 0) - { - report.add("WARNING", "This response comes from a slave core. Please consider to ask the same request to its corresponding master core, in order to get more information about the requested Node"); - } + coreNames().stream() + .filter(coreName -> params.get(CoreAdminParams.CORE) == null || coreName.equals(params.get(CoreAdminParams.CORE))) + .filter(this::isMasterOrStandalone) + .forEach(coreName -> coreSummary(params, report, coreName)); } - private void actionTXREPORT(SolrQueryResponse rsp, SolrParams params, String cname) - throws AuthenticationException, IOException, JSONException, EncoderException - { - NamedList report = new SimpleOrderedMap<>(); - rsp.add("report", report); - - MetadataTracker tracker = trackerRegistry.getTrackerForCore(cname, MetadataTracker.class); - if (tracker != null) - { - Long txid = - ofNullable(params.get(ARG_TXID)) - .map(Long::valueOf) - .orElseThrow(() -> new AlfrescoRuntimeException("No " + ARG_TXID + " parameter set.")); - - if (cname == null) - { - throw new AlfrescoRuntimeException("No cname parameter set"); - } - - report.add(cname, buildTxReport(getTrackerRegistry(), informationServers.get(cname), cname, tracker, txid)); - } - else - { - report.add("WARNING", "This response comes from a slave core. Please consider to ask the same request to its corresponding master core, in order to get more information about the requested Node"); - } - } - - private void actionACLTXREPORT(SolrQueryResponse rsp, SolrParams params, String cname) throws JSONException - { - if (params.get(ARG_ACLTXID) == null) - { - throw new AlfrescoRuntimeException("No acltxid parameter set"); - } - - NamedList report = new SimpleOrderedMap<>(); - rsp.add("report", report); - - Long acltxid = - ofNullable(params.get(ARG_ACLTXID)) - .map(Long::valueOf) - .orElseThrow(() -> new AlfrescoRuntimeException("No " + ARG_ACLTXID + " parameter set.")); - - if (cname != null) - { - ofNullable(trackerRegistry.getTrackerForCore(cname, AclTracker.class)) - .ifPresent(tracker -> report.add(cname, buildAclTxReport(trackerRegistry, informationServers.get(cname), cname, tracker, acltxid))); - } - else - { - trackerRegistry.getCoreNames() - .forEach(coreName -> - ofNullable(trackerRegistry.getTrackerForCore(coreName, AclTracker.class)) - .ifPresent(tracker -> report.add(cname, buildAclTxReport(trackerRegistry, informationServers.get(cname), cname, tracker, acltxid)))); - } - - if (report.size() == 0) - { - report.add("WARNING", "This response comes from a slave core. Please consider to ask the same request to its corresponding master core, in order to get more information about the requested Node"); - } - } - - private void actionREPORT(SolrQueryResponse rsp, SolrParams params, String cname) throws JSONException - { - NamedList report = new SimpleOrderedMap<>(); - rsp.add("report", report); - - Long fromTime = getSafeLong(params, "fromTime"); - Long toTime = getSafeLong(params, "toTime"); - Long fromTx = getSafeLong(params, "fromTx"); - Long toTx = getSafeLong(params, "toTx"); - Long fromAclTx = getSafeLong(params, "fromAclTx"); - Long toAclTx = getSafeLong(params, "toAclTx"); - - if (cname != null) - { - if (trackerRegistry.hasTrackersForCore(cname) && isMasterOrStandalone(cname)) - { - report.add(cname, buildTrackerReport(trackerRegistry, informationServers.get(cname),cname, fromTx, toTx, fromAclTx, toAclTx, fromTime, toTime)); - } - } - else - { - trackerRegistry.getCoreNames().stream() - .filter(trackerRegistry::hasTrackersForCore) - .filter(this::isMasterOrStandalone) - .forEach(coreName -> report.add(coreName, buildTrackerReport(trackerRegistry, informationServers.get(coreName), coreName, fromTx, toTx, fromAclTx, toAclTx, fromTime, toTime))); - } - } - - private DocRouter getDocRouter(String cname) - { - Collection trackers = trackerRegistry.getTrackersForCore(cname); - MetadataTracker metadataTracker = null; - for(Tracker tracker : trackers) - { - if(tracker instanceof MetadataTracker) - { - metadataTracker = (MetadataTracker)tracker; - } - } - - return metadataTracker.getDocRouter(); - } - - - private void rangeCheck(SolrQueryResponse rsp,String cname) throws IOException - { - InformationServer informationServer = informationServers.get(cname); - - DocRouter docRouter = getDocRouter(cname); - - if(docRouter instanceof DBIDRangeRouter) - { - DBIDRangeRouter dbidRangeRouter = (DBIDRangeRouter) docRouter; - - if(!dbidRangeRouter.getInitialized()) - { - rsp.add("expand", 0); - rsp.add("exception", "DBIDRangeRouter not initialized yet."); - return; - } - - long startRange = dbidRangeRouter.getStartRange(); - long endRange = dbidRangeRouter.getEndRange(); - - long maxNodeId = informationServer.maxNodeId(); - long minNodeId = informationServer.minNodeId(); - long nodeCount = informationServer.nodeCount(); - - long bestGuess = -1; // -1 means expansion cannot be done. Either because expansion - // has already happened or we're above safe range - - long range = endRange - startRange; // We want this many nodes on the server - - long midpoint = startRange + ((long) (range * .5)); - - long safe = startRange + ((long) (range * .75)); - - long offset = maxNodeId-startRange; - - double density = 0; - - if(offset > 0) - { - density = ((double)nodeCount) / ((double)offset); // This is how dense we are so far. - } - - if (!dbidRangeRouter.getExpanded()) - { - if(maxNodeId <= safe) - { - if (maxNodeId >= midpoint) - { - if(density >= 1 || density == 0) - { - //This is fully dense shard or an empty shard. - // If it does happen, no expand is required. - bestGuess=0; - } - else - { - double multiplier = 1/density; - bestGuess = (long)(range*multiplier)-range; // This is how much to add - } - } - else - { - bestGuess = 0; // We're below the midpoint so it's to early to make a guess. - } - } - } - - rsp.add("start", startRange); - rsp.add("end", endRange); - rsp.add("nodeCount", nodeCount); - rsp.add("minDbid", minNodeId); - rsp.add("maxDbid", maxNodeId); - rsp.add("density", Math.abs(density)); - rsp.add("expand", bestGuess); - rsp.add("expanded", dbidRangeRouter.getExpanded()); - } - else - { - rsp.add("expand", -1); - rsp.add("exception", "ERROR: Wrong document router type:"+docRouter.getClass().getSimpleName()); - } - } - - private synchronized void expand(SolrQueryResponse rsp, SolrParams params, String cname) throws IOException - { - InformationServer informationServer = informationServers.get(cname); - DocRouter docRouter = getDocRouter(cname); - - if(docRouter instanceof DBIDRangeRouter) - { - long expansion = Long.parseLong(params.get("add")); - DBIDRangeRouter dbidRangeRouter = (DBIDRangeRouter)docRouter; - - if(!dbidRangeRouter.getInitialized()) - { - rsp.add("expand", -1); - rsp.add("exception", "DBIDRangeRouter not initialized yet."); - return; - } - - if(dbidRangeRouter.getExpanded()) - { - rsp.add("expand", -1); - rsp.add("exception", "dbid range has already been expanded."); - return; - } - - long currentEndRange = dbidRangeRouter.getEndRange(); - long startRange = dbidRangeRouter.getStartRange(); - long maxNodeId = informationServer.maxNodeId(); - - long range = currentEndRange - startRange; - long safe = startRange + ((long) (range * .75)); - - if(maxNodeId > safe) - { - rsp.add("expand", -1); - rsp.add("exception", "Expansion cannot occur if max DBID in the index is more then 75% of range."); - return; - } - - long newEndRange = expansion+dbidRangeRouter.getEndRange(); - try - { - informationServer.capIndex(newEndRange); - informationServer.hardCommit(); - dbidRangeRouter.setEndRange(newEndRange); - dbidRangeRouter.setExpanded(true); - assert newEndRange == dbidRangeRouter.getEndRange(); - rsp.add("expand", dbidRangeRouter.getEndRange()); - } - catch(Throwable t) - { - rsp.add("expand", -1); - rsp.add("exception", t.getMessage()); - LOGGER.error("exception expanding", t); - } - } - else - { - rsp.add("expand", -1); - rsp.add("exception", "Wrong document router type:" + docRouter.getClass().getSimpleName()); - } - } - - private void actionNODEREPORTS(SolrQueryResponse rsp, SolrParams params, String cname) throws JSONException - { - Long dbid = - ofNullable(params.get(ARG_NODEID)) - .map(Long::valueOf) - .orElseThrow(() -> new AlfrescoRuntimeException("No dbid parameter set.")); - - NamedList report = new SimpleOrderedMap<>(); - rsp.add("report", report); - - if (cname != null) - { - report.add(cname, buildNodeReport(nodeStatePublisher(cname), dbid)); - } - else - { - trackerRegistry.getCoreNames().forEach(coreName -> report.add(coreName, buildNodeReport(nodeStatePublisher(coreName), dbid))); - } - } - - private void actionSUMMARY(SolrParams params, NamedList report, String coreName) throws IOException + private void coreSummary(SolrParams params, NamedList report, String coreName) { boolean detail = getSafeBoolean(params, "detail"); boolean hist = getSafeBoolean(params, "hist"); boolean values = getSafeBoolean(params, "values"); boolean reset = getSafeBoolean(params, "reset"); - + InformationServer srv = informationServers.get(coreName); if (srv != null) { - if (isMasterOrStandalone(coreName)) + try { - addMasterOrStandaloneCoreSummary(trackerRegistry, coreName, detail, hist, values, srv, report); - - if (reset) + if (isMasterOrStandalone(coreName)) { - srv.getTrackerStats().reset(); + addMasterOrStandaloneCoreSummary(trackerRegistry, coreName, detail, hist, values, srv, report); + + if (reset) + { + srv.getTrackerStats().reset(); + } + } else + { + addSlaveCoreSummary(trackerRegistry, coreName, detail, hist, values, srv, report); } } - else + catch(Exception exception) { - addSlaveCoreSummary(trackerRegistry, coreName, detail, hist, values, srv, report); + throw new AlfrescoRuntimeException("", exception); } } else @@ -1068,129 +1139,15 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler } } - private void actionINDEX(SolrParams params, String coreName) + private DocRouter getDocRouter(String cname) { - if (isMasterOrStandalone(coreName)) - { - if (params.get(ARG_TXID) != null) - { - Long txid = Long.valueOf(params.get(ARG_TXID)); - MetadataTracker tracker = trackerRegistry.getTrackerForCore(coreName, MetadataTracker.class); - tracker.addTransactionToIndex(txid); - } - - if (params.get(ARG_ACLTXID) != null) - { - Long acltxid = Long.valueOf(params.get(ARG_ACLTXID)); - AclTracker tracker = trackerRegistry.getTrackerForCore(coreName, AclTracker.class); - tracker.addAclChangeSetToIndex(acltxid); - } - - if (params.get(ARG_NODEID) != null) - { - Long nodeid = Long.valueOf(params.get(ARG_NODEID)); - MetadataTracker tracker = trackerRegistry.getTrackerForCore(coreName, MetadataTracker.class); - tracker.addNodeToIndex(nodeid); - } - - if (params.get(ARG_ACLID) != null) - { - Long aclid = Long.valueOf(params.get(ARG_ACLID)); - AclTracker tracker = trackerRegistry.getTrackerForCore(coreName, AclTracker.class); - tracker.addAclToIndex(aclid); - } - } - } - - private void actionRETRY(SolrQueryResponse rsp, String coreName) throws IOException - { - if (isMasterOrStandalone(coreName)) - { - MetadataTracker tracker = trackerRegistry.getTrackerForCore(coreName, MetadataTracker.class); - InformationServer srv = informationServers.get(coreName); - - Set errorDocIds = srv.getErrorDocIds(); - for (Long nodeid : errorDocIds) - { - tracker.addNodeToReindex(nodeid); - } - rsp.add(coreName, errorDocIds); - } - } - - private void actionREINDEX(SolrParams params, String coreName) - { - if (isMasterOrStandalone(coreName)) - { - if (params.get(ARG_TXID) != null) - { - Long txid = Long.valueOf(params.get(ARG_TXID)); - MetadataTracker tracker = trackerRegistry.getTrackerForCore(coreName, MetadataTracker.class); - tracker.addTransactionToReindex(txid); - } - - if (params.get(ARG_ACLTXID) != null) - { - Long acltxid = Long.valueOf(params.get(ARG_ACLTXID)); - AclTracker tracker = trackerRegistry.getTrackerForCore(coreName, AclTracker.class); - tracker.addAclChangeSetToReindex(acltxid); - } - - if (params.get(ARG_NODEID) != null) - { - Long nodeid = Long.valueOf(params.get(ARG_NODEID)); - MetadataTracker tracker = trackerRegistry.getTrackerForCore(coreName, MetadataTracker.class); - tracker.addNodeToReindex(nodeid); - } - - if (params.get(ARG_ACLID) != null) - { - Long aclid = Long.valueOf(params.get(ARG_ACLID)); - AclTracker tracker = trackerRegistry.getTrackerForCore(coreName, AclTracker.class); - tracker.addAclToReindex(aclid); - } - - if (params.get(ARG_QUERY) != null) - { - String query = params.get(ARG_QUERY); - MetadataTracker tracker = trackerRegistry.getTrackerForCore(coreName, MetadataTracker.class); - tracker.addQueryToReindex(query); - } - } - } - - private void actionPURGE(SolrParams params, String coreName) - { - if (isMasterOrStandalone(coreName)) - { - if (params.get(ARG_TXID) != null) - { - Long txid = Long.valueOf(params.get(ARG_TXID)); - MetadataTracker tracker = trackerRegistry.getTrackerForCore(coreName, MetadataTracker.class); - tracker.addTransactionToPurge(txid); - } - - if (params.get(ARG_ACLTXID) != null) - { - Long acltxid = Long.valueOf(params.get(ARG_ACLTXID)); - AclTracker tracker = trackerRegistry.getTrackerForCore(coreName, AclTracker.class); - tracker.addAclChangeSetToPurge(acltxid); - } - - if (params.get(ARG_NODEID) != null) - { - Long nodeid = Long.valueOf(params.get(ARG_NODEID)); - MetadataTracker tracker = trackerRegistry.getTrackerForCore(coreName, MetadataTracker.class); - tracker.addNodeToPurge(nodeid); - } - - if (params.get(ARG_ACLID) != null) - { - Long aclid = Long.valueOf(params.get(ARG_ACLID)); - AclTracker tracker = trackerRegistry.getTrackerForCore(coreName, AclTracker.class); - tracker.addAclToPurge(aclid); - } - } + return notNullOrEmpty(trackerRegistry.getTrackersForCore(cname)) + .stream() + .filter(tracker -> tracker instanceof MetadataTracker) + .findAny() + .map(MetadataTracker.class::cast) + .map(MetadataTracker::getDocRouter) + .orElse(null); } public ConcurrentHashMap getInformationServers() @@ -1238,8 +1195,59 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler .orElse(trackerRegistry.getTrackerForCore(coreName, SlaveCoreStatePublisher.class)); } + /** + * Quickly checks if the given name is associated to a master or standalone core. + * + * @param coreName the core name. + * @return true if the name is associated with a master or standalone mode, false otherwise. + */ private boolean isMasterOrStandalone(String coreName) { return trackerRegistry.getTrackerForCore(coreName, MetadataTracker.class) != null; } -} + + /** + * Adds to the returned report an information message alerting the receiver that this core is a slave, + * and therefore the same request should be re-submited to the corresponding master. + * + * @param report the response report. + */ + private void addAlertMessage(NamedList report) + { + report.add( + "WARNING", + "The requested endpoint is not available on the slave. " + + "Please re-submit the same request to the corresponding Master"); + } + + private BiConsumer> apply(SolrParams params, String parameterName, Consumer action) + { + return (parameter, consumer) -> + ofNullable(params.get(parameterName)) + .map(Long::valueOf) + .ifPresent(action); + } + + private Collection coreNames() + { + return notNullOrEmpty(trackerRegistry.getCoreNames()); + } + + /** + * Returns the core name indicated in the request parameters. + * A first attempt is done in order to check if a standard {@link CoreAdminParams#CORE} parameter is in the request. + * If not, the alternative "coreName" parameter name is used. + * + * @param params the request parameters. + * @return the core name specified in the request, null if the parameter is not found. + */ + private String coreName(SolrParams params) + { + return CORE_PARAMETER_NAMES.stream() + .map(params::get) + .filter(Objects::nonNull) + .map(String::trim) + .findFirst() + .orElse(null); + } +} \ No newline at end of file diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/HandlerReportBuilder.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/HandlerReportHelper.java similarity index 98% rename from search-services/alfresco-search/src/main/java/org/alfresco/solr/HandlerReportBuilder.java rename to search-services/alfresco-search/src/main/java/org/alfresco/solr/HandlerReportHelper.java index 8aca5f99c..a3c2b069d 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/HandlerReportBuilder.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/HandlerReportHelper.java @@ -22,12 +22,10 @@ package org.alfresco.solr; import org.alfresco.error.AlfrescoRuntimeException; -import org.alfresco.httpclient.AuthenticationException; import org.alfresco.service.cmr.repository.datatype.Duration; import org.alfresco.solr.client.Node; import org.alfresco.solr.tracker.*; import org.alfresco.util.CachingDateFormat; -import org.apache.commons.codec.EncoderException; import org.apache.solr.common.util.NamedList; import org.apache.solr.common.util.SimpleOrderedMap; import org.json.JSONException; @@ -43,7 +41,7 @@ import static java.util.Optional.ofNullable; /** * Methods taken from AlfrescoCoreAdminHandler that deal with building reports */ -class HandlerReportBuilder +class HandlerReportHelper { static NamedList buildAclReport(AclTracker tracker, Long aclid) throws JSONException { @@ -60,8 +58,7 @@ class HandlerReportBuilder return nr; } - static NamedList buildTxReport(TrackerRegistry trackerRegistry, InformationServer srv, String coreName, MetadataTracker tracker, Long txid) - throws AuthenticationException, IOException, JSONException, EncoderException + static NamedList buildTxReport(TrackerRegistry trackerRegistry, InformationServer srv, String coreName, MetadataTracker tracker, Long txid) throws JSONException { NamedList nr = new SimpleOrderedMap<>(); nr.add("TXID", txid); @@ -139,7 +136,8 @@ class HandlerReportBuilder } else { - payload.add("WARNING", "This response comes from a slave core. Please consider to ask the same to its corresponding master core, in order to get more information about the requested Node"); + payload.add("WARNING", "This response comes from a slave core and it contains minimal information about the node. " + + "Please consider to re-submit the same request to the corresponding Master, in order to get more information."); } ofNullable(nodeReport.getIndexedNodeDocCount()).ifPresent(value -> payload.add("Indexed Node Doc Count", value)); diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/utils/Utils.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/utils/Utils.java new file mode 100644 index 000000000..2254b9cf0 --- /dev/null +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/utils/Utils.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2005-2019 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.solr.utils; + +import java.util.Collection; +import java.util.Collections; + +public abstract class Utils +{ + /** + * Returns the same input collection if that is not null, otherwise a new empty collection. + * Provides a safe way for iterating over a returned collection (which could be null). + * + * @param values the collection. + * @param the collection type. + * @return the same input collection if that is not null, otherwise a new empty collection. + */ + public static Collection notNullOrEmpty(Collection values) + { + return values != null ? values : Collections.emptyList(); + } + + /** + * Converts the given input in an Integer, otherwise it returns null. + * + * @param value the numeric string. + * @return the corresponding Integer or null in case the input is NaN. + */ + public static Integer toIntOrNull(String value) + { + try + { + return Integer.valueOf(value); + } + catch(NumberFormatException nfe) + { + return null; + } + } +} diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/AlfrescoCoreAdminHandlerTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/AlfrescoCoreAdminHandlerTest.java index 955f365b5..c40e07681 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/AlfrescoCoreAdminHandlerTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/AlfrescoCoreAdminHandlerTest.java @@ -20,15 +20,21 @@ package org.alfresco.solr; import static java.util.Arrays.asList; +import static java.util.Collections.emptyList; +import static java.util.Collections.singletonList; import static org.alfresco.solr.AlfrescoCoreAdminHandler.ALFRESCO_CORE_NAME; import static org.alfresco.solr.AlfrescoCoreAdminHandler.ARCHIVE_CORE_NAME; import static org.alfresco.solr.AlfrescoCoreAdminHandler.ARG_TXID; import static org.alfresco.solr.AlfrescoCoreAdminHandler.STORE_REF_MAP; import static org.alfresco.solr.AlfrescoCoreAdminHandler.VERSION_CORE_NAME; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; import static org.mockito.Mockito.spy; @@ -49,6 +55,7 @@ import org.apache.solr.common.SolrException; import org.apache.solr.common.params.CoreAdminParams; import org.apache.solr.common.params.SolrParams; import org.apache.solr.common.util.NamedList; +import org.apache.solr.core.SolrCore; import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.response.SolrQueryResponse; import org.junit.Before; @@ -105,6 +112,81 @@ public class AlfrescoCoreAdminHandlerTest when(req.getParams()).thenReturn(params); } + @Test + public void extractShardsWithEmptyParameter_shouldReturnAnEmptyList() + { + assertTrue(alfrescoCoreAdminHandler.extractShards("", Integer.MAX_VALUE).isEmpty()); + } + + @Test + public void extractShardsWithNullParameter_shouldReturnAnEmptyList() + { + assertTrue(alfrescoCoreAdminHandler.extractShards(null, Integer.MAX_VALUE).isEmpty()); + } + + @Test + public void extractShardsWithOneInvalidShard_shouldReturnAnEmptyList() + { + assertTrue(alfrescoCoreAdminHandler.extractShards("This is an invalid shard id", Integer.MAX_VALUE).isEmpty()); + } + + @Test + public void extractShardsWithOneShards_shouldReturnSingletonList() + { + assertEquals(singletonList(1), alfrescoCoreAdminHandler.extractShards("1", Integer.MAX_VALUE)); + } + + @Test + public void extractShardsWithSeveralValidShards_shouldReturnAllOfThemInTheList() + { + assertEquals(asList(1,5,6,11,23), alfrescoCoreAdminHandler.extractShards("1,5,6,11,23", Integer.MAX_VALUE)); + } + + @Test + public void extractShardsWithSeveralValidShards_shouldReturnOnlyValidIdentifiers() + { + assertEquals(asList(1,5,6,11,23), alfrescoCoreAdminHandler.extractShards("1,5,A,6,xyz,11,BB,23,o01z", Integer.MAX_VALUE)); + } + + @Test + public void extractShardsWithSeveralValidShardsAndLimit_shouldConsiderOnlyShardsLesserThanLimit() + { + assertEquals(asList(1,5,6,11,12), alfrescoCoreAdminHandler.extractShards("1,5,6,11,23,25,99,223,12", 23)); + } + + @Test + public void hasAlfrescoCoreWhenInputIsNull_shouldReturnFalse() + { + assertFalse(alfrescoCoreAdminHandler.hasAlfrescoCore(null)); + } + + @Test + public void hasAlfrescoCoreWhenWeHaveNoCore_shouldReturnFalse() + { + assertFalse(alfrescoCoreAdminHandler.hasAlfrescoCore(emptyList())); + } + + @Test + public void hasAlfrescoCoreWhenDoesntHaveAnyTracker_shouldReturnFalse() + { + when(trackerRegistry.hasTrackersForCore(anyString())).thenReturn(false); + assertFalse(alfrescoCoreAdminHandler.hasAlfrescoCore(emptyList())); + } + + @Test + public void hasAlfrescoCoreWithRegisteredTrackers_shouldReturnTrue() + { + when(trackerRegistry.hasTrackersForCore("CoreD")).thenReturn(true); + assertTrue(alfrescoCoreAdminHandler.hasAlfrescoCore(asList(dummyCore("CoreA"), dummyCore("CoreB"), dummyCore("CoreC"), dummyCore("CoreD")))); + } + + private SolrCore dummyCore(String name) + { + SolrCore core = mock(SolrCore.class); + when(core.getName()).thenReturn(name); + return core; + } + /** Check that a transaction report can be generated. */ @Test public void handleCustomActionTXReportSuccess() throws Exception @@ -212,10 +294,9 @@ public class AlfrescoCoreAdminHandlerTest public void coreNamesAreTrimmed_oneCoreNameAtTime() { AlfrescoCoreAdminHandler spy = spy(new AlfrescoCoreAdminHandler() { @Override - protected boolean newCore(String coreName, int numShards, StoreRef storeRef, String templateName, int replicationFactor, int nodeInstance, int numNodes, String shardIds, Properties extraProperties, SolrQueryResponse rsp) + protected void newCore(String coreName, int numShards, StoreRef storeRef, String templateName, int replicationFactor, int nodeInstance, int numNodes, String shardIds, Properties extraProperties, SolrQueryResponse rsp) { // Do nothing here otherwise we cannot spy it - return true; } }); @@ -238,10 +319,9 @@ public class AlfrescoCoreAdminHandlerTest public void validAndInvalidCoreNames() { AlfrescoCoreAdminHandler spy = spy(new AlfrescoCoreAdminHandler() { @Override - protected boolean newCore(String coreName, int numShards, StoreRef storeRef, String templateName, int replicationFactor, int nodeInstance, int numNodes, String shardIds, Properties extraProperties, SolrQueryResponse rsp) + protected void newCore(String coreName, int numShards, StoreRef storeRef, String templateName, int replicationFactor, int nodeInstance, int numNodes, String shardIds, Properties extraProperties, SolrQueryResponse rsp) { // Do nothing here otherwise we cannot spy it - return true; } }); From ba470e8913c847dbc130463ed5c1a38c6dfda09e Mon Sep 17 00:00:00 2001 From: agazzarini Date: Mon, 11 Nov 2019 10:51:11 +0100 Subject: [PATCH 40/42] [ SEARCH-1917 ] better core name parameter handling --- .../solr/AlfrescoCoreAdminHandler.java | 59 +++++++++++++------ 1 file changed, 41 insertions(+), 18 deletions(-) diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/AlfrescoCoreAdminHandler.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/AlfrescoCoreAdminHandler.java index e43d9b536..c0ba58644 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/AlfrescoCoreAdminHandler.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/AlfrescoCoreAdminHandler.java @@ -286,8 +286,11 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler protected void handleCustomAction(SolrQueryRequest req, SolrQueryResponse rsp) { SolrParams params = req.getParams(); - String action = params.get(CoreAdminParams.ACTION); - action = Objects.requireNonNullElse(action.toUpperCase(), ""); + String action = + ofNullable(params.get(CoreAdminParams.ACTION)) + .map(String::trim) + .map(String::toUpperCase) + .orElse(""); try { switch (action) @@ -651,7 +654,7 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler private void actionCHECK(SolrParams params) { - String cname = params.get(CoreAdminParams.CORE); + String cname = coreName(params); coreNames().stream() .filter(coreName -> cname == null || coreName.equals(cname)) .map(trackerRegistry::getTrackersForCore) @@ -670,8 +673,10 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler NamedList report = new SimpleOrderedMap<>(); rsp.add(REPORT, report); + String requestedCoreName = coreName(params); + coreNames().stream() - .filter(coreName -> params.get(CoreAdminParams.CORE) == null || coreName.equals(params.get(CoreAdminParams.CORE))) + .filter(coreName -> requestedCoreName == null || coreName.equals(requestedCoreName)) .filter(trackerRegistry::hasTrackersForCore) .map(coreName -> new Pair<>(coreName, nodeStatePublisher(coreName))) .filter(coreNameAndPublisher -> coreNameAndPublisher.getSecond() != null) @@ -691,8 +696,10 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler NamedList report = new SimpleOrderedMap<>(); rsp.add(REPORT, report); + String requestedCoreName = coreName(params); + coreNames().stream() - .filter(coreName -> params.get(CoreAdminParams.CORE) == null || coreName.equals(params.get(CoreAdminParams.CORE))) + .filter(coreName -> requestedCoreName == null || coreName.equals(requestedCoreName)) .map(coreName -> new Pair<>(coreName, trackerRegistry.getTrackerForCore(coreName, AclTracker.class))) .filter(coreNameAndAclTracker -> coreNameAndAclTracker.getSecond() != null) .forEach(coreNameAndAclTracker -> @@ -709,7 +716,7 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler private void actionTXREPORT(SolrQueryResponse rsp, SolrParams params) throws JSONException { String coreName = - ofNullable(params.get(CoreAdminParams.CORE)) + ofNullable(coreName(params)) .orElseThrow(() -> new AlfrescoRuntimeException("No " + params.get(CoreAdminParams.CORE + " parameter set."))); NamedList report = new SimpleOrderedMap<>(); @@ -741,8 +748,10 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler NamedList report = new SimpleOrderedMap<>(); rsp.add(REPORT, report); + String requestedCoreName = coreName(params); + coreNames().stream() - .filter(coreName -> params.get(CoreAdminParams.CORE) == null || coreName.equals(params.get(CoreAdminParams.CORE))) + .filter(coreName -> requestedCoreName == null || coreName.equals(requestedCoreName)) .map(coreName -> new Pair<>(coreName, trackerRegistry.getTrackerForCore(coreName, AclTracker.class))) .filter(coreNameAndAclTracker -> coreNameAndAclTracker.getSecond() != null) .forEach(coreNameAndAclTracker -> @@ -764,7 +773,7 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler private void rangeCheck(SolrQueryResponse rsp, SolrParams params) throws IOException { String coreName = - ofNullable(params.get(CoreAdminParams.CORE)) + ofNullable(coreName(params)) .orElseThrow(() -> new AlfrescoRuntimeException("No " + params.get(CoreAdminParams.CORE + " parameter set."))); if (isMasterOrStandalone(coreName)) @@ -860,7 +869,7 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler private synchronized void expand(SolrQueryResponse rsp, SolrParams params) throws IOException { String coreName = - ofNullable(params.get(CoreAdminParams.CORE)) + ofNullable(coreName(params)) .orElseThrow(() -> new AlfrescoRuntimeException("No " + params.get(CoreAdminParams.CORE + " parameter set."))); if (isMasterOrStandalone(coreName)) @@ -944,8 +953,10 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler Long fromAclTx = getSafeLong(params, "fromAclTx"); Long toAclTx = getSafeLong(params, "toAclTx"); + String requestedCoreName = coreName(params); + coreNames().stream() - .filter(coreName -> params.get(CoreAdminParams.CORE) == null || coreName.equals(params.get(CoreAdminParams.CORE))) + .filter(coreName -> requestedCoreName == null || coreName.equals(requestedCoreName)) .filter(trackerRegistry::hasTrackersForCore) .filter(this::isMasterOrStandalone) .forEach(coreName -> @@ -980,8 +991,10 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler .andThen(apply(params, ARG_ACLID, aclTracker::addAclToPurge)); }; + String requestedCoreName = coreName(params); + coreNames().stream() - .filter(coreName -> params.get(CoreAdminParams.CORE) == null || coreName.equals(params.get(CoreAdminParams.CORE))) + .filter(coreName -> requestedCoreName == null || coreName.equals(requestedCoreName)) .filter(this::isMasterOrStandalone) .forEach(purgeOnSpecificCore); } @@ -1000,8 +1013,10 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler ofNullable(params.get(ARG_QUERY)).ifPresent(metadataTracker::addQueryToReindex); }; + String requestedCoreName = coreName(params); + coreNames().stream() - .filter(coreName -> params.get(CoreAdminParams.CORE) == null || coreName.equals(params.get(CoreAdminParams.CORE))) + .filter(coreName -> requestedCoreName == null || coreName.equals(requestedCoreName)) .filter(this::isMasterOrStandalone) .forEach(reindexOnSpecificCore); } @@ -1026,8 +1041,10 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler } }; + String requestedCoreName = coreName(params); + coreNames().stream() - .filter(coreName -> params.get(CoreAdminParams.CORE) == null || coreName.equals(params.get(CoreAdminParams.CORE))) + .filter(coreName -> requestedCoreName == null || coreName.equals(requestedCoreName)) .filter(this::isMasterOrStandalone) .forEach(retryOnSpecificCore); } @@ -1044,16 +1061,20 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler .andThen(apply(params, ARG_ACLID, aclTracker::addAclToIndex)); }; + String requestedCoreName = coreName(params); + coreNames().stream() - .filter(coreName -> params.get(CoreAdminParams.CORE) == null || coreName.equals(params.get(CoreAdminParams.CORE))) + .filter(coreName -> requestedCoreName == null || coreName.equals(requestedCoreName)) .filter(this::isMasterOrStandalone) .forEach(indexOnSpecificCore); } private void actionFIX(SolrParams params) throws JSONException { + String requestedCoreName = coreName(params); + coreNames().stream() - .filter(coreName -> params.get(CoreAdminParams.CORE) == null || coreName.equals(params.get(CoreAdminParams.CORE))) + .filter(coreName -> requestedCoreName == null || coreName.equals(requestedCoreName)) .filter(this::isMasterOrStandalone) .forEach(this::fixOnSpecificCore); } @@ -1097,8 +1118,10 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler NamedList report = new SimpleOrderedMap<>(); rsp.add("Summary", report); + String requestedCoreName = coreName(params); + coreNames().stream() - .filter(coreName -> params.get(CoreAdminParams.CORE) == null || coreName.equals(params.get(CoreAdminParams.CORE))) + .filter(coreName -> requestedCoreName == null || coreName.equals(requestedCoreName)) .filter(this::isMasterOrStandalone) .forEach(coreName -> coreSummary(params, report, coreName)); } @@ -1220,12 +1243,12 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler "Please re-submit the same request to the corresponding Master"); } - private BiConsumer> apply(SolrParams params, String parameterName, Consumer action) + private BiConsumer> apply(SolrParams params, String parameterName, Consumer executeSideEffectAction) { return (parameter, consumer) -> ofNullable(params.get(parameterName)) .map(Long::valueOf) - .ifPresent(action); + .ifPresent(executeSideEffectAction); } private Collection coreNames() From 7f9e5e193dec0648c958bf3390df69c7fae517eb Mon Sep 17 00:00:00 2001 From: agazzarini Date: Mon, 11 Nov 2019 13:10:43 +0100 Subject: [PATCH 41/42] [ SEARCH-1917 ] Working implementation + Unit tests --- .../solr/AlfrescoCoreAdminHandler.java | 67 ++++++------ .../solr/AlfrescoCoreAdminHandlerTest.java | 101 ++++++++++++++++-- 2 files changed, 125 insertions(+), 43 deletions(-) diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/AlfrescoCoreAdminHandler.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/AlfrescoCoreAdminHandler.java index c0ba58644..3aea3584f 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/AlfrescoCoreAdminHandler.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/AlfrescoCoreAdminHandler.java @@ -70,7 +70,6 @@ import java.util.Objects; import java.util.Properties; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; -import java.util.function.BiConsumer; import java.util.function.Consumer; import java.util.stream.Collectors; @@ -593,8 +592,6 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler .anyMatch(trackerRegistry::hasTrackersForCore); } - // ::::: - private void updateShared(SolrQueryRequest req) { SolrParams params = req.getParams(); @@ -604,7 +601,9 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler File config = new File(AlfrescoSolrDataModel.getResourceDirectory(), AlfrescoSolrDataModel.SHARED_PROPERTIES); updateSharedProperties(params, config, hasAlfrescoCore(coreContainer.getCores())); - coreContainer.getCores().forEach(aCore -> coreContainer.reload(aCore.getName())); + coreContainer.getCores().stream() + .map(SolrCore::getName) + .forEach(coreContainer::reload); } catch (IOException e) { @@ -678,7 +677,7 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler coreNames().stream() .filter(coreName -> requestedCoreName == null || coreName.equals(requestedCoreName)) .filter(trackerRegistry::hasTrackersForCore) - .map(coreName -> new Pair<>(coreName, nodeStatePublisher(coreName))) + .map(coreName -> new Pair<>(coreName, coreStatePublisher(coreName))) .filter(coreNameAndPublisher -> coreNameAndPublisher.getSecond() != null) .forEach(coreNameAndPublisher -> report.add( @@ -985,10 +984,10 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler final MetadataTracker metadataTracker = trackerRegistry.getTrackerForCore(coreName, MetadataTracker.class); final AclTracker aclTracker = trackerRegistry.getTrackerForCore(coreName, AclTracker.class); - apply(params, ARG_TXID, metadataTracker::addTransactionToPurge) - .andThen(apply(params, ARG_ACLTXID, aclTracker::addAclChangeSetToPurge)) - .andThen(apply(params, ARG_NODEID, metadataTracker::addNodeToPurge)) - .andThen(apply(params, ARG_ACLID, aclTracker::addAclToPurge)); + apply(params, ARG_TXID, metadataTracker::addTransactionToPurge); + apply(params, ARG_ACLTXID, aclTracker::addAclChangeSetToPurge); + apply(params, ARG_NODEID, metadataTracker::addNodeToPurge); + apply(params, ARG_ACLID, aclTracker::addAclToPurge); }; String requestedCoreName = coreName(params); @@ -1005,10 +1004,10 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler final MetadataTracker metadataTracker = trackerRegistry.getTrackerForCore(coreName, MetadataTracker.class); final AclTracker aclTracker = trackerRegistry.getTrackerForCore(coreName, AclTracker.class); - apply(params, ARG_TXID, metadataTracker::addTransactionToReindex) - .andThen(apply(params, ARG_ACLTXID, aclTracker::addAclChangeSetToReindex)) - .andThen(apply(params, ARG_NODEID, metadataTracker::addNodeToReindex)) - .andThen(apply(params, ARG_ACLID, aclTracker::addAclToReindex)); + apply(params, ARG_TXID, metadataTracker::addTransactionToReindex); + apply(params, ARG_ACLTXID, aclTracker::addAclChangeSetToReindex); + apply(params, ARG_NODEID, metadataTracker::addNodeToReindex); + apply(params, ARG_ACLID, aclTracker::addAclToReindex); ofNullable(params.get(ARG_QUERY)).ifPresent(metadataTracker::addQueryToReindex); }; @@ -1055,10 +1054,10 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler final MetadataTracker metadataTracker = trackerRegistry.getTrackerForCore(coreName, MetadataTracker.class); final AclTracker aclTracker = trackerRegistry.getTrackerForCore(coreName, AclTracker.class); - apply(params, ARG_TXID, metadataTracker::addTransactionToIndex) - .andThen(apply(params, ARG_ACLTXID, aclTracker::addAclChangeSetToIndex)) - .andThen(apply(params, ARG_NODEID, metadataTracker::addNodeToIndex)) - .andThen(apply(params, ARG_ACLID, aclTracker::addAclToIndex)); + apply(params, ARG_TXID, metadataTracker::addTransactionToIndex); + apply(params, ARG_ACLTXID, aclTracker::addAclChangeSetToIndex); + apply(params, ARG_NODEID, metadataTracker::addNodeToIndex); + apply(params, ARG_ACLID, aclTracker::addAclToIndex); }; String requestedCoreName = coreName(params); @@ -1113,7 +1112,7 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler } } - private void actionSUMMARY(SolrQueryResponse rsp, SolrParams params) + void actionSUMMARY(SolrQueryResponse rsp, SolrParams params) { NamedList report = new SimpleOrderedMap<>(); rsp.add("Summary", report); @@ -1122,7 +1121,6 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler coreNames().stream() .filter(coreName -> requestedCoreName == null || coreName.equals(requestedCoreName)) - .filter(this::isMasterOrStandalone) .forEach(coreName -> coreSummary(params, report, coreName)); } @@ -1162,13 +1160,9 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler } } - private DocRouter getDocRouter(String cname) + DocRouter getDocRouter(String cname) { - return notNullOrEmpty(trackerRegistry.getTrackersForCore(cname)) - .stream() - .filter(tracker -> tracker instanceof MetadataTracker) - .findAny() - .map(MetadataTracker.class::cast) + return ofNullable(trackerRegistry.getTrackerForCore(cname, MetadataTracker.class)) .map(MetadataTracker::getDocRouter) .orElse(null); } @@ -1211,7 +1205,7 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler * @param coreName the owning core name. * @return the component which is in charge to publish the core state. */ - private CoreStatePublisher nodeStatePublisher(String coreName) + CoreStatePublisher coreStatePublisher(String coreName) { return ofNullable(trackerRegistry.getTrackerForCore(coreName, MetadataTracker.class)) .map(CoreStatePublisher.class::cast) @@ -1224,7 +1218,7 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler * @param coreName the core name. * @return true if the name is associated with a master or standalone mode, false otherwise. */ - private boolean isMasterOrStandalone(String coreName) + boolean isMasterOrStandalone(String coreName) { return trackerRegistry.getTrackerForCore(coreName, MetadataTracker.class) != null; } @@ -1243,19 +1237,18 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler "Please re-submit the same request to the corresponding Master"); } - private BiConsumer> apply(SolrParams params, String parameterName, Consumer executeSideEffectAction) - { - return (parameter, consumer) -> - ofNullable(params.get(parameterName)) - .map(Long::valueOf) - .ifPresent(executeSideEffectAction); - } - - private Collection coreNames() + Collection coreNames() { return notNullOrEmpty(trackerRegistry.getCoreNames()); } + private void apply(SolrParams params, String parameterName, Consumer executeSideEffectAction) + { + ofNullable(params.get(parameterName)) + .map(Long::valueOf) + .ifPresent(executeSideEffectAction); + } + /** * Returns the core name indicated in the request parameters. * A first attempt is done in order to check if a standard {@link CoreAdminParams#CORE} parameter is in the request. @@ -1264,7 +1257,7 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler * @param params the request parameters. * @return the core name specified in the request, null if the parameter is not found. */ - private String coreName(SolrParams params) + String coreName(SolrParams params) { return CORE_PARAMETER_NAMES.stream() .map(params::get) diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/AlfrescoCoreAdminHandlerTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/AlfrescoCoreAdminHandlerTest.java index c40e07681..6470a0993 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/AlfrescoCoreAdminHandlerTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/AlfrescoCoreAdminHandlerTest.java @@ -29,6 +29,8 @@ import static org.alfresco.solr.AlfrescoCoreAdminHandler.STORE_REF_MAP; import static org.alfresco.solr.AlfrescoCoreAdminHandler.VERSION_CORE_NAME; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; @@ -48,11 +50,15 @@ import java.util.stream.Collectors; import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.solr.adapters.IOpenBitSet; import org.alfresco.solr.tracker.AclTracker; +import org.alfresco.solr.tracker.DocRouter; import org.alfresco.solr.tracker.IndexHealthReport; import org.alfresco.solr.tracker.MetadataTracker; +import org.alfresco.solr.tracker.PropertyRouter; +import org.alfresco.solr.tracker.SlaveCoreStatePublisher; import org.alfresco.solr.tracker.TrackerRegistry; import org.apache.solr.common.SolrException; import org.apache.solr.common.params.CoreAdminParams; +import org.apache.solr.common.params.ModifiableSolrParams; import org.apache.solr.common.params.SolrParams; import org.apache.solr.common.util.NamedList; import org.apache.solr.core.SolrCore; @@ -169,7 +175,6 @@ public class AlfrescoCoreAdminHandlerTest @Test public void hasAlfrescoCoreWhenDoesntHaveAnyTracker_shouldReturnFalse() { - when(trackerRegistry.hasTrackersForCore(anyString())).thenReturn(false); assertFalse(alfrescoCoreAdminHandler.hasAlfrescoCore(emptyList())); } @@ -180,6 +185,95 @@ public class AlfrescoCoreAdminHandlerTest assertTrue(alfrescoCoreAdminHandler.hasAlfrescoCore(asList(dummyCore("CoreA"), dummyCore("CoreB"), dummyCore("CoreC"), dummyCore("CoreD")))); } + @Test + public void trackerRegistryHasNoCoreNames_itShouldReturnAnEmptyList() + { + assertTrue(alfrescoCoreAdminHandler.coreNames().isEmpty()); + } + + @Test + public void coreDetectedAsMasterOrStandalone() + { + MetadataTracker coreStatePublisher = mock(MetadataTracker.class); + + when(trackerRegistry.getTrackerForCore(anyString(), eq(MetadataTracker.class))) + .thenReturn(coreStatePublisher); + + assertTrue(alfrescoCoreAdminHandler.isMasterOrStandalone("ThisIsTheCoreName")); + } + + @Test + public void coreDetectedAsSlave() + { + when(trackerRegistry.getTrackerForCore(anyString(), eq(MetadataTracker.class))).thenReturn(null); + assertFalse(alfrescoCoreAdminHandler.isMasterOrStandalone("ThisIsTheCoreName")); + } + + @Test + public void coreIsMaster_thenCoreStatePublisherInstanceCorrespondsToMetadataTracker() + { + MetadataTracker coreStatePublisher = mock(MetadataTracker.class); + + when(trackerRegistry.getTrackerForCore(anyString(), eq(MetadataTracker.class))) + .thenReturn(coreStatePublisher); + + assertSame(coreStatePublisher, alfrescoCoreAdminHandler.coreStatePublisher("ThisIsTheCoreName")); + } + + @Test + public void coreIsSlave_thenCoreStatePublisherInstanceCorrespondsToSlaveCoreStatePublisher() + { + SlaveCoreStatePublisher coreStatePublisher = mock(SlaveCoreStatePublisher.class); + + when(trackerRegistry.getTrackerForCore(anyString(), eq(MetadataTracker.class))).thenReturn(null); + when(trackerRegistry.getTrackerForCore(anyString(), eq(SlaveCoreStatePublisher.class))).thenReturn(coreStatePublisher); + + assertSame(coreStatePublisher, alfrescoCoreAdminHandler.coreStatePublisher("ThisIsTheCoreName")); + } + + @Test + public void coreIsSlave_thenDocRouterIsNull() + { + String coreName = "aCore"; + when(trackerRegistry.getTrackerForCore(eq(coreName), eq(MetadataTracker.class))).thenReturn(null); + assertNull(alfrescoCoreAdminHandler.getDocRouter("aCore")); + } + + @Test + public void coreIsMaster_thenDocRouterIsProperlyReturned() + { + DocRouter expectedRouter = new PropertyRouter("someProperty_.{1,35}"); + + MetadataTracker coreStatePublisher = mock(MetadataTracker.class); + when(coreStatePublisher.getDocRouter()).thenReturn(expectedRouter); + when(trackerRegistry.getTrackerForCore(anyString(), eq(MetadataTracker.class))).thenReturn(coreStatePublisher); + + assertSame(expectedRouter, alfrescoCoreAdminHandler.getDocRouter("aCore")); + } + + @Test + public void targetCoreNameCanBeSpecifiedInSeveralWays() + { + String coreName = "ThisIsTheCoreName"; + + ModifiableSolrParams params = new ModifiableSolrParams(); + + assertNull(alfrescoCoreAdminHandler.coreName(params)); + + params.set(CoreAdminParams.CORE, coreName); + + assertEquals(coreName, alfrescoCoreAdminHandler.coreName(params)); + + params.remove(CoreAdminParams.CORE); + assertNull(alfrescoCoreAdminHandler.coreName(params)); + + params.set("coreName", coreName); + + assertEquals(coreName, alfrescoCoreAdminHandler.coreName(params)); + assertEquals(coreName, alfrescoCoreAdminHandler.coreName(params)); + } + + private SolrCore dummyCore(String name) { SolrCore core = mock(SolrCore.class); @@ -225,8 +319,6 @@ public class AlfrescoCoreAdminHandlerTest public void handleCustomActionTXReportMissingTXId() { when(params.get(CoreAdminParams.ACTION)).thenReturn(TXREPORT); - when(params.get(ARG_TXID)).thenReturn(null); - alfrescoCoreAdminHandler.handleCustomAction(req, rsp); verify(rsp, never()).add(anyString(), any()); @@ -238,11 +330,8 @@ public class AlfrescoCoreAdminHandlerTest { when(params.get(CoreAdminParams.ACTION)).thenReturn(TXREPORT); when(params.get(CoreAdminParams.CORE)).thenReturn(null); - when(params.get(ARG_TXID)).thenReturn(TX_ID); alfrescoCoreAdminHandler.handleCustomAction(req, rsp); - - verify(rsp, never()).add(anyString(), any()); } /** Check that when an unknown action is provided we don't generate a report. */ From 2ad47af4f8d8ff2c9d8dc240e8a42c34370e0da9 Mon Sep 17 00:00:00 2001 From: agazzarini Date: Mon, 11 Nov 2019 14:53:42 +0100 Subject: [PATCH 42/42] [ SEARCH-1917 ] Minor fixes --- .../java/org/alfresco/solr/AlfrescoCoreAdminHandler.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/AlfrescoCoreAdminHandler.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/AlfrescoCoreAdminHandler.java index 3aea3584f..7255a8d65 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/AlfrescoCoreAdminHandler.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/AlfrescoCoreAdminHandler.java @@ -716,7 +716,7 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler { String coreName = ofNullable(coreName(params)) - .orElseThrow(() -> new AlfrescoRuntimeException("No " + params.get(CoreAdminParams.CORE + " parameter set."))); + .orElseThrow(() -> new AlfrescoRuntimeException("No " + CoreAdminParams.CORE + " parameter set.")); NamedList report = new SimpleOrderedMap<>(); rsp.add(REPORT, report); @@ -773,7 +773,7 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler { String coreName = ofNullable(coreName(params)) - .orElseThrow(() -> new AlfrescoRuntimeException("No " + params.get(CoreAdminParams.CORE + " parameter set."))); + .orElseThrow(() -> new AlfrescoRuntimeException("No " + CoreAdminParams.CORE + " parameter set.")); if (isMasterOrStandalone(coreName)) { @@ -869,7 +869,7 @@ public class AlfrescoCoreAdminHandler extends CoreAdminHandler { String coreName = ofNullable(coreName(params)) - .orElseThrow(() -> new AlfrescoRuntimeException("No " + params.get(CoreAdminParams.CORE + " parameter set."))); + .orElseThrow(() -> new AlfrescoRuntimeException("No " + CoreAdminParams.CORE + " parameter set.")); if (isMasterOrStandalone(coreName)) {