Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ab10938911 | ||
|
|
3212c47967 | ||
|
|
ff068d8d3f | ||
|
|
354ea3f337 | ||
|
|
b737bccd1c | ||
|
|
ed97efb4ed | ||
|
|
b6bae65e03 | ||
|
|
fe95ff6239 | ||
|
|
a1144fcad4 | ||
|
|
299be529ba | ||
|
|
ff331cac48 | ||
|
|
d86c96fcb1 | ||
|
|
933a786038 | ||
|
|
bb183c5e50 | ||
|
|
f909f3429b | ||
|
|
fe2eaa0588 | ||
|
|
68471be9ef | ||
|
|
82410805db | ||
|
|
ceb8d2c690 | ||
|
|
1c15853652 | ||
|
|
cf1bc8d2be | ||
|
|
a49ddbd373 | ||
|
|
738e5b98f8 | ||
|
|
9d9d17c49b | ||
|
|
43109e7d9c | ||
|
|
dcb37c3dc8 | ||
|
|
68ffb56cc9 | ||
|
|
dc436e9ce0 | ||
|
|
18c39b0fc5 | ||
|
|
b7aa615103 | ||
|
|
e8f133b873 |
+23
-24
@@ -6,16 +6,21 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.inteligr8.alfresco</groupId>
|
<groupId>com.inteligr8.alfresco</groupId>
|
||||||
<artifactId>asie-platform-module-parent</artifactId>
|
<artifactId>asie-platform-module-parent</artifactId>
|
||||||
<version>1.3-SNAPSHOT</version>
|
<version>1.3.4</version>
|
||||||
<relativePath>../</relativePath>
|
<relativePath>../</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
<groupId>com.inteligr8.alfresco</groupId>
|
||||||
<artifactId>asie-api</artifactId>
|
<artifactId>asie-api</artifactId>
|
||||||
<version>1.2-SNAPSHOT-asie2</version>
|
<version>1.1.1-asie2</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>ASIE Jakarta RS API</name>
|
<name>ASIE Jakarta RS API</name>
|
||||||
<description>Alfresco Search & Insight Engine Jakarta RS API</description>
|
<description>Alfresco Search & Insight Engine Jakarta RS API</description>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<alfresco.platform.version>23.2.0</alfresco.platform.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
<dependencyManagement>
|
<dependencyManagement>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
@@ -33,11 +38,22 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.inteligr8</groupId>
|
<groupId>com.inteligr8</groupId>
|
||||||
<artifactId>solr-api</artifactId>
|
<artifactId>solr-api</artifactId>
|
||||||
<version>1.2-SNAPSHOT-solr6</version>
|
<version>1.1.0-solr6</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-data-model</artifactId>
|
<artifactId>alfresco-data-model</artifactId>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>*</groupId>
|
||||||
|
<artifactId>*</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-lang3</artifactId>
|
||||||
|
<version>3.17.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.logging.log4j</groupId>
|
<groupId>org.apache.logging.log4j</groupId>
|
||||||
@@ -47,44 +63,27 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.inteligr8</groupId>
|
<groupId>com.inteligr8</groupId>
|
||||||
<artifactId>common-rest-client</artifactId>
|
<artifactId>common-rest-client</artifactId>
|
||||||
<version>${commom-rest-client.base.version}-jersey</version>
|
<version>3.0.2-jersey</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.glassfish.jersey.inject</groupId>
|
<groupId>org.glassfish.jersey.inject</groupId>
|
||||||
<artifactId>jersey-hk2</artifactId>
|
<artifactId>jersey-hk2</artifactId>
|
||||||
<version>4.0.2</version>
|
<version>3.1.10</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.junit.jupiter</groupId>
|
<groupId>org.junit.jupiter</groupId>
|
||||||
<artifactId>junit-jupiter-api</artifactId>
|
<artifactId>junit-jupiter-api</artifactId>
|
||||||
|
<version>5.11.2</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<groupId>io.repaint.maven</groupId>
|
|
||||||
<artifactId>tiles-maven-plugin</artifactId>
|
|
||||||
<extensions>true</extensions>
|
|
||||||
<configuration>
|
|
||||||
<tiles>
|
|
||||||
<!-- Documentation: https://git.inteligr8.com/inteligr8/ootbee-beedk/src/stable/beedk-acs-platform-webapp-tile -->
|
|
||||||
<!-- TODO spin up just ASIE
|
|
||||||
<tile>com.inteligr8.ootbee:beedk-acs-platform-webapp-tile:[1.1.6,2.0.0)</tile>
|
|
||||||
-->
|
|
||||||
</tiles>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
|
|
||||||
<repositories>
|
<repositories>
|
||||||
<repository>
|
<repository>
|
||||||
<id>alfresco-public</id>
|
<id>alfresco-public</id>
|
||||||
<url>https://artifacts.alfresco.com/nexus/repository/releases/</url>
|
<url>https://artifacts.alfresco.com/nexus/repository/public/</url>
|
||||||
</repository>
|
</repository>
|
||||||
</repositories>
|
</repositories>
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ public class IndexRequest extends JsonFormattedResponseRequest<IndexRequest> {
|
|||||||
@QueryParam("acltxid")
|
@QueryParam("acltxid")
|
||||||
private Long aclTransactionId;
|
private Long aclTransactionId;
|
||||||
|
|
||||||
@QueryParam("nodeid")
|
@QueryParam("nodeId")
|
||||||
private Long nodeId;
|
private Long nodeId;
|
||||||
|
|
||||||
@QueryParam("aclid")
|
@QueryParam("aclid")
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package com.inteligr8.alfresco.asie.model.core;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
import org.alfresco.service.cmr.repository.StoreRef;
|
import org.alfresco.service.cmr.repository.StoreRef;
|
||||||
import org.springframework.util.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import com.inteligr8.solr.model.JsonFormattedResponseRequest;
|
import com.inteligr8.solr.model.JsonFormattedResponseRequest;
|
||||||
|
|
||||||
@@ -89,7 +89,7 @@ public class NewCoreRequest extends JsonFormattedResponseRequest<NewCoreRequest>
|
|||||||
}
|
}
|
||||||
|
|
||||||
public NewCoreRequest withShardIds(Collection<String> shardIds) {
|
public NewCoreRequest withShardIds(Collection<String> shardIds) {
|
||||||
this.shardIds = StringUtils.collectionToDelimitedString(shardIds, ",");
|
this.shardIds = StringUtils.join(shardIds, ",");
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ public class PurgeRequest extends JsonFormattedResponseRequest<PurgeRequest> {
|
|||||||
@QueryParam("acltxid")
|
@QueryParam("acltxid")
|
||||||
private Long aclTransactionId;
|
private Long aclTransactionId;
|
||||||
|
|
||||||
@QueryParam("nodeid")
|
@QueryParam("nodeId")
|
||||||
private Long nodeId;
|
private Long nodeId;
|
||||||
|
|
||||||
@QueryParam("aclid")
|
@QueryParam("aclid")
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ public class ReindexRequest extends JsonFormattedResponseRequest<ReindexRequest>
|
|||||||
@QueryParam("acltxid")
|
@QueryParam("acltxid")
|
||||||
private Long aclTransactionId;
|
private Long aclTransactionId;
|
||||||
|
|
||||||
@QueryParam("nodeid")
|
@QueryParam("nodeId")
|
||||||
private Long nodeId;
|
private Long nodeId;
|
||||||
|
|
||||||
@QueryParam("aclid")
|
@QueryParam("aclid")
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@ import org.slf4j.LoggerFactory;
|
|||||||
|
|
||||||
import com.inteligr8.alfresco.asie.AsieClient;
|
import com.inteligr8.alfresco.asie.AsieClient;
|
||||||
|
|
||||||
public class AbstractApiIT {
|
public class AbstractApiUnitTest {
|
||||||
|
|
||||||
protected Logger logger = LoggerFactory.getLogger(this.getClass());
|
protected Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||||
|
|
||||||
+1
-1
@@ -11,7 +11,7 @@ import com.inteligr8.solr.model.Action.Status;
|
|||||||
import com.inteligr8.solr.model.Cores;
|
import com.inteligr8.solr.model.Cores;
|
||||||
import com.inteligr8.solr.model.ResponseHeader;
|
import com.inteligr8.solr.model.ResponseHeader;
|
||||||
|
|
||||||
public class CoreAdminReindexIT extends AbstractApiIT {
|
public class CoreAdminReindexUnitTest extends AbstractApiUnitTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void reindex() {
|
public void reindex() {
|
||||||
+1
-1
@@ -19,7 +19,7 @@ import com.inteligr8.solr.model.core.StatusResponse;
|
|||||||
|
|
||||||
import jakarta.ws.rs.ProcessingException;
|
import jakarta.ws.rs.ProcessingException;
|
||||||
|
|
||||||
public class CoreAdminStatusIT extends AbstractApiIT {
|
public class CoreAdminStatusUnitTest extends AbstractApiUnitTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void noHost() {
|
public void noHost() {
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.inteligr8.alfresco</groupId>
|
<groupId>com.inteligr8.alfresco</groupId>
|
||||||
<artifactId>asie-platform-module-parent</artifactId>
|
<artifactId>asie-platform-module-parent</artifactId>
|
||||||
<version>1.3-SNAPSHOT</version>
|
<version>1.2.2</version>
|
||||||
<relativePath>../</relativePath>
|
<relativePath>../</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
@@ -16,10 +16,10 @@
|
|||||||
<name>ASIE Platform Module for ACS Community</name>
|
<name>ASIE Platform Module for ACS Community</name>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<alfresco.sdk.version>4.16.0</alfresco.sdk.version>
|
<alfresco.sdk.version>4.9.0</alfresco.sdk.version>
|
||||||
<alfresco.platform.version>26.1.0</alfresco.platform.version>
|
<alfresco.platform.version>23.3.0</alfresco.platform.version>
|
||||||
<alfresco.platform.war.version>26.1.0.61</alfresco.platform.war.version>
|
<alfresco.platform.war.version>23.3.0.98</alfresco.platform.war.version>
|
||||||
<tomcat-rad.version>2.3-tomcat-11.0.22</tomcat-rad.version>
|
<tomcat-rad.version>10-2.1</tomcat-rad.version>
|
||||||
|
|
||||||
<beedk.rad.acs-search.enabled>true</beedk.rad.acs-search.enabled>
|
<beedk.rad.acs-search.enabled>true</beedk.rad.acs-search.enabled>
|
||||||
</properties>
|
</properties>
|
||||||
@@ -59,7 +59,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.inteligr8.alfresco</groupId>
|
<groupId>com.inteligr8.alfresco</groupId>
|
||||||
<artifactId>cxf-jaxrs-platform-module</artifactId>
|
<artifactId>cxf-jaxrs-platform-module</artifactId>
|
||||||
<version>1.4.0-acs-v26.1</version>
|
<version>1.3.1-acs-v23.3</version>
|
||||||
<type>amp</type>
|
<type>amp</type>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
@@ -81,6 +81,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>io.repaint.maven</groupId>
|
<groupId>io.repaint.maven</groupId>
|
||||||
<artifactId>tiles-maven-plugin</artifactId>
|
<artifactId>tiles-maven-plugin</artifactId>
|
||||||
|
<version>2.40</version>
|
||||||
<extensions>true</extensions>
|
<extensions>true</extensions>
|
||||||
<configuration>
|
<configuration>
|
||||||
<tiles>
|
<tiles>
|
||||||
@@ -99,7 +100,7 @@
|
|||||||
<repositories>
|
<repositories>
|
||||||
<repository>
|
<repository>
|
||||||
<id>alfresco-public</id>
|
<id>alfresco-public</id>
|
||||||
<url>https://artifacts.alfresco.com/nexus/repository/releases/</url>
|
<url>https://artifacts.alfresco.com/nexus/content/groups/public</url>
|
||||||
</repository>
|
</repository>
|
||||||
</repositories>
|
</repositories>
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
+21
-15
@@ -6,7 +6,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.inteligr8.alfresco</groupId>
|
<groupId>com.inteligr8.alfresco</groupId>
|
||||||
<artifactId>asie-platform-module-parent</artifactId>
|
<artifactId>asie-platform-module-parent</artifactId>
|
||||||
<version>1.3-SNAPSHOT</version>
|
<version>1.3.4</version>
|
||||||
<relativePath>../</relativePath>
|
<relativePath>../</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
@@ -16,10 +16,10 @@
|
|||||||
<name>ASIE Platform Module for ACS Enterprise</name>
|
<name>ASIE Platform Module for ACS Enterprise</name>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<alfresco.platform.version>26.1.0</alfresco.platform.version>
|
<alfresco.sdk.version>4.9.0</alfresco.sdk.version>
|
||||||
<alfresco.platform.war.version>26.1.0.61</alfresco.platform.war.version>
|
<alfresco.platform.version>23.3.0</alfresco.platform.version>
|
||||||
<tomcat-rad.version>2.3-tomcat-11.0.22</tomcat-rad.version>
|
<alfresco.platform.war.version>23.3.0.98</alfresco.platform.war.version>
|
||||||
<jackson.version>2.17.2</jackson.version>
|
<tomcat-rad.version>10-2.1</tomcat-rad.version>
|
||||||
|
|
||||||
<beedk.rad.acs-search.enabled>true</beedk.rad.acs-search.enabled>
|
<beedk.rad.acs-search.enabled>true</beedk.rad.acs-search.enabled>
|
||||||
</properties>
|
</properties>
|
||||||
@@ -37,13 +37,10 @@
|
|||||||
</dependencyManagement>
|
</dependencyManagement>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<!-- Alfresco Modules required to use this module -->
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.inteligr8.alfresco</groupId>
|
<groupId>com.inteligr8.alfresco</groupId>
|
||||||
<artifactId>cxf-jaxrs-platform-module</artifactId>
|
<artifactId>asie-shared</artifactId>
|
||||||
<version>1.4.0-acs-v26.1</version>
|
<version>${project.version}</version>
|
||||||
<type>amp</type>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- Needed by this module, but provided by ACS -->
|
<!-- Needed by this module, but provided by ACS -->
|
||||||
@@ -53,11 +50,19 @@
|
|||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- core dependency, but dependencies of provided ones above should override -->
|
<!-- Alfresco Modules required to use this module -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.inteligr8.alfresco</groupId>
|
<groupId>com.inteligr8.alfresco</groupId>
|
||||||
<artifactId>asie-shared</artifactId>
|
<artifactId>cxf-jaxrs-platform-module</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>1.3.2-acs-v23.3</version>
|
||||||
|
<type>amp</type>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Provided by cxf-jaxrs-platform-module, but packaged due to shared -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.inteligr8</groupId>
|
||||||
|
<artifactId>common-rest-client</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- Provided by cxf-jaxrs-platform-module, but packaged due to solr-api -->
|
<!-- Provided by cxf-jaxrs-platform-module, but packaged due to solr-api -->
|
||||||
@@ -75,13 +80,13 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.fasterxml.jackson.datatype</groupId>
|
<groupId>com.fasterxml.jackson.datatype</groupId>
|
||||||
<artifactId>jackson-datatype-jsr310</artifactId>
|
<artifactId>jackson-datatype-jsr310</artifactId>
|
||||||
<version>${jackson.version}</version>
|
<version>2.17.3</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.fasterxml.jackson.module</groupId>
|
<groupId>com.fasterxml.jackson.module</groupId>
|
||||||
<artifactId>jackson-module-jakarta-xmlbind-annotations</artifactId>
|
<artifactId>jackson-module-jakarta-xmlbind-annotations</artifactId>
|
||||||
<version>${jackson.version}</version>
|
<version>2.17.2</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
@@ -103,6 +108,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>io.repaint.maven</groupId>
|
<groupId>io.repaint.maven</groupId>
|
||||||
<artifactId>tiles-maven-plugin</artifactId>
|
<artifactId>tiles-maven-plugin</artifactId>
|
||||||
|
<version>2.40</version>
|
||||||
<extensions>true</extensions>
|
<extensions>true</extensions>
|
||||||
<configuration>
|
<configuration>
|
||||||
<tiles>
|
<tiles>
|
||||||
|
|||||||
+1
-1
@@ -264,7 +264,7 @@ public class ShardDiscoveryService implements com.inteligr8.alfresco.asie.spi.Sh
|
|||||||
ShardInstanceState nodeShardState = ShardInstanceState.from(shardState);
|
ShardInstanceState nodeShardState = ShardInstanceState.from(shardState);
|
||||||
|
|
||||||
Pair<SolrHost, ShardInstanceState> pair = new Pair<>(node, nodeShardState);
|
Pair<SolrHost, ShardInstanceState> pair = new Pair<>(node, nodeShardState);
|
||||||
if (!shardNodeStates.containsKey(shardId) || comparator.compare(pair, shardNodeStates.get(shardId)) < 0)
|
if (comparator.compare(pair, shardNodeStates.get(shardId)) < 0)
|
||||||
shardNodeStates.put(shardId, pair);
|
shardNodeStates.put(shardId, pair);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
<groupId>com.inteligr8.alfresco</groupId>
|
<groupId>com.inteligr8.alfresco</groupId>
|
||||||
<artifactId>asie-platform-module-parent</artifactId>
|
<artifactId>asie-platform-module-parent</artifactId>
|
||||||
<version>1.3-SNAPSHOT</version>
|
<version>1.3.4</version>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
|
|
||||||
<name>ASIE Platform Module Parent</name>
|
<name>ASIE Platform Module Parent</name>
|
||||||
@@ -43,21 +43,15 @@
|
|||||||
<maven.compiler.target>17</maven.compiler.target>
|
<maven.compiler.target>17</maven.compiler.target>
|
||||||
<maven.compiler.release>17</maven.compiler.release>
|
<maven.compiler.release>17</maven.compiler.release>
|
||||||
<maven.deploy.skip>true</maven.deploy.skip>
|
<maven.deploy.skip>true</maven.deploy.skip>
|
||||||
|
|
||||||
<!-- must be aligned with the target ACS platform junit -->
|
|
||||||
<junit.version>5.12.2</junit.version>
|
|
||||||
|
|
||||||
<commom-rest-client.base.version>3.0.4</commom-rest-client.base.version>
|
|
||||||
|
|
||||||
<alfresco.platform.version>26.1.0</alfresco.platform.version>
|
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencyManagement>
|
<dependencyManagement>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
<!-- Provided by cxf-jaxrs-platform-module, but packaged due to shared -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.junit.jupiter</groupId>
|
<groupId>com.inteligr8</groupId>
|
||||||
<artifactId>junit-jupiter-api</artifactId>
|
<artifactId>common-rest-client</artifactId>
|
||||||
<version>${junit.version}</version>
|
<version>3.0.3-cxf</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</dependencyManagement>
|
</dependencyManagement>
|
||||||
@@ -65,48 +59,43 @@
|
|||||||
<build>
|
<build>
|
||||||
<pluginManagement>
|
<pluginManagement>
|
||||||
<plugins>
|
<plugins>
|
||||||
<!-- helps avoid vulnerable dependencies -->
|
<!-- avoids log4j dependency -->
|
||||||
<plugin>
|
|
||||||
<artifactId>maven-site-plugin</artifactId>
|
|
||||||
<version>3.22.0</version>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
<version>3.15.0</version>
|
<version>3.14.1</version>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
<!-- avoids struts dependency -->
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-site-plugin</artifactId>
|
||||||
|
<version>3.21.0</version>
|
||||||
|
</plugin>
|
||||||
|
<!-- Force use of a new maven-dependency-plugin that doesn't download struts dependency -->
|
||||||
<plugin>
|
<plugin>
|
||||||
<artifactId>maven-dependency-plugin</artifactId>
|
<artifactId>maven-dependency-plugin</artifactId>
|
||||||
<version>3.11.0</version>
|
<version>3.9.0</version>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<artifactId>maven-surefire-plugin</artifactId>
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
<version>3.5.6</version>
|
<version>3.5.4</version>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.junit.jupiter</groupId>
|
<groupId>org.junit.jupiter</groupId>
|
||||||
<artifactId>junit-jupiter-engine</artifactId>
|
<artifactId>junit-jupiter-engine</artifactId>
|
||||||
<version>${junit.version}</version>
|
<version>5.14.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<artifactId>maven-failsafe-plugin</artifactId>
|
<artifactId>maven-failsafe-plugin</artifactId>
|
||||||
<version>3.5.6</version>
|
<version>3.5.4</version>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.junit.jupiter</groupId>
|
<groupId>org.junit.jupiter</groupId>
|
||||||
<artifactId>junit-jupiter-engine</artifactId>
|
<artifactId>junit-jupiter-engine</artifactId>
|
||||||
<version>${junit.version}</version>
|
<version>5.14.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
<plugin>
|
|
||||||
<groupId>io.repaint.maven</groupId>
|
|
||||||
<artifactId>tiles-maven-plugin</artifactId>
|
|
||||||
<version>2.45</version>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
</plugins>
|
||||||
</pluginManagement>
|
</pluginManagement>
|
||||||
</build>
|
</build>
|
||||||
@@ -162,7 +151,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.sonatype.central</groupId>
|
<groupId>org.sonatype.central</groupId>
|
||||||
<artifactId>central-publishing-maven-plugin</artifactId>
|
<artifactId>central-publishing-maven-plugin</artifactId>
|
||||||
<version>0.10.0</version>
|
<version>0.8.0</version>
|
||||||
<extensions>true</extensions>
|
<extensions>true</extensions>
|
||||||
<configuration>
|
<configuration>
|
||||||
<publishingServerId>central</publishingServerId>
|
<publishingServerId>central</publishingServerId>
|
||||||
|
|||||||
+5
-7
@@ -6,7 +6,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.inteligr8.alfresco</groupId>
|
<groupId>com.inteligr8.alfresco</groupId>
|
||||||
<artifactId>asie-platform-module-parent</artifactId>
|
<artifactId>asie-platform-module-parent</artifactId>
|
||||||
<version>1.3-SNAPSHOT</version>
|
<version>1.3.4</version>
|
||||||
<relativePath>../</relativePath>
|
<relativePath>../</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
@@ -16,9 +16,8 @@
|
|||||||
<name>ASIE Shared Library for Platform Modules</name>
|
<name>ASIE Shared Library for Platform Modules</name>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<alfresco.sdk.version>4.16.0</alfresco.sdk.version>
|
<alfresco.sdk.version>4.9.0</alfresco.sdk.version>
|
||||||
|
<alfresco.platform.version>23.3.0</alfresco.platform.version>
|
||||||
<common-rest-client.version>${commom-rest-client.base.version}-cxf</common-rest-client.version>
|
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencyManagement>
|
<dependencyManagement>
|
||||||
@@ -37,12 +36,11 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.inteligr8.alfresco</groupId>
|
<groupId>com.inteligr8.alfresco</groupId>
|
||||||
<artifactId>asie-api</artifactId>
|
<artifactId>asie-api</artifactId>
|
||||||
<version>1.2-SNAPSHOT-asie2</version>
|
<version>1.1.1-asie2</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.inteligr8</groupId>
|
<groupId>com.inteligr8</groupId>
|
||||||
<artifactId>common-rest-client</artifactId>
|
<artifactId>common-rest-client</artifactId>
|
||||||
<version>${common-rest-client.version}</version>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- Needed by this module, but provided by ACS -->
|
<!-- Needed by this module, but provided by ACS -->
|
||||||
@@ -73,7 +71,7 @@
|
|||||||
<repositories>
|
<repositories>
|
||||||
<repository>
|
<repository>
|
||||||
<id>alfresco-public</id>
|
<id>alfresco-public</id>
|
||||||
<url>https://artifacts.alfresco.com/nexus/repository/releases/</url>
|
<url>https://artifacts.alfresco.com/nexus/content/groups/public</url>
|
||||||
</repository>
|
</repository>
|
||||||
</repositories>
|
</repositories>
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@@ -9,8 +9,14 @@ import java.util.Map;
|
|||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
|
import org.alfresco.model.ContentModel;
|
||||||
|
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeService;
|
||||||
|
import org.alfresco.service.cmr.repository.StoreRef;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.extensions.webscripts.WebScriptException;
|
import org.springframework.extensions.webscripts.WebScriptException;
|
||||||
import org.springframework.extensions.webscripts.WebScriptRequest;
|
import org.springframework.extensions.webscripts.WebScriptRequest;
|
||||||
import org.springframework.extensions.webscripts.WebScriptResponse;
|
import org.springframework.extensions.webscripts.WebScriptResponse;
|
||||||
|
|||||||
+4
-4
@@ -44,10 +44,10 @@ public class ReconcileAcsNodesWebScript extends AbstractAsieWebScript {
|
|||||||
public void reconciled(long nodeDbId) {
|
public void reconciled(long nodeDbId) {
|
||||||
if (includeReconciled) {
|
if (includeReconciled) {
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
List<Long> reconciledNodeDbIds = (List<Long>) responseMap.get("reconciled");
|
List<Long> unreconciledNodeDbIds = (List<Long>) responseMap.get("reconciled");
|
||||||
if (reconciledNodeDbIds == null)
|
if (unreconciledNodeDbIds == null)
|
||||||
responseMap.put("reconciled", reconciledNodeDbIds = new LinkedList<>());
|
responseMap.put("reconciled", unreconciledNodeDbIds = new LinkedList<>());
|
||||||
reconciledNodeDbIds.add(nodeDbId);
|
unreconciledNodeDbIds.add(nodeDbId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+10
-2
@@ -12,12 +12,17 @@ import java.util.concurrent.Future;
|
|||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
|
import org.alfresco.model.ContentModel;
|
||||||
import org.alfresco.repo.index.shard.Floc;
|
import org.alfresco.repo.index.shard.Floc;
|
||||||
import org.alfresco.repo.index.shard.Shard;
|
import org.alfresco.repo.index.shard.Shard;
|
||||||
import org.alfresco.repo.index.shard.ShardInstance;
|
import org.alfresco.repo.index.shard.ShardInstance;
|
||||||
import org.alfresco.repo.index.shard.ShardRegistry;
|
import org.alfresco.repo.index.shard.ShardRegistry;
|
||||||
import org.alfresco.repo.index.shard.ShardState;
|
import org.alfresco.repo.index.shard.ShardState;
|
||||||
import org.alfresco.service.cmr.repository.StoreRef;
|
import org.alfresco.service.cmr.repository.StoreRef;
|
||||||
|
import org.alfresco.service.cmr.search.SearchParameters;
|
||||||
|
import org.alfresco.service.cmr.search.SearchService;
|
||||||
|
import org.alfresco.service.namespace.NamespaceService;
|
||||||
|
import org.alfresco.service.namespace.QName;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@@ -40,6 +45,9 @@ public abstract class AbstractActionService {
|
|||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private NamespaceService namespaceService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ApiService apiService;
|
private ApiService apiService;
|
||||||
|
|
||||||
@@ -50,10 +58,10 @@ public abstract class AbstractActionService {
|
|||||||
@Qualifier(Constants.QUALIFIER_ASIE)
|
@Qualifier(Constants.QUALIFIER_ASIE)
|
||||||
private ShardRegistry shardRegistry;
|
private ShardRegistry shardRegistry;
|
||||||
|
|
||||||
@Value("${inteligr8.asie.default.concurrentQueueSize}")
|
@Value("${inteligr8.asie.default.concurrentQueueSize:64}")
|
||||||
private int concurrentQueueSize;
|
private int concurrentQueueSize;
|
||||||
|
|
||||||
@Value("${inteligr8.asie.default.concurrency}")
|
@Value("${inteligr8.asie.default.concurrency:16}")
|
||||||
private int concurrency;
|
private int concurrency;
|
||||||
|
|
||||||
protected int getConcurrency() {
|
protected int getConcurrency() {
|
||||||
|
|||||||
+55
-71
@@ -8,22 +8,23 @@ import java.util.Map.Entry;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
|
import org.alfresco.model.ContentModel;
|
||||||
import org.alfresco.repo.index.shard.Floc;
|
import org.alfresco.repo.index.shard.Floc;
|
||||||
import org.alfresco.repo.index.shard.Shard;
|
import org.alfresco.repo.index.shard.Shard;
|
||||||
import org.alfresco.repo.index.shard.ShardInstance;
|
import org.alfresco.repo.index.shard.ShardInstance;
|
||||||
import org.alfresco.repo.index.shard.ShardRegistry;
|
import org.alfresco.repo.index.shard.ShardRegistry;
|
||||||
import org.alfresco.repo.index.shard.ShardState;
|
import org.alfresco.repo.index.shard.ShardState;
|
||||||
import org.alfresco.service.cmr.repository.StoreRef;
|
import org.alfresco.service.cmr.repository.StoreRef;
|
||||||
|
import org.alfresco.service.cmr.search.SearchParameters;
|
||||||
|
import org.alfresco.service.cmr.search.SearchService;
|
||||||
import org.alfresco.service.namespace.NamespaceService;
|
import org.alfresco.service.namespace.NamespaceService;
|
||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.DisposableBean;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Qualifier;
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
@@ -40,7 +41,7 @@ import com.inteligr8.solr.model.Action;
|
|||||||
import com.inteligr8.solr.model.ActionResponse;
|
import com.inteligr8.solr.model.ActionResponse;
|
||||||
import com.inteligr8.solr.model.BaseResponse;
|
import com.inteligr8.solr.model.BaseResponse;
|
||||||
|
|
||||||
public abstract class AbstractNodeActionService implements DisposableBean {
|
public abstract class AbstractNodeActionService {
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||||
|
|
||||||
@@ -60,10 +61,10 @@ public abstract class AbstractNodeActionService implements DisposableBean {
|
|||||||
@Qualifier(Constants.QUALIFIER_ASIE)
|
@Qualifier(Constants.QUALIFIER_ASIE)
|
||||||
private ShardRegistry shardRegistry;
|
private ShardRegistry shardRegistry;
|
||||||
|
|
||||||
@Value("${inteligr8.asie.default.concurrentQueueSize}")
|
@Value("${inteligr8.asie.default.concurrentQueueSize:64}")
|
||||||
private int concurrentQueueSize;
|
private int concurrentQueueSize;
|
||||||
|
|
||||||
@Value("${inteligr8.asie.default.concurrency}")
|
@Value("${inteligr8.asie.default.concurrency:16}")
|
||||||
private int concurrency;
|
private int concurrency;
|
||||||
|
|
||||||
protected int getConcurrency() {
|
protected int getConcurrency() {
|
||||||
@@ -78,22 +79,6 @@ public abstract class AbstractNodeActionService implements DisposableBean {
|
|||||||
|
|
||||||
protected abstract String getActionName();
|
protected abstract String getActionName();
|
||||||
|
|
||||||
@Override
|
|
||||||
public void destroy() {
|
|
||||||
ExecutorService executor = this.executorManager.get(this.getThreadNamePrefix());
|
|
||||||
if (executor != null) {
|
|
||||||
this.logger.info("Shutting down throttled thread pool executor: {}", this.getThreadNamePrefix());
|
|
||||||
executor.shutdown();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private ThrottledThreadPoolExecutor getExecutor() {
|
|
||||||
return this.executorManager.createThrottled(
|
|
||||||
this.getThreadNamePrefix(),
|
|
||||||
this.getConcurrency(), this.getConcurrency(), this.getConcurrentQueueSize(),
|
|
||||||
1L, TimeUnit.MINUTES);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method executes an action on the specified node in Solr using its
|
* This method executes an action on the specified node in Solr using its
|
||||||
* ACS unique database identifier. The callback handles all the return
|
* ACS unique database identifier. The callback handles all the return
|
||||||
@@ -148,15 +133,16 @@ public abstract class AbstractNodeActionService implements DisposableBean {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Future<Void> _action(
|
private Future<Void> _action(long nodeDbId, ActionCallback callback, Long fullQueueExpireTimeMillis) throws TimeoutException, InterruptedException {
|
||||||
final long nodeDbId,
|
|
||||||
final ActionCallback callback,
|
|
||||||
Long fullQueueExpireTimeMillis) throws TimeoutException, InterruptedException {
|
|
||||||
List<com.inteligr8.alfresco.asie.model.ShardInstance> eligibleInstances = this.findPossibleShardInstances(nodeDbId);
|
List<com.inteligr8.alfresco.asie.model.ShardInstance> eligibleInstances = this.findPossibleShardInstances(nodeDbId);
|
||||||
this.logger.debug("Will attempt to {} ACS node against {} shard instances: {}", this.getActionName(), eligibleInstances.size(), nodeDbId);
|
this.logger.debug("Will attempt to {} ACS node against {} shard instances: {}", this.getActionName(), eligibleInstances.size(), nodeDbId);
|
||||||
|
|
||||||
CompositeFuture<Void> future = new CompositeFuture<>();
|
CompositeFuture<Void> future = new CompositeFuture<>();
|
||||||
ThrottledThreadPoolExecutor executor = this.getExecutor();
|
|
||||||
|
ThrottledThreadPoolExecutor executor = this.executorManager.createThrottled(
|
||||||
|
this.getThreadNamePrefix(),
|
||||||
|
this.getConcurrency(), this.getConcurrency(), this.getConcurrentQueueSize(),
|
||||||
|
1L, TimeUnit.MINUTES);
|
||||||
|
|
||||||
for (final com.inteligr8.alfresco.asie.model.ShardInstance instance : eligibleInstances) {
|
for (final com.inteligr8.alfresco.asie.model.ShardInstance instance : eligibleInstances) {
|
||||||
this.logger.trace("Will attempt to {} ACS node against shard instance: {}: {}", this.getActionName(), nodeDbId, instance);
|
this.logger.trace("Will attempt to {} ACS node against shard instance: {}: {}", this.getActionName(), nodeDbId, instance);
|
||||||
@@ -164,12 +150,49 @@ public abstract class AbstractNodeActionService implements DisposableBean {
|
|||||||
Callable<Void> callable = new Callable<>() {
|
Callable<Void> callable = new Callable<>() {
|
||||||
@Override
|
@Override
|
||||||
public Void call() {
|
public Void call() {
|
||||||
|
String core = instance.extractShard().getCoreName();
|
||||||
|
SolrHost host = instance.extractNode();
|
||||||
|
URL url = host.toUrl(apiService.isSecure() ? "https" : "http");
|
||||||
|
CoreAdminApi api = apiService.createApi(url.toString(), CoreAdminApi.class);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
actionToShard(nodeDbId, callback, instance);
|
logger.debug("Performing {} of ACS node against shard instance: {}: {}", getActionName(), nodeDbId, instance);
|
||||||
|
BaseResponse apiResponse = execute(api, core, nodeDbId);
|
||||||
|
logger.trace("Performed {} of ACS node against shard instance: {}: {}", getActionName(), nodeDbId, instance);
|
||||||
|
|
||||||
|
Action action = null;
|
||||||
|
if (apiResponse instanceof ActionCoreResponse<?>) {
|
||||||
|
action = ((ActionCoreResponse<Action>) apiResponse).getCores().getByCore(core);
|
||||||
|
} else if (apiResponse instanceof ActionResponse<?>) {
|
||||||
|
action = ((ActionResponse<Action>) apiResponse).getAction();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action == null) {
|
||||||
|
callback.unknownResult(instance);
|
||||||
|
} else {
|
||||||
|
switch (action.getStatus()) {
|
||||||
|
case Scheduled:
|
||||||
|
callback.scheduled(instance);
|
||||||
|
break;
|
||||||
|
case Success:
|
||||||
|
callback.success(instance);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (apiResponse instanceof com.inteligr8.alfresco.asie.model.BaseResponse) {
|
||||||
|
com.inteligr8.alfresco.asie.model.BaseResponse asieResponse = (com.inteligr8.alfresco.asie.model.BaseResponse) apiResponse;
|
||||||
|
logger.debug("Performance of {} of ACS node against shard instance failed: {}: {}: {}", getActionName(), nodeDbId, instance, asieResponse.getException());
|
||||||
|
callback.error(instance, asieResponse.getException());
|
||||||
|
} else {
|
||||||
|
logger.debug("Performance of {} of ACS node against shard instance failed: {}: {}: {}", getActionName(), nodeDbId, instance, apiResponse.getResponseHeader().getStatus());
|
||||||
|
callback.error(instance, String.valueOf(apiResponse.getResponseHeader().getStatus()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.error("An unexpected exception occurred", e);
|
logger.error("An exception occurred", e);
|
||||||
callback.error(instance, e.getMessage());
|
callback.error(instance, e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -184,54 +207,15 @@ public abstract class AbstractNodeActionService implements DisposableBean {
|
|||||||
return future;
|
return future;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
protected void actionToShard(long nodeDbId, ActionCallback callback, com.inteligr8.alfresco.asie.model.ShardInstance instance) {
|
|
||||||
String core = instance.extractShard().getCoreName();
|
|
||||||
SolrHost host = instance.extractNode();
|
|
||||||
URL url = host.toUrl(this.apiService.isSecure() ? "https" : "http");
|
|
||||||
CoreAdminApi api = this.apiService.createApi(url.toString(), CoreAdminApi.class);
|
|
||||||
|
|
||||||
this.logger.debug("Performing {} of ACS node against shard instance: {}: {}", this.getActionName(), nodeDbId, instance);
|
|
||||||
BaseResponse apiResponse = execute(api, core, nodeDbId);
|
|
||||||
this.logger.trace("Performed {} of ACS node against shard instance: {}: {}", this.getActionName(), nodeDbId, instance);
|
|
||||||
|
|
||||||
Action action = null;
|
|
||||||
if (apiResponse instanceof ActionCoreResponse<?>) {
|
|
||||||
action = ((ActionCoreResponse<Action>) apiResponse).getCores().getByCore(core);
|
|
||||||
} else if (apiResponse instanceof ActionResponse<?>) {
|
|
||||||
action = ((ActionResponse<Action>) apiResponse).getAction();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (action == null) {
|
|
||||||
callback.unknownResult(instance);
|
|
||||||
} else {
|
|
||||||
switch (action.getStatus()) {
|
|
||||||
case Scheduled:
|
|
||||||
callback.scheduled(instance);
|
|
||||||
break;
|
|
||||||
case Success:
|
|
||||||
callback.success(instance);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
if (apiResponse instanceof com.inteligr8.alfresco.asie.model.BaseResponse) {
|
|
||||||
com.inteligr8.alfresco.asie.model.BaseResponse asieResponse = (com.inteligr8.alfresco.asie.model.BaseResponse) apiResponse;
|
|
||||||
this.logger.debug("Performance of {} of ACS node against shard instance failed: {}: {}: {}",
|
|
||||||
this.getActionName(), nodeDbId, instance, asieResponse.getException());
|
|
||||||
callback.error(instance, asieResponse.getException());
|
|
||||||
} else {
|
|
||||||
this.logger.debug("Performance of {} of ACS node against shard instance failed: {}: {}: {}",
|
|
||||||
this.getActionName(), nodeDbId, instance, apiResponse.getResponseHeader().getStatus());
|
|
||||||
callback.error(instance, String.valueOf(apiResponse.getResponseHeader().getStatus()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract BaseResponse execute(CoreAdminApi api, String core, long nodeDbId);
|
protected abstract BaseResponse execute(CoreAdminApi api, String core, long nodeDbId);
|
||||||
|
|
||||||
private List<com.inteligr8.alfresco.asie.model.ShardInstance> findPossibleShardInstances(long nodeDbId) {
|
private List<com.inteligr8.alfresco.asie.model.ShardInstance> findPossibleShardInstances(long nodeDbId) {
|
||||||
if (this.shardRegistry == null)
|
if (this.shardRegistry == null)
|
||||||
throw new UnsupportedOperationException("ACS instances without a sharding configuration are not yet implemented");
|
throw new UnsupportedOperationException("ACS instances without a sharding configuration are not yet implemented");
|
||||||
|
|
||||||
|
SearchParameters searchParams = new SearchParameters();
|
||||||
|
searchParams.setLanguage(SearchService.LANGUAGE_FTS_ALFRESCO);
|
||||||
|
searchParams.setQuery("@" + this.formatForFts(ContentModel.PROP_NODE_DBID) + ":" + nodeDbId);
|
||||||
|
|
||||||
List<com.inteligr8.alfresco.asie.model.ShardInstance> instances = new LinkedList<>();
|
List<com.inteligr8.alfresco.asie.model.ShardInstance> instances = new LinkedList<>();
|
||||||
|
|
||||||
|
|||||||
+92
-134
@@ -1,10 +1,11 @@
|
|||||||
package com.inteligr8.alfresco.asie.service;
|
package com.inteligr8.alfresco.asie.service;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
@@ -25,6 +26,7 @@ import org.apache.commons.collections4.SetUtils;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.DisposableBean;
|
import org.springframework.beans.factory.DisposableBean;
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@@ -37,7 +39,7 @@ import com.inteligr8.alfresco.asie.util.CompositeFuture;
|
|||||||
import com.inteligr8.alfresco.asie.util.ThrottledThreadPoolExecutor;
|
import com.inteligr8.alfresco.asie.util.ThrottledThreadPoolExecutor;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
public class AcsReconcileService implements DisposableBean {
|
public class AcsReconcileService implements InitializingBean, DisposableBean {
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||||
private final Logger reconcileLogger = LoggerFactory.getLogger("inteligr8.asie.reconcile");
|
private final Logger reconcileLogger = LoggerFactory.getLogger("inteligr8.asie.reconcile");
|
||||||
@@ -59,42 +61,30 @@ public class AcsReconcileService implements DisposableBean {
|
|||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ReindexService reindexService;
|
private ReindexService reindexService;
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private ExecutorManager executorManager;
|
|
||||||
|
|
||||||
@Value("${inteligr8.asie.reconciliation.nodesChunkSize}")
|
@Value("${inteligr8.asie.reconciliation.nodesChunkSize:250}")
|
||||||
private int nodesChunkSize;
|
private int nodesChunkSize;
|
||||||
|
|
||||||
@Value("${inteligr8.asie.reconciliation.nodeTimeoutSeconds}")
|
@Value("${inteligr8.asie.reconciliation.nodeTimeoutSeconds:10}")
|
||||||
private int nodeTimeoutSeconds;
|
private int nodeTimeoutSeconds;
|
||||||
|
|
||||||
@Value("${inteligr8.asie.reconciliation.concurrentQueueSize}")
|
@Value("${inteligr8.asie.reconciliation.concurrentQueueSize:64}")
|
||||||
private int concurrentQueueSize;
|
private int concurrentQueueSize;
|
||||||
|
|
||||||
@Value("${inteligr8.asie.reconciliation.concurrency}")
|
@Value("${inteligr8.asie.reconciliation.concurrency:2}")
|
||||||
private int concurrency;
|
private int concurrency;
|
||||||
|
|
||||||
@Value("${inteligr8.asie.reconciliation.waitAfterSolrNodeActionMillis}")
|
private ThrottledThreadPoolExecutor executor;
|
||||||
private long waitAfterSolrNodeActionMillis;
|
|
||||||
|
@Override
|
||||||
@Value("${inteligr8.asie.reconciliation.waitAfterSolrNodeReconcileMillis}")
|
public void afterPropertiesSet() {
|
||||||
private long waitAfterSolrNodeReconcileMillis;
|
this.executor = new ThrottledThreadPoolExecutor(this.concurrency, this.concurrency, this.concurrentQueueSize, 1L, TimeUnit.MINUTES, "solr-reconcile");
|
||||||
|
this.executor.prestartAllCoreThreads();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void destroy() {
|
public void destroy() {
|
||||||
ExecutorService executor = this.executorManager.get("solr-reconcile");
|
this.executor.shutdown();
|
||||||
if (executor != null) {
|
|
||||||
this.logger.info("Shutting down throttled thread pool executor: {}", "solr-reconcile");
|
|
||||||
executor.shutdown();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private ThrottledThreadPoolExecutor getExecutor() {
|
|
||||||
return this.executorManager.createThrottled(
|
|
||||||
"solr-reconcile",
|
|
||||||
this.concurrency, this.concurrency, this.concurrentQueueSize,
|
|
||||||
10L, TimeUnit.SECONDS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -106,7 +96,7 @@ public class AcsReconcileService implements DisposableBean {
|
|||||||
*
|
*
|
||||||
* There are two sets of parameters regarding timeouts. The queue timeouts
|
* There are two sets of parameters regarding timeouts. The queue timeouts
|
||||||
* are for how long the requesting thread should wait for a full queue to
|
* are for how long the requesting thread should wait for a full queue to
|
||||||
* open up space for new reconcile executions. The execution timeouts are
|
* open up space for new re-index executions. The execution timeouts are
|
||||||
* for how long the execution should be allowed to take once dequeued.
|
* for how long the execution should be allowed to take once dequeued.
|
||||||
* There is no timeout for how long the execution is queued.
|
* There is no timeout for how long the execution is queued.
|
||||||
*
|
*
|
||||||
@@ -117,10 +107,10 @@ public class AcsReconcileService implements DisposableBean {
|
|||||||
* @param callback A callback to process multiple returned values from the re-index.
|
* @param callback A callback to process multiple returned values from the re-index.
|
||||||
* @param queueTimeout A timeout for how long the calling thread should wait for space on the queue.
|
* @param queueTimeout A timeout for how long the calling thread should wait for space on the queue.
|
||||||
* @param queueUnit The time units for the `queueTimeout`.
|
* @param queueUnit The time units for the `queueTimeout`.
|
||||||
* @param execTimeout A timeout for the elapsed time the reconcile execution should take when dequeued.
|
* @param execTimeout A timeout for the elapsed time the reindex execution should take when dequeued.
|
||||||
* @param execUnit The time units for the `execTimeout`.
|
* @param execUnit The time units for the `execTimeout`.
|
||||||
* @throws TimeoutException Either the queue or execution timeout lapsed.
|
* @throws TimeoutException Either the queue or execution timeout lapsed.
|
||||||
* @throws InterruptedException The reconciliation was interrupted (server shutdown).
|
* @throws InterruptedException The re-index was interrupted (server shutdown).
|
||||||
*/
|
*/
|
||||||
public void reconcile(
|
public void reconcile(
|
||||||
long fromDbId, long toDbId, Integer nodesChunkSize,
|
long fromDbId, long toDbId, Integer nodesChunkSize,
|
||||||
@@ -129,10 +119,18 @@ public class AcsReconcileService implements DisposableBean {
|
|||||||
ReconcileCallback callback,
|
ReconcileCallback callback,
|
||||||
long queueTimeout, TimeUnit queueUnit,
|
long queueTimeout, TimeUnit queueUnit,
|
||||||
long execTimeout, TimeUnit execUnit) throws InterruptedException, TimeoutException {
|
long execTimeout, TimeUnit execUnit) throws InterruptedException, TimeoutException {
|
||||||
|
if (nodesChunkSize == null)
|
||||||
|
nodesChunkSize = this.nodesChunkSize;
|
||||||
if (this.logger.isTraceEnabled())
|
if (this.logger.isTraceEnabled())
|
||||||
this.logger.trace("reconcile({}, {}, {}, {}, {}, {}, {})", fromDbId, toDbId, nodesChunkSize, indexUnreconciled, reindexReconciled, queueUnit.toMillis(queueTimeout), execUnit.toMillis(execTimeout));
|
this.logger.trace("reconcile({}, {}, {}, {}, {}, {}, {})", fromDbId, toDbId, nodesChunkSize, indexUnreconciled, reindexReconciled, queueUnit.toMillis(queueTimeout), execUnit.toMillis(execTimeout));
|
||||||
|
|
||||||
|
CompositeFuture<Void> future = new CompositeFuture<>();
|
||||||
|
|
||||||
Future<Void> future = this._reconcile(fromDbId, toDbId, nodesChunkSize, indexUnreconciled, reindexReconciled, callback, queueTimeout, queueUnit, execTimeout, execUnit);
|
for (long startDbId = fromDbId; startDbId < toDbId; startDbId += nodesChunkSize) {
|
||||||
|
long endDbId = Math.min(toDbId, startDbId + nodesChunkSize);
|
||||||
|
future.combine(this.reconcileChunk(startDbId, endDbId, indexUnreconciled, reindexReconciled, callback, queueTimeout, queueUnit, execTimeout, execUnit));
|
||||||
|
future.purge(true);
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
future.get(execTimeout, execUnit);
|
future.get(execTimeout, execUnit);
|
||||||
@@ -141,52 +139,27 @@ public class AcsReconcileService implements DisposableBean {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* This method reconciles the specified node range between ACS and Solr.
|
|
||||||
* The node range is specified using the ACS unique database identifiers.
|
|
||||||
* There is no other reasonably efficient attack vector. The callback
|
|
||||||
* handles all the return values. This is the synchronous alternative to
|
|
||||||
* the other `reconcile` method.
|
|
||||||
*
|
|
||||||
* @param fromDbId A node database ID, inclusive.
|
|
||||||
* @param toDbId A node database ID, exclusive.
|
|
||||||
* @param indexUnreconciled For nodes not found in Solr, attempt to index against all applicable Solr instances.
|
|
||||||
* @param reindexReconciled For nodes found in Solr, attempt to re-index against all applicable Solr instances.
|
|
||||||
* @param callback A callback to process multiple returned values from the re-index.
|
|
||||||
* @throws InterruptedException The reconciliation was interrupted (server shutdown).
|
|
||||||
*/
|
|
||||||
public Future<Void> reconcile(
|
public Future<Void> reconcile(
|
||||||
long fromDbId, long toDbId, Integer nodesChunkSize,
|
long fromDbId, long toDbId, Integer nodesChunkSize,
|
||||||
boolean indexUnreconciled,
|
boolean indexUnreconciled,
|
||||||
boolean reindexReconciled,
|
boolean reindexReconciled,
|
||||||
ReconcileCallback callback) throws InterruptedException {
|
ReconcileCallback callback) throws InterruptedException {
|
||||||
|
if (nodesChunkSize == null)
|
||||||
|
nodesChunkSize = this.nodesChunkSize;
|
||||||
this.logger.trace("reconcile({}, {}, {}, {}, {})", fromDbId, toDbId, nodesChunkSize, indexUnreconciled, reindexReconciled);
|
this.logger.trace("reconcile({}, {}, {}, {}, {})", fromDbId, toDbId, nodesChunkSize, indexUnreconciled, reindexReconciled);
|
||||||
|
|
||||||
|
CompositeFuture<Void> future = new CompositeFuture<>();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return this._reconcile(fromDbId, toDbId, nodesChunkSize, indexUnreconciled, reindexReconciled, callback, -1L, null, -1L, null);
|
for (long startDbId = fromDbId; startDbId < toDbId; startDbId += nodesChunkSize) {
|
||||||
|
long endDbId = Math.min(toDbId, startDbId + nodesChunkSize);
|
||||||
|
future.combine(this.reconcileChunk(startDbId, endDbId, indexUnreconciled, reindexReconciled, callback, -1L, null, -1L, null));
|
||||||
|
future.purge(true);
|
||||||
|
}
|
||||||
} catch (TimeoutException te) {
|
} catch (TimeoutException te) {
|
||||||
throw new RuntimeException("This should never happen: " + te.getMessage(), te);
|
throw new RuntimeException("This should never happen: " + te.getMessage(), te);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
protected Future<Void> _reconcile(
|
|
||||||
long fromDbId, long toDbId, Integer nodesChunkSize,
|
|
||||||
boolean indexUnreconciled,
|
|
||||||
boolean reindexReconciled,
|
|
||||||
ReconcileCallback callback,
|
|
||||||
long queueTimeout, TimeUnit queueUnit,
|
|
||||||
long execTimeout, TimeUnit execUnit) throws InterruptedException, TimeoutException {
|
|
||||||
if (nodesChunkSize == null)
|
|
||||||
nodesChunkSize = this.nodesChunkSize;
|
|
||||||
|
|
||||||
CompositeFuture<Void> future = new CompositeFuture<>();
|
|
||||||
|
|
||||||
for (long startDbId = fromDbId; startDbId < toDbId; startDbId += nodesChunkSize) {
|
|
||||||
long endDbId = Math.min(toDbId, startDbId + nodesChunkSize);
|
|
||||||
future.combine(this.reconcileChunk(startDbId, endDbId, indexUnreconciled, reindexReconciled, callback, queueTimeout, queueUnit, execTimeout, execUnit));
|
|
||||||
future.purge(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
return future;
|
return future;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -232,14 +205,12 @@ public class AcsReconcileService implements DisposableBean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CompositeFuture<Void> future = new CompositeFuture<>();
|
CompositeFuture<Void> future = new CompositeFuture<>();
|
||||||
ThrottledThreadPoolExecutor executor = this.getExecutor();
|
|
||||||
|
|
||||||
for (long _nodeDbId = fromDbId; _nodeDbId < toDbId; _nodeDbId++) {
|
for (long _nodeDbId = fromDbId; _nodeDbId < toDbId; _nodeDbId++) {
|
||||||
final long nodeDbId = _nodeDbId;
|
final long nodeDbId = _nodeDbId;
|
||||||
this.logger.trace("Attempting to reconcile ACS node: {}", nodeDbId);
|
this.logger.trace("Attempting to reconcile ACS node: {}", nodeDbId);
|
||||||
|
|
||||||
Callable<Void> callable;
|
Callable<Void> callable;
|
||||||
boolean callingSolr = false;
|
|
||||||
|
|
||||||
final int dbIdIndex = (int) (nodeDbId - fromDbId);
|
final int dbIdIndex = (int) (nodeDbId - fromDbId);
|
||||||
if (nodeRefs[dbIdIndex] != null) {
|
if (nodeRefs[dbIdIndex] != null) {
|
||||||
@@ -251,157 +222,144 @@ public class AcsReconcileService implements DisposableBean {
|
|||||||
callback.reconciled(nodeDbId);
|
callback.reconciled(nodeDbId);
|
||||||
|
|
||||||
if (reindexReconciled)
|
if (reindexReconciled)
|
||||||
reindex(nodeDbId, nodeRefs[dbIdIndex], callback);
|
reindex(nodeDbId, nodeRefs[dbIdIndex], callback, execTimeout, execUnit);
|
||||||
// purposefully forgetting about the returned future
|
|
||||||
// its results will be logged
|
|
||||||
// the reconcile thread will continue independently
|
|
||||||
// the callback will lag
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if (reindexReconciled)
|
|
||||||
callingSolr = true;
|
|
||||||
} else {
|
} else {
|
||||||
callable = new Callable<Void>() {
|
callable = new Callable<Void>() {
|
||||||
@Override
|
@Override
|
||||||
public Void call() throws InterruptedException, TimeoutException {
|
public Void call() throws InterruptedException, TimeoutException {
|
||||||
reconcile(nodeDbId, indexUnreconciled, callback);
|
reconcile(nodeDbId, indexUnreconciled, callback, execTimeout, execUnit);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
callingSolr = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (queueTimeout < 0L) {
|
if (queueTimeout < 0L) {
|
||||||
future.combine(executor.submit(callable, -1L, null));
|
future.combine(this.executor.submit(callable, -1L, null));
|
||||||
} else {
|
} else {
|
||||||
future.combine(executor.submit(callable, queueTimeout, queueUnit));
|
future.combine(this.executor.submit(callable, queueTimeout, queueUnit));
|
||||||
}
|
|
||||||
|
|
||||||
if (callingSolr && this.waitAfterSolrNodeReconcileMillis > 0L) {
|
|
||||||
this.logger.trace("Waiting between each node reconcile");
|
|
||||||
Thread.sleep(this.waitAfterSolrNodeReconcileMillis);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return future;
|
return future;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean reconcile(long nodeDbId,
|
public void reconcile(long nodeDbId,
|
||||||
boolean index,
|
boolean index,
|
||||||
ReconcileCallback callback) throws InterruptedException, TimeoutException {
|
ReconcileCallback callback,
|
||||||
|
long execTimeout, TimeUnit execUnit) throws InterruptedException, TimeoutException {
|
||||||
NodeRef nodeRef = this.nodeService.getNodeRef(nodeDbId);
|
NodeRef nodeRef = this.nodeService.getNodeRef(nodeDbId);
|
||||||
if (nodeRef == null) {
|
if (nodeRef == null) {
|
||||||
this.logger.trace("No such ACS node: {}; skipping ...", nodeDbId);
|
this.logger.trace("No such ACS node: {}; skipping ...", nodeDbId);
|
||||||
return false;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!StoreRef.STORE_REF_WORKSPACE_SPACESSTORE.equals(nodeRef.getStoreRef())) {
|
if (!StoreRef.STORE_REF_WORKSPACE_SPACESSTORE.equals(nodeRef.getStoreRef())) {
|
||||||
this.logger.trace("A deliberately ignored store in the DB is not indexed in Solr: {}: {}", nodeDbId, nodeRef);
|
this.logger.trace("A deliberately ignored store in the DB is not indexed in Solr: {}: {}", nodeDbId, nodeRef);
|
||||||
return false;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Set<QName> aspects = this.nodeService.getAspects(nodeRef);
|
Set<QName> aspects = this.nodeService.getAspects(nodeRef);
|
||||||
aspects.retainAll(this.ignoreNodesWithAspects);
|
aspects.retainAll(this.ignoreNodesWithAspects);
|
||||||
if (!aspects.isEmpty()) {
|
if (!aspects.isEmpty()) {
|
||||||
this.logger.trace("A deliberately ignored node in the DB is not indexed in Solr: {}: {}: {}", nodeDbId, nodeRef, aspects);
|
this.logger.trace("A deliberately ignored node in the DB is not indexed in Solr: {}: {}: {}", nodeDbId, nodeRef, aspects);
|
||||||
return false;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!index) {
|
if (!index) {
|
||||||
this.logger.debug("A node in the DB is not indexed in Solr: {}: {}", nodeDbId, nodeRef);
|
this.logger.debug("A node in the DB is not indexed in Solr: {}: {}", nodeDbId, nodeRef);
|
||||||
this.reconcileLogger.info("UNRECONCILED: {} <=> {}", nodeDbId, nodeRef);
|
this.reconcileLogger.info("UNRECONCILED: {} <=> {}", nodeDbId, nodeRef);
|
||||||
callback.unreconciled(nodeDbId);
|
callback.unreconciled(nodeDbId);
|
||||||
return false;
|
|
||||||
} else {
|
} else {
|
||||||
this.logger.debug("A node in the DB is not indexed in Solr; attempt to index: {}: {}", nodeDbId, nodeRef);
|
logger.debug("A node in the DB is not indexed in Solr; attempt to index: {}: {}", nodeDbId, nodeRef);
|
||||||
this.index(nodeDbId, nodeRef, callback);
|
this.index(nodeDbId, nodeRef, callback, execTimeout, execUnit);
|
||||||
// purposefully forgetting about the returned future
|
|
||||||
// its results will be logged
|
|
||||||
// the reconcile thread will continue independently
|
|
||||||
// the callback will lag
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Future<Void> index(long nodeDbId, NodeRef nodeRef, ReconcileCallback callback) throws InterruptedException, TimeoutException {
|
public void index(long nodeDbId, NodeRef nodeRef,
|
||||||
|
ReconcileCallback callback,
|
||||||
|
long execTimeout, TimeUnit execUnit) throws InterruptedException, TimeoutException {
|
||||||
|
Set<ShardInstance> syncHosts = new HashSet<>();
|
||||||
|
Set<ShardInstance> asyncHosts = new HashSet<>();
|
||||||
|
Map<ShardInstance, String> errorHosts = new HashMap<>();
|
||||||
|
|
||||||
IndexCallback indexCallback = new IndexCallback() {
|
IndexCallback indexCallback = new IndexCallback() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void success(ShardInstance instance) {
|
public void success(ShardInstance instance) {
|
||||||
reconcileLogger.info("INDEXED: {} <=> {} in {}", nodeDbId, nodeRef, instance);
|
reconcileLogger.info("INDEXED: {} <=> {} in {}", nodeDbId, nodeRef, instance);
|
||||||
if (callback != null)
|
syncHosts.add(instance);
|
||||||
callback.processed(nodeDbId,
|
|
||||||
Collections.singleton(instance), Collections.emptySet(),
|
|
||||||
Collections.emptyMap());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void scheduled(ShardInstance instance) {
|
public void scheduled(ShardInstance instance) {
|
||||||
reconcileLogger.info("INDEXING: {} <=> {} in {}", nodeDbId, nodeRef, instance);
|
reconcileLogger.info("INDEXING: {} <=> {} in {}", nodeDbId, nodeRef, instance);
|
||||||
if (callback != null)
|
asyncHosts.add(instance);
|
||||||
callback.processed(nodeDbId,
|
|
||||||
Collections.emptySet(), Collections.singleton(instance),
|
|
||||||
Collections.emptyMap());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void error(ShardInstance instance, String message) {
|
public void error(ShardInstance instance, String message) {
|
||||||
reconcileLogger.info("FAILED INDEX: {} <=> {} in {}", nodeDbId, nodeRef, instance);
|
reconcileLogger.info("FAILED INDEX: {} <=> {} in {}", nodeDbId, nodeRef, instance);
|
||||||
if (callback != null)
|
errorHosts.put(instance, message);
|
||||||
callback.processed(nodeDbId,
|
|
||||||
Collections.emptySet(), Collections.emptySet(),
|
|
||||||
Collections.singletonMap(instance, message));
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Future<Void> future = this.indexService.index(nodeDbId, indexCallback);
|
try {
|
||||||
|
if (execTimeout < 0L) {
|
||||||
if (this.waitAfterSolrNodeActionMillis > 0L) {
|
this.indexService.index(nodeDbId, indexCallback).get();
|
||||||
Thread.sleep(this.waitAfterSolrNodeActionMillis);
|
} else {
|
||||||
|
this.indexService.index(nodeDbId, indexCallback).get(execTimeout, execUnit);
|
||||||
|
}
|
||||||
|
} catch (ExecutionException ee) {
|
||||||
|
throw new RuntimeException("An unexpected exception occurred: " + ee.getMessage(), ee);
|
||||||
}
|
}
|
||||||
|
|
||||||
return future;
|
if (callback != null)
|
||||||
|
callback.processed(nodeDbId, syncHosts, asyncHosts, errorHosts);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Future<Void> reindex(long nodeDbId, NodeRef nodeRef, ReconcileCallback callback) throws InterruptedException {
|
public void reindex(long nodeDbId, NodeRef nodeRef,
|
||||||
|
ReconcileCallback callback,
|
||||||
|
long execTimeout, TimeUnit execUnit) throws InterruptedException, TimeoutException {
|
||||||
|
Set<ShardInstance> syncHosts = new HashSet<>();
|
||||||
|
Set<ShardInstance> asyncHosts = new HashSet<>();
|
||||||
|
Map<ShardInstance, String> errorHosts = new HashMap<>();
|
||||||
|
|
||||||
ReindexCallback reindexCallback = new ReindexCallback() {
|
ReindexCallback reindexCallback = new ReindexCallback() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void success(ShardInstance instance) {
|
public void success(ShardInstance instance) {
|
||||||
reconcileLogger.info("REINDEXED: {} <=> {} in {}", nodeDbId, nodeRef, instance);
|
reconcileLogger.info("REINDEXED: {} <=> {} in {}", nodeDbId, nodeRef, instance);
|
||||||
if (callback != null)
|
syncHosts.add(instance);
|
||||||
callback.processed(nodeDbId,
|
|
||||||
Collections.singleton(instance), Collections.emptySet(),
|
|
||||||
Collections.emptyMap());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void scheduled(ShardInstance instance) {
|
public void scheduled(ShardInstance instance) {
|
||||||
reconcileLogger.info("REINDEXING: {} <=> {} in {}", nodeDbId, nodeRef, instance);
|
reconcileLogger.info("REINDEXING: {} <=> {} in {}", nodeDbId, nodeRef, instance);
|
||||||
if (callback != null)
|
asyncHosts.add(instance);
|
||||||
callback.processed(nodeDbId,
|
|
||||||
Collections.emptySet(), Collections.singleton(instance),
|
|
||||||
Collections.emptyMap());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void error(ShardInstance instance, String message) {
|
public void error(ShardInstance instance, String message) {
|
||||||
reconcileLogger.info("FAILED REINDEX: {} <=> {} in {}", nodeDbId, nodeRef, instance);
|
reconcileLogger.info("FAILED REINDEX: {} <=> {} in {}", nodeDbId, nodeRef, instance);
|
||||||
if (callback != null)
|
errorHosts.put(instance, message);
|
||||||
callback.processed(nodeDbId,
|
|
||||||
Collections.emptySet(), Collections.emptySet(),
|
|
||||||
Collections.singletonMap(instance, message));
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Future<Void> future = this.reindexService.reindex(nodeDbId, reindexCallback);
|
|
||||||
|
|
||||||
if (this.waitAfterSolrNodeActionMillis > 0L) {
|
try {
|
||||||
Thread.sleep(this.waitAfterSolrNodeActionMillis);
|
if (execTimeout < 0L) {
|
||||||
|
this.reindexService.reindex(nodeDbId, reindexCallback).get();
|
||||||
|
} else {
|
||||||
|
this.reindexService.reindex(nodeDbId, reindexCallback).get(execTimeout, execUnit);
|
||||||
|
}
|
||||||
|
} catch (ExecutionException ee) {
|
||||||
|
throw new RuntimeException("An unexpected exception occurred: " + ee.getMessage(), ee);
|
||||||
}
|
}
|
||||||
|
|
||||||
return future;
|
if (callback != null)
|
||||||
|
callback.processed(nodeDbId, syncHosts, asyncHosts, errorHosts);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String formatForFts(QName qname) {
|
private String formatForFts(QName qname) {
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ public class ApiService implements InitializingBean {
|
|||||||
@Value("${inteligr8.asie.basePath}")
|
@Value("${inteligr8.asie.basePath}")
|
||||||
private String solrBaseUrl;
|
private String solrBaseUrl;
|
||||||
|
|
||||||
@Value("${inteligr8.asie.reconciliation.nodesChunkSize}")
|
@Value("${inteligr8.asie.reconciliation.nodesChunkSize:250}")
|
||||||
private int nodesChunkSize;
|
private int nodesChunkSize;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -6,8 +6,6 @@ import java.util.concurrent.ExecutorService;
|
|||||||
import java.util.concurrent.RejectedExecutionHandler;
|
import java.util.concurrent.RejectedExecutionHandler;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.beans.factory.DisposableBean;
|
import org.springframework.beans.factory.DisposableBean;
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
@@ -32,36 +30,42 @@ import com.inteligr8.alfresco.asie.util.ThrottledThreadPoolExecutor;
|
|||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
public class ExecutorManager implements InitializingBean, DisposableBean, RemovalListener<String, ExecutorService> {
|
public class ExecutorManager implements InitializingBean, DisposableBean, RemovalListener<String, ExecutorService> {
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
@Value("${inteligr8.asie.executors.expireTimeInMinutes:30}")
|
||||||
|
|
||||||
@Value("${inteligr8.asie.executors.expireTimeInMinutes}")
|
|
||||||
private int expireTimeInMinutes;
|
private int expireTimeInMinutes;
|
||||||
|
|
||||||
private Cache<String, ThrottledThreadPoolExecutor> cache;
|
private Cache<String, ExecutorService> refCache;
|
||||||
|
private Cache<String, ExecutorService> expiringCache;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void afterPropertiesSet() throws Exception {
|
public void afterPropertiesSet() throws Exception {
|
||||||
this.cache = CacheBuilder.newBuilder()
|
// a weak value happens when the executor is no longer referenced
|
||||||
|
// the possible references are by the caller temporarily using and the `expiringCache` (below; so it expired)
|
||||||
|
// this keeps the pool from being shutdown after it expires if the caller is still referencing it
|
||||||
|
// ultimately, if it is cached, it will be in this cache and MAY be in the `expiringCache`.
|
||||||
|
this.refCache = CacheBuilder.newBuilder()
|
||||||
|
.initialCapacity(8)
|
||||||
|
.weakValues()
|
||||||
|
.removalListener(this)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
this.expiringCache = CacheBuilder.newBuilder()
|
||||||
.initialCapacity(8)
|
.initialCapacity(8)
|
||||||
.expireAfterAccess(this.expireTimeInMinutes, TimeUnit.MINUTES)
|
.expireAfterAccess(this.expireTimeInMinutes, TimeUnit.MINUTES)
|
||||||
.removalListener(this)
|
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void destroy() throws Exception {
|
public void destroy() throws Exception {
|
||||||
this.cache.invalidateAll();
|
this.refCache.invalidateAll();
|
||||||
this.cache.cleanUp();
|
this.refCache.cleanUp();
|
||||||
|
this.expiringCache.invalidateAll();
|
||||||
|
this.expiringCache.cleanUp();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRemoval(RemovalNotification<String, ExecutorService> notification) {
|
public void onRemoval(RemovalNotification<String, ExecutorService> notification) {
|
||||||
this.logger.debug("Throttled thread pool removed/expired from cache: {}", notification.getKey());
|
notification.getValue().shutdown();
|
||||||
if (!notification.getValue().isShutdown()) {
|
|
||||||
notification.getValue().shutdown();
|
|
||||||
this.logger.info("Throttled thread pool shut down: {}", notification.getKey());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ThrottledThreadPoolExecutor createThrottled(
|
public ThrottledThreadPoolExecutor createThrottled(
|
||||||
@@ -84,10 +88,9 @@ public class ExecutorManager implements InitializingBean, DisposableBean, Remova
|
|||||||
final RejectedExecutionHandler rejectedExecutionHandler) {
|
final RejectedExecutionHandler rejectedExecutionHandler) {
|
||||||
try {
|
try {
|
||||||
// if it is already cached, reuse the cache; otherwise create one
|
// if it is already cached, reuse the cache; otherwise create one
|
||||||
return this.cache.get(name, new Callable<ThrottledThreadPoolExecutor>() {
|
final ExecutorService executor = this.refCache.get(name, new Callable<ThrottledThreadPoolExecutor>() {
|
||||||
@Override
|
@Override
|
||||||
public ThrottledThreadPoolExecutor call() {
|
public ThrottledThreadPoolExecutor call() {
|
||||||
logger.info("Creating throttled thread pool: {}", name);
|
|
||||||
ThrottledThreadPoolExecutor executor = null;
|
ThrottledThreadPoolExecutor executor = null;
|
||||||
if (rejectedExecutionHandler == null) {
|
if (rejectedExecutionHandler == null) {
|
||||||
executor = new ThrottledThreadPoolExecutor(coreThreadPoolSize, maximumThreadPoolSize, maximumQueueSize,
|
executor = new ThrottledThreadPoolExecutor(coreThreadPoolSize, maximumThreadPoolSize, maximumQueueSize,
|
||||||
@@ -100,9 +103,14 @@ public class ExecutorManager implements InitializingBean, DisposableBean, Remova
|
|||||||
rejectedExecutionHandler);
|
rejectedExecutionHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.debug("Created throttled thread pool: {}; threads: {}; queue: {}", name, maximumThreadPoolSize, maximumQueueSize);
|
|
||||||
executor.prestartAllCoreThreads();
|
executor.prestartAllCoreThreads();
|
||||||
logger.trace("Started {} core threads in thread pool: {}", coreThreadPoolSize, name);
|
return executor;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return (ThrottledThreadPoolExecutor) this.expiringCache.get(name, new Callable<ExecutorService>() {
|
||||||
|
@Override
|
||||||
|
public ExecutorService call() throws Exception {
|
||||||
return executor;
|
return executor;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -112,7 +120,19 @@ public class ExecutorManager implements InitializingBean, DisposableBean, Remova
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ExecutorService get(String name) {
|
public ExecutorService get(String name) {
|
||||||
return this.cache.getIfPresent(name);
|
// grab from the expiring cache first, so we can
|
||||||
|
ExecutorService executor = this.expiringCache.getIfPresent(name);
|
||||||
|
if (executor != null)
|
||||||
|
return executor;
|
||||||
|
|
||||||
|
executor = this.refCache.getIfPresent(name);
|
||||||
|
if (executor == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
// the executor expired, but it was still referenced by the caller
|
||||||
|
// re-cache it
|
||||||
|
this.expiringCache.put(name, executor);
|
||||||
|
return executor;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,6 @@
|
|||||||
package com.inteligr8.alfresco.asie.service;
|
package com.inteligr8.alfresco.asie.service;
|
||||||
|
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.time.Instant;
|
|
||||||
import java.time.temporal.TemporalAccessor;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
|
|
||||||
import org.alfresco.error.AlfrescoRuntimeException;
|
import org.alfresco.error.AlfrescoRuntimeException;
|
||||||
@@ -12,7 +9,6 @@ import org.alfresco.service.cmr.repository.NodeService;
|
|||||||
import org.alfresco.service.namespace.NamespaceService;
|
import org.alfresco.service.namespace.NamespaceService;
|
||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
import org.apache.commons.codec.digest.MurmurHash3;
|
import org.apache.commons.codec.digest.MurmurHash3;
|
||||||
import org.joda.time.ReadablePartial;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@@ -72,22 +68,9 @@ public class SolrShardHashService {
|
|||||||
this.logger.debug("Unable to determine shard instance ID because property does not exist on node: {}: {}", nodeRef, hashableProperty);
|
this.logger.debug("Unable to determine shard instance ID because property does not exist on node: {}: {}", nodeRef, hashableProperty);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.logger.trace("Discovered node property for sharding: {} => {}", nodeRef, fullPropertyValue);
|
|
||||||
|
|
||||||
String hashableValue = null;
|
|
||||||
if (fullPropertyValue instanceof TemporalAccessor) {
|
|
||||||
Instant instant = Instant.from((TemporalAccessor) fullPropertyValue);
|
|
||||||
hashableValue = instant.toString();
|
|
||||||
} else if (fullPropertyValue instanceof ReadablePartial) {
|
|
||||||
hashableValue = ((ReadablePartial) fullPropertyValue).toString();
|
|
||||||
} else if (fullPropertyValue instanceof Date) {
|
|
||||||
Instant instant = ((Date) fullPropertyValue).toInstant();
|
|
||||||
hashableValue = instant.toString();
|
|
||||||
} else {
|
|
||||||
hashableValue = fullPropertyValue.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
this.logger.trace("Discovered node property for sharding: {} => {}", nodeRef, fullPropertyValue);
|
||||||
|
String hashableValue = fullPropertyValue.toString();
|
||||||
if (shardset.getRegex() != null) {
|
if (shardset.getRegex() != null) {
|
||||||
Matcher matcher = shardset.getRegex().matcher(hashableValue);
|
Matcher matcher = shardset.getRegex().matcher(hashableValue);
|
||||||
if (!matcher.find()) {
|
if (!matcher.find()) {
|
||||||
@@ -101,7 +84,6 @@ public class SolrShardHashService {
|
|||||||
int shardHash = this.hash(hashableValue, shardset.getShards().intValue());
|
int shardHash = this.hash(hashableValue, shardset.getShards().intValue());
|
||||||
this.logger.debug("Hash shardable value to shard instance ID: {}: {} => {}", nodeRef, hashableValue, shardHash);
|
this.logger.debug("Hash shardable value to shard instance ID: {}: {} => {}", nodeRef, hashableValue, shardHash);
|
||||||
return shardHash;
|
return shardHash;
|
||||||
// TODO replicate hash algorithm for other shard methods
|
|
||||||
default:
|
default:
|
||||||
this.logger.trace("Unable to determine shard instance ID due to shard method: {}", shardset.getMethod());
|
this.logger.trace("Unable to determine shard instance ID due to shard method: {}", shardset.getMethod());
|
||||||
return -1;
|
return -1;
|
||||||
|
|||||||
@@ -125,9 +125,7 @@ public interface ShardDiscoveryService {
|
|||||||
public class ShardedNodeShardStateComparator implements Comparator<Pair<SolrHost, ShardInstanceState>> {
|
public class ShardedNodeShardStateComparator implements Comparator<Pair<SolrHost, ShardInstanceState>> {
|
||||||
@Override
|
@Override
|
||||||
public int compare(Pair<SolrHost, ShardInstanceState> p1, Pair<SolrHost, ShardInstanceState> p2) {
|
public int compare(Pair<SolrHost, ShardInstanceState> p1, Pair<SolrHost, ShardInstanceState> p2) {
|
||||||
if (p1 == null) return 1;
|
return - Long.compare(p1.getSecond().getLastIndexedTxId(), p2.getSecond().getLastIndexedTxId());
|
||||||
else if (p2 == null) return -1;
|
|
||||||
else return - Long.compare(p1.getSecond().getLastIndexedTxId(), p2.getSecond().getLastIndexedTxId());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -79,14 +79,12 @@ public class CompositeFuture<T> implements Future<T> {
|
|||||||
List<T> results = new ArrayList<>(this.futures.size());
|
List<T> results = new ArrayList<>(this.futures.size());
|
||||||
for (Future<T> future : this.futures) {
|
for (Future<T> future : this.futures) {
|
||||||
if (future instanceof RunnableFuture<?>) {
|
if (future instanceof RunnableFuture<?>) {
|
||||||
this.logger.trace("Waiting {} ms since the start of the exectuion of the future to complete", unit.toMillis(timeout));
|
this.logger.debug("Waiting {} ms since the start of the exectuion of the future to complete", unit.toMillis(timeout));
|
||||||
results.add(((RunnableFuture<T>) future).get(timeout, unit));
|
results.add(((RunnableFuture<T>) future).get(timeout, unit));
|
||||||
this.logger.trace("Exectuion completed", unit.toMillis(timeout));
|
|
||||||
} else {
|
} else {
|
||||||
long remainingTimeMillis = expireTimeMillis - System.currentTimeMillis();
|
long remainingTimeMillis = expireTimeMillis - System.currentTimeMillis();
|
||||||
this.logger.trace("Waiting {} ms for the future to complete", remainingTimeMillis);
|
this.logger.debug("Waiting {} ms for the future to complete", remainingTimeMillis);
|
||||||
results.add(future.get(remainingTimeMillis, TimeUnit.MILLISECONDS));
|
results.add(future.get(remainingTimeMillis, TimeUnit.MILLISECONDS));
|
||||||
this.logger.trace("Exectuion completed", unit.toMillis(timeout));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,39 +124,24 @@ public class CompositeFuture<T> implements Future<T> {
|
|||||||
List<CompositeFuture<?>> cfutures = new LinkedList<>();
|
List<CompositeFuture<?>> cfutures = new LinkedList<>();
|
||||||
int removedCancelled = 0;
|
int removedCancelled = 0;
|
||||||
int removedDone = 0;
|
int removedDone = 0;
|
||||||
int remain = 0;
|
|
||||||
|
|
||||||
Iterator<Future<T>> i = this.futures.iterator();
|
Iterator<Future<T>> i = this.futures.iterator();
|
||||||
while (i.hasNext()) {
|
while (i.hasNext()) {
|
||||||
Future<T> future = i.next();
|
Future<T> future = i.next();
|
||||||
if (future.isCancelled()) {
|
if (future.isCancelled()) {
|
||||||
if (includeCancelled) {
|
if (includeCancelled) {
|
||||||
this.logger.trace("Removing cancelled future");
|
|
||||||
removedCancelled++;
|
removedCancelled++;
|
||||||
i.remove();
|
i.remove();
|
||||||
} else {
|
|
||||||
remain++;
|
|
||||||
}
|
}
|
||||||
} else if (future.isDone()) {
|
} else if (future.isDone()) {
|
||||||
try {
|
removedDone++;
|
||||||
future.get();
|
i.remove();
|
||||||
} catch (InterruptedException ie) {
|
|
||||||
this.logger.trace("Future completed because it was interrupted");
|
|
||||||
} catch (ExecutionException ee) {
|
|
||||||
this.logger.error(ee.getMessage(), ee);
|
|
||||||
} finally {
|
|
||||||
this.logger.trace("Removing completed future");
|
|
||||||
removedDone++;
|
|
||||||
i.remove();
|
|
||||||
}
|
|
||||||
} else if (future instanceof CompositeFuture<?>) {
|
} else if (future instanceof CompositeFuture<?>) {
|
||||||
cfutures.add((CompositeFuture<?>) future);
|
cfutures.add((CompositeFuture<?>) future);
|
||||||
} else {
|
|
||||||
remain++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.logger.debug("Purged {} cancelled and {} completed futures; {} remain", removedCancelled, removedDone, remain);
|
this.logger.debug("Purged {} cancelled and {} completed futures", removedCancelled, removedDone);
|
||||||
|
|
||||||
for (CompositeFuture<?> cfuture : cfutures)
|
for (CompositeFuture<?> cfuture : cfutures)
|
||||||
cfuture.purge(includeCancelled);
|
cfuture.purge(includeCancelled);
|
||||||
|
|||||||
+4
-1
@@ -80,11 +80,14 @@ public class ThrottledThreadPoolExecutor extends ThreadPoolExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private WaitableRunnable submit(WaitableRunnable runnable, long throttlingBlockTimeout, TimeUnit throttlingBlockUnit) throws InterruptedException, TimeoutException {
|
private WaitableRunnable submit(WaitableRunnable runnable, long throttlingBlockTimeout, TimeUnit throttlingBlockUnit) throws InterruptedException, TimeoutException {
|
||||||
|
// if no core threads are running, the queue won't be monitored for runnables
|
||||||
|
this.prestartAllCoreThreads();
|
||||||
|
|
||||||
if (throttlingBlockTimeout < 0L) {
|
if (throttlingBlockTimeout < 0L) {
|
||||||
this.getQueue().put(runnable);
|
this.getQueue().put(runnable);
|
||||||
} else {
|
} else {
|
||||||
if (!this.getQueue().offer(runnable, throttlingBlockTimeout, throttlingBlockUnit))
|
if (!this.getQueue().offer(runnable, throttlingBlockTimeout, throttlingBlockUnit))
|
||||||
throw new TimeoutException("Timeout waiting for queue space for runnable");
|
throw new TimeoutException();
|
||||||
}
|
}
|
||||||
|
|
||||||
return runnable;
|
return runnable;
|
||||||
|
|||||||
-19
@@ -1,27 +1,8 @@
|
|||||||
|
|
||||||
# defaulting to 3 days = 60 * 24 * 3 = 4320
|
# defaulting to 3 days = 60 * 24 * 3 = 4320
|
||||||
# once the node is selected, no other node for the shard will be used for the backup
|
|
||||||
inteligr8.asie.backup.persistTimeMinutes=4320
|
inteligr8.asie.backup.persistTimeMinutes=4320
|
||||||
|
|
||||||
# what authorities (users or groups) may use the REST services provided by this module?
|
|
||||||
inteligr8.asie.allowedAuthorities=GROUP_ALFRESCO_ADMINISTRATORS
|
inteligr8.asie.allowedAuthorities=GROUP_ALFRESCO_ADMINISTRATORS
|
||||||
|
|
||||||
# same as solr.baseUrl, but that property is private to the Search subsystem
|
# same as solr.baseUrl, but that property is private to the Search subsystem
|
||||||
inteligr8.asie.basePath=/solr
|
inteligr8.asie.basePath=/solr
|
||||||
|
|
||||||
|
|
||||||
# How long should idle executors remain before being shutdown?
|
|
||||||
# They will re-initialize if needed again
|
|
||||||
inteligr8.asie.executors.expireTimeInMinutes=30
|
|
||||||
|
|
||||||
# Reconciliation configuration; each node will be processed in its own thread
|
|
||||||
inteligr8.asie.reconciliation.nodesChunkSize=250
|
|
||||||
inteligr8.asie.reconciliation.nodeTimeoutSeconds=10
|
|
||||||
inteligr8.asie.reconciliation.concurrentQueueSize=32
|
|
||||||
inteligr8.asie.reconciliation.concurrency=2
|
|
||||||
inteligr8.asie.reconciliation.waitAfterSolrNodeActionMillis=0
|
|
||||||
inteligr8.asie.reconciliation.waitAfterSolrNodeReconcileMillis=0
|
|
||||||
|
|
||||||
# Action (like indexing and re-indexing) configuration
|
|
||||||
inteligr8.asie.default.concurrentQueueSize=32
|
|
||||||
inteligr8.asie.default.concurrency=2
|
|
||||||
|
|||||||
+5
-5
@@ -6,31 +6,31 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.inteligr8.alfresco</groupId>
|
<groupId>com.inteligr8.alfresco</groupId>
|
||||||
<artifactId>asie-platform-module-parent</artifactId>
|
<artifactId>asie-platform-module-parent</artifactId>
|
||||||
<version>1.3-SNAPSHOT</version>
|
<version>1.3.4</version>
|
||||||
<relativePath>../</relativePath>
|
<relativePath>../</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<groupId>com.inteligr8</groupId>
|
<groupId>com.inteligr8</groupId>
|
||||||
<artifactId>solr-api</artifactId>
|
<artifactId>solr-api</artifactId>
|
||||||
<version>1.2-SNAPSHOT-solr6</version>
|
<version>1.1.0-solr6</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>Apache Solr Jakarta RS API</name>
|
<name>Apache Solr Jakarta RS API</name>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<jackson.version>2.22.1</jackson.version>
|
<jackson.version>2.18.0</jackson.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>jakarta.annotation</groupId>
|
<groupId>jakarta.annotation</groupId>
|
||||||
<artifactId>jakarta.annotation-api</artifactId>
|
<artifactId>jakarta.annotation-api</artifactId>
|
||||||
<version>3.0.0</version>
|
<version>2.1.1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>jakarta.ws.rs</groupId>
|
<groupId>jakarta.ws.rs</groupId>
|
||||||
<artifactId>jakarta.ws.rs-api</artifactId>
|
<artifactId>jakarta.ws.rs-api</artifactId>
|
||||||
<version>4.0.0</version>
|
<version>3.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.fasterxml.jackson.module</groupId>
|
<groupId>com.fasterxml.jackson.module</groupId>
|
||||||
|
|||||||
Reference in New Issue
Block a user