diff --git a/module/.gitignore b/enterprise-module/.gitignore similarity index 100% rename from module/.gitignore rename to enterprise-module/.gitignore diff --git a/module/README.md b/enterprise-module/README.md similarity index 100% rename from module/README.md rename to enterprise-module/README.md diff --git a/module/pom.xml b/enterprise-module/pom.xml similarity index 88% rename from module/pom.xml rename to enterprise-module/pom.xml index 0c873d6..3782581 100644 --- a/module/pom.xml +++ b/enterprise-module/pom.xml @@ -10,10 +10,10 @@ ../ - asie-platform-module + asie-enterprise-platform-module jar - ASIE Platform Module + ASIE Platform Module for ACS Enterprise 5.2.0 @@ -30,6 +30,13 @@ import + + + com.inteligr8 + common-rest-client + provided + + jakarta.ws.rs @@ -57,8 +64,8 @@ com.inteligr8.alfresco - asie-api - 1.0-SNAPSHOT-asie2 + asie-shared + ${project.version} diff --git a/module/rad.ps1 b/enterprise-module/rad.ps1 similarity index 100% rename from module/rad.ps1 rename to enterprise-module/rad.ps1 diff --git a/module/rad.sh b/enterprise-module/rad.sh similarity index 100% rename from module/rad.sh rename to enterprise-module/rad.sh diff --git a/module/research/acs-enterprise-shard-attributes.json b/enterprise-module/research/acs-enterprise-shard-attributes.json similarity index 100% rename from module/research/acs-enterprise-shard-attributes.json rename to enterprise-module/research/acs-enterprise-shard-attributes.json diff --git a/enterprise-module/src/main/java/com/inteligr8/alfresco/asie/enterprise/EnterpriseConstants.java b/enterprise-module/src/main/java/com/inteligr8/alfresco/asie/enterprise/EnterpriseConstants.java new file mode 100644 index 0000000..51cbb47 --- /dev/null +++ b/enterprise-module/src/main/java/com/inteligr8/alfresco/asie/enterprise/EnterpriseConstants.java @@ -0,0 +1,10 @@ +package com.inteligr8.alfresco.asie.enterprise; + +public interface EnterpriseConstants { + + static final String BEAN_SHARD_REGISTRY = "search.ShardRegistry"; + + static final String ATTR_SHARD_STATE = ".SHARD_STATE"; + static final String ATTR_SHARD_SUBSCRIPTION = ".SHARD_SUBSCRIPTION"; + +} diff --git a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/bootstrap/ShardPurgeService.java b/enterprise-module/src/main/java/com/inteligr8/alfresco/asie/enterprise/bootstrap/ShardPurgeOnInitService.java similarity index 59% rename from module/src/main/java/com/inteligr8/alfresco/asie/enterprise/bootstrap/ShardPurgeService.java rename to enterprise-module/src/main/java/com/inteligr8/alfresco/asie/enterprise/bootstrap/ShardPurgeOnInitService.java index 9948a51..3718679 100644 --- a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/bootstrap/ShardPurgeService.java +++ b/enterprise-module/src/main/java/com/inteligr8/alfresco/asie/enterprise/bootstrap/ShardPurgeOnInitService.java @@ -1,16 +1,14 @@ package com.inteligr8.alfresco.asie.enterprise.bootstrap; -import org.alfresco.service.cmr.attributes.AttributeService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.ApplicationEvent; import org.springframework.extensions.surf.util.AbstractLifecycleBean; import org.springframework.stereotype.Component; -import com.inteligr8.alfresco.asie.Constants; +import com.inteligr8.alfresco.asie.spi.ShardStateService; /** * This is a workaround to a bug with the Alfresco Enterprise Solr purge @@ -18,28 +16,26 @@ import com.inteligr8.alfresco.asie.Constants; * all the fancy stuff and just hard purges the shards. */ @Component -public class ShardPurgeService extends AbstractLifecycleBean { +public class ShardPurgeOnInitService extends AbstractLifecycleBean { private final Logger logger = LoggerFactory.getLogger(this.getClass()); @Autowired - @Qualifier(Constants.QUALIFIER_ASIE) - private AttributeService attributeService; + private ShardStateService sss; @Value("${search.solrShardRegistry.purgeOnInit}") private boolean enabled; @Override protected void onBootstrap(ApplicationEvent event) { - this.logger.info("Using workaround for Alfresco Enterprise Solr ShardRegistry purge"); - this.attributeService.removeAttributes(Constants.ATTR_SHARD_STATE); - this.attributeService.removeAttributes(Constants.ATTR_SHARD_SUBSCRIPTION); - this.attributeService.removeAttributes(Constants.ATTR_ASIE); + if (this.enabled) { + this.logger.debug("Purge on initialization is enabled with 'search.solrShardRegistry.purgeOnInit'"); + this.sss.clear(); + } } @Override protected void onShutdown(ApplicationEvent event) { - // nothing to do } } diff --git a/enterprise-module/src/main/java/com/inteligr8/alfresco/asie/enterprise/provider/ShardRegistryProvider.java b/enterprise-module/src/main/java/com/inteligr8/alfresco/asie/enterprise/provider/ShardRegistryProvider.java new file mode 100644 index 0000000..9f43796 --- /dev/null +++ b/enterprise-module/src/main/java/com/inteligr8/alfresco/asie/enterprise/provider/ShardRegistryProvider.java @@ -0,0 +1,30 @@ +package com.inteligr8.alfresco.asie.enterprise.provider; + +import org.alfresco.repo.index.shard.ShardRegistry; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Scope; + +import com.inteligr8.alfresco.asie.Constants; +import com.inteligr8.alfresco.asie.enterprise.EnterpriseConstants; +import com.inteligr8.alfresco.asie.provider.AbstractProvider; + +@Configuration +public class ShardRegistryProvider extends AbstractProvider { + + /** + * This allows for the selection of the primary or first ShardRegistry + * registered in the Spring BeanFactory. + * + * @return A ShardRegistry. + */ + @Bean(Constants.BEAN_SHARD_REGISTRY) + @Qualifier(Constants.QUALIFIER_ASIE) + @Scope(ConfigurableBeanFactory.SCOPE_SINGLETON) + public ShardRegistry selectBean() { + return this.getPrimaryOrNamed(ShardRegistry.class, EnterpriseConstants.BEAN_SHARD_REGISTRY); + } + +} diff --git a/enterprise-module/src/main/java/com/inteligr8/alfresco/asie/enterprise/service/ShardStateService.java b/enterprise-module/src/main/java/com/inteligr8/alfresco/asie/enterprise/service/ShardStateService.java new file mode 100644 index 0000000..f60fc39 --- /dev/null +++ b/enterprise-module/src/main/java/com/inteligr8/alfresco/asie/enterprise/service/ShardStateService.java @@ -0,0 +1,84 @@ +package com.inteligr8.alfresco.asie.enterprise.service; + +import java.io.Serializable; +import java.util.Arrays; + +import org.alfresco.repo.cache.SimpleCache; +import org.alfresco.repo.index.shard.ShardInstance; +import org.alfresco.repo.index.shard.ShardState; +import org.alfresco.service.cmr.attributes.AttributeService; +import org.alfresco.service.cmr.attributes.AttributeService.AttributeQueryCallback; +import org.apache.commons.lang3.ArrayUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; + +import com.inteligr8.alfresco.asie.Constants; +import com.inteligr8.alfresco.asie.enterprise.EnterpriseConstants; + +@Component +public class ShardStateService implements com.inteligr8.alfresco.asie.spi.ShardStateService { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Autowired + @Qualifier(Constants.QUALIFIER_ASIE) + private AttributeService attrService; + + @Autowired + @Qualifier(Constants.BEAN_SHARD_STATE_CACHE) + private SimpleCache shardStateCache; + + @Autowired + @Qualifier(Constants.BEAN_SHARD_GUID_CACHE) + private SimpleCache shardToGuidCache; + + public void clear() { + this.logger.info("Removing all nodes/shards from the shard registry"); + + // this clears the state from the backend database + this.attrService.removeAttributes(EnterpriseConstants.ATTR_SHARD_STATE); + this.attrService.removeAttributes(EnterpriseConstants.ATTR_SHARD_SUBSCRIPTION); + this.attrService.removeAttributes(Constants.ATTR_ASIE); + + // this clears the state from Hazelcast + this.shardStateCache.clear(); + this.shardToGuidCache.clear(); + } + + public void remove(Serializable... keys) { + if (keys.length == 0) + throw new IllegalArgumentException(); + + this.logger.info("Removing from the shard registry: {}", Arrays.toString(keys)); + + Serializable[] shardStateKeys = keys; + Serializable[] shardSubKeys; + if (EnterpriseConstants.ATTR_SHARD_STATE.equals(keys[0])) { + shardSubKeys = ArrayUtils.clone(keys); + shardSubKeys[0] = EnterpriseConstants.ATTR_SHARD_SUBSCRIPTION; + } else { + shardStateKeys = ArrayUtils.addFirst(keys, EnterpriseConstants.ATTR_SHARD_STATE); + shardSubKeys = ArrayUtils.addFirst(keys, EnterpriseConstants.ATTR_SHARD_SUBSCRIPTION); + } + + ShardState shardState = (ShardState) this.attrService.getAttribute(shardStateKeys); + + // this clears the state from the backend database + this.attrService.removeAttribute(shardStateKeys); + this.attrService.removeAttribute(shardSubKeys); + + // this clears the state from Hazelcast + if (shardState != null) { + this.shardStateCache.remove(shardState.getShardInstance()); + this.shardToGuidCache.remove(shardState.getShardInstance()); + } + } + + public void iterate(AttributeQueryCallback callback) { + this.attrService.getAttributes(callback, EnterpriseConstants.ATTR_SHARD_STATE); + } + +} diff --git a/enterprise-module/src/main/resources/alfresco/module/com_inteligr8_alfresco_asie-enterprise-platform-module/alfresco-global.properties b/enterprise-module/src/main/resources/alfresco/module/com_inteligr8_alfresco_asie-enterprise-platform-module/alfresco-global.properties new file mode 100644 index 0000000..e69de29 diff --git a/enterprise-module/src/main/resources/alfresco/module/com_inteligr8_alfresco_asie-enterprise-platform-module/log4j2.properties b/enterprise-module/src/main/resources/alfresco/module/com_inteligr8_alfresco_asie-enterprise-platform-module/log4j2.properties new file mode 100644 index 0000000..f7cf5f9 --- /dev/null +++ b/enterprise-module/src/main/resources/alfresco/module/com_inteligr8_alfresco_asie-enterprise-platform-module/log4j2.properties @@ -0,0 +1,3 @@ + +logger.inteligr8-asie.name=com.inteligr8.alfresco.asie.enterprise +logger.inteligr8-asie.level=INFO diff --git a/module/src/main/resources/alfresco/module/com_inteligr8_alfresco_asie-platform-module/module-context.xml b/enterprise-module/src/main/resources/alfresco/module/com_inteligr8_alfresco_asie-enterprise-platform-module/module-context.xml similarity index 80% rename from module/src/main/resources/alfresco/module/com_inteligr8_alfresco_asie-platform-module/module-context.xml rename to enterprise-module/src/main/resources/alfresco/module/com_inteligr8_alfresco_asie-enterprise-platform-module/module-context.xml index 769f7e9..e273dda 100644 --- a/module/src/main/resources/alfresco/module/com_inteligr8_alfresco_asie-platform-module/module-context.xml +++ b/enterprise-module/src/main/resources/alfresco/module/com_inteligr8_alfresco_asie-enterprise-platform-module/module-context.xml @@ -6,10 +6,6 @@ xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> - - - diff --git a/module/src/main/resources/alfresco/module/com_inteligr8_alfresco_asie-platform-module/module.properties b/enterprise-module/src/main/resources/alfresco/module/com_inteligr8_alfresco_asie-enterprise-platform-module/module.properties similarity index 100% rename from module/src/main/resources/alfresco/module/com_inteligr8_alfresco_asie-platform-module/module.properties rename to enterprise-module/src/main/resources/alfresco/module/com_inteligr8_alfresco_asie-enterprise-platform-module/module.properties diff --git a/module/src/main/java/com/inteligr8/alfresco/asie/Constants.java b/module/src/main/java/com/inteligr8/alfresco/asie/Constants.java deleted file mode 100644 index f98112e..0000000 --- a/module/src/main/java/com/inteligr8/alfresco/asie/Constants.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.inteligr8.alfresco.asie; - -public interface Constants { - - static final String QUALIFIER_ASIE = "asie"; - static final String BEAN_SOLR_ADMIN_CLIENT = "search.SolrAdminClient"; - static final String BEAN_SHARD_REGISTRY = "search.ShardRegistry"; - static final String ATTR_SHARD_STATE = ".SHARD_STATE"; - static final String ATTR_SHARD_SUBSCRIPTION = ".SHARD_SUBSCRIPTION"; - static final String ATTR_ASIE = "inteligr8.asie"; - static final String ATTR_UNLOADED_NODE_CORES = "unloadedNode.cores"; - -} diff --git a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/service/ShardAnalysisService.java b/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/service/ShardAnalysisService.java deleted file mode 100644 index 0bfbdd0..0000000 --- a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/service/ShardAnalysisService.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.inteligr8.alfresco.asie.enterprise.service; - -import java.util.Collection; - -import org.alfresco.repo.index.shard.ShardInstance; -import org.alfresco.repo.index.shard.ShardState; -import org.springframework.stereotype.Component; - -@Component -public class ShardAnalysisService { - - public ShardInstance computeLeadShard(Collection shardNodesCache) { - if (shardNodesCache.isEmpty()) - return null; - - long latestTime = 0L; - ShardInstance latestNode = null; - - for (ShardState shardNodeCache : shardNodesCache) { - if (latestTime < shardNodeCache.getLastIndexedTxCommitTime()) { - latestNode = shardNodeCache.getShardInstance(); - latestTime = shardNodeCache.getLastIndexedTxCommitTime(); - } - } - - return latestNode; - } - -} diff --git a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/service/ShardStateService.java b/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/service/ShardStateService.java deleted file mode 100644 index 202e7ce..0000000 --- a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/service/ShardStateService.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.inteligr8.alfresco.asie.enterprise.service; - -import org.alfresco.repo.cache.SimpleCache; -import org.alfresco.repo.index.shard.ShardInstance; -import org.alfresco.repo.index.shard.ShardState; -import org.alfresco.service.cmr.attributes.AttributeService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.stereotype.Component; - -import com.inteligr8.alfresco.asie.Constants; - -@Component -public class ShardStateService { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - @Autowired - @Qualifier(Constants.QUALIFIER_ASIE) - private AttributeService attrService; - - @Autowired - @Qualifier("shardStateCache") - private SimpleCache shardStateCache; - - @Autowired - @Qualifier("shardToGuidCache") - private SimpleCache shardToGuidCache; - - public void clear() { - this.logger.info("Removing all nodes/shards from the shard registry"); - - // this clears the state from the backend database - this.attrService.removeAttribute(Constants.ATTR_SHARD_STATE); - this.attrService.removeAttribute(Constants.ATTR_SHARD_SUBSCRIPTION); - - // this clears the state from Hazelcast - this.shardStateCache.clear(); - this.shardToGuidCache.clear(); - } - - public void clear(String guid) { - this.logger.info("Removing node from the shard registry: {}", guid); - - ShardState shardState = (ShardState) this.attrService.getAttribute(Constants.ATTR_SHARD_STATE, guid); - - // this clears the state from the backend database - this.attrService.removeAttribute(Constants.ATTR_SHARD_STATE, guid); - this.attrService.removeAttribute(Constants.ATTR_SHARD_SUBSCRIPTION, guid); - - // this clears the state from Hazelcast - if (shardState != null) { - this.shardStateCache.remove(shardState.getShardInstance()); - this.shardToGuidCache.remove(shardState.getShardInstance()); - } - } - -} diff --git a/module/src/main/resources/alfresco/module/com_inteligr8_alfresco_asie-platform-module/alfresco-global.properties b/module/src/main/resources/alfresco/module/com_inteligr8_alfresco_asie-platform-module/alfresco-global.properties deleted file mode 100644 index a29c9b1..0000000 --- a/module/src/main/resources/alfresco/module/com_inteligr8_alfresco_asie-platform-module/alfresco-global.properties +++ /dev/null @@ -1,8 +0,0 @@ - -# defaulting to 3 days = 60 * 24 * 3 = 4320 -inteligr8.asie.backup.persistTimeMinutes=4320 - -inteligr8.asie.allowedAuthorities=ALFRESCO_ADMINISTRATORS - -# same as solr.baseUrl, but that property is private to the Search subsystem -inteligr8.asie.basePath=/solr diff --git a/pom.xml b/pom.xml index 67c11ea..cb67871 100644 --- a/pom.xml +++ b/pom.xml @@ -70,7 +70,8 @@ solr-api asie-api - module + shared + enterprise-module diff --git a/shared/.gitignore b/shared/.gitignore new file mode 100644 index 0000000..e59065e --- /dev/null +++ b/shared/.gitignore @@ -0,0 +1,12 @@ +# Maven +target +pom.xml.versionsBackup + +# Eclipse +.project +.classpath +.settings +.vscode + +# IDEA +/.idea/ diff --git a/shared/README.md b/shared/README.md new file mode 100644 index 0000000..1aa10d1 --- /dev/null +++ b/shared/README.md @@ -0,0 +1 @@ +# ASIE Platform Module Library diff --git a/shared/pom.xml b/shared/pom.xml new file mode 100644 index 0000000..a817053 --- /dev/null +++ b/shared/pom.xml @@ -0,0 +1,73 @@ + + 4.0.0 + + + com.inteligr8.alfresco + asie-platform-module-parent + 1.0-SNAPSHOT + ../ + + + asie-shared + jar + + ASIE Shared Library for Platform Modules + + + 5.2.0 + 23.3.0 + + + + + + org.alfresco + acs-community-packaging + ${alfresco.platform.version} + pom + import + + + + + + + com.inteligr8.alfresco + asie-api + 1.0-SNAPSHOT-asie2 + + + com.inteligr8 + common-rest-client + 3.0.1-cxf + + + + + org.alfresco + alfresco-repository + provided + + + + + junit + junit + test + + + org.mockito + mockito-core + test + + + + + + alfresco-public + https://artifacts.alfresco.com/nexus/content/groups/public + + + diff --git a/shared/rad.ps1 b/shared/rad.ps1 new file mode 100644 index 0000000..61bcb2f --- /dev/null +++ b/shared/rad.ps1 @@ -0,0 +1,74 @@ + +function discoverArtifactId { + $script:ARTIFACT_ID=(mvn -q -Dexpression=project"."artifactId -DforceStdout help:evaluate) +} + +function rebuild { + echo "Rebuilding project ..." + mvn process-classes +} + +function start_ { + echo "Rebuilding project and starting Docker containers to support rapid application development ..." + mvn -Drad process-classes +} + +function start_log { + echo "Rebuilding project and starting Docker containers to support rapid application development ..." + mvn -Drad "-Ddocker.showLogs" process-classes +} + +function stop_ { + discoverArtifactId + echo "Stopping Docker containers that supported rapid application development ..." + docker container ls --filter name=${ARTIFACT_ID}-* + echo "Stopping containers ..." + docker container stop (docker container ls -q --filter name=${ARTIFACT_ID}-*) + echo "Removing containers ..." + docker container rm (docker container ls -aq --filter name=${ARTIFACT_ID}-*) +} + +function tail_logs { + param ( + $container + ) + + discoverArtifactId + docker container logs -f (docker container ls -q --filter name=${ARTIFACT_ID}-${container}) +} + +function list { + discoverArtifactId + docker container ls --filter name=${ARTIFACT_ID}-* +} + +switch ($args[0]) { + "start" { + start_ + } + "start_log" { + start_log + } + "stop" { + stop_ + } + "restart" { + stop_ + start_ + } + "rebuild" { + rebuild + } + "tail" { + tail_logs $args[1] + } + "containers" { + list + } + default { + echo "Usage: .\rad.ps1 [ start | start_log | stop | restart | rebuild | tail {container} | containers ]" + } +} + +echo "Completed!" + diff --git a/shared/rad.sh b/shared/rad.sh new file mode 100644 index 0000000..7cb0a80 --- /dev/null +++ b/shared/rad.sh @@ -0,0 +1,71 @@ +#!/bin/sh + +discoverArtifactId() { + ARTIFACT_ID=`mvn -q -Dexpression=project.artifactId -DforceStdout help:evaluate` +} + +rebuild() { + echo "Rebuilding project ..." + mvn process-classes +} + +start() { + echo "Rebuilding project and starting Docker containers to support rapid application development ..." + mvn -Drad process-classes +} + +start_log() { + echo "Rebuilding project and starting Docker containers to support rapid application development ..." + mvn -Drad -Ddocker.showLogs process-classes +} + +stop() { + discoverArtifactId + echo "Stopping Docker containers that supported rapid application development ..." + docker container ls --filter name=${ARTIFACT_ID}-* + echo "Stopping containers ..." + docker container stop `docker container ls -q --filter name=${ARTIFACT_ID}-*` + echo "Removing containers ..." + docker container rm `docker container ls -aq --filter name=${ARTIFACT_ID}-*` +} + +tail_logs() { + discoverArtifactId + docker container logs -f `docker container ls -q --filter name=${ARTIFACT_ID}-$1` +} + +list() { + discoverArtifactId + docker container ls --filter name=${ARTIFACT_ID}-* +} + +case "$1" in + start) + start + ;; + start_log) + start_log + ;; + stop) + stop + ;; + restart) + stop + start + ;; + rebuild) + rebuild + ;; + tail) + tail_logs $2 + ;; + containers) + list + ;; + *) + echo "Usage: ./rad.sh [ start | start_log | stop | restart | rebuild | tail {container} | containers ]" + exit 1 +esac + +echo "Completed!" + diff --git a/shared/src/main/java/com/inteligr8/alfresco/asie/Constants.java b/shared/src/main/java/com/inteligr8/alfresco/asie/Constants.java new file mode 100644 index 0000000..b56c3be --- /dev/null +++ b/shared/src/main/java/com/inteligr8/alfresco/asie/Constants.java @@ -0,0 +1,23 @@ +package com.inteligr8.alfresco.asie; + +public interface Constants { + + static final String QUALIFIER_ASIE = "asie"; + + // OOTB + static final String BEAN_SHARD_STATE_CACHE = "shardStateCache"; + static final String BEAN_SHARD_GUID_CACHE = "shardToGuidCache"; + + static final String BEAN_OFFILINE_SHARD_STATE_CACHE = "offlineShardStateCache"; + static final String BEAN_CORE_EXPLICIT_CACHE = "coreExplicitIdCache"; + static final String BEAN_OBJECT_MAPPER = "asie.ObjectMapper"; + static final String BEAN_ATTRIBUTE_SERVICE = "asie.AttributeService"; + static final String BEAN_SHARD_REGISTRY = "asie.ShardRegistry"; + + static final String ATTR_ASIE = "inteligr8.asie"; + static final String ATTR_ASIE_NODES = "inteligr8.asie.nodes"; + static final String ATTR_STATE = "state"; + static final String ATTR_ONLINE = "online"; + static final String ATTR_UNLOADED = "unloadedNode.cores"; + +} diff --git a/module/src/main/java/com/inteligr8/alfresco/asie/compute/SolrShardEnumeratedHashTable.java b/shared/src/main/java/com/inteligr8/alfresco/asie/compute/SolrShardEnumeratedHashTable.java similarity index 100% rename from module/src/main/java/com/inteligr8/alfresco/asie/compute/SolrShardEnumeratedHashTable.java rename to shared/src/main/java/com/inteligr8/alfresco/asie/compute/SolrShardEnumeratedHashTable.java diff --git a/module/src/main/java/com/inteligr8/alfresco/asie/compute/SolrShardHashTable.java b/shared/src/main/java/com/inteligr8/alfresco/asie/compute/SolrShardHashTable.java similarity index 100% rename from module/src/main/java/com/inteligr8/alfresco/asie/compute/SolrShardHashTable.java rename to shared/src/main/java/com/inteligr8/alfresco/asie/compute/SolrShardHashTable.java diff --git a/module/src/main/java/com/inteligr8/alfresco/asie/compute/SolrShardNumericHashTable.java b/shared/src/main/java/com/inteligr8/alfresco/asie/compute/SolrShardNumericHashTable.java similarity index 100% rename from module/src/main/java/com/inteligr8/alfresco/asie/compute/SolrShardNumericHashTable.java rename to shared/src/main/java/com/inteligr8/alfresco/asie/compute/SolrShardNumericHashTable.java diff --git a/shared/src/main/java/com/inteligr8/alfresco/asie/model/Node.java b/shared/src/main/java/com/inteligr8/alfresco/asie/model/Node.java new file mode 100644 index 0000000..92613b7 --- /dev/null +++ b/shared/src/main/java/com/inteligr8/alfresco/asie/model/Node.java @@ -0,0 +1,56 @@ +package com.inteligr8.alfresco.asie.model; + +import java.io.Serializable; + +import org.alfresco.repo.index.shard.ShardInstance; + +public class Node implements Serializable { + + private static final long serialVersionUID = -8834744746109388928L; + + private final String id; + private final ShardInstance shardNode; + + public Node(ShardInstance shardNode) { + this.shardNode = shardNode; + this.id = this.getHostname() + ":" + this.getPort() + this.getPath(); + } + + public String getId() { + return this.id; + } + + public String getHostname() { + return this.shardNode.getHostName(); + } + + public int getPort() { + return this.shardNode.getPort(); + } + + public String getPath() { + // baseUrl is to the shard; we want to the node, so exclude the core + int lastSlash = this.shardNode.getBaseUrl().lastIndexOf('/'); + return this.shardNode.getBaseUrl().substring(0, lastSlash); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof Node)) + return false; + + Node node = (Node) obj; + return this.id.equals(node.id); + } + + @Override + public int hashCode() { + return this.id.hashCode(); + } + + @Override + public String toString() { + return this.id; + } + +} diff --git a/module/src/main/java/com/inteligr8/alfresco/asie/model/NodeParameterSet.java b/shared/src/main/java/com/inteligr8/alfresco/asie/model/NodeParameterSet.java similarity index 100% rename from module/src/main/java/com/inteligr8/alfresco/asie/model/NodeParameterSet.java rename to shared/src/main/java/com/inteligr8/alfresco/asie/model/NodeParameterSet.java diff --git a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/model/NodeShardParameterSet.java b/shared/src/main/java/com/inteligr8/alfresco/asie/model/NodeShardParameterSet.java similarity index 78% rename from module/src/main/java/com/inteligr8/alfresco/asie/enterprise/model/NodeShardParameterSet.java rename to shared/src/main/java/com/inteligr8/alfresco/asie/model/NodeShardParameterSet.java index 33a7739..635f53c 100644 --- a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/model/NodeShardParameterSet.java +++ b/shared/src/main/java/com/inteligr8/alfresco/asie/model/NodeShardParameterSet.java @@ -1,6 +1,4 @@ -package com.inteligr8.alfresco.asie.enterprise.model; - -import com.inteligr8.alfresco.asie.model.NodeParameterSet; +package com.inteligr8.alfresco.asie.model; public class NodeShardParameterSet extends NodeParameterSet { diff --git a/module/src/main/java/com/inteligr8/alfresco/asie/model/RequestParameterSet.java b/shared/src/main/java/com/inteligr8/alfresco/asie/model/RequestParameterSet.java similarity index 100% rename from module/src/main/java/com/inteligr8/alfresco/asie/model/RequestParameterSet.java rename to shared/src/main/java/com/inteligr8/alfresco/asie/model/RequestParameterSet.java diff --git a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/model/ShardParameterSet.java b/shared/src/main/java/com/inteligr8/alfresco/asie/model/ShardParameterSet.java similarity index 70% rename from module/src/main/java/com/inteligr8/alfresco/asie/enterprise/model/ShardParameterSet.java rename to shared/src/main/java/com/inteligr8/alfresco/asie/model/ShardParameterSet.java index 1134fb8..2036d75 100644 --- a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/model/ShardParameterSet.java +++ b/shared/src/main/java/com/inteligr8/alfresco/asie/model/ShardParameterSet.java @@ -1,6 +1,4 @@ -package com.inteligr8.alfresco.asie.enterprise.model; - -import com.inteligr8.alfresco.asie.model.RequestParameterSet; +package com.inteligr8.alfresco.asie.model; public class ShardParameterSet implements RequestParameterSet { diff --git a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/model/ShardSet.java b/shared/src/main/java/com/inteligr8/alfresco/asie/model/ShardSet.java similarity index 98% rename from module/src/main/java/com/inteligr8/alfresco/asie/enterprise/model/ShardSet.java rename to shared/src/main/java/com/inteligr8/alfresco/asie/model/ShardSet.java index 25fefce..a3b2bb3 100644 --- a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/model/ShardSet.java +++ b/shared/src/main/java/com/inteligr8/alfresco/asie/model/ShardSet.java @@ -1,4 +1,4 @@ -package com.inteligr8.alfresco.asie.enterprise.model; +package com.inteligr8.alfresco.asie.model; import java.util.HashMap; import java.util.Map; diff --git a/shared/src/main/java/com/inteligr8/alfresco/asie/provider/AbstractProvider.java b/shared/src/main/java/com/inteligr8/alfresco/asie/provider/AbstractProvider.java new file mode 100644 index 0000000..bc7b173 --- /dev/null +++ b/shared/src/main/java/com/inteligr8/alfresco/asie/provider/AbstractProvider.java @@ -0,0 +1,34 @@ +package com.inteligr8.alfresco.asie.provider; + +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; + +public abstract class AbstractProvider { + + @Autowired + private ApplicationContext context; + + public abstract T selectBean(); + + protected U getPrimaryOrNamed(Class type, String beanName) { + ObjectProvider provider = this.context.getBeanProvider(type); + + // this will select the primary or if there is just one impl, that one impl + U u = provider.getIfUnique(); + if (u == null) { + // this will select the named bean; throwing exception if there is none + u = this.context.getBean(beanName, type); + } + + return u; + } + + protected U getPrimary(Class type) { + ObjectProvider provider = this.context.getBeanProvider(type); + + // this will select the primary or if there is just one impl, that one impl + return provider.getObject(); + } + +} diff --git a/module/src/main/java/com/inteligr8/alfresco/asie/provider/AttributeServiceProvider.java b/shared/src/main/java/com/inteligr8/alfresco/asie/provider/AttributeServiceProvider.java similarity index 56% rename from module/src/main/java/com/inteligr8/alfresco/asie/provider/AttributeServiceProvider.java rename to shared/src/main/java/com/inteligr8/alfresco/asie/provider/AttributeServiceProvider.java index 826d9fb..83cd47f 100644 --- a/module/src/main/java/com/inteligr8/alfresco/asie/provider/AttributeServiceProvider.java +++ b/shared/src/main/java/com/inteligr8/alfresco/asie/provider/AttributeServiceProvider.java @@ -1,11 +1,8 @@ package com.inteligr8.alfresco.asie.provider; import org.alfresco.service.cmr.attributes.AttributeService; -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.config.ConfigurableBeanFactory; -import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Scope; @@ -13,10 +10,7 @@ import org.springframework.context.annotation.Scope; import com.inteligr8.alfresco.asie.Constants; @Configuration -public class AttributeServiceProvider { - - @Autowired - private ApplicationContext context; +public class AttributeServiceProvider extends AbstractProvider { /** * This allows for the selection of the primary or first AttributeService @@ -27,24 +21,11 @@ public class AttributeServiceProvider { * * @return An AttributeService. */ - @Bean("asieAttributeService") + @Bean(Constants.BEAN_ATTRIBUTE_SERVICE) @Qualifier(Constants.QUALIFIER_ASIE) @Scope(ConfigurableBeanFactory.SCOPE_SINGLETON) - public AttributeService selectAttributeService() { + public AttributeService selectBean() { return this.getPrimaryOrNamed(AttributeService.class, "attributeService"); } - - private T getPrimaryOrNamed(Class type, String beanName) { - ObjectProvider provider = this.context.getBeanProvider(type); - - // this will select the primary or if there is just one impl, that one impl - T t = provider.getIfUnique(); - if (t == null) { - // this will select the named bean; throwing exception if there is none - t = this.context.getBean(beanName, type); - } - - return t; - } } diff --git a/module/src/main/java/com/inteligr8/alfresco/asie/provider/ObjectMapperProvider.java b/shared/src/main/java/com/inteligr8/alfresco/asie/provider/ObjectMapperProvider.java similarity index 96% rename from module/src/main/java/com/inteligr8/alfresco/asie/provider/ObjectMapperProvider.java rename to shared/src/main/java/com/inteligr8/alfresco/asie/provider/ObjectMapperProvider.java index 4763e73..c9a2063 100644 --- a/module/src/main/java/com/inteligr8/alfresco/asie/provider/ObjectMapperProvider.java +++ b/shared/src/main/java/com/inteligr8/alfresco/asie/provider/ObjectMapperProvider.java @@ -14,7 +14,7 @@ import com.inteligr8.alfresco.asie.Constants; @Configuration public class ObjectMapperProvider { - @Bean("asieObjectMapper") + @Bean(Constants.BEAN_OBJECT_MAPPER) @Qualifier(Constants.QUALIFIER_ASIE) @Scope(ConfigurableBeanFactory.SCOPE_SINGLETON) public ObjectMapper createObjectMapper() { diff --git a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/AbstractAsieNodeShardWebScript.java b/shared/src/main/java/com/inteligr8/alfresco/asie/rest/AbstractAsieNodeShardWebScript.java similarity index 89% rename from module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/AbstractAsieNodeShardWebScript.java rename to shared/src/main/java/com/inteligr8/alfresco/asie/rest/AbstractAsieNodeShardWebScript.java index c71df64..2e9689a 100644 --- a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/AbstractAsieNodeShardWebScript.java +++ b/shared/src/main/java/com/inteligr8/alfresco/asie/rest/AbstractAsieNodeShardWebScript.java @@ -1,4 +1,4 @@ -package com.inteligr8.alfresco.asie.enterprise.rest; +package com.inteligr8.alfresco.asie.rest; import java.io.IOException; @@ -7,9 +7,9 @@ import org.slf4j.LoggerFactory; import org.springframework.extensions.webscripts.WebScriptRequest; import org.springframework.extensions.webscripts.WebScriptResponse; -import com.inteligr8.alfresco.asie.enterprise.model.ShardSet; +import com.inteligr8.alfresco.asie.model.ShardSet; -public abstract class AbstractAsieNodeShardWebScript extends AbstractAsieEnterpriseWebScript { +public abstract class AbstractAsieNodeShardWebScript extends AbstractAsieShardableWebScript { private final Logger logger = LoggerFactory.getLogger(this.getClass()); diff --git a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/AbstractAsieNodeWebScript.java b/shared/src/main/java/com/inteligr8/alfresco/asie/rest/AbstractAsieNodeWebScript.java similarity index 92% rename from module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/AbstractAsieNodeWebScript.java rename to shared/src/main/java/com/inteligr8/alfresco/asie/rest/AbstractAsieNodeWebScript.java index a31a38c..b44ddb5 100644 --- a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/AbstractAsieNodeWebScript.java +++ b/shared/src/main/java/com/inteligr8/alfresco/asie/rest/AbstractAsieNodeWebScript.java @@ -1,4 +1,4 @@ -package com.inteligr8.alfresco.asie.enterprise.rest; +package com.inteligr8.alfresco.asie.rest; import java.io.IOException; import java.util.Set; @@ -12,9 +12,9 @@ import org.springframework.extensions.webscripts.WebScriptRequest; import org.springframework.extensions.webscripts.WebScriptResponse; import org.springframework.http.HttpStatus; -import com.inteligr8.alfresco.asie.enterprise.service.ShardDiscoveryService; +import com.inteligr8.alfresco.asie.service.ShardDiscoveryService; -public abstract class AbstractAsieNodeWebScript extends AbstractAsieEnterpriseWebScript { +public abstract class AbstractAsieNodeWebScript extends AbstractAsieShardableWebScript { private final Logger logger = LoggerFactory.getLogger(this.getClass()); diff --git a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/AbstractAsieShardWebScript.java b/shared/src/main/java/com/inteligr8/alfresco/asie/rest/AbstractAsieShardWebScript.java similarity index 88% rename from module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/AbstractAsieShardWebScript.java rename to shared/src/main/java/com/inteligr8/alfresco/asie/rest/AbstractAsieShardWebScript.java index 5a04c1b..81e672f 100644 --- a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/AbstractAsieShardWebScript.java +++ b/shared/src/main/java/com/inteligr8/alfresco/asie/rest/AbstractAsieShardWebScript.java @@ -1,4 +1,4 @@ -package com.inteligr8.alfresco.asie.enterprise.rest; +package com.inteligr8.alfresco.asie.rest; import java.io.IOException; import java.util.Set; @@ -12,10 +12,10 @@ import org.springframework.extensions.webscripts.WebScriptRequest; import org.springframework.extensions.webscripts.WebScriptResponse; import org.springframework.http.HttpStatus; -import com.inteligr8.alfresco.asie.enterprise.model.ShardSet; -import com.inteligr8.alfresco.asie.enterprise.service.ShardDiscoveryService; +import com.inteligr8.alfresco.asie.model.ShardSet; +import com.inteligr8.alfresco.asie.service.ShardDiscoveryService; -public abstract class AbstractAsieShardWebScript extends AbstractAsieEnterpriseWebScript { +public abstract class AbstractAsieShardWebScript extends AbstractAsieShardableWebScript { private final Logger logger = LoggerFactory.getLogger(this.getClass()); diff --git a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/AbstractAsieEnterpriseWebScript.java b/shared/src/main/java/com/inteligr8/alfresco/asie/rest/AbstractAsieShardableWebScript.java similarity index 92% rename from module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/AbstractAsieEnterpriseWebScript.java rename to shared/src/main/java/com/inteligr8/alfresco/asie/rest/AbstractAsieShardableWebScript.java index 298514b..a3bf089 100644 --- a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/AbstractAsieEnterpriseWebScript.java +++ b/shared/src/main/java/com/inteligr8/alfresco/asie/rest/AbstractAsieShardableWebScript.java @@ -1,4 +1,4 @@ -package com.inteligr8.alfresco.asie.enterprise.rest; +package com.inteligr8.alfresco.asie.rest; import java.text.NumberFormat; import java.time.LocalDate; @@ -24,12 +24,11 @@ import com.inteligr8.alfresco.asie.api.CoreAdminApi; import com.inteligr8.alfresco.asie.compute.SolrShardEnumeratedHashTable; import com.inteligr8.alfresco.asie.compute.SolrShardHashTable; import com.inteligr8.alfresco.asie.compute.SolrShardNumericHashTable; -import com.inteligr8.alfresco.asie.enterprise.rest.model.ShardInfo; -import com.inteligr8.alfresco.asie.enterprise.rest.model.ShardSetInfo; -import com.inteligr8.alfresco.asie.rest.AbstractAsieWebScript; +import com.inteligr8.alfresco.asie.rest.model.ShardInfo; +import com.inteligr8.alfresco.asie.rest.model.ShardSetInfo; import com.inteligr8.alfresco.asie.service.SolrShardHashService; -public abstract class AbstractAsieEnterpriseWebScript extends AbstractAsieWebScript { +public abstract class AbstractAsieShardableWebScript extends AbstractAsieWebScript { private final Pattern sampleTypePattern = Pattern.compile("([A-Za-z]+)([0-9]+)"); @@ -41,7 +40,7 @@ public abstract class AbstractAsieEnterpriseWebScript extends AbstractAsieWebScr } @Autowired - @Qualifier(Constants.BEAN_SHARD_REGISTRY) + @Qualifier(Constants.QUALIFIER_ASIE) private ShardRegistry shardRegistry; @Autowired diff --git a/module/src/main/java/com/inteligr8/alfresco/asie/rest/AbstractAsieWebScript.java b/shared/src/main/java/com/inteligr8/alfresco/asie/rest/AbstractAsieWebScript.java similarity index 50% rename from module/src/main/java/com/inteligr8/alfresco/asie/rest/AbstractAsieWebScript.java rename to shared/src/main/java/com/inteligr8/alfresco/asie/rest/AbstractAsieWebScript.java index f83a7d3..bf48032 100644 --- a/module/src/main/java/com/inteligr8/alfresco/asie/rest/AbstractAsieWebScript.java +++ b/shared/src/main/java/com/inteligr8/alfresco/asie/rest/AbstractAsieWebScript.java @@ -1,13 +1,9 @@ package com.inteligr8.alfresco.asie.rest; import java.io.IOException; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; import java.util.HashSet; import java.util.Set; -import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -15,12 +11,7 @@ import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; -import org.springframework.extensions.webscripts.AbstractWebScript; -import org.springframework.extensions.webscripts.Description.RequiredAuthentication; -import org.springframework.extensions.webscripts.WebScriptException; import org.springframework.extensions.webscripts.WebScriptRequest; -import org.springframework.extensions.webscripts.WebScriptResponse; -import org.springframework.http.HttpStatus; import com.fasterxml.jackson.databind.ObjectMapper; import com.inteligr8.alfresco.asie.Constants; @@ -31,7 +22,6 @@ import com.inteligr8.rs.ClientCxfConfiguration; import com.inteligr8.rs.ClientCxfImpl; import jakarta.ws.rs.client.ClientRequestContext; -import net.sf.acegisecurity.GrantedAuthority; public abstract class AbstractAsieWebScript extends AbstractWebScript implements InitializingBean { @@ -81,30 +71,12 @@ public abstract class AbstractAsieWebScript extends AbstractWebScript implements } @Override - public final void execute(WebScriptRequest request, WebScriptResponse response) throws IOException { - if (RequiredAuthentication.user.equals(this.getDescription().getRequiredAuthentication())) { - if (!this.isAuthorized()) - throw new WebScriptException(HttpStatus.FORBIDDEN.value(), "You are not authorized for access this resource."); - } - - this.executeAuthorized(request, response); + protected Set getAuthorities() { + return this.authorizedAuthorities; } - - private boolean isAuthorized() { - if (this.authorizedAuthorities.contains(AuthenticationUtil.getFullyAuthenticatedUser())) - return true; - for (GrantedAuthority auth : AuthenticationUtil.getFullAuthentication().getAuthorities()) { - if (this.authorizedAuthorities.contains(auth.getAuthority())) - return true; - } - - return false; - } - - public abstract void executeAuthorized(WebScriptRequest request, WebScriptResponse response) throws IOException; - public ObjectMapper getObjectMapper() { - return objectMapper; + protected ObjectMapper getObjectMapper() { + return this.objectMapper; } protected CoreAdminApi createApi(String hostname, int port) { @@ -164,64 +136,5 @@ public abstract class AbstractAsieWebScript extends AbstractWebScript implements client.register(); return client; } - - protected String getRequiredPathParameter(WebScriptRequest req, String pathParamName) { - String pathParamValue = this.getOptionalPathParameter(req, pathParamName); - if (pathParamValue == null) - throw new WebScriptException(HttpStatus.BAD_REQUEST.value(), "The '" + pathParamName + "' path parameter is required"); - return pathParamValue; - } - - protected T getRequiredPathParameter(WebScriptRequest req, String pathParamName, Class type) { - T pathParamValue = this.getOptionalPathParameter(req, pathParamName, type); - if (pathParamValue == null) - throw new WebScriptException(HttpStatus.BAD_REQUEST.value(), "The '" + pathParamName + "' path parameter is required"); - return pathParamValue; - } - - protected String getOptionalPathParameter(WebScriptRequest req, String pathParamName) { - return StringUtils.trimToNull(req.getServiceMatch().getTemplateVars().get(pathParamName)); - } - - protected T getOptionalPathParameter(WebScriptRequest req, String pathParamName, Class type) { - String str = StringUtils.trimToNull(req.getServiceMatch().getTemplateVars().get(pathParamName)); - return this.getOptionalParameter(req, pathParamName, str, "path element", type); - } - - protected String getOptionalQueryParameter(WebScriptRequest req, String queryParamName) { - return StringUtils.trimToNull(req.getParameter(queryParamName)); - } - - protected T getOptionalQueryParameter(WebScriptRequest req, String queryParamName, Class type) { - String str = StringUtils.trimToNull(req.getParameter(queryParamName)); - return this.getOptionalParameter(req, queryParamName, str, "query parameter", type); - } - - protected T getOptionalParameter(WebScriptRequest req, String paramName, String paramValue, String paramTypeDisplay, Class type) { - if (paramValue == null) - return null; - if (type.equals(String.class)) - return type.cast(paramValue); - - try { - try { - Constructor constructor = type.getConstructor(String.class); - return constructor.newInstance(paramValue); - } catch (NoSuchMethodException nsme) { - Method method = type.getDeclaredMethod("valueOf", String.class); - @SuppressWarnings("unchecked") - T t = (T) method.invoke(null, paramValue); - return t; - } - } catch (InvocationTargetException ite) { - if (ite.getTargetException() instanceof NumberFormatException) { - throw new WebScriptException(HttpStatus.BAD_REQUEST.value(), "The `" + paramName + "` " + paramTypeDisplay + " '" + paramValue + "' must be a number"); - } else { - throw new WebScriptException(HttpStatus.INTERNAL_SERVER_ERROR.value(), "An unexpected issue occurred", ite); - } - } catch (NoSuchMethodException | IllegalAccessException | InstantiationException e) { - throw new WebScriptException(HttpStatus.INTERNAL_SERVER_ERROR.value(), "An unexpected issue occurred", e); - } - } } diff --git a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/AbstractUnregisterNodeWebScript.java b/shared/src/main/java/com/inteligr8/alfresco/asie/rest/AbstractUnregisterNodeWebScript.java similarity index 74% rename from module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/AbstractUnregisterNodeWebScript.java rename to shared/src/main/java/com/inteligr8/alfresco/asie/rest/AbstractUnregisterNodeWebScript.java index b3f37ad..08ab4cf 100644 --- a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/AbstractUnregisterNodeWebScript.java +++ b/shared/src/main/java/com/inteligr8/alfresco/asie/rest/AbstractUnregisterNodeWebScript.java @@ -1,16 +1,18 @@ -package com.inteligr8.alfresco.asie.enterprise.rest; +package com.inteligr8.alfresco.asie.rest; import java.io.IOException; import java.io.Serializable; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; import java.util.Map; -import java.util.Map.Entry; import org.alfresco.repo.index.shard.ShardState; import org.alfresco.service.cmr.attributes.AttributeService; import org.alfresco.service.cmr.attributes.AttributeService.AttributeQueryCallback; +import org.apache.commons.lang3.tuple.Pair; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -22,10 +24,9 @@ import org.springframework.http.HttpStatus; import com.inteligr8.alfresco.asie.Constants; import com.inteligr8.alfresco.asie.api.CoreAdminApi; -import com.inteligr8.alfresco.asie.enterprise.service.ShardBackupService; -import com.inteligr8.alfresco.asie.enterprise.service.ShardStateService; import com.inteligr8.alfresco.asie.model.NodeParameterSet; -import com.inteligr8.alfresco.asie.model.core.DisableIndexingRequest; +import com.inteligr8.alfresco.asie.service.ShardBackupService; +import com.inteligr8.alfresco.asie.spi.ShardStateService; import com.inteligr8.solr.model.CoreMetadata; import com.inteligr8.solr.model.core.StatusRequest; import com.inteligr8.solr.model.core.StatusResponse; @@ -52,7 +53,7 @@ public abstract class AbstractUnregisterNodeWebScript guidCores = new HashMap<>(); + final List> matchingCores = new LinkedList<>(); AttributeQueryCallback callback = new AttributeQueryCallback() { @Override @@ -61,17 +62,16 @@ public abstract class AbstractUnregisterNodeWebScript(); try { - for (Entry guidCore : guidCores.entrySet()) { - ShardState shardNode = guidCore.getValue(); + for (Pair matchingCore : matchingCores) { + ShardState shardNode = matchingCore.getValue(); String core = shardNode.getPropertyBag().get("coreName"); StatusResponse status = this.getCoreStatus(nodeHostname, nodePort, core); @@ -90,14 +90,13 @@ public abstract class AbstractUnregisterNodeWebScript getAuthorities(); + + @Override + public final void execute(WebScriptRequest request, WebScriptResponse response) throws IOException { + if (RequiredAuthentication.user.equals(this.getDescription().getRequiredAuthentication())) { + if (!this.isAuthorized()) + throw new WebScriptException(HttpStatus.FORBIDDEN.value(), "You are not authorized for access this resource."); + } + + this.executeAuthorized(request, response); + } + + protected boolean isAuthorized() { + if (this.getAuthorities().contains(AuthenticationUtil.getFullyAuthenticatedUser())) + return true; + for (GrantedAuthority auth : AuthenticationUtil.getFullAuthentication().getAuthorities()) { + if (this.getAuthorities().contains(auth.getAuthority())) + return true; + } + + return false; + } + + public abstract void executeAuthorized(WebScriptRequest request, WebScriptResponse response) throws IOException; + + protected String getRequiredPathParameter(WebScriptRequest req, String pathParamName) { + String pathParamValue = this.getOptionalPathParameter(req, pathParamName); + if (pathParamValue == null) + throw new WebScriptException(HttpStatus.BAD_REQUEST.value(), "The '" + pathParamName + "' path parameter is required"); + return pathParamValue; + } + + protected T getRequiredPathParameter(WebScriptRequest req, String pathParamName, Class type) { + T pathParamValue = this.getOptionalPathParameter(req, pathParamName, type); + if (pathParamValue == null) + throw new WebScriptException(HttpStatus.BAD_REQUEST.value(), "The '" + pathParamName + "' path parameter is required"); + return pathParamValue; + } + + protected String getOptionalPathParameter(WebScriptRequest req, String pathParamName) { + return StringUtils.trimToNull(req.getServiceMatch().getTemplateVars().get(pathParamName)); + } + + protected T getOptionalPathParameter(WebScriptRequest req, String pathParamName, Class type) { + String str = StringUtils.trimToNull(req.getServiceMatch().getTemplateVars().get(pathParamName)); + return this.getOptionalParameter(req, pathParamName, str, "path element", type); + } + + protected String getOptionalQueryParameter(WebScriptRequest req, String queryParamName) { + return StringUtils.trimToNull(req.getParameter(queryParamName)); + } + + protected T getOptionalQueryParameter(WebScriptRequest req, String queryParamName, Class type) { + String str = StringUtils.trimToNull(req.getParameter(queryParamName)); + return this.getOptionalParameter(req, queryParamName, str, "query parameter", type); + } + + protected T getOptionalParameter(WebScriptRequest req, String paramName, String paramValue, String paramTypeDisplay, Class type) { + if (paramValue == null) + return null; + if (type.equals(String.class)) + return type.cast(paramValue); + + try { + try { + Constructor constructor = type.getConstructor(String.class); + return constructor.newInstance(paramValue); + } catch (NoSuchMethodException nsme) { + Method method = type.getDeclaredMethod("valueOf", String.class); + @SuppressWarnings("unchecked") + T t = (T) method.invoke(null, paramValue); + return t; + } + } catch (InvocationTargetException ite) { + if (ite.getTargetException() instanceof NumberFormatException) { + throw new WebScriptException(HttpStatus.BAD_REQUEST.value(), "The `" + paramName + "` " + paramTypeDisplay + " '" + paramValue + "' must be a number"); + } else { + throw new WebScriptException(HttpStatus.INTERNAL_SERVER_ERROR.value(), "An unexpected issue occurred", ite); + } + } catch (NoSuchMethodException | IllegalAccessException | InstantiationException e) { + throw new WebScriptException(HttpStatus.INTERNAL_SERVER_ERROR.value(), "An unexpected issue occurred", e); + } + } + +} diff --git a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/ClearRegistryWebScript.java b/shared/src/main/java/com/inteligr8/alfresco/asie/rest/ClearRegistryWebScript.java similarity index 72% rename from module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/ClearRegistryWebScript.java rename to shared/src/main/java/com/inteligr8/alfresco/asie/rest/ClearRegistryWebScript.java index 4bcd655..38b4889 100644 --- a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/ClearRegistryWebScript.java +++ b/shared/src/main/java/com/inteligr8/alfresco/asie/rest/ClearRegistryWebScript.java @@ -1,4 +1,4 @@ -package com.inteligr8.alfresco.asie.enterprise.rest; +package com.inteligr8.alfresco.asie.rest; import java.io.IOException; @@ -9,10 +9,10 @@ import org.springframework.extensions.webscripts.WebScriptResponse; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Component; -import com.inteligr8.alfresco.asie.enterprise.service.ShardBackupService; -import com.inteligr8.alfresco.asie.enterprise.service.ShardStateService; +import com.inteligr8.alfresco.asie.service.ShardBackupService; +import com.inteligr8.alfresco.asie.spi.ShardStateService; -@Component(value = "webscript.com.inteligr8.alfresco.asie.enterprise.registry.delete") +@Component(value = "webscript.com.inteligr8.alfresco.asie.registry.delete") public class ClearRegistryWebScript extends AbstractWebScript { @Autowired diff --git a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/GetBackupNodeWebScript.java b/shared/src/main/java/com/inteligr8/alfresco/asie/rest/GetBackupNodeWebScript.java similarity index 74% rename from module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/GetBackupNodeWebScript.java rename to shared/src/main/java/com/inteligr8/alfresco/asie/rest/GetBackupNodeWebScript.java index 6405e8f..800ae7e 100644 --- a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/GetBackupNodeWebScript.java +++ b/shared/src/main/java/com/inteligr8/alfresco/asie/rest/GetBackupNodeWebScript.java @@ -1,4 +1,4 @@ -package com.inteligr8.alfresco.asie.enterprise.rest; +package com.inteligr8.alfresco.asie.rest; import java.io.IOException; import java.util.Set; @@ -12,9 +12,10 @@ import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.stereotype.Component; -import com.inteligr8.alfresco.asie.enterprise.service.ShardBackupService; +import com.inteligr8.alfresco.asie.model.Node; +import com.inteligr8.alfresco.asie.service.ShardBackupService; -@Component(value = "webscript.com.inteligr8.alfresco.asie.enterprise.backupNode.get") +@Component(value = "webscript.com.inteligr8.alfresco.asie.backupNode.get") public class GetBackupNodeWebScript extends AbstractAsieShardWebScript { @Autowired @@ -25,11 +26,11 @@ public class GetBackupNodeWebScript extends AbstractAsieShardWebScript { if (shardNodes.isEmpty()) throw new WebScriptException(HttpStatus.NOT_FOUND.value(), "The ASIE shard state could not be found"); - String nodeId = this.sbs.fetchNodeId(shardNodes); + Node node = this.sbs.fetchNode(shardNodes); res.setContentType(MediaType.APPLICATION_JSON_VALUE); res.setContentEncoding("utf-8"); - this.getObjectMapper().writeValue(res.getWriter(), nodeId); + this.getObjectMapper().writeValue(res.getWriter(), node.getId()); } } diff --git a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/GetLeadNodeWebScript.java b/shared/src/main/java/com/inteligr8/alfresco/asie/rest/GetLeadNodeWebScript.java similarity index 71% rename from module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/GetLeadNodeWebScript.java rename to shared/src/main/java/com/inteligr8/alfresco/asie/rest/GetLeadNodeWebScript.java index 48733ed..60faaec 100644 --- a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/GetLeadNodeWebScript.java +++ b/shared/src/main/java/com/inteligr8/alfresco/asie/rest/GetLeadNodeWebScript.java @@ -1,4 +1,4 @@ -package com.inteligr8.alfresco.asie.enterprise.rest; +package com.inteligr8.alfresco.asie.rest; import java.io.IOException; import java.util.Set; @@ -13,27 +13,27 @@ import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.stereotype.Component; -import com.inteligr8.alfresco.asie.enterprise.rest.model.NodeInfo; -import com.inteligr8.alfresco.asie.enterprise.service.ShardAnalysisService; +import com.inteligr8.alfresco.asie.model.Node; +import com.inteligr8.alfresco.asie.spi.ShardDiscoveryService; -@Component(value = "webscript.com.inteligr8.alfresco.asie.enterprise.leadNode.get") +@Component(value = "webscript.com.inteligr8.alfresco.asie.leadNode.get") public class GetLeadNodeWebScript extends AbstractAsieShardWebScript { @Autowired - private ShardAnalysisService sas; + private ShardDiscoveryService sds; @Override public void execute(WebScriptRequest req, WebScriptResponse res, Set shardNodesCache) throws IOException { if (shardNodesCache.isEmpty()) throw new WebScriptException(HttpStatus.NOT_FOUND.value(), "The ASIE shard state could not be found"); - ShardInstance latestNode = this.sas.computeLeadShard(shardNodesCache); + ShardInstance latestNode = this.sds.computeLeadShard(shardNodesCache); if (latestNode == null) throw new WebScriptException(HttpStatus.NOT_FOUND.value(), "The ASIE shard state could not be found"); res.setContentType(MediaType.APPLICATION_JSON_VALUE); res.setContentEncoding("utf-8"); - this.getObjectMapper().writeValue(res.getWriter(), NodeInfo.determineId(latestNode)); + this.getObjectMapper().writeValue(res.getWriter(), new Node(latestNode).getId()); } } diff --git a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/GetNodeWebScript.java b/shared/src/main/java/com/inteligr8/alfresco/asie/rest/GetNodeWebScript.java similarity index 83% rename from module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/GetNodeWebScript.java rename to shared/src/main/java/com/inteligr8/alfresco/asie/rest/GetNodeWebScript.java index 70a7c00..3620d31 100644 --- a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/GetNodeWebScript.java +++ b/shared/src/main/java/com/inteligr8/alfresco/asie/rest/GetNodeWebScript.java @@ -1,4 +1,4 @@ -package com.inteligr8.alfresco.asie.enterprise.rest; +package com.inteligr8.alfresco.asie.rest; import java.io.IOException; import java.time.Instant; @@ -13,12 +13,12 @@ import org.springframework.extensions.webscripts.WebScriptResponse; import org.springframework.stereotype.Component; import com.inteligr8.alfresco.asie.compute.SolrShardHashTable; -import com.inteligr8.alfresco.asie.enterprise.rest.model.NodeInfo; -import com.inteligr8.alfresco.asie.enterprise.rest.model.NodeShardInfo; -import com.inteligr8.alfresco.asie.enterprise.rest.model.ShardInfo; -import com.inteligr8.alfresco.asie.enterprise.rest.model.ShardSetInfo; +import com.inteligr8.alfresco.asie.rest.model.NodeInfo; +import com.inteligr8.alfresco.asie.rest.model.NodeShardInfo; +import com.inteligr8.alfresco.asie.rest.model.ShardInfo; +import com.inteligr8.alfresco.asie.rest.model.ShardSetInfo; -@Component(value = "webscript.com.inteligr8.alfresco.asie.enterprise.node.get") +@Component(value = "webscript.com.inteligr8.alfresco.asie.node.get") public class GetNodeWebScript extends AbstractAsieNodeWebScript { @Override diff --git a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/GetNodesWebScript.java b/shared/src/main/java/com/inteligr8/alfresco/asie/rest/GetNodesWebScript.java similarity index 79% rename from module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/GetNodesWebScript.java rename to shared/src/main/java/com/inteligr8/alfresco/asie/rest/GetNodesWebScript.java index 72a501f..0e47169 100644 --- a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/GetNodesWebScript.java +++ b/shared/src/main/java/com/inteligr8/alfresco/asie/rest/GetNodesWebScript.java @@ -1,4 +1,4 @@ -package com.inteligr8.alfresco.asie.enterprise.rest; +package com.inteligr8.alfresco.asie.rest; import java.io.IOException; import java.util.Map; @@ -18,13 +18,14 @@ import org.springframework.http.HttpStatus; import org.springframework.stereotype.Component; import com.inteligr8.alfresco.asie.compute.SolrShardHashTable; -import com.inteligr8.alfresco.asie.enterprise.rest.model.NodeInfo; -import com.inteligr8.alfresco.asie.enterprise.rest.model.NodeShardInfo; -import com.inteligr8.alfresco.asie.enterprise.rest.model.ShardInfo; -import com.inteligr8.alfresco.asie.enterprise.rest.model.ShardSetInfo; +import com.inteligr8.alfresco.asie.model.Node; +import com.inteligr8.alfresco.asie.rest.model.NodeInfo; +import com.inteligr8.alfresco.asie.rest.model.NodeShardInfo; +import com.inteligr8.alfresco.asie.rest.model.ShardInfo; +import com.inteligr8.alfresco.asie.rest.model.ShardSetInfo; -@Component(value = "webscript.com.inteligr8.alfresco.asie.enterprise.nodes.get") -public class GetNodesWebScript extends AbstractAsieEnterpriseWebScript { +@Component(value = "webscript.com.inteligr8.alfresco.asie.nodes.get") +public class GetNodesWebScript extends AbstractAsieShardableWebScript { private final Logger logger = LoggerFactory.getLogger(this.getClass()); @@ -47,7 +48,8 @@ public class GetNodesWebScript extends AbstractAsieEnterpriseWebScript { for (Entry> registeredShards : floc.getValue().entrySet()) { for (ShardState registeredShardNode : registeredShards.getValue()) { - NodeInfo node = nodes.get(NodeInfo.determineId(registeredShardNode.getShardInstance())); + String nodeId = new Node(registeredShardNode.getShardInstance()).getId(); + NodeInfo node = nodes.get(nodeId); if (node == null) { node = new NodeShardInfo(registeredShardNode.getShardInstance()); nodes.put(node.getId(), node); diff --git a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/GetPropertyHashShardsWebScript.java b/shared/src/main/java/com/inteligr8/alfresco/asie/rest/GetPropertyHashShardsWebScript.java similarity index 90% rename from module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/GetPropertyHashShardsWebScript.java rename to shared/src/main/java/com/inteligr8/alfresco/asie/rest/GetPropertyHashShardsWebScript.java index b69aafd..0139460 100644 --- a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/GetPropertyHashShardsWebScript.java +++ b/shared/src/main/java/com/inteligr8/alfresco/asie/rest/GetPropertyHashShardsWebScript.java @@ -1,4 +1,4 @@ -package com.inteligr8.alfresco.asie.enterprise.rest; +package com.inteligr8.alfresco.asie.rest; import java.io.IOException; import java.time.Instant; @@ -30,14 +30,14 @@ import org.springframework.http.MediaType; import org.springframework.stereotype.Component; import com.inteligr8.alfresco.asie.compute.SolrShardHashTable; -import com.inteligr8.alfresco.asie.enterprise.rest.model.NodeInfo; -import com.inteligr8.alfresco.asie.enterprise.rest.model.PropertyHashShardSetInfo; -import com.inteligr8.alfresco.asie.enterprise.rest.model.ShardInfo; -import com.inteligr8.alfresco.asie.enterprise.rest.model.ShardNodeInfo; -import com.inteligr8.alfresco.asie.enterprise.service.ShardDiscoveryService; +import com.inteligr8.alfresco.asie.rest.model.NodeInfo; +import com.inteligr8.alfresco.asie.rest.model.PropertyHashShardSetInfo; +import com.inteligr8.alfresco.asie.rest.model.ShardInfo; +import com.inteligr8.alfresco.asie.rest.model.ShardNodeInfo; +import com.inteligr8.alfresco.asie.service.ShardDiscoveryService; -@Component(value = "webscript.com.inteligr8.alfresco.asie.enterprise.propertyHashShards.get") -public class GetPropertyHashShardsWebScript extends AbstractAsieEnterpriseWebScript { +@Component(value = "webscript.com.inteligr8.alfresco.asie.propertyHashShards.get") +public class GetPropertyHashShardsWebScript extends AbstractAsieShardableWebScript { private final Logger logger = LoggerFactory.getLogger(this.getClass()); diff --git a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/GetSampleHashesWebScript.java b/shared/src/main/java/com/inteligr8/alfresco/asie/rest/GetSampleHashesWebScript.java similarity index 93% rename from module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/GetSampleHashesWebScript.java rename to shared/src/main/java/com/inteligr8/alfresco/asie/rest/GetSampleHashesWebScript.java index 5d08cf4..2feac30 100644 --- a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/GetSampleHashesWebScript.java +++ b/shared/src/main/java/com/inteligr8/alfresco/asie/rest/GetSampleHashesWebScript.java @@ -1,4 +1,4 @@ -package com.inteligr8.alfresco.asie.enterprise.rest; +package com.inteligr8.alfresco.asie.rest; import java.io.IOException; import java.util.Arrays; @@ -24,8 +24,8 @@ import com.inteligr8.alfresco.asie.compute.SolrShardHashTable; import com.inteligr8.alfresco.asie.compute.SolrShardNumericHashTable; import com.inteligr8.alfresco.asie.service.SolrShardHashService; -@Component(value = "webscript.com.inteligr8.alfresco.asie.enterprise.sampleHashes.get") -public class GetSampleHashesWebScript extends AbstractAsieEnterpriseWebScript { +@Component(value = "webscript.com.inteligr8.alfresco.asie.sampleHashes.get") +public class GetSampleHashesWebScript extends AbstractAsieShardableWebScript { private final Logger logger = LoggerFactory.getLogger(this.getClass()); diff --git a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/GetShardWebScript.java b/shared/src/main/java/com/inteligr8/alfresco/asie/rest/GetShardWebScript.java similarity index 84% rename from module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/GetShardWebScript.java rename to shared/src/main/java/com/inteligr8/alfresco/asie/rest/GetShardWebScript.java index 2feafb7..197fb37 100644 --- a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/GetShardWebScript.java +++ b/shared/src/main/java/com/inteligr8/alfresco/asie/rest/GetShardWebScript.java @@ -1,4 +1,4 @@ -package com.inteligr8.alfresco.asie.enterprise.rest; +package com.inteligr8.alfresco.asie.rest; import java.io.IOException; import java.time.Instant; @@ -15,12 +15,12 @@ import org.springframework.http.MediaType; import org.springframework.stereotype.Component; import com.inteligr8.alfresco.asie.compute.SolrShardHashTable; -import com.inteligr8.alfresco.asie.enterprise.rest.model.NodeInfo; -import com.inteligr8.alfresco.asie.enterprise.rest.model.ShardInfo; -import com.inteligr8.alfresco.asie.enterprise.rest.model.ShardNodeInfo; -import com.inteligr8.alfresco.asie.enterprise.rest.model.ShardSetInfo; +import com.inteligr8.alfresco.asie.rest.model.NodeInfo; +import com.inteligr8.alfresco.asie.rest.model.ShardInfo; +import com.inteligr8.alfresco.asie.rest.model.ShardNodeInfo; +import com.inteligr8.alfresco.asie.rest.model.ShardSetInfo; -@Component(value = "webscript.com.inteligr8.alfresco.asie.enterprise.shard.get") +@Component(value = "webscript.com.inteligr8.alfresco.asie.shard.get") public class GetShardWebScript extends AbstractAsieShardWebScript { @Override diff --git a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/GetShardsWebScript.java b/shared/src/main/java/com/inteligr8/alfresco/asie/rest/GetShardsWebScript.java similarity index 87% rename from module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/GetShardsWebScript.java rename to shared/src/main/java/com/inteligr8/alfresco/asie/rest/GetShardsWebScript.java index 41f3f91..8a5a4b1 100644 --- a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/GetShardsWebScript.java +++ b/shared/src/main/java/com/inteligr8/alfresco/asie/rest/GetShardsWebScript.java @@ -1,4 +1,4 @@ -package com.inteligr8.alfresco.asie.enterprise.rest; +package com.inteligr8.alfresco.asie.rest; import java.io.IOException; import java.time.Instant; @@ -22,13 +22,13 @@ import org.springframework.http.MediaType; import org.springframework.stereotype.Component; import com.inteligr8.alfresco.asie.compute.SolrShardHashTable; -import com.inteligr8.alfresco.asie.enterprise.rest.model.NodeInfo; -import com.inteligr8.alfresco.asie.enterprise.rest.model.ShardInfo; -import com.inteligr8.alfresco.asie.enterprise.rest.model.ShardNodeInfo; -import com.inteligr8.alfresco.asie.enterprise.rest.model.ShardSetInfo; +import com.inteligr8.alfresco.asie.rest.model.NodeInfo; +import com.inteligr8.alfresco.asie.rest.model.ShardInfo; +import com.inteligr8.alfresco.asie.rest.model.ShardNodeInfo; +import com.inteligr8.alfresco.asie.rest.model.ShardSetInfo; -@Component(value = "webscript.com.inteligr8.alfresco.asie.enterprise.shards.get") -public class GetShardsWebScript extends AbstractAsieEnterpriseWebScript { +@Component(value = "webscript.com.inteligr8.alfresco.asie.shards.get") +public class GetShardsWebScript extends AbstractAsieShardableWebScript { private final Logger logger = LoggerFactory.getLogger(this.getClass()); diff --git a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/ReloadNodeShardWebScript.java b/shared/src/main/java/com/inteligr8/alfresco/asie/rest/ReloadNodeShardWebScript.java similarity index 96% rename from module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/ReloadNodeShardWebScript.java rename to shared/src/main/java/com/inteligr8/alfresco/asie/rest/ReloadNodeShardWebScript.java index da920d8..434f315 100644 --- a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/ReloadNodeShardWebScript.java +++ b/shared/src/main/java/com/inteligr8/alfresco/asie/rest/ReloadNodeShardWebScript.java @@ -1,4 +1,4 @@ -package com.inteligr8.alfresco.asie.enterprise.rest; +package com.inteligr8.alfresco.asie.rest; import java.io.IOException; import java.io.Serializable; @@ -28,7 +28,7 @@ import com.inteligr8.solr.model.core.ReloadRequest; import jakarta.ws.rs.BadRequestException; import jakarta.ws.rs.InternalServerErrorException; -@Component(value = "webscript.com.inteligr8.alfresco.asie.enterprise.nodeShard.post") +@Component(value = "webscript.com.inteligr8.alfresco.asie.nodeShard.post") public class ReloadNodeShardWebScript extends AbstractAsieNodeWebScript { private final Logger logger = LoggerFactory.getLogger(this.getClass()); @@ -47,7 +47,7 @@ public class ReloadNodeShardWebScript extends AbstractAsieNodeWebScript { Serializable[] keys = new String[] { Constants.ATTR_ASIE, - Constants.ATTR_UNLOADED_NODE_CORES, + Constants.ATTR_UNLOADED, nodeHostname + ":" + nodePort }; diff --git a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/ReloadNodeWebScript.java b/shared/src/main/java/com/inteligr8/alfresco/asie/rest/ReloadNodeWebScript.java similarity index 96% rename from module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/ReloadNodeWebScript.java rename to shared/src/main/java/com/inteligr8/alfresco/asie/rest/ReloadNodeWebScript.java index 1f846cf..cf1cad9 100644 --- a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/ReloadNodeWebScript.java +++ b/shared/src/main/java/com/inteligr8/alfresco/asie/rest/ReloadNodeWebScript.java @@ -1,4 +1,4 @@ -package com.inteligr8.alfresco.asie.enterprise.rest; +package com.inteligr8.alfresco.asie.rest; import java.io.IOException; import java.io.Serializable; @@ -30,7 +30,7 @@ import com.inteligr8.solr.model.core.ReloadRequest; import jakarta.ws.rs.BadRequestException; import jakarta.ws.rs.InternalServerErrorException; -@Component(value = "webscript.com.inteligr8.alfresco.asie.enterprise.node.post") +@Component(value = "webscript.com.inteligr8.alfresco.asie.node.post") public class ReloadNodeWebScript extends AbstractAsieNodeWebScript { private final Logger logger = LoggerFactory.getLogger(this.getClass()); @@ -45,7 +45,7 @@ public class ReloadNodeWebScript extends AbstractAsieNodeWebScript { throws IOException { Serializable[] keys = new String[] { Constants.ATTR_ASIE, - Constants.ATTR_UNLOADED_NODE_CORES, + Constants.ATTR_UNLOADED, nodeHostname + ":" + nodePort }; diff --git a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/UnloadNodeShardWebScript.java b/shared/src/main/java/com/inteligr8/alfresco/asie/rest/UnloadNodeShardWebScript.java similarity index 77% rename from module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/UnloadNodeShardWebScript.java rename to shared/src/main/java/com/inteligr8/alfresco/asie/rest/UnloadNodeShardWebScript.java index 2bcd870..fbfde41 100644 --- a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/UnloadNodeShardWebScript.java +++ b/shared/src/main/java/com/inteligr8/alfresco/asie/rest/UnloadNodeShardWebScript.java @@ -1,13 +1,13 @@ -package com.inteligr8.alfresco.asie.enterprise.rest; +package com.inteligr8.alfresco.asie.rest; import org.alfresco.repo.index.shard.ShardState; import org.springframework.extensions.webscripts.WebScriptRequest; import org.springframework.stereotype.Component; -import com.inteligr8.alfresco.asie.enterprise.model.NodeShardParameterSet; -import com.inteligr8.alfresco.asie.enterprise.model.ShardSet; +import com.inteligr8.alfresco.asie.model.NodeShardParameterSet; +import com.inteligr8.alfresco.asie.model.ShardSet; -@Component(value = "webscript.com.inteligr8.alfresco.asie.enterprise.nodeShard.delete") +@Component(value = "webscript.com.inteligr8.alfresco.asie.nodeShard.delete") public class UnloadNodeShardWebScript extends AbstractUnregisterNodeWebScript { @Override diff --git a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/UnloadNodeWebScript.java b/shared/src/main/java/com/inteligr8/alfresco/asie/rest/UnloadNodeWebScript.java similarity index 76% rename from module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/UnloadNodeWebScript.java rename to shared/src/main/java/com/inteligr8/alfresco/asie/rest/UnloadNodeWebScript.java index f624437..04a58ba 100644 --- a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/UnloadNodeWebScript.java +++ b/shared/src/main/java/com/inteligr8/alfresco/asie/rest/UnloadNodeWebScript.java @@ -1,11 +1,11 @@ -package com.inteligr8.alfresco.asie.enterprise.rest; +package com.inteligr8.alfresco.asie.rest; import org.springframework.extensions.webscripts.WebScriptRequest; import org.springframework.stereotype.Component; import com.inteligr8.alfresco.asie.model.NodeParameterSet; -@Component(value = "webscript.com.inteligr8.alfresco.asie.enterprise.node.delete") +@Component(value = "webscript.com.inteligr8.alfresco.asie.node.delete") public class UnloadNodeWebScript extends AbstractUnregisterNodeWebScript { @Override diff --git a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/model/NodeInfo.java b/shared/src/main/java/com/inteligr8/alfresco/asie/rest/model/NodeInfo.java similarity index 66% rename from module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/model/NodeInfo.java rename to shared/src/main/java/com/inteligr8/alfresco/asie/rest/model/NodeInfo.java index d2b6ac8..6ac3d1d 100644 --- a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/model/NodeInfo.java +++ b/shared/src/main/java/com/inteligr8/alfresco/asie/rest/model/NodeInfo.java @@ -1,4 +1,4 @@ -package com.inteligr8.alfresco.asie.enterprise.rest.model; +package com.inteligr8.alfresco.asie.rest.model; import java.util.Map; import java.util.TreeMap; @@ -6,13 +6,9 @@ import java.util.TreeMap; import org.alfresco.repo.index.shard.ShardInstance; import com.fasterxml.jackson.annotation.JsonProperty; +import com.inteligr8.alfresco.asie.model.Node; public abstract class NodeInfo { - - public static String determineId(ShardInstance nodeCache) { - int lastSlash = nodeCache.getBaseUrl().lastIndexOf('/'); - return nodeCache.getHostName() + ":" + nodeCache.getPort() + nodeCache.getBaseUrl().substring(0, lastSlash); - } @JsonProperty private String id; @@ -24,7 +20,7 @@ public abstract class NodeInfo { } public NodeInfo(ShardInstance nodeCache) { - this.setId(determineId(nodeCache)); + this.setId(new Node(nodeCache).getId()); } public String getId() { diff --git a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/model/NodeShardInfo.java b/shared/src/main/java/com/inteligr8/alfresco/asie/rest/model/NodeShardInfo.java similarity index 90% rename from module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/model/NodeShardInfo.java rename to shared/src/main/java/com/inteligr8/alfresco/asie/rest/model/NodeShardInfo.java index 5d10536..dad9cbb 100644 --- a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/model/NodeShardInfo.java +++ b/shared/src/main/java/com/inteligr8/alfresco/asie/rest/model/NodeShardInfo.java @@ -1,4 +1,4 @@ -package com.inteligr8.alfresco.asie.enterprise.rest.model; +package com.inteligr8.alfresco.asie.rest.model; import java.util.Map; diff --git a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/model/PropertyHashShardSetInfo.java b/shared/src/main/java/com/inteligr8/alfresco/asie/rest/model/PropertyHashShardSetInfo.java similarity index 91% rename from module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/model/PropertyHashShardSetInfo.java rename to shared/src/main/java/com/inteligr8/alfresco/asie/rest/model/PropertyHashShardSetInfo.java index 4a389ef..fdbf5b6 100644 --- a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/model/PropertyHashShardSetInfo.java +++ b/shared/src/main/java/com/inteligr8/alfresco/asie/rest/model/PropertyHashShardSetInfo.java @@ -1,4 +1,4 @@ -package com.inteligr8.alfresco.asie.enterprise.rest.model; +package com.inteligr8.alfresco.asie.rest.model; import java.util.Map; @@ -8,7 +8,7 @@ import org.alfresco.repo.index.shard.ShardState; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.inteligr8.alfresco.asie.enterprise.model.ShardSet; +import com.inteligr8.alfresco.asie.model.ShardSet; import com.fasterxml.jackson.annotation.JsonProperty; @JsonInclude(Include.NON_EMPTY) diff --git a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/model/ShardInfo.java b/shared/src/main/java/com/inteligr8/alfresco/asie/rest/model/ShardInfo.java similarity index 97% rename from module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/model/ShardInfo.java rename to shared/src/main/java/com/inteligr8/alfresco/asie/rest/model/ShardInfo.java index 09f2399..3eab39e 100644 --- a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/model/ShardInfo.java +++ b/shared/src/main/java/com/inteligr8/alfresco/asie/rest/model/ShardInfo.java @@ -1,4 +1,4 @@ -package com.inteligr8.alfresco.asie.enterprise.rest.model; +package com.inteligr8.alfresco.asie.rest.model; import java.time.Instant; import java.time.OffsetDateTime; diff --git a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/model/ShardNodeInfo.java b/shared/src/main/java/com/inteligr8/alfresco/asie/rest/model/ShardNodeInfo.java similarity index 95% rename from module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/model/ShardNodeInfo.java rename to shared/src/main/java/com/inteligr8/alfresco/asie/rest/model/ShardNodeInfo.java index 6ed16b6..0fbf5a8 100644 --- a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/model/ShardNodeInfo.java +++ b/shared/src/main/java/com/inteligr8/alfresco/asie/rest/model/ShardNodeInfo.java @@ -1,4 +1,4 @@ -package com.inteligr8.alfresco.asie.enterprise.rest.model; +package com.inteligr8.alfresco.asie.rest.model; import java.time.Instant; import java.time.OffsetDateTime; diff --git a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/model/ShardSetInfo.java b/shared/src/main/java/com/inteligr8/alfresco/asie/rest/model/ShardSetInfo.java similarity index 93% rename from module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/model/ShardSetInfo.java rename to shared/src/main/java/com/inteligr8/alfresco/asie/rest/model/ShardSetInfo.java index f44722a..88ea1a0 100644 --- a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/rest/model/ShardSetInfo.java +++ b/shared/src/main/java/com/inteligr8/alfresco/asie/rest/model/ShardSetInfo.java @@ -1,4 +1,4 @@ -package com.inteligr8.alfresco.asie.enterprise.rest.model; +package com.inteligr8.alfresco.asie.rest.model; import java.util.Map; import java.util.Set; @@ -10,7 +10,7 @@ import org.alfresco.repo.index.shard.ShardState; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.inteligr8.alfresco.asie.enterprise.model.ShardSet; +import com.inteligr8.alfresco.asie.model.ShardSet; import com.fasterxml.jackson.annotation.JsonProperty; @JsonInclude(Include.NON_EMPTY) diff --git a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/service/ShardBackupService.java b/shared/src/main/java/com/inteligr8/alfresco/asie/service/ShardBackupService.java similarity index 81% rename from module/src/main/java/com/inteligr8/alfresco/asie/enterprise/service/ShardBackupService.java rename to shared/src/main/java/com/inteligr8/alfresco/asie/service/ShardBackupService.java index 2a3da36..480fb0d 100644 --- a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/service/ShardBackupService.java +++ b/shared/src/main/java/com/inteligr8/alfresco/asie/service/ShardBackupService.java @@ -1,4 +1,4 @@ -package com.inteligr8.alfresco.asie.enterprise.service; +package com.inteligr8.alfresco.asie.service; import java.io.Serializable; import java.util.Collection; @@ -15,16 +15,17 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import com.inteligr8.alfresco.asie.Constants; -import com.inteligr8.alfresco.asie.enterprise.rest.model.NodeInfo; +import com.inteligr8.alfresco.asie.model.Node; +import com.inteligr8.alfresco.asie.spi.ShardDiscoveryService; @Component -public class ShardBackupService { +public class ShardBackupService implements com.inteligr8.alfresco.asie.spi.ShardBackupService { private static final String ATTR_BACKUP_NODE = "backupNode"; private final Logger logger = LoggerFactory.getLogger(this.getClass()); @Autowired - private ShardAnalysisService sas; + private ShardDiscoveryService sds; @Autowired @Qualifier(Constants.QUALIFIER_ASIE) @@ -33,7 +34,7 @@ public class ShardBackupService { @Value("${inteligr8.asie.backup.persistTimeMinutes}") private int persistTimeMinutes; - public String fetchNodeId(Collection shardNodes) { + public Node fetchNode(Collection shardNodes) { if (shardNodes.isEmpty()) return null; @@ -46,8 +47,8 @@ public class ShardBackupService { this.logger.debug("Found backup node: {}", backupNode); if (backupNode == null || backupNode.isExpired()) { - ShardInstance backupShardInstance = this.sas.computeLeadShard(shardNodes); - backupNode = new PersistedNode(NodeInfo.determineId(backupShardInstance)); + ShardInstance backupShardInstance = this.sds.computeLeadShard(shardNodes); + backupNode = new PersistedNode(new Node(backupShardInstance)); this.attributeService.setAttribute(backupNode, Constants.ATTR_ASIE, ATTR_BACKUP_NODE, shardKey); } @@ -70,12 +71,12 @@ public class ShardBackupService { private class PersistedNode implements Serializable { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 4105196543023419818L; - private final String node; + private final Node node; private long expireTimeMillis; - PersistedNode(String node) { + PersistedNode(Node node) { this.node = node; this.reset(); } @@ -88,7 +89,7 @@ public class ShardBackupService { return this.expireTimeMillis < System.currentTimeMillis(); } - String getNode() { + Node getNode() { return this.node; } diff --git a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/service/ShardDiscoveryService.java b/shared/src/main/java/com/inteligr8/alfresco/asie/service/ShardDiscoveryService.java similarity index 82% rename from module/src/main/java/com/inteligr8/alfresco/asie/enterprise/service/ShardDiscoveryService.java rename to shared/src/main/java/com/inteligr8/alfresco/asie/service/ShardDiscoveryService.java index 8ed5b1e..9dfe2d5 100644 --- a/module/src/main/java/com/inteligr8/alfresco/asie/enterprise/service/ShardDiscoveryService.java +++ b/shared/src/main/java/com/inteligr8/alfresco/asie/service/ShardDiscoveryService.java @@ -1,4 +1,4 @@ -package com.inteligr8.alfresco.asie.enterprise.service; +package com.inteligr8.alfresco.asie.service; import java.net.InetAddress; import java.net.UnknownHostException; @@ -25,16 +25,33 @@ import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; import com.inteligr8.alfresco.asie.Constants; -import com.inteligr8.alfresco.asie.enterprise.model.ShardSet; +import com.inteligr8.alfresco.asie.model.ShardSet; @Component -public class ShardDiscoveryService { +public class ShardDiscoveryService implements com.inteligr8.alfresco.asie.spi.ShardDiscoveryService { private final Logger logger = LoggerFactory.getLogger(this.getClass()); @Autowired - @Qualifier(Constants.BEAN_SHARD_REGISTRY) + @Qualifier(Constants.QUALIFIER_ASIE) private ShardRegistry shardRegistry; + + public ShardInstance computeLeadShard(Collection shardNodesCache) { + if (shardNodesCache.isEmpty()) + return null; + + long latestTime = 0L; + ShardInstance latestNode = null; + + for (ShardState shardNodeCache : shardNodesCache) { + if (latestTime < shardNodeCache.getLastIndexedTxCommitTime()) { + latestNode = shardNodeCache.getShardInstance(); + latestTime = shardNodeCache.getLastIndexedTxCommitTime(); + } + } + + return latestNode; + } public Set findByNode(String nodeHostname, int nodePort) { Map>> flocs = this.shardRegistry.getFlocs(); @@ -114,11 +131,11 @@ public class ShardDiscoveryService { return filteredFlocs; } - public Set findByShard(Map> shards, int shardId) { + public Set filterByShard(Map> shards, int shardId) { if (shards == null) return null; - for (Entry> shard : shards.entrySet()) { + for (Entry> shard : shards.entrySet()) { if (shard.getKey().getInstance() == shardId) return shard.getValue(); } @@ -128,7 +145,7 @@ public class ShardDiscoveryService { public Set findByShard(ShardSet shardSet, int shardId) { Map> shards = this.findByShardSet(shardSet); - return this.findByShard(shards, shardId); + return this.filterByShard(shards, shardId); } private InetAddress resolve(String hostname) { diff --git a/module/src/main/java/com/inteligr8/alfresco/asie/service/SolrShardHashService.java b/shared/src/main/java/com/inteligr8/alfresco/asie/service/SolrShardHashService.java similarity index 100% rename from module/src/main/java/com/inteligr8/alfresco/asie/service/SolrShardHashService.java rename to shared/src/main/java/com/inteligr8/alfresco/asie/service/SolrShardHashService.java diff --git a/shared/src/main/java/com/inteligr8/alfresco/asie/spi/ShardBackupService.java b/shared/src/main/java/com/inteligr8/alfresco/asie/spi/ShardBackupService.java new file mode 100644 index 0000000..7cfa9b8 --- /dev/null +++ b/shared/src/main/java/com/inteligr8/alfresco/asie/spi/ShardBackupService.java @@ -0,0 +1,17 @@ +package com.inteligr8.alfresco.asie.spi; + +import java.util.Collection; + +import org.alfresco.repo.index.shard.ShardState; + +import com.inteligr8.alfresco.asie.model.Node; + +public interface ShardBackupService { + + Node fetchNode(Collection shardNodes); + + void forget(); + + void forget(ShardState shardNode); + +} diff --git a/shared/src/main/java/com/inteligr8/alfresco/asie/spi/ShardDiscoveryService.java b/shared/src/main/java/com/inteligr8/alfresco/asie/spi/ShardDiscoveryService.java new file mode 100644 index 0000000..ba9e20a --- /dev/null +++ b/shared/src/main/java/com/inteligr8/alfresco/asie/spi/ShardDiscoveryService.java @@ -0,0 +1,72 @@ +package com.inteligr8.alfresco.asie.spi; + +import java.util.Collection; +import java.util.Map; +import java.util.Set; + +import org.alfresco.repo.index.shard.Floc; +import org.alfresco.repo.index.shard.Shard; +import org.alfresco.repo.index.shard.ShardInstance; +import org.alfresco.repo.index.shard.ShardMethodEnum; +import org.alfresco.repo.index.shard.ShardState; +import org.alfresco.util.Pair; + +import com.inteligr8.alfresco.asie.model.ShardSet; + +public interface ShardDiscoveryService { + + /** + * Determine the lead shard in the specified node/shard snapshot metadata. + * + * @param shardNodes A collection of snapshot metadata. + * @return A single node/shard holding the latest snapshot metadata. + */ + ShardInstance computeLeadShard(Collection shardNodes); + + /** + * Find the latest snapshot of each shard on the specified node. + * + * @param nodeHostname The hostname of a ASIE node. + * @param nodePort The port of an ASIE node. + * @return A set of the latest snapshot metadata of shards. + */ + Set findByNode(String nodeHostname, int nodePort); + + /** + * Find the shards, their nodes, and the latest snapshot of each within the + * specified shard set. + * + * @param shardSet A shard set. + * @return A map of shards to sets of the latest snapshot metadata of those shards and their nodes. + */ + Map> findByShardSet(ShardSet shardSet); + + /** + * Find the shards, their nodes, and the latest snapshot of each using the + * specified shard method. + * + * @param shardMethod A shard method. + * @return A collection of maps of shards to sets of the latest snapshot metadata of those shards and their nodes. + */ + Collection>>> findByShardMethod(ShardMethodEnum shardMethod); + + /** + * Filter the latest snapshot of each shard. + * + * @param shards A map of shards to sets of the latest snapshot metadata of those shards and their nodes. + * @param shardId A 0-based index of a shard. + * @return A set of the latest snapshot metadata of shards. + */ + Set filterByShard(Map> shards, int shardId); + + /** + * Find the latest snapshot of each shard and their nodes within the + * specified shard set. + * + * @param shardSet A shard set. + * @param shardId A 0-based index of a shard. + * @return A set of the latest snapshot metadata of shards. + */ + Set findByShard(ShardSet shardSet, int shardId); + +} diff --git a/shared/src/main/java/com/inteligr8/alfresco/asie/spi/ShardStateService.java b/shared/src/main/java/com/inteligr8/alfresco/asie/spi/ShardStateService.java new file mode 100644 index 0000000..5c82b90 --- /dev/null +++ b/shared/src/main/java/com/inteligr8/alfresco/asie/spi/ShardStateService.java @@ -0,0 +1,18 @@ +package com.inteligr8.alfresco.asie.spi; + +import java.io.Serializable; + +import org.alfresco.service.cmr.attributes.AttributeService.AttributeQueryCallback; + +public interface ShardStateService { + + /** + * Clears the shard state. + */ + void clear(); + + void remove(Serializable... keys); + + void iterate(AttributeQueryCallback callback); + +} diff --git a/module/src/main/resources/alfresco/extension/templates/webscripts/com/inteligr8/alfresco/asie/enterprise/backupNode.get.desc.xml b/shared/src/main/resources/alfresco/extension/templates/webscripts/com/inteligr8/alfresco/asie/backupNode.get.desc.xml similarity index 100% rename from module/src/main/resources/alfresco/extension/templates/webscripts/com/inteligr8/alfresco/asie/enterprise/backupNode.get.desc.xml rename to shared/src/main/resources/alfresco/extension/templates/webscripts/com/inteligr8/alfresco/asie/backupNode.get.desc.xml diff --git a/module/src/main/resources/alfresco/extension/templates/webscripts/com/inteligr8/alfresco/asie/enterprise/leadNode.get.desc.xml b/shared/src/main/resources/alfresco/extension/templates/webscripts/com/inteligr8/alfresco/asie/leadNode.get.desc.xml similarity index 100% rename from module/src/main/resources/alfresco/extension/templates/webscripts/com/inteligr8/alfresco/asie/enterprise/leadNode.get.desc.xml rename to shared/src/main/resources/alfresco/extension/templates/webscripts/com/inteligr8/alfresco/asie/leadNode.get.desc.xml diff --git a/module/src/main/resources/alfresco/extension/templates/webscripts/com/inteligr8/alfresco/asie/enterprise/node.delete.desc.xml b/shared/src/main/resources/alfresco/extension/templates/webscripts/com/inteligr8/alfresco/asie/node.delete.desc.xml similarity index 100% rename from module/src/main/resources/alfresco/extension/templates/webscripts/com/inteligr8/alfresco/asie/enterprise/node.delete.desc.xml rename to shared/src/main/resources/alfresco/extension/templates/webscripts/com/inteligr8/alfresco/asie/node.delete.desc.xml diff --git a/module/src/main/resources/alfresco/extension/templates/webscripts/com/inteligr8/alfresco/asie/enterprise/node.get.desc.xml b/shared/src/main/resources/alfresco/extension/templates/webscripts/com/inteligr8/alfresco/asie/node.get.desc.xml similarity index 100% rename from module/src/main/resources/alfresco/extension/templates/webscripts/com/inteligr8/alfresco/asie/enterprise/node.get.desc.xml rename to shared/src/main/resources/alfresco/extension/templates/webscripts/com/inteligr8/alfresco/asie/node.get.desc.xml diff --git a/module/src/main/resources/alfresco/extension/templates/webscripts/com/inteligr8/alfresco/asie/enterprise/node.post.desc.xml b/shared/src/main/resources/alfresco/extension/templates/webscripts/com/inteligr8/alfresco/asie/node.post.desc.xml similarity index 100% rename from module/src/main/resources/alfresco/extension/templates/webscripts/com/inteligr8/alfresco/asie/enterprise/node.post.desc.xml rename to shared/src/main/resources/alfresco/extension/templates/webscripts/com/inteligr8/alfresco/asie/node.post.desc.xml diff --git a/module/src/main/resources/alfresco/extension/templates/webscripts/com/inteligr8/alfresco/asie/enterprise/nodeShard.delete.desc.xml b/shared/src/main/resources/alfresco/extension/templates/webscripts/com/inteligr8/alfresco/asie/nodeShard.delete.desc.xml similarity index 100% rename from module/src/main/resources/alfresco/extension/templates/webscripts/com/inteligr8/alfresco/asie/enterprise/nodeShard.delete.desc.xml rename to shared/src/main/resources/alfresco/extension/templates/webscripts/com/inteligr8/alfresco/asie/nodeShard.delete.desc.xml diff --git a/module/src/main/resources/alfresco/extension/templates/webscripts/com/inteligr8/alfresco/asie/enterprise/nodeShard.post.desc.xml b/shared/src/main/resources/alfresco/extension/templates/webscripts/com/inteligr8/alfresco/asie/nodeShard.post.desc.xml similarity index 100% rename from module/src/main/resources/alfresco/extension/templates/webscripts/com/inteligr8/alfresco/asie/enterprise/nodeShard.post.desc.xml rename to shared/src/main/resources/alfresco/extension/templates/webscripts/com/inteligr8/alfresco/asie/nodeShard.post.desc.xml diff --git a/module/src/main/resources/alfresco/extension/templates/webscripts/com/inteligr8/alfresco/asie/enterprise/nodes.get.desc.xml b/shared/src/main/resources/alfresco/extension/templates/webscripts/com/inteligr8/alfresco/asie/nodes.get.desc.xml similarity index 100% rename from module/src/main/resources/alfresco/extension/templates/webscripts/com/inteligr8/alfresco/asie/enterprise/nodes.get.desc.xml rename to shared/src/main/resources/alfresco/extension/templates/webscripts/com/inteligr8/alfresco/asie/nodes.get.desc.xml diff --git a/module/src/main/resources/alfresco/extension/templates/webscripts/com/inteligr8/alfresco/asie/enterprise/propertyHashShards.get.desc.xml b/shared/src/main/resources/alfresco/extension/templates/webscripts/com/inteligr8/alfresco/asie/propertyHashShards.get.desc.xml similarity index 100% rename from module/src/main/resources/alfresco/extension/templates/webscripts/com/inteligr8/alfresco/asie/enterprise/propertyHashShards.get.desc.xml rename to shared/src/main/resources/alfresco/extension/templates/webscripts/com/inteligr8/alfresco/asie/propertyHashShards.get.desc.xml diff --git a/module/src/main/resources/alfresco/extension/templates/webscripts/com/inteligr8/alfresco/asie/enterprise/registry.delete.desc.xml b/shared/src/main/resources/alfresco/extension/templates/webscripts/com/inteligr8/alfresco/asie/registry.delete.desc.xml similarity index 100% rename from module/src/main/resources/alfresco/extension/templates/webscripts/com/inteligr8/alfresco/asie/enterprise/registry.delete.desc.xml rename to shared/src/main/resources/alfresco/extension/templates/webscripts/com/inteligr8/alfresco/asie/registry.delete.desc.xml diff --git a/module/src/main/resources/alfresco/extension/templates/webscripts/com/inteligr8/alfresco/asie/enterprise/sampleHashes.get.desc.xml b/shared/src/main/resources/alfresco/extension/templates/webscripts/com/inteligr8/alfresco/asie/sampleHashes.get.desc.xml similarity index 100% rename from module/src/main/resources/alfresco/extension/templates/webscripts/com/inteligr8/alfresco/asie/enterprise/sampleHashes.get.desc.xml rename to shared/src/main/resources/alfresco/extension/templates/webscripts/com/inteligr8/alfresco/asie/sampleHashes.get.desc.xml diff --git a/module/src/main/resources/alfresco/extension/templates/webscripts/com/inteligr8/alfresco/asie/enterprise/shard.get.desc.xml b/shared/src/main/resources/alfresco/extension/templates/webscripts/com/inteligr8/alfresco/asie/shard.get.desc.xml similarity index 100% rename from module/src/main/resources/alfresco/extension/templates/webscripts/com/inteligr8/alfresco/asie/enterprise/shard.get.desc.xml rename to shared/src/main/resources/alfresco/extension/templates/webscripts/com/inteligr8/alfresco/asie/shard.get.desc.xml diff --git a/module/src/main/resources/alfresco/extension/templates/webscripts/com/inteligr8/alfresco/asie/enterprise/shards.get.desc.xml b/shared/src/main/resources/alfresco/extension/templates/webscripts/com/inteligr8/alfresco/asie/shards.get.desc.xml similarity index 100% rename from module/src/main/resources/alfresco/extension/templates/webscripts/com/inteligr8/alfresco/asie/enterprise/shards.get.desc.xml rename to shared/src/main/resources/alfresco/extension/templates/webscripts/com/inteligr8/alfresco/asie/shards.get.desc.xml diff --git a/shared/src/main/resources/alfresco/module/com_inteligr8_alfresco_asie-shared/alfresco-global.properties b/shared/src/main/resources/alfresco/module/com_inteligr8_alfresco_asie-shared/alfresco-global.properties new file mode 100644 index 0000000..47624f6 --- /dev/null +++ b/shared/src/main/resources/alfresco/module/com_inteligr8_alfresco_asie-shared/alfresco-global.properties @@ -0,0 +1,22 @@ + +# defaulting to 3 days = 60 * 24 * 3 = 4320 +inteligr8.asie.backup.persistTimeMinutes=4320 + +inteligr8.asie.allowedAuthorities=ALFRESCO_ADMINISTRATORS + +# same as solr.baseUrl, but that property is private to the Search subsystem +inteligr8.asie.basePath=/solr + + + +# Overrides of alfresco-repository.jar/alfresco/caches.properties +cache.shardStateSharedCache.tx.maxItems=0 +cache.shardStateSharedCache.tx.statsEnabled=${caches.tx.statsEnabled} +cache.shardStateSharedCache.maxItems=0 +cache.shardStateSharedCache.timeToLiveSeconds=1800 +cache.shardStateSharedCache.maxIdleSeconds=0 +cache.shardStateSharedCache.cluster.type=fully-distributed +cache.shardStateSharedCache.backup-count=1 +cache.shardStateSharedCache.eviction-policy=LRU +cache.shardStateSharedCache.merge-policy=com.hazelcast.spi.merge.PutIfAbsentMergePolicy +cache.shardStateSharedCache.readBackupData=false diff --git a/module/src/main/resources/alfresco/module/com_inteligr8_alfresco_asie-platform-module/log4j2.properties b/shared/src/main/resources/alfresco/module/com_inteligr8_alfresco_asie-shared/log4j2.properties similarity index 100% rename from module/src/main/resources/alfresco/module/com_inteligr8_alfresco_asie-platform-module/log4j2.properties rename to shared/src/main/resources/alfresco/module/com_inteligr8_alfresco_asie-shared/log4j2.properties diff --git a/shared/src/main/resources/alfresco/module/com_inteligr8_alfresco_asie-shared/module-context.xml b/shared/src/main/resources/alfresco/module/com_inteligr8_alfresco_asie-shared/module-context.xml new file mode 100644 index 0000000..43ceb92 --- /dev/null +++ b/shared/src/main/resources/alfresco/module/com_inteligr8_alfresco_asie-shared/module-context.xml @@ -0,0 +1,14 @@ + + + + + + + + +