diff --git a/pom.xml b/pom.xml
index 9061665..8e5bc51 100644
--- a/pom.xml
+++ b/pom.xml
@@ -45,12 +45,12 @@
org.sonatype.nexus.plugins
nexus-plugins
- 2.11.2-06
+ 2.11.3-01
${project.name}
- Facilitates push-replication to remote proxy repositories.
+ Facilitates push-replication to remote proxy repositories (6).
${project.parent.version}
@@ -67,6 +67,13 @@
${nexus.version}
provided
+
+ org.sonatype.nexus.plugins
+ nexus-capabilities-plugin
+ ${nexus-plugin.type}
+ ${nexus.version}
+ provided
+
org.sonatype.nexus
nexus-plugin-testsupport
@@ -136,6 +143,11 @@
jackson-jaxrs
1.9.13
+
+ org.codehaus.jackson
+ jackson-mapper-asl
+ 1.9.13
+
org.sonatype.nexus
nexus-client-core
diff --git a/replication-plugin.xml b/replication-plugin.xml
index 6c34fa2..80be65d 100644
--- a/replication-plugin.xml
+++ b/replication-plugin.xml
@@ -18,7 +18,10 @@ requestsQueueSize and requestsSendingThreadsCount attributes define thread pool
requests from master to peers asynchronously.
The default values are: 500 for requestsQueueSize and 1 for requestsSendingThreadsCount
-->
-
+
http://localhost:8083/nexus
diff --git a/src/main/java/com/griddynamics/cd/nrp/internal/ReplicationPluginConfigurationStorage.java b/src/main/java/com/griddynamics/cd/nrp/internal/ReplicationPluginConfigurationStorage.java
new file mode 100644
index 0000000..4ea467c
--- /dev/null
+++ b/src/main/java/com/griddynamics/cd/nrp/internal/ReplicationPluginConfigurationStorage.java
@@ -0,0 +1,135 @@
+package com.griddynamics.cd.nrp.internal;
+
+import lombok.NoArgsConstructor;
+import lombok.NonNull;
+import lombok.RequiredArgsConstructor;
+import lombok.ToString;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+import java.util.LinkedHashSet;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicReference;
+
+@Named(value = "replicationPluginConfigurationStorage")
+@Singleton
+public class ReplicationPluginConfigurationStorage {
+
+ Logger logger =
+ LoggerFactory.getLogger(ReplicationPluginConfigurationStorage.class);
+
+ private final AtomicReference masterServerURLPrefix = new AtomicReference<>();
+ private final AtomicReference requestQueueSize = new AtomicReference<>();
+ private final AtomicReference requestSendingThreadCount = new AtomicReference<>();
+ private final AtomicReference requestQueueDumpFileName = new AtomicReference<>();;
+ private final AtomicReference> servers = new AtomicReference<>();
+
+ @Inject
+ public ReplicationPluginConfigurationStorage() {
+ servers.set(new LinkedHashSet());
+ }
+
+ public String getMasterServerURLPrefix() {
+ String retVal = masterServerURLPrefix.get();
+ if(retVal == null){
+ throw new RuntimeException("Replication plugin configuration not ready yet!");
+ }
+ return retVal;
+ }
+
+ public void setMasterServerURLPrefix(String masterServerURLPrefix) {
+ this.masterServerURLPrefix.set(masterServerURLPrefix);
+ logger.info(toString());
+ }
+
+ public String getRequestQueueDumpFileName() {
+ String retVal = requestQueueDumpFileName.get();
+ if(retVal == null){
+ throw new RuntimeException("Replication plugin configuration not ready yet!");
+ }
+ return retVal;
+ }
+
+ public void setRequestQueueDumpFileName(String requestQueueDumpFileName) {
+ this.requestQueueDumpFileName.set(requestQueueDumpFileName);
+ logger.info(toString());
+ }
+
+ public Set getServers() {
+ Set retVal = servers.get();
+ if(retVal == null){
+ throw new RuntimeException("Replication plugin configuration not ready yet!");
+ }
+ return retVal;
+ }
+
+ public void setServers(Set nexusServers) {
+ servers.get().clear();
+ servers.get().addAll(nexusServers);
+ logger.info(toString());
+ }
+
+ public int getRequestSendingThreadCount() {
+ Integer retVal = requestSendingThreadCount.get();
+ if(retVal == null){
+ throw new RuntimeException("Replication plugin configuration not ready yet!");
+ }
+ return retVal;
+ }
+
+ public void setRequestSendingThreadCount(int requestSendingThreadCount) {
+ this.requestSendingThreadCount.set(requestSendingThreadCount);
+ logger.info(toString());
+ }
+
+ public int getRequestQueueSize() {
+ Integer retVal = requestQueueSize.get();
+ if(retVal == null){
+ throw new RuntimeException("Replication plugin configuration not ready yet!");
+ }
+ return retVal;
+ }
+
+ public void setRequestQueueSize(int requestQueueSize) {
+ this.requestQueueSize.set(requestQueueSize);
+ logger.info(toString());
+ }
+
+ @Override
+ public String toString() {
+ return "ReplicationPluginConfigurationStorage{" +
+ "masterServerURLPrefix='" + masterServerURLPrefix + '\'' +
+ ", requestQueueSize=" + requestQueueSize.get() +
+ ", requestSendingThreadCount=" + requestSendingThreadCount.get() +
+ ", requestQueueDumpFileName='" + requestQueueDumpFileName + '\'' +
+ ", servers=" + servers +
+ '}';
+ }
+
+ @NoArgsConstructor
+ @RequiredArgsConstructor
+ @ToString
+ public static class NexusServer {
+ @NonNull
+ private String url;
+ @NonNull
+ private String user;
+ @NonNull
+ private String password;
+
+ public String getUrl() {
+ return url;
+ }
+
+ public String getUser() {
+ return user;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+ }
+}
diff --git a/src/main/java/com/griddynamics/cd/nrp/internal/capabilities/GridCapabilitiesBooter.java b/src/main/java/com/griddynamics/cd/nrp/internal/capabilities/GridCapabilitiesBooter.java
new file mode 100644
index 0000000..53a576f
--- /dev/null
+++ b/src/main/java/com/griddynamics/cd/nrp/internal/capabilities/GridCapabilitiesBooter.java
@@ -0,0 +1,31 @@
+package com.griddynamics.cd.nrp.internal.capabilities;
+
+import javax.inject.Named;
+
+import com.google.common.collect.ImmutableMap;
+import org.sonatype.nexus.plugins.capabilities.CapabilityRegistry;
+import org.sonatype.nexus.plugins.capabilities.support.CapabilityBooterSupport;
+
+import org.eclipse.sisu.EagerSingleton;
+
+import java.util.Collections;
+
+@Named
+@EagerSingleton
+public class GridCapabilitiesBooter
+ extends CapabilityBooterSupport
+{
+
+ @Override
+ protected void boot(final CapabilityRegistry registry)
+ throws Exception
+ {
+ maybeAddCapability(
+ registry,
+ GridCapabilityDescriptor.TYPE,
+ true, // enabled
+ null, // no notes
+ Collections.emptyMap());
+ }
+
+}
diff --git a/src/main/java/com/griddynamics/cd/nrp/internal/capabilities/GridCapability.java b/src/main/java/com/griddynamics/cd/nrp/internal/capabilities/GridCapability.java
new file mode 100644
index 0000000..ea14302
--- /dev/null
+++ b/src/main/java/com/griddynamics/cd/nrp/internal/capabilities/GridCapability.java
@@ -0,0 +1,80 @@
+package com.griddynamics.cd.nrp.internal.capabilities;
+
+import com.griddynamics.cd.nrp.internal.ReplicationPluginConfigurationStorage;
+import com.griddynamics.cd.nrp.internal.uploading.ArtifactUpdateApiClient;
+import com.griddynamics.cd.nrp.internal.uploading.impl.factories.JerseyClientFactory;
+import org.jetbrains.annotations.NonNls;
+import org.sonatype.nexus.capability.support.CapabilitySupport;
+import org.sonatype.nexus.plugins.capabilities.Condition;
+import org.sonatype.nexus.plugins.capabilities.Evaluable;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import java.util.HashMap;
+import java.util.Map;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+@Named(GridCapabilityDescriptor.TYPE_ID)
+public class GridCapability
+ extends CapabilitySupport {
+ @NonNls
+ public static final String NL = System.getProperty("line.separator");
+
+ private final ReplicationPluginConfigurationStorage gridRegistry;
+ private final ArtifactUpdateApiClient artifactUpdateApiClient;
+ private final JerseyClientFactory jerseyClientFactory;
+
+ @Inject
+ public GridCapability(final ReplicationPluginConfigurationStorage replicationPluginConfigurationStorage,
+ final ArtifactUpdateApiClient artifactUpdateApiClient,
+ final JerseyClientFactory jerseyClientFactory) {
+ this.gridRegistry = checkNotNull(replicationPluginConfigurationStorage);
+ this.artifactUpdateApiClient = artifactUpdateApiClient;
+ this.jerseyClientFactory = jerseyClientFactory;
+ }
+
+ @Override
+ protected GridCapabilityConfiguration createConfig(final Map properties) throws Exception {
+ Map newProperties = new HashMap<>(properties);
+ return new GridCapabilityConfiguration(newProperties);
+ }
+
+ @Override
+ public void configure(final GridCapabilityConfiguration config){
+ gridRegistry.setMasterServerURLPrefix(config.getMasterServerURLPrefix());
+ gridRegistry.setRequestQueueSize(config.getRequestQueueSize());
+ gridRegistry.setRequestSendingThreadCount(config.getRequestSendingThreadCount());
+ gridRegistry.setRequestQueueDumpFileName(config.getRequestQueueDumpFileName());
+ gridRegistry.setServers(config.getNexusServers());
+ jerseyClientFactory.onActivate();
+ artifactUpdateApiClient.onActivate();
+ }
+
+ @Override
+ public Condition activationCondition() {
+ return conditions().capabilities().evaluable(
+ new Evaluable() {
+ @Override
+ public boolean isSatisfied() {
+ return true;
+ }
+
+ @Override
+ public String explainSatisfied() {
+ return "\"createrepo\" and \"mergerepo\" are available";
+ }
+
+ @Override
+ public String explainUnsatisfied() {
+ return "";
+ }
+ }
+ );
+ }
+
+ @Override
+ protected String renderStatus() {
+ return "Sample Nexus replication plugin status";
+ }
+}
diff --git a/src/main/java/com/griddynamics/cd/nrp/internal/capabilities/GridCapabilityConfiguration.java b/src/main/java/com/griddynamics/cd/nrp/internal/capabilities/GridCapabilityConfiguration.java
new file mode 100644
index 0000000..da7eecc
--- /dev/null
+++ b/src/main/java/com/griddynamics/cd/nrp/internal/capabilities/GridCapabilityConfiguration.java
@@ -0,0 +1,84 @@
+package com.griddynamics.cd.nrp.internal.capabilities;
+
+import com.google.common.collect.Maps;
+import com.griddynamics.cd.nrp.internal.ReplicationPluginConfigurationStorage;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+public class GridCapabilityConfiguration {
+
+ public static final String MASTER_SERVER_URL_PREFIX = "myUrl";
+ public static final String REQUESTS_QUEUE_SIZE = "requestsQueueSize";
+ public static final String REQUESTS_SENDING_THREADS_COUNT = "requestsSendingThreadsCount";
+ public static final String QUEUE_DUMP_FILE_NAME = "queueDumpFileName";
+ public static final String SERVERS = "servers";
+
+ Logger logger =
+ LoggerFactory.getLogger(GridCapabilityConfiguration.class);
+
+
+ private final String masterServerURLPrefix;
+ private final int requestQueueSize;
+ private final int requestSendingThreadCount;
+ private final String requestQueueDumpFileName;
+ private final Set nexusServers;
+
+ public GridCapabilityConfiguration(final Map properties) {
+ this.masterServerURLPrefix = properties.get(MASTER_SERVER_URL_PREFIX);
+ this.requestQueueSize = Integer.parseInt(properties.get(REQUESTS_QUEUE_SIZE));
+ this.requestSendingThreadCount = Integer.parseInt(properties.get(REQUESTS_SENDING_THREADS_COUNT));
+ this.requestQueueDumpFileName = properties.get(QUEUE_DUMP_FILE_NAME);
+ this.nexusServers = new LinkedHashSet<>();
+ try {
+ ObjectMapper objectMapper = new ObjectMapper();
+ List