Loading enterprise-module/pom.xml +3 −0 Original line number Diff line number Diff line Loading @@ -69,6 +69,7 @@ <dependency> <groupId>jakarta.ws.rs</groupId> <artifactId>jakarta.ws.rs-api</artifactId> <version>4.0.0</version> <scope>provided</scope> </dependency> <dependency> Loading @@ -79,11 +80,13 @@ <dependency> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-jsr310</artifactId> <version>2.17.3</version> <scope>provided</scope> </dependency> <dependency> <groupId>com.fasterxml.jackson.module</groupId> <artifactId>jackson-module-jakarta-xmlbind-annotations</artifactId> <version>2.17.2</version> <scope>provided</scope> </dependency> Loading shared/src/main/java/com/inteligr8/alfresco/asie/service/AbstractNodeActionService.java +51 −28 Original line number Diff line number Diff line Loading @@ -11,6 +11,7 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.regex.Matcher; import org.alfresco.model.ContentModel; import org.alfresco.repo.index.shard.Floc; Loading @@ -18,6 +19,8 @@ import org.alfresco.repo.index.shard.Shard; import org.alfresco.repo.index.shard.ShardInstance; import org.alfresco.repo.index.shard.ShardRegistry; import org.alfresco.repo.index.shard.ShardState; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.cmr.search.SearchParameters; import org.alfresco.service.cmr.search.SearchService; Loading Loading @@ -48,12 +51,18 @@ public abstract class AbstractNodeActionService { @Autowired private NamespaceService namespaceService; @Autowired private NodeService nodeService; @Autowired private ApiService apiService; @Autowired private ExecutorManager executorManager; @Autowired private SolrShardHashService shardHashService; @Autowired(required = false) @Qualifier(Constants.QUALIFIER_ASIE) private ShardRegistry shardRegistry; Loading Loading @@ -216,40 +225,54 @@ public abstract class AbstractNodeActionService { List<com.inteligr8.alfresco.asie.model.ShardInstance> instances = new LinkedList<>(); List<ShardInstance> slicedInstances = this.shardRegistry.getIndexSlice(searchParams); if (slicedInstances != null) { this.logger.trace("Due to a sharding method, considering only applicable shards and their ASIE nodes: {}: {}", nodeDbId, slicedInstances); // we need a ShardRegistry method like getIndexSlice, but // (1) works with shard methods other than explicit // (2) returns all possible instances/nodes, not just one node per instance for (ShardInstance instance : slicedInstances) instances.add(this.toModel(instance)); } else { for (Entry<Floc, Map<Shard, Set<ShardState>>> floc : this.shardRegistry.getFlocs().entrySet()) { if (!floc.getKey().getStoreRefs().contains(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE)) continue; Integer shardHash = null; ShardSet shardset = null; for (Entry<Shard, Set<ShardState>> shard : floc.getValue().entrySet()) { for (ShardState shardState : shard.getValue()) instances.add(this.toModel(shardState.getShardInstance(), shardState)); for (ShardState shardState : shard.getValue()) { // every shard and instance (state) in the FLOC is the same // but we need one ShardState to determine the full configuration // so we are computing the shardHash once and caching it if (shardset == null) { shardset = ShardSet.from(floc.getKey(), shardState); switch (shardset.getMethod()) { case PROPERTY: this.logger.trace("Using property-based sharding method; discovering target shard ..."); NodeRef nodeRef = this.nodeService.getNodeRef(nodeDbId); Object propValue = this.nodeService.getProperty(nodeRef, QName.createQName(shardset.getPrefixedProperty(), this.namespaceService)); if (propValue != null) { this.logger.trace("Discovered node property for sharding: {} <=> {} => {}", nodeDbId, nodeRef, propValue); Matcher matcher = shardset.getRegex().matcher(propValue.toString()); String hashable = matcher.group(1); this.logger.trace("Extracted shardable value from node: {} <=> {} => {}", nodeDbId, propValue, hashable); shardHash = this.shardHashService.hash(hashable, shardset.getShards().intValue()); this.logger.debug("Hash shardable value to shard instance ID: {} <=> {} => {}", nodeDbId, hashable, shardHash); } break; default: this.logger.trace("Despite sharding, considering all shards and nodes without optimization: {}: {}", nodeDbId, instances); } this.logger.trace("Despite sharding, considering all shards and nodes: {}: {}", nodeDbId, instances); } return instances; if (shardHash != null) { if (shard.getKey().getInstance() == shardHash) instances.add(this.toModel(shardState.getShardInstance(), shardState)); } else { instances.add(this.toModel(shardState.getShardInstance(), shardState)); } } } } private com.inteligr8.alfresco.asie.model.ShardInstance toModel(ShardInstance instance) { // get any random shardState Floc floc = instance.getShard().getFloc(); Map<Shard, Set<ShardState>> shardsStates = this.shardRegistry.getFlocs().get(floc); if (shardsStates == null) throw new IllegalStateException(); Set<ShardState> shardStates = shardsStates.get(instance.getShard()); if (shardStates == null || shardStates.isEmpty()) throw new IllegalStateException(); ShardState anyShardState = shardStates.iterator().next(); return this.toModel(instance, anyShardState); return instances; } private com.inteligr8.alfresco.asie.model.ShardInstance toModel(ShardInstance instance, ShardState anyShardState) { Loading shared/src/main/java/com/inteligr8/alfresco/asie/service/AcsReconcileService.java +6 −6 Original line number Diff line number Diff line Loading @@ -289,19 +289,19 @@ public class AcsReconcileService implements InitializingBean, DisposableBean { @Override public void success(ShardInstance instance) { reconcileLogger.info("INDEXED: {} <=> {}", nodeDbId, nodeRef); reconcileLogger.info("INDEXED: {} <=> {} in {}", nodeDbId, nodeRef, instance); syncHosts.add(instance); } @Override public void scheduled(ShardInstance instance) { reconcileLogger.info("INDEXING: {} <=> {}", nodeDbId, nodeRef); reconcileLogger.info("INDEXING: {} <=> {} in {}", nodeDbId, nodeRef, instance); asyncHosts.add(instance); } @Override public void error(ShardInstance instance, String message) { reconcileLogger.info("FAILED INDEX: {} <=> {}", nodeDbId, nodeRef); reconcileLogger.info("FAILED INDEX: {} <=> {} in {}", nodeDbId, nodeRef, instance); errorHosts.put(instance, message); } }; Loading Loading @@ -331,19 +331,19 @@ public class AcsReconcileService implements InitializingBean, DisposableBean { @Override public void success(ShardInstance instance) { reconcileLogger.info("REINDEXED: {} <=> {}", nodeDbId, nodeRef); reconcileLogger.info("REINDEXED: {} <=> {} in {}", nodeDbId, nodeRef, instance); syncHosts.add(instance); } @Override public void scheduled(ShardInstance instance) { reconcileLogger.info("REINDEXING: {} <=> {}", nodeDbId, nodeRef); reconcileLogger.info("REINDEXING: {} <=> {} in {}", nodeDbId, nodeRef, instance); asyncHosts.add(instance); } @Override public void error(ShardInstance instance, String message) { reconcileLogger.info("FAILED REINDEX: {} <=> {}", nodeDbId, nodeRef); reconcileLogger.info("FAILED REINDEX: {} <=> {} in {}", nodeDbId, nodeRef, instance); errorHosts.put(instance, message); } }; Loading Loading
enterprise-module/pom.xml +3 −0 Original line number Diff line number Diff line Loading @@ -69,6 +69,7 @@ <dependency> <groupId>jakarta.ws.rs</groupId> <artifactId>jakarta.ws.rs-api</artifactId> <version>4.0.0</version> <scope>provided</scope> </dependency> <dependency> Loading @@ -79,11 +80,13 @@ <dependency> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-jsr310</artifactId> <version>2.17.3</version> <scope>provided</scope> </dependency> <dependency> <groupId>com.fasterxml.jackson.module</groupId> <artifactId>jackson-module-jakarta-xmlbind-annotations</artifactId> <version>2.17.2</version> <scope>provided</scope> </dependency> Loading
shared/src/main/java/com/inteligr8/alfresco/asie/service/AbstractNodeActionService.java +51 −28 Original line number Diff line number Diff line Loading @@ -11,6 +11,7 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.regex.Matcher; import org.alfresco.model.ContentModel; import org.alfresco.repo.index.shard.Floc; Loading @@ -18,6 +19,8 @@ import org.alfresco.repo.index.shard.Shard; import org.alfresco.repo.index.shard.ShardInstance; import org.alfresco.repo.index.shard.ShardRegistry; import org.alfresco.repo.index.shard.ShardState; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.cmr.search.SearchParameters; import org.alfresco.service.cmr.search.SearchService; Loading Loading @@ -48,12 +51,18 @@ public abstract class AbstractNodeActionService { @Autowired private NamespaceService namespaceService; @Autowired private NodeService nodeService; @Autowired private ApiService apiService; @Autowired private ExecutorManager executorManager; @Autowired private SolrShardHashService shardHashService; @Autowired(required = false) @Qualifier(Constants.QUALIFIER_ASIE) private ShardRegistry shardRegistry; Loading Loading @@ -216,40 +225,54 @@ public abstract class AbstractNodeActionService { List<com.inteligr8.alfresco.asie.model.ShardInstance> instances = new LinkedList<>(); List<ShardInstance> slicedInstances = this.shardRegistry.getIndexSlice(searchParams); if (slicedInstances != null) { this.logger.trace("Due to a sharding method, considering only applicable shards and their ASIE nodes: {}: {}", nodeDbId, slicedInstances); // we need a ShardRegistry method like getIndexSlice, but // (1) works with shard methods other than explicit // (2) returns all possible instances/nodes, not just one node per instance for (ShardInstance instance : slicedInstances) instances.add(this.toModel(instance)); } else { for (Entry<Floc, Map<Shard, Set<ShardState>>> floc : this.shardRegistry.getFlocs().entrySet()) { if (!floc.getKey().getStoreRefs().contains(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE)) continue; Integer shardHash = null; ShardSet shardset = null; for (Entry<Shard, Set<ShardState>> shard : floc.getValue().entrySet()) { for (ShardState shardState : shard.getValue()) instances.add(this.toModel(shardState.getShardInstance(), shardState)); for (ShardState shardState : shard.getValue()) { // every shard and instance (state) in the FLOC is the same // but we need one ShardState to determine the full configuration // so we are computing the shardHash once and caching it if (shardset == null) { shardset = ShardSet.from(floc.getKey(), shardState); switch (shardset.getMethod()) { case PROPERTY: this.logger.trace("Using property-based sharding method; discovering target shard ..."); NodeRef nodeRef = this.nodeService.getNodeRef(nodeDbId); Object propValue = this.nodeService.getProperty(nodeRef, QName.createQName(shardset.getPrefixedProperty(), this.namespaceService)); if (propValue != null) { this.logger.trace("Discovered node property for sharding: {} <=> {} => {}", nodeDbId, nodeRef, propValue); Matcher matcher = shardset.getRegex().matcher(propValue.toString()); String hashable = matcher.group(1); this.logger.trace("Extracted shardable value from node: {} <=> {} => {}", nodeDbId, propValue, hashable); shardHash = this.shardHashService.hash(hashable, shardset.getShards().intValue()); this.logger.debug("Hash shardable value to shard instance ID: {} <=> {} => {}", nodeDbId, hashable, shardHash); } break; default: this.logger.trace("Despite sharding, considering all shards and nodes without optimization: {}: {}", nodeDbId, instances); } this.logger.trace("Despite sharding, considering all shards and nodes: {}: {}", nodeDbId, instances); } return instances; if (shardHash != null) { if (shard.getKey().getInstance() == shardHash) instances.add(this.toModel(shardState.getShardInstance(), shardState)); } else { instances.add(this.toModel(shardState.getShardInstance(), shardState)); } } } } private com.inteligr8.alfresco.asie.model.ShardInstance toModel(ShardInstance instance) { // get any random shardState Floc floc = instance.getShard().getFloc(); Map<Shard, Set<ShardState>> shardsStates = this.shardRegistry.getFlocs().get(floc); if (shardsStates == null) throw new IllegalStateException(); Set<ShardState> shardStates = shardsStates.get(instance.getShard()); if (shardStates == null || shardStates.isEmpty()) throw new IllegalStateException(); ShardState anyShardState = shardStates.iterator().next(); return this.toModel(instance, anyShardState); return instances; } private com.inteligr8.alfresco.asie.model.ShardInstance toModel(ShardInstance instance, ShardState anyShardState) { Loading
shared/src/main/java/com/inteligr8/alfresco/asie/service/AcsReconcileService.java +6 −6 Original line number Diff line number Diff line Loading @@ -289,19 +289,19 @@ public class AcsReconcileService implements InitializingBean, DisposableBean { @Override public void success(ShardInstance instance) { reconcileLogger.info("INDEXED: {} <=> {}", nodeDbId, nodeRef); reconcileLogger.info("INDEXED: {} <=> {} in {}", nodeDbId, nodeRef, instance); syncHosts.add(instance); } @Override public void scheduled(ShardInstance instance) { reconcileLogger.info("INDEXING: {} <=> {}", nodeDbId, nodeRef); reconcileLogger.info("INDEXING: {} <=> {} in {}", nodeDbId, nodeRef, instance); asyncHosts.add(instance); } @Override public void error(ShardInstance instance, String message) { reconcileLogger.info("FAILED INDEX: {} <=> {}", nodeDbId, nodeRef); reconcileLogger.info("FAILED INDEX: {} <=> {} in {}", nodeDbId, nodeRef, instance); errorHosts.put(instance, message); } }; Loading Loading @@ -331,19 +331,19 @@ public class AcsReconcileService implements InitializingBean, DisposableBean { @Override public void success(ShardInstance instance) { reconcileLogger.info("REINDEXED: {} <=> {}", nodeDbId, nodeRef); reconcileLogger.info("REINDEXED: {} <=> {} in {}", nodeDbId, nodeRef, instance); syncHosts.add(instance); } @Override public void scheduled(ShardInstance instance) { reconcileLogger.info("REINDEXING: {} <=> {}", nodeDbId, nodeRef); reconcileLogger.info("REINDEXING: {} <=> {} in {}", nodeDbId, nodeRef, instance); asyncHosts.add(instance); } @Override public void error(ShardInstance instance, String message) { reconcileLogger.info("FAILED REINDEX: {} <=> {}", nodeDbId, nodeRef); reconcileLogger.info("FAILED REINDEX: {} <=> {} in {}", nodeDbId, nodeRef, instance); errorHosts.put(instance, message); } }; Loading