From 3e544c125bad79fd25dd9b741b5616ada998abb3 Mon Sep 17 00:00:00 2001 From: "Brian M. Long" Date: Thu, 31 Oct 2024 14:55:42 -0400 Subject: [PATCH] initial community-module (incomplete/breaking) --- community-module/.gitignore | 12 + community-module/README.md | 1 + community-module/pom.xml | 86 +++++ community-module/rad.ps1 | 74 ++++ community-module/rad.sh | 71 ++++ .../asie/provider/ShardRegistryProvider.java | 28 ++ .../asie/service/ShardStateService.java | 80 ++++ .../asie/service/SolrShardRegistry.java | 363 ++++++++++++++++++ .../alfresco-global.properties | 28 ++ .../log4j2.properties | 3 + .../module-context.xml | 18 + .../module.properties | 10 + pom.xml | 1 + 13 files changed, 775 insertions(+) create mode 100644 community-module/.gitignore create mode 100644 community-module/README.md create mode 100644 community-module/pom.xml create mode 100644 community-module/rad.ps1 create mode 100644 community-module/rad.sh create mode 100644 community-module/src/main/java/com/inteligr8/alfresco/asie/provider/ShardRegistryProvider.java create mode 100644 community-module/src/main/java/com/inteligr8/alfresco/asie/service/ShardStateService.java create mode 100644 community-module/src/main/java/com/inteligr8/alfresco/asie/service/SolrShardRegistry.java create mode 100644 community-module/src/main/resources/alfresco/module/com_inteligr8_alfresco_asie-community-platform-module/alfresco-global.properties create mode 100644 community-module/src/main/resources/alfresco/module/com_inteligr8_alfresco_asie-community-platform-module/log4j2.properties create mode 100644 community-module/src/main/resources/alfresco/module/com_inteligr8_alfresco_asie-community-platform-module/module-context.xml create mode 100644 community-module/src/main/resources/alfresco/module/com_inteligr8_alfresco_asie-community-platform-module/module.properties diff --git a/community-module/.gitignore b/community-module/.gitignore new file mode 100644 index 0000000..e59065e --- /dev/null +++ b/community-module/.gitignore @@ -0,0 +1,12 @@ +# Maven +target +pom.xml.versionsBackup + +# Eclipse +.project +.classpath +.settings +.vscode + +# IDEA +/.idea/ diff --git a/community-module/README.md b/community-module/README.md new file mode 100644 index 0000000..1aa10d1 --- /dev/null +++ b/community-module/README.md @@ -0,0 +1 @@ +# ASIE Platform Module Library diff --git a/community-module/pom.xml b/community-module/pom.xml new file mode 100644 index 0000000..25fdbab --- /dev/null +++ b/community-module/pom.xml @@ -0,0 +1,86 @@ + + 4.0.0 + + + com.inteligr8.alfresco + asie-platform-module-parent + 1.0-SNAPSHOT + ../ + + + asie-community-platform-module + jar + + ASIE Platform Module for ACS Community + + + 5.2.0 + 23.3.0 + + + + + + org.alfresco + acs-community-packaging + ${alfresco.platform.version} + pom + import + + + + + + + com.inteligr8.alfresco + asie-shared + ${project.version} + provided + + + + + org.alfresco + alfresco-repository + provided + + + + + junit + junit + test + + + org.mockito + mockito-core + test + + + + + + + io.repaint.maven + tiles-maven-plugin + 2.40 + true + + + + com.inteligr8.ootbee:beedk-acs-platform-module-tile:[1.1.6,2.0.0) + + + + + + + + + alfresco-public + https://artifacts.alfresco.com/nexus/content/groups/public + + + diff --git a/community-module/rad.ps1 b/community-module/rad.ps1 new file mode 100644 index 0000000..61bcb2f --- /dev/null +++ b/community-module/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/community-module/rad.sh b/community-module/rad.sh new file mode 100644 index 0000000..7cb0a80 --- /dev/null +++ b/community-module/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/community-module/src/main/java/com/inteligr8/alfresco/asie/provider/ShardRegistryProvider.java b/community-module/src/main/java/com/inteligr8/alfresco/asie/provider/ShardRegistryProvider.java new file mode 100644 index 0000000..5355d0f --- /dev/null +++ b/community-module/src/main/java/com/inteligr8/alfresco/asie/provider/ShardRegistryProvider.java @@ -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 { + + /** + * 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); + } + +} diff --git a/community-module/src/main/java/com/inteligr8/alfresco/asie/service/ShardStateService.java b/community-module/src/main/java/com/inteligr8/alfresco/asie/service/ShardStateService.java new file mode 100644 index 0000000..c93c5ef --- /dev/null +++ b/community-module/src/main/java/com/inteligr8/alfresco/asie/service/ShardStateService.java @@ -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 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); + } + +} diff --git a/community-module/src/main/java/com/inteligr8/alfresco/asie/service/SolrShardRegistry.java b/community-module/src/main/java/com/inteligr8/alfresco/asie/service/SolrShardRegistry.java new file mode 100644 index 0000000..9a96726 --- /dev/null +++ b/community-module/src/main/java/com/inteligr8/alfresco/asie/service/SolrShardRegistry.java @@ -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 onlineShardCache; + + @Autowired + @Qualifier(Constants.BEAN_OFFILINE_SHARD_STATE_CACHE) + private SimpleCache offlineShardCache; + + @Autowired + @Qualifier(Constants.BEAN_CORE_EXPLICIT_CACHE) + private SimpleCache coreExplicitIdCache; + + @Autowired + @Qualifier(Constants.BEAN_FLOC_CACHE) + private SimpleCache 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 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 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>> getFlocs() { + Map>> flocs = new HashMap<>(); + + for (ShardInstance shardNode : this.onlineShardCache.getKeys()) { + Floc floc = shardNode.getShard().getFloc(); + + Map> shards = flocs.get(floc); + if (shards == null) + flocs.put(floc, shards = new HashMap<>()); + + Set 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 getShardInstanceList(String coreName) { + Set 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 getIndexSlice(SearchParameters searchParameters) { + for (Floc floc : this.flocCache.getKeys()) { + Set 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; + + } + +} diff --git a/community-module/src/main/resources/alfresco/module/com_inteligr8_alfresco_asie-community-platform-module/alfresco-global.properties b/community-module/src/main/resources/alfresco/module/com_inteligr8_alfresco_asie-community-platform-module/alfresco-global.properties new file mode 100644 index 0000000..ef89240 --- /dev/null +++ b/community-module/src/main/resources/alfresco/module/com_inteligr8_alfresco_asie-community-platform-module/alfresco-global.properties @@ -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 diff --git a/community-module/src/main/resources/alfresco/module/com_inteligr8_alfresco_asie-community-platform-module/log4j2.properties b/community-module/src/main/resources/alfresco/module/com_inteligr8_alfresco_asie-community-platform-module/log4j2.properties new file mode 100644 index 0000000..6c345f1 --- /dev/null +++ b/community-module/src/main/resources/alfresco/module/com_inteligr8_alfresco_asie-community-platform-module/log4j2.properties @@ -0,0 +1,3 @@ + +logger.inteligr8-asie.name=com.inteligr8.alfresco.asie +logger.inteligr8-asie.level=INFO diff --git a/community-module/src/main/resources/alfresco/module/com_inteligr8_alfresco_asie-community-platform-module/module-context.xml b/community-module/src/main/resources/alfresco/module/com_inteligr8_alfresco_asie-community-platform-module/module-context.xml new file mode 100644 index 0000000..0eebd98 --- /dev/null +++ b/community-module/src/main/resources/alfresco/module/com_inteligr8_alfresco_asie-community-platform-module/module-context.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + diff --git a/community-module/src/main/resources/alfresco/module/com_inteligr8_alfresco_asie-community-platform-module/module.properties b/community-module/src/main/resources/alfresco/module/com_inteligr8_alfresco_asie-community-platform-module/module.properties new file mode 100644 index 0000000..2d638d2 --- /dev/null +++ b/community-module/src/main/resources/alfresco/module/com_inteligr8_alfresco_asie-community-platform-module/module.properties @@ -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=* diff --git a/pom.xml b/pom.xml index 0fb6d55..6ccf9b6 100644 --- a/pom.xml +++ b/pom.xml @@ -72,6 +72,7 @@ asie-api shared enterprise-module + community-module