initial community-module (incomplete/breaking)
This commit is contained in:
12
community-module/.gitignore
vendored
Normal file
12
community-module/.gitignore
vendored
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
# Maven
|
||||||
|
target
|
||||||
|
pom.xml.versionsBackup
|
||||||
|
|
||||||
|
# Eclipse
|
||||||
|
.project
|
||||||
|
.classpath
|
||||||
|
.settings
|
||||||
|
.vscode
|
||||||
|
|
||||||
|
# IDEA
|
||||||
|
/.idea/
|
1
community-module/README.md
Normal file
1
community-module/README.md
Normal file
@@ -0,0 +1 @@
|
|||||||
|
# ASIE Platform Module Library
|
86
community-module/pom.xml
Normal file
86
community-module/pom.xml
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>com.inteligr8.alfresco</groupId>
|
||||||
|
<artifactId>asie-platform-module-parent</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<relativePath>../</relativePath>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>asie-community-platform-module</artifactId>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>ASIE Platform Module for ACS Community</name>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<alfresco.sdk.version>5.2.0</alfresco.sdk.version>
|
||||||
|
<alfresco.platform.version>23.3.0</alfresco.platform.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencyManagement>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.alfresco</groupId>
|
||||||
|
<artifactId>acs-community-packaging</artifactId>
|
||||||
|
<version>${alfresco.platform.version}</version>
|
||||||
|
<type>pom</type>
|
||||||
|
<scope>import</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</dependencyManagement>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.inteligr8.alfresco</groupId>
|
||||||
|
<artifactId>asie-shared</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Needed by this module, but provided by ACS -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.alfresco</groupId>
|
||||||
|
<artifactId>alfresco-repository</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Including for testing purposes only -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mockito</groupId>
|
||||||
|
<artifactId>mockito-core</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>io.repaint.maven</groupId>
|
||||||
|
<artifactId>tiles-maven-plugin</artifactId>
|
||||||
|
<version>2.40</version>
|
||||||
|
<extensions>true</extensions>
|
||||||
|
<configuration>
|
||||||
|
<tiles>
|
||||||
|
<!-- Documentation: https://bitbucket.org/inteligr8/ootbee-beedk/src/stable/beedk-acs-platform-module-tile -->
|
||||||
|
<tile>com.inteligr8.ootbee:beedk-acs-platform-module-tile:[1.1.6,2.0.0)</tile>
|
||||||
|
</tiles>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>alfresco-public</id>
|
||||||
|
<url>https://artifacts.alfresco.com/nexus/content/groups/public</url>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
</project>
|
74
community-module/rad.ps1
Normal file
74
community-module/rad.ps1
Normal file
@@ -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!"
|
||||||
|
|
71
community-module/rad.sh
Normal file
71
community-module/rad.sh
Normal file
@@ -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!"
|
||||||
|
|
@@ -0,0 +1,28 @@
|
|||||||
|
package com.inteligr8.alfresco.asie.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;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class ShardRegistryProvider extends AbstractProvider<ShardRegistry> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.getPrimary(ShardRegistry.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,80 @@
|
|||||||
|
package com.inteligr8.alfresco.asie.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<ShardInstance, ShardState> shardStateCache;
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,363 @@
|
|||||||
|
package com.inteligr8.alfresco.asie.service;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.OptionalInt;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import org.alfresco.repo.cache.SimpleCache;
|
||||||
|
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.ShardRegistry;
|
||||||
|
import org.alfresco.repo.index.shard.ShardState;
|
||||||
|
import org.alfresco.repo.search.impl.QueryParserUtils;
|
||||||
|
import org.alfresco.repo.search.impl.parsers.AlfrescoFunctionEvaluationContext;
|
||||||
|
import org.alfresco.repo.search.impl.parsers.CMISLexer;
|
||||||
|
import org.alfresco.repo.search.impl.parsers.FTSLexer;
|
||||||
|
import org.alfresco.repo.search.impl.parsers.FTSParser;
|
||||||
|
import org.alfresco.repo.search.impl.parsers.FTSQueryParser;
|
||||||
|
import org.alfresco.repo.search.impl.querymodel.Conjunction;
|
||||||
|
import org.alfresco.repo.search.impl.querymodel.Constraint;
|
||||||
|
import org.alfresco.repo.search.impl.querymodel.Disjunction;
|
||||||
|
import org.alfresco.repo.search.impl.querymodel.FunctionalConstraint;
|
||||||
|
import org.alfresco.repo.search.impl.querymodel.QueryEngine;
|
||||||
|
import org.alfresco.repo.search.impl.querymodel.QueryModelFactory;
|
||||||
|
import org.alfresco.repo.search.impl.querymodel.QueryOptions;
|
||||||
|
import org.alfresco.repo.search.impl.querymodel.QueryOptions.Connective;
|
||||||
|
import org.alfresco.repo.search.impl.querymodel.impl.BaseConstraint;
|
||||||
|
import org.alfresco.repo.search.impl.querymodel.impl.lucene.LuceneQueryBuilderComponent;
|
||||||
|
import org.alfresco.service.cmr.attributes.AttributeService;
|
||||||
|
import org.alfresco.service.cmr.attributes.AttributeService.AttributeQueryCallback;
|
||||||
|
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||||
|
import org.alfresco.service.cmr.search.SearchParameters;
|
||||||
|
import org.alfresco.service.cmr.search.SearchParameters.Operator;
|
||||||
|
import org.alfresco.service.cmr.search.SearchService;
|
||||||
|
import org.alfresco.service.namespace.NamespaceService;
|
||||||
|
import org.alfresco.service.namespace.QName;
|
||||||
|
import org.antlr.runtime.ANTLRStringStream;
|
||||||
|
import org.antlr.runtime.CharStream;
|
||||||
|
import org.antlr.runtime.CommonTokenStream;
|
||||||
|
import org.antlr.runtime.tree.CommonTree;
|
||||||
|
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.model.Node;
|
||||||
|
import com.inteligr8.alfresco.asie.model.ShardSet;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class SolrShardRegistry extends AbstractLifecycleBean implements ShardRegistry {
|
||||||
|
|
||||||
|
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||||
|
private final Pattern coreShardPattern = Pattern.compile("(.+)-[0-9]+");
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ShardStateService sss;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
@Qualifier(Constants.QUALIFIER_ASIE)
|
||||||
|
private AttributeService attrService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private NamespaceService namespaceService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
@Qualifier(Constants.BEAN_SHARD_STATE_CACHE)
|
||||||
|
private SimpleCache<ShardInstance, ShardState> onlineShardCache;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
@Qualifier(Constants.BEAN_OFFILINE_SHARD_STATE_CACHE)
|
||||||
|
private SimpleCache<ShardInstance, ShardState> offlineShardCache;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
@Qualifier(Constants.BEAN_CORE_EXPLICIT_CACHE)
|
||||||
|
private SimpleCache<String, QName> coreExplicitIdCache;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
@Qualifier(Constants.BEAN_FLOC_CACHE)
|
||||||
|
private SimpleCache<Floc, Boolean> flocCache;
|
||||||
|
|
||||||
|
@Value("${inteligr8.asie.registerUnknownShardOffline}")
|
||||||
|
private boolean registerOffline;
|
||||||
|
|
||||||
|
@Value("${inteligr8.asie.offlineIdleShardInSeconds}")
|
||||||
|
private int offlineIdleShardInSeconds;
|
||||||
|
|
||||||
|
@Value("${inteligr8.asie.forgetOfflineShardInSeconds}")
|
||||||
|
private int forgetOfflineShardInSeconds;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onBootstrap(ApplicationEvent event) {
|
||||||
|
this.attrService.getAttributes(new AttributeQueryCallback() {
|
||||||
|
@Override
|
||||||
|
public boolean handleAttribute(Long id, Serializable value, Serializable[] keys) {
|
||||||
|
switch ((String) keys[2]) {
|
||||||
|
case Constants.ATTR_STATE:
|
||||||
|
ShardState shardNodeState = (ShardState) value;
|
||||||
|
ShardInstance shardNode = shardNodeState.getShardInstance();
|
||||||
|
cacheShard(shardNode, shardNodeState, (String) keys[1]);
|
||||||
|
|
||||||
|
if (ShardMethodEnum.EXPLICIT_ID.toString().equals(shardNodeState.getPropertyBag().get("shard.method"))) {
|
||||||
|
String coreName = shardNode.getShard().getFloc().getPropertyBag().get("coreName");
|
||||||
|
if (coreName != null && !coreExplicitIdCache.contains(coreName)) {
|
||||||
|
String property = shardNodeState.getPropertyBag().get("shard.key");
|
||||||
|
QName propertyQname = QName.createQName(property, namespaceService);
|
||||||
|
|
||||||
|
logger.debug("Mapping core to explicit ID: {} => {}", coreName, propertyQname);
|
||||||
|
coreExplicitIdCache.put(coreName, propertyQname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, Constants.ATTR_ASIE_NODES);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onShutdown(ApplicationEvent event) {
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void cacheShard(ShardInstance shardNode, ShardState shardNodeState, String nodeId) {
|
||||||
|
SimpleCache<ShardInstance, ShardState> shardCache = this.onlineShardCache;
|
||||||
|
ShardState cachedShardNodeState = this.onlineShardCache.get(shardNode);
|
||||||
|
if (cachedShardNodeState == null) {
|
||||||
|
cachedShardNodeState = this.offlineShardCache.get(shardNode);
|
||||||
|
shardCache = this.offlineShardCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cachedShardNodeState == null) {
|
||||||
|
Boolean online = (Boolean) this.attrService.getAttribute(Constants.ATTR_ASIE_NODES, nodeId, Constants.ATTR_ONLINE);
|
||||||
|
if (online != null) {
|
||||||
|
if (online.booleanValue()) {
|
||||||
|
this.onlineShardCache.put(shardNode, cachedShardNodeState);
|
||||||
|
} else {
|
||||||
|
this.offlineShardCache.put(shardNode, cachedShardNodeState);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (this.registerOffline) {
|
||||||
|
this.offlineShardCache.put(shardNode, cachedShardNodeState);
|
||||||
|
} else {
|
||||||
|
this.onlineShardCache.put(shardNode, cachedShardNodeState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (cachedShardNodeState.getLastIndexedTxId() < shardNodeState.getLastIndexedTxId()) {
|
||||||
|
shardCache.put(shardNode, shardNodeState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void fixFlocPropertyBag(ShardState shardNodeState) {
|
||||||
|
Floc floc = shardNodeState.getShardInstance().getShard().getFloc();
|
||||||
|
if (floc.getPropertyBag().isEmpty()) {
|
||||||
|
for (Entry<String, String> prop : shardNodeState.getPropertyBag().entrySet()) {
|
||||||
|
if (prop.getKey().startsWith("shard.")) {
|
||||||
|
floc.getPropertyBag().put(prop.getKey(), prop.getValue());
|
||||||
|
} else if (prop.getKey().equals("coreName")) {
|
||||||
|
String coreName = this.extractCoreName(prop.getValue());
|
||||||
|
if (coreName != null)
|
||||||
|
floc.getPropertyBag().put(prop.getKey(), coreName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String extractCoreName(String coreShardName) {
|
||||||
|
Matcher matcher = coreShardPattern.matcher(coreShardName);
|
||||||
|
if (!matcher.matches())
|
||||||
|
return null;
|
||||||
|
return matcher.group(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void registerShardState(ShardState shardNodeState) {
|
||||||
|
ShardInstance shardNode = shardNodeState.getShardInstance();
|
||||||
|
Node node = new Node(shardNode);
|
||||||
|
this.fixFlocPropertyBag(shardNodeState);
|
||||||
|
this.cacheShard(shardNode, shardNodeState, node.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<Floc, Map<Shard, Set<ShardState>>> getFlocs() {
|
||||||
|
Map<Floc, Map<Shard, Set<ShardState>>> flocs = new HashMap<>();
|
||||||
|
|
||||||
|
for (ShardInstance shardNode : this.onlineShardCache.getKeys()) {
|
||||||
|
Floc floc = shardNode.getShard().getFloc();
|
||||||
|
|
||||||
|
Map<Shard, Set<ShardState>> shards = flocs.get(floc);
|
||||||
|
if (shards == null)
|
||||||
|
flocs.put(floc, shards = new HashMap<>());
|
||||||
|
|
||||||
|
Set<ShardState> shardNodeStates = shards.get(shardNode.getShard());
|
||||||
|
if (shardNodeStates == null)
|
||||||
|
shards.put(shardNode.getShard(), shardNodeStates = new HashSet<>());
|
||||||
|
|
||||||
|
ShardState shardNodeState = this.onlineShardCache.get(shardNode);
|
||||||
|
if (shardNodeState != null) // in case it was removed during the looping (very rare)
|
||||||
|
shardNodeStates.add(shardNodeState);
|
||||||
|
}
|
||||||
|
|
||||||
|
return flocs;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void purge() {
|
||||||
|
this.sss.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void purgeAgedOutShards() {
|
||||||
|
long onlineExpired = System.currentTimeMillis() - this.offlineIdleShardInSeconds * 1000L;
|
||||||
|
long offlineExpired = System.currentTimeMillis() - this.forgetOfflineShardInSeconds * 1000L;
|
||||||
|
|
||||||
|
for (ShardInstance shardNode : this.onlineShardCache.getKeys()) {
|
||||||
|
ShardState shardNodeState = this.onlineShardCache.get(shardNode);
|
||||||
|
if (shardNodeState.getLastUpdated() < onlineExpired) {
|
||||||
|
this.logger.warn("Taking shard offline: {}", shardNode);
|
||||||
|
this.onlineShardCache.remove(shardNode);
|
||||||
|
this.offlineShardCache.put(shardNode, shardNodeState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (ShardInstance shardNode : this.offlineShardCache.getKeys()) {
|
||||||
|
ShardState shardNodeState = this.offlineShardCache.get(shardNode);
|
||||||
|
if (shardNodeState.getLastUpdated() < offlineExpired) {
|
||||||
|
this.logger.info("Forgetting about already offline shard: {}", shardNode);
|
||||||
|
this.offlineShardCache.remove(shardNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public QName getExplicitIdProperty(String coreName) {
|
||||||
|
return this.coreExplicitIdCache.get(coreName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<Integer> getShardInstanceList(String coreName) {
|
||||||
|
Set<Integer> shardIds = new HashSet<>();
|
||||||
|
|
||||||
|
for (ShardInstance shardNode : this.onlineShardCache.getKeys()) {
|
||||||
|
shardIds.add(shardNode.getShard().getInstance());
|
||||||
|
}
|
||||||
|
|
||||||
|
return shardIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OptionalInt getShardInstanceByTransactionTimestamp(String coreId, long txnTimestamp) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ShardInstance> getIndexSlice(SearchParameters searchParameters) {
|
||||||
|
for (Floc floc : this.flocCache.getKeys()) {
|
||||||
|
Set<Integer> shardIds = new HashSet<>();
|
||||||
|
|
||||||
|
switch (floc.getShardMethod()) {
|
||||||
|
case EXPLICIT_ID:
|
||||||
|
String property = floc.getPropertyBag().get("shard.key");
|
||||||
|
// check filters and other parameters
|
||||||
|
if (searchParameters.getQuery() != null) {
|
||||||
|
SearchTerm term = this.extractPropertySearchTeam(searchParameters, property);
|
||||||
|
if (term != null && term.operator.equals("=")) {
|
||||||
|
try {
|
||||||
|
shardIds.add(Integer.parseInt(term.value));
|
||||||
|
} catch (NumberFormatException nfe) {
|
||||||
|
// skip
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
searchParameters.get
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private SearchTerm extractPropertySearchTeam(SearchParameters searchParameters, String property) {
|
||||||
|
switch (searchParameters.getLanguage()) {
|
||||||
|
case SearchService.LANGUAGE_CMIS_ALFRESCO:
|
||||||
|
case SearchService.LANGUAGE_CMIS_STRICT:
|
||||||
|
case SearchService.LANGUAGE_INDEX_CMIS:
|
||||||
|
case SearchService.LANGUAGE_SOLR_CMIS:
|
||||||
|
return this.extractCmisPropertySearchTerm(searchParameters, property, "=");
|
||||||
|
case SearchService.LANGUAGE_FTS_ALFRESCO:
|
||||||
|
case SearchService.LANGUAGE_INDEX_ALFRESCO:
|
||||||
|
case SearchService.LANGUAGE_INDEX_FTS_ALFRESCO:
|
||||||
|
case SearchService.LANGUAGE_LUCENE:
|
||||||
|
case SearchService.LANGUAGE_SOLR_ALFRESCO:
|
||||||
|
case SearchService.LANGUAGE_SOLR_FTS_ALFRESCO:
|
||||||
|
return this.extractFtsPropertySearchTerm(searchParameters, "=@" + property);
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private QueryEngine queryEngine;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DictionaryService dictionaryService;
|
||||||
|
|
||||||
|
private SearchTerm extractFtsPropertySearchTerm(SearchParameters searchParameters, String field) {
|
||||||
|
// TODO include filter and other possible constraints
|
||||||
|
|
||||||
|
if (searchParameters.getQuery() == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
CharStream cs = new ANTLRStringStream(searchParameters.getQuery());
|
||||||
|
FTSLexer lexer = new FTSLexer(cs);
|
||||||
|
CommonTokenStream tokens = new CommonTokenStream(lexer);
|
||||||
|
FTSParser parser = new FTSParser(tokens);
|
||||||
|
parser.setDefaultFieldConjunction(searchParameters.getDefaultFTSOperator().equals(Operator.AND));
|
||||||
|
parser.setMode(searchParameters.getDefaultFTSOperator().equals(Operator.AND) ? FTSParser.Mode.DEFAULT_CONJUNCTION : FTSParser.Mode.DEFAULT_DISJUNCTION);
|
||||||
|
CommonTree ftsNode = (CommonTree) parser.ftsQuery().getTree();
|
||||||
|
}
|
||||||
|
|
||||||
|
private SearchTerm extractCmisPropertySearchTerm(SearchParameters searchParameters, String field, String operator) {
|
||||||
|
// TODO include filter and other possible constraints
|
||||||
|
|
||||||
|
if (searchParameters.getQuery() == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
CharStream cs = new ANTLRStringStream(searchParameters.getQuery());
|
||||||
|
CMISLexer lexer = new CMISLexer();
|
||||||
|
CommonTokenStream tokens = new CommonTokenStream(lexer);
|
||||||
|
FTSParser parser = new FTSParser(tokens);
|
||||||
|
parser.setDefaultFieldConjunction(searchParameters.getDefaultFTSOperator().equals(Operator.AND));
|
||||||
|
parser.setMode(searchParameters.getDefaultFTSOperator().equals(Operator.AND) ? FTSParser.Mode.DEFAULT_CONJUNCTION : FTSParser.Mode.DEFAULT_DISJUNCTION);
|
||||||
|
CommonTree ftsNode = (CommonTree) parser.ftsQuery().getTree();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private class SearchTerm {
|
||||||
|
|
||||||
|
private String field;
|
||||||
|
private String operator;
|
||||||
|
private String value;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,28 @@
|
|||||||
|
|
||||||
|
inteligr8.asie.registerUnknownShardOffline=false
|
||||||
|
inteligr8.asie.idleShardExpirationInSeconds=${}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# maxItems needs to be greater than total shards, including HA instances
|
||||||
|
cache.offlineShardStateSharedCache.tx.maxItems=1024
|
||||||
|
cache.offlineShardStateSharedCache.tx.statsEnabled=${caches.tx.statsEnabled}
|
||||||
|
cache.offlineShardStateSharedCache.maxItems=1024
|
||||||
|
cache.offlineShardStateSharedCache.timeToLiveSeconds=1800
|
||||||
|
cache.offlineShardStateSharedCache.maxIdleSeconds=0
|
||||||
|
cache.offlineShardStateSharedCache.cluster.type=fully-distributed
|
||||||
|
cache.offlineShardStateSharedCache.backup-count=1
|
||||||
|
cache.offlineShardStateSharedCache.eviction-policy=LRU
|
||||||
|
cache.offlineShardStateSharedCache.merge-policy=com.hazelcast.spi.merge.PutIfAbsentMergePolicy
|
||||||
|
cache.offlineShardStateSharedCache.readBackupData=false
|
||||||
|
|
||||||
|
cache.coreExplicitIdSharedCache.tx.maxItems=1024
|
||||||
|
cache.coreExplicitIdSharedCache.tx.statsEnabled=${caches.tx.statsEnabled}
|
||||||
|
cache.coreExplicitIdSharedCache.maxItems=1024
|
||||||
|
cache.coreExplicitIdSharedCache.timeToLiveSeconds=1800
|
||||||
|
cache.coreExplicitIdSharedCache.maxIdleSeconds=0
|
||||||
|
cache.coreExplicitIdSharedCache.cluster.type=fully-distributed
|
||||||
|
cache.coreExplicitIdSharedCache.backup-count=1
|
||||||
|
cache.coreExplicitIdSharedCache.eviction-policy=LRU
|
||||||
|
cache.coreExplicitIdSharedCache.merge-policy=com.hazelcast.spi.merge.PutIfAbsentMergePolicy
|
||||||
|
cache.coreExplicitIdSharedCache.readBackupData=false
|
@@ -0,0 +1,3 @@
|
|||||||
|
|
||||||
|
logger.inteligr8-asie.name=com.inteligr8.alfresco.asie
|
||||||
|
logger.inteligr8-asie.level=INFO
|
@@ -0,0 +1,18 @@
|
|||||||
|
<?xml version='1.0' encoding='UTF-8'?>
|
||||||
|
|
||||||
|
<!-- Use this file for beans to be loaded in whatever order Alfresco/Spring decides -->
|
||||||
|
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
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">
|
||||||
|
|
||||||
|
<bean name="offlineShardStateCache" factory-bean="cacheFactory" factory-method="createCache">
|
||||||
|
<constructor-arg value="cache.offlineShardStateSharedCache" />
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean name="coreExplicitIdCache" factory-bean="cacheFactory" factory-method="createCache">
|
||||||
|
<constructor-arg value="cache.coreExplicitIdSharedCache" />
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
</beans>
|
@@ -0,0 +1,10 @@
|
|||||||
|
module.id=com_inteligr8_alfresco_${project.artifactId}
|
||||||
|
module.aliases=
|
||||||
|
module.title=${project.name}
|
||||||
|
module.description=${project.description}
|
||||||
|
module.version=${module.version}
|
||||||
|
|
||||||
|
module.repo.version.min=23.0
|
||||||
|
|
||||||
|
# this is creating all sorts of problems; probably because of the non-standard versioning
|
||||||
|
module.depends.com.inteligr8.alfresco.cxf-jaxrs-platform-module=*
|
Reference in New Issue
Block a user