From b550dd57fc92e552d65db463ed16321c09e362bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Magry=C5=9B?= Date: Thu, 2 Jul 2015 13:55:51 +0200 Subject: [PATCH 1/3] Capabilities skeleton. --- pom.xml | 14 +- replication-plugin.xml | 5 +- .../ReplicationPluginCapabilitiesBooter.java | 30 ++++ .../ReplicationPluginCapability.java | 80 ++++++++++ ...licationPluginCapabilityConfiguration.java | 84 ++++++++++ ...ReplicationPluginCapabilityDescriptor.java | 147 ++++++++++++++++++ .../internal/model/config/NexusServer.java | 43 ----- .../ReplicationPluginConfiguration.java | 70 --------- ...ReplicationPluginConfigurationStorage.java | 135 ++++++++++++++++ .../internal/ArtifactMetaInfoQueueDump.java | 46 ------ .../uploading/ArtifactUpdateApiClient.java | 2 + .../uploading/ConfigurationsManager.java | 22 --- .../impl/ArtifactUpdateApiClientImpl.java | 110 ++++--------- .../impl/ConfigurationsManagerImpl.java | 110 ------------- .../uploading/impl/FileBlockingQueue.java | 27 +++- .../impl/UploadEventListenerImpl.java | 20 ++- .../AsyncWebResourceBuilderFactory.java | 38 +++++ .../factories/FileBlockingQueueFactory.java | 34 ++++ .../impl/factories/JerseyClientFactory.java | 61 ++++++++ 19 files changed, 697 insertions(+), 381 deletions(-) create mode 100644 src/main/java/com/griddynamics/cd/nrp/internal/capabilities/ReplicationPluginCapabilitiesBooter.java create mode 100644 src/main/java/com/griddynamics/cd/nrp/internal/capabilities/ReplicationPluginCapability.java create mode 100644 src/main/java/com/griddynamics/cd/nrp/internal/capabilities/ReplicationPluginCapabilityConfiguration.java create mode 100644 src/main/java/com/griddynamics/cd/nrp/internal/capabilities/ReplicationPluginCapabilityDescriptor.java delete mode 100644 src/main/java/com/griddynamics/cd/nrp/internal/model/config/NexusServer.java delete mode 100644 src/main/java/com/griddynamics/cd/nrp/internal/model/config/ReplicationPluginConfiguration.java create mode 100644 src/main/java/com/griddynamics/cd/nrp/internal/model/config/ReplicationPluginConfigurationStorage.java delete mode 100644 src/main/java/com/griddynamics/cd/nrp/internal/model/internal/ArtifactMetaInfoQueueDump.java delete mode 100644 src/main/java/com/griddynamics/cd/nrp/internal/uploading/ConfigurationsManager.java delete mode 100644 src/main/java/com/griddynamics/cd/nrp/internal/uploading/impl/ConfigurationsManagerImpl.java create mode 100644 src/main/java/com/griddynamics/cd/nrp/internal/uploading/impl/factories/AsyncWebResourceBuilderFactory.java create mode 100644 src/main/java/com/griddynamics/cd/nrp/internal/uploading/impl/factories/FileBlockingQueueFactory.java create mode 100644 src/main/java/com/griddynamics/cd/nrp/internal/uploading/impl/factories/JerseyClientFactory.java diff --git a/pom.xml b/pom.xml index de10428..f3fcac3 100644 --- a/pom.xml +++ b/pom.xml @@ -45,7 +45,7 @@ org.sonatype.nexus.plugins nexus-plugins - 2.11.2-06 + 2.11.3-01 @@ -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/capabilities/ReplicationPluginCapabilitiesBooter.java b/src/main/java/com/griddynamics/cd/nrp/internal/capabilities/ReplicationPluginCapabilitiesBooter.java new file mode 100644 index 0000000..a7506fd --- /dev/null +++ b/src/main/java/com/griddynamics/cd/nrp/internal/capabilities/ReplicationPluginCapabilitiesBooter.java @@ -0,0 +1,30 @@ +package com.griddynamics.cd.nrp.internal.capabilities; + +import javax.inject.Named; + +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 ReplicationPluginCapabilitiesBooter + extends CapabilityBooterSupport +{ + + @Override + protected void boot(final CapabilityRegistry registry) + throws Exception + { + maybeAddCapability( + registry, + ReplicationPluginCapabilityDescriptor.TYPE, + true, // enabled + null, // no notes + Collections.emptyMap()); + } + +} diff --git a/src/main/java/com/griddynamics/cd/nrp/internal/capabilities/ReplicationPluginCapability.java b/src/main/java/com/griddynamics/cd/nrp/internal/capabilities/ReplicationPluginCapability.java new file mode 100644 index 0000000..0a33537 --- /dev/null +++ b/src/main/java/com/griddynamics/cd/nrp/internal/capabilities/ReplicationPluginCapability.java @@ -0,0 +1,80 @@ +package com.griddynamics.cd.nrp.internal.capabilities; + +import com.griddynamics.cd.nrp.internal.model.config.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(ReplicationPluginCapabilityDescriptor.TYPE_ID) +public class ReplicationPluginCapability + 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 ReplicationPluginCapability(final ReplicationPluginConfigurationStorage replicationPluginConfigurationStorage, + final ArtifactUpdateApiClient artifactUpdateApiClient, + final JerseyClientFactory jerseyClientFactory) { + this.gridRegistry = checkNotNull(replicationPluginConfigurationStorage); + this.artifactUpdateApiClient = artifactUpdateApiClient; + this.jerseyClientFactory = jerseyClientFactory; + } + + @Override + protected ReplicationPluginCapabilityConfiguration createConfig(final Map properties) throws Exception { + Map newProperties = new HashMap<>(properties); + return new ReplicationPluginCapabilityConfiguration(newProperties); + } + + @Override + public void configure(final ReplicationPluginCapabilityConfiguration 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/ReplicationPluginCapabilityConfiguration.java b/src/main/java/com/griddynamics/cd/nrp/internal/capabilities/ReplicationPluginCapabilityConfiguration.java new file mode 100644 index 0000000..273ba36 --- /dev/null +++ b/src/main/java/com/griddynamics/cd/nrp/internal/capabilities/ReplicationPluginCapabilityConfiguration.java @@ -0,0 +1,84 @@ +package com.griddynamics.cd.nrp.internal.capabilities; + +import com.google.common.collect.Maps; +import com.griddynamics.cd.nrp.internal.model.config.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 ReplicationPluginCapabilityConfiguration { + + 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(ReplicationPluginCapabilityConfiguration.class); + + + private final String masterServerURLPrefix; + private final int requestQueueSize; + private final int requestSendingThreadCount; + private final String requestQueueDumpFileName; + private final Set nexusServers; + + public ReplicationPluginCapabilityConfiguration(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 servers = (List) objectMapper.readValue(properties.get(SERVERS), Map.class).get("servers"); + for (Map server : servers) { + this.nexusServers.add( + new ReplicationPluginConfigurationStorage.NexusServer( + (String) server.get("url"), + (String) server.get("user"), + (String) server.get("password") + ) + ); + } + + } catch (Exception e) { + logger.error(e.getMessage(),e); + } + } + + public Map asMap() { + final Map props = Maps.newHashMap(); + props.put(MASTER_SERVER_URL_PREFIX, masterServerURLPrefix); + props.put(REQUESTS_QUEUE_SIZE, String.valueOf(requestQueueSize)); + props.put(REQUESTS_SENDING_THREADS_COUNT, String.valueOf(requestSendingThreadCount)); + props.put(QUEUE_DUMP_FILE_NAME, requestQueueDumpFileName); + return props; + } + + public String getMasterServerURLPrefix() { + return masterServerURLPrefix; + } + + public int getRequestQueueSize() { + return requestQueueSize; + } + + public int getRequestSendingThreadCount() { + return requestSendingThreadCount; + } + + public String getRequestQueueDumpFileName() { + return requestQueueDumpFileName; + } + + public Set getNexusServers() { + return nexusServers; + } +} diff --git a/src/main/java/com/griddynamics/cd/nrp/internal/capabilities/ReplicationPluginCapabilityDescriptor.java b/src/main/java/com/griddynamics/cd/nrp/internal/capabilities/ReplicationPluginCapabilityDescriptor.java new file mode 100644 index 0000000..d407d22 --- /dev/null +++ b/src/main/java/com/griddynamics/cd/nrp/internal/capabilities/ReplicationPluginCapabilityDescriptor.java @@ -0,0 +1,147 @@ +package com.griddynamics.cd.nrp.internal.capabilities; + +import com.google.common.collect.Lists; +import org.sonatype.nexus.capability.support.CapabilityDescriptorSupport; +import org.sonatype.nexus.formfields.FormField; +import org.sonatype.nexus.formfields.NumberTextFormField; +import org.sonatype.nexus.formfields.StringTextFormField; +import org.sonatype.nexus.formfields.TextAreaFormField; +import org.sonatype.nexus.plugins.capabilities.*; +import org.sonatype.nexus.plugins.capabilities.support.validator.Validators; +import org.sonatype.sisu.goodies.i18n.I18N; +import org.sonatype.sisu.goodies.i18n.MessageBundle; + +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Singleton; +import java.util.List; +import java.util.Set; + +import static org.sonatype.nexus.plugins.capabilities.CapabilityType.capabilityType; +import static org.sonatype.nexus.plugins.capabilities.Tag.categoryTag; +import static org.sonatype.nexus.plugins.capabilities.Tag.tags; + +@Singleton +@Named(ReplicationPluginCapabilityDescriptor.TYPE_ID) +public class ReplicationPluginCapabilityDescriptor + extends CapabilityDescriptorSupport + implements Taggable { + public static final String TYPE_ID = "nexus-replication-plugin"; + + public static final CapabilityType TYPE = capabilityType(TYPE_ID); + + private static interface Messages + extends MessageBundle { + @DefaultMessage("Nexus Replication Plugin Configuration") + String name(); + + @DefaultMessage("Master server's URL prefix") + String masterServerURLPrefixLabel(); + + @DefaultMessage("Master server's URL prefix (e.g. http://localhost:8081/nexus") + String masterServerURLPrefixHelp(); + + @DefaultMessage("Request queue size") + String requestQueueSizeLabel(); + + @DefaultMessage("Request queue size (default 500)") + String requestQueueSizeHelp(); + + @DefaultMessage("Request sending thread count") + String requestSendingThreadCountLabel(); + + @DefaultMessage("Request sending thread count (default 1)") + String requestSendingThreadCountHelp(); + + @DefaultMessage("Request queue dump file") + String requestQueueDumpFileNameLabel(); + + @DefaultMessage("Request queue dump file (default /tmp/nexus-replication-plugin-queue-backup)") + String requestQueueDumpFileNameHelp(); + + @DefaultMessage("Slave servers (in JSON)") + String serversLabel(); + + @DefaultMessage("Slave servers in JSON, like: {\"servers\":[{\"url\":\"http://localhost:8083/nexus\",\"user\":\"admin\",\"password\":\"admin123\"},{\"url\":\"http://localhost:8082/nexus\",\"user\":\"admin\",\"password\":\"admin123\"}]}") + String serversHelp(); + + } + + private static final Messages messages = I18N.create(Messages.class); + + private final Validators validators; + + private final List formFields; + + @Inject + public ReplicationPluginCapabilityDescriptor(final Validators validators) { + this.validators = validators; + + this.formFields = Lists.newArrayList( + new StringTextFormField( + ReplicationPluginCapabilityConfiguration.MASTER_SERVER_URL_PREFIX, + messages.masterServerURLPrefixLabel(), + messages.masterServerURLPrefixHelp(), + FormField.OPTIONAL + ).withInitialValue("http://localhost:8081/nexus"), + new NumberTextFormField( + ReplicationPluginCapabilityConfiguration.REQUESTS_QUEUE_SIZE, + messages.requestQueueSizeLabel(), + messages.requestQueueSizeHelp(), + FormField.OPTIONAL + ).withInitialValue(500), + new NumberTextFormField( + ReplicationPluginCapabilityConfiguration.REQUESTS_SENDING_THREADS_COUNT, + messages.requestSendingThreadCountLabel(), + messages.requestSendingThreadCountHelp(), + FormField.OPTIONAL + ).withInitialValue(1), + new StringTextFormField( + ReplicationPluginCapabilityConfiguration.QUEUE_DUMP_FILE_NAME, + messages.requestQueueDumpFileNameLabel(), + messages.requestQueueDumpFileNameHelp(), + FormField.OPTIONAL + ).withInitialValue("/tmp/nexus-replication-plugin-queue-backup"), + new TextAreaFormField( + ReplicationPluginCapabilityConfiguration.SERVERS, + messages.serversLabel(), + messages.serversHelp(), + FormField.OPTIONAL + ).withInitialValue("{\"servers\":[{\"url\":\"http://localhost:8083/nexus\",\"user\":\"admin\",\"password\":\"admin123\"},{\"url\":\"http://localhost:8082/nexus\",\"user\":\"admin\",\"password\":\"admin123\"}]}") + ); + } + + @Override + public Validator validator() { + return validators.logical().and( + validators.capability().uniquePer(TYPE) + ); + } + + @Override + public Validator validator(final CapabilityIdentity id) { + return validators.logical().and( + validators.capability().uniquePerExcluding(id, TYPE) + ); + } + + @Override + public CapabilityType type() { + return TYPE; + } + + @Override + public String name() { + return messages.name(); + } + + @Override + public List formFields() { + return formFields; + } + + @Override + public Set getTags() { + return tags(categoryTag("Grid")); + } +} diff --git a/src/main/java/com/griddynamics/cd/nrp/internal/model/config/NexusServer.java b/src/main/java/com/griddynamics/cd/nrp/internal/model/config/NexusServer.java deleted file mode 100644 index a479160..0000000 --- a/src/main/java/com/griddynamics/cd/nrp/internal/model/config/NexusServer.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2015, Grid Dynamics International, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.griddynamics.cd.nrp.internal.model.config; - -import lombok.*; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; - -/** - * DTO Class encapsulates replication nexus server api access configuration - */ -@NoArgsConstructor -@RequiredArgsConstructor -@XmlAccessorType(XmlAccessType.FIELD) -public class NexusServer { - @Getter - @NonNull - @XmlElement(name = "url") - private String url; - @Getter - @NonNull - @XmlElement(name = "user") - private String user; - @Getter - @NonNull - @XmlElement(name = "password") - private String password; -} diff --git a/src/main/java/com/griddynamics/cd/nrp/internal/model/config/ReplicationPluginConfiguration.java b/src/main/java/com/griddynamics/cd/nrp/internal/model/config/ReplicationPluginConfiguration.java deleted file mode 100644 index 47a4feb..0000000 --- a/src/main/java/com/griddynamics/cd/nrp/internal/model/config/ReplicationPluginConfiguration.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2015, Grid Dynamics International, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.griddynamics.cd.nrp.internal.model.config; - -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.NonNull; -import lombok.RequiredArgsConstructor; - -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlElementWrapper; -import javax.xml.bind.annotation.XmlRootElement; -import java.util.HashSet; -import java.util.Set; - -/** - * DTO Class encapsulates replication plugin configurations - */ -@NoArgsConstructor -@RequiredArgsConstructor -@XmlRootElement(name = "configurations") -public class ReplicationPluginConfiguration { - @XmlElement(name = "server") - @XmlElementWrapper(name = "servers") - private final Set servers = new HashSet<>(); - @Getter - @NonNull - @XmlAttribute(name = "myUrl") - private String myUrl; - @XmlAttribute(name = "requestsQueueSize") - private Integer requestsQueueSize = 500; - @XmlAttribute(name = "requestsSendingThreadsCount") - private Integer requestsSendingThreadsCount = 1; - @XmlAttribute(name = "queueDumpFileName") - private String queueDumpFileName; - - public void addServer(NexusServer server) { - servers.add(server); - } - - public Integer getRequestsQueueSize() { - return requestsQueueSize; - } - - public String getQueueDumpFileName() { - return queueDumpFileName; - } - - public Integer getRequestsSendingThreadsCount() { - return requestsSendingThreadsCount; - } - - public Set getServers() { - return servers; - } -} diff --git a/src/main/java/com/griddynamics/cd/nrp/internal/model/config/ReplicationPluginConfigurationStorage.java b/src/main/java/com/griddynamics/cd/nrp/internal/model/config/ReplicationPluginConfigurationStorage.java new file mode 100644 index 0000000..7833313 --- /dev/null +++ b/src/main/java/com/griddynamics/cd/nrp/internal/model/config/ReplicationPluginConfigurationStorage.java @@ -0,0 +1,135 @@ +package com.griddynamics.cd.nrp.internal.model.config; + +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/model/internal/ArtifactMetaInfoQueueDump.java b/src/main/java/com/griddynamics/cd/nrp/internal/model/internal/ArtifactMetaInfoQueueDump.java deleted file mode 100644 index e635f42..0000000 --- a/src/main/java/com/griddynamics/cd/nrp/internal/model/internal/ArtifactMetaInfoQueueDump.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2015, Grid Dynamics International, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.griddynamics.cd.nrp.internal.model.internal; - -import com.griddynamics.cd.nrp.internal.model.api.ArtifactMetaInfo; - -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlElementWrapper; -import javax.xml.bind.annotation.XmlRootElement; -import java.util.HashSet; -import java.util.Set; - -/** - * DTO Class encapsulates artifact replication queue - */ -@XmlRootElement(name = "artifactMetaInfoBlockingQueueDump") -public class ArtifactMetaInfoQueueDump { - @XmlElement(name = "artifactMetaInfo") - @XmlElementWrapper(name = "artifactMetaInfos") - private final Set artifactMetaInfos = new HashSet<>(); - - public void addArtifactMetaInfo(ArtifactMetaInfo artifactMetaInfo) { - artifactMetaInfos.add(artifactMetaInfo); - } - public void addAllArtifactMetaInfo(Set artifactMetaInfo) { - artifactMetaInfos.addAll(artifactMetaInfo); - } - - public Set getArtifactMetaInfos() { - return artifactMetaInfos; - } - -} diff --git a/src/main/java/com/griddynamics/cd/nrp/internal/uploading/ArtifactUpdateApiClient.java b/src/main/java/com/griddynamics/cd/nrp/internal/uploading/ArtifactUpdateApiClient.java index 5f6087a..b721b23 100644 --- a/src/main/java/com/griddynamics/cd/nrp/internal/uploading/ArtifactUpdateApiClient.java +++ b/src/main/java/com/griddynamics/cd/nrp/internal/uploading/ArtifactUpdateApiClient.java @@ -18,6 +18,8 @@ import com.griddynamics.cd.nrp.internal.model.api.ArtifactMetaInfo; public interface ArtifactUpdateApiClient { + void onActivate(); + void offerRequest(ArtifactMetaInfo artifactMetaInfo); } diff --git a/src/main/java/com/griddynamics/cd/nrp/internal/uploading/ConfigurationsManager.java b/src/main/java/com/griddynamics/cd/nrp/internal/uploading/ConfigurationsManager.java deleted file mode 100644 index 17f9c4a..0000000 --- a/src/main/java/com/griddynamics/cd/nrp/internal/uploading/ConfigurationsManager.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2015, Grid Dynamics International, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.griddynamics.cd.nrp.internal.uploading; - -import com.griddynamics.cd.nrp.internal.model.config.ReplicationPluginConfiguration; - -public interface ConfigurationsManager { - ReplicationPluginConfiguration getConfiguration(); -} diff --git a/src/main/java/com/griddynamics/cd/nrp/internal/uploading/impl/ArtifactUpdateApiClientImpl.java b/src/main/java/com/griddynamics/cd/nrp/internal/uploading/impl/ArtifactUpdateApiClientImpl.java index 95b8551..a0a72b6 100644 --- a/src/main/java/com/griddynamics/cd/nrp/internal/uploading/impl/ArtifactUpdateApiClientImpl.java +++ b/src/main/java/com/griddynamics/cd/nrp/internal/uploading/impl/ArtifactUpdateApiClientImpl.java @@ -15,27 +15,20 @@ */ package com.griddynamics.cd.nrp.internal.uploading.impl; +import com.griddynamics.cd.nrp.internal.model.config.ReplicationPluginConfigurationStorage; import com.griddynamics.cd.nrp.internal.model.api.ArtifactMetaInfo; -import com.griddynamics.cd.nrp.internal.model.config.ReplicationPluginConfiguration; -import com.griddynamics.cd.nrp.internal.model.internal.ArtifactMetaInfoQueueDump; import com.griddynamics.cd.nrp.internal.model.api.RestResponse; -import com.griddynamics.cd.nrp.internal.model.config.NexusServer; import com.griddynamics.cd.nrp.internal.uploading.ArtifactUpdateApiClient; -import com.griddynamics.cd.nrp.internal.uploading.ConfigurationsManager; +import com.griddynamics.cd.nrp.internal.uploading.impl.factories.AsyncWebResourceBuilderFactory; +import com.griddynamics.cd.nrp.internal.uploading.impl.factories.FileBlockingQueueFactory; import com.sun.jersey.api.client.AsyncWebResource; -import com.sun.jersey.api.client.Client; import com.sun.jersey.api.client.GenericType; import com.sun.jersey.api.client.async.ITypeListener; -import com.sun.jersey.api.client.config.ClientConfig; -import com.sun.jersey.api.client.config.DefaultClientConfig; -import com.sun.jersey.api.client.filter.HTTPBasicAuthFilter; import org.sonatype.sisu.goodies.common.ComponentSupport; import javax.inject.Inject; import javax.inject.Named; import javax.inject.Singleton; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.UriBuilder; import javax.xml.bind.JAXBContext; import javax.xml.bind.Unmarshaller; import java.io.File; @@ -62,34 +55,32 @@ public class ArtifactUpdateApiClientImpl extends ComponentSupport implements Art */ public static final int QUEUE_TIMEOUT_IN_SECOND = 1; - /** - * Provides access to the plugin configurations - */ - private final ConfigurationsManager configurationsManager; - + private final FileBlockingQueueFactory fileBlockingQueueFactory; + private final AsyncWebResourceBuilderFactory asyncWebResourceBuilderFactory; + private final ReplicationPluginConfigurationStorage replicationPluginConfigurationStorage; /** * ExecutorService shares between clients. All treads are created in the same executor */ - private final ExecutorService jerseyHttpClientExecutor; - private final FileBlockingQueue fileBlockingQueue; + private FileBlockingQueue fileBlockingQueue; @Inject - public ArtifactUpdateApiClientImpl(ConfigurationsManager configurationsManager) { - this.configurationsManager = configurationsManager; - this.fileBlockingQueue = initFileBlockingQueue(configurationsManager.getConfiguration()); - this.jerseyHttpClientExecutor = new ThreadPoolExecutor( - configurationsManager.getConfiguration().getRequestsSendingThreadsCount(), - configurationsManager.getConfiguration().getRequestsSendingThreadsCount(), - 30, - TimeUnit.SECONDS, - new LinkedBlockingQueue( - configurationsManager.getConfiguration().getRequestsQueueSize()) - ); - initBackgroundWorkers(configurationsManager.getConfiguration()); + public ArtifactUpdateApiClientImpl(FileBlockingQueueFactory fileBlockingQueueFactory, + AsyncWebResourceBuilderFactory asyncWebResourceBuilderFactory, + ReplicationPluginConfigurationStorage replicationPluginConfigurationStorage) { + this.fileBlockingQueueFactory = fileBlockingQueueFactory; + this.asyncWebResourceBuilderFactory = asyncWebResourceBuilderFactory; + this.replicationPluginConfigurationStorage = replicationPluginConfigurationStorage; + } + + @Override + public void onActivate(){ + this.fileBlockingQueue = initFileBlockingQueue(replicationPluginConfigurationStorage); + initBackgroundWorkers(replicationPluginConfigurationStorage); } - private void initBackgroundWorkers(ReplicationPluginConfiguration replicationPluginConfiguration) { - int requestsSendingThreadsCount = replicationPluginConfiguration.getRequestsSendingThreadsCount(); + private void initBackgroundWorkers(ReplicationPluginConfigurationStorage replicationPluginConfigurationStorage) { + int requestsSendingThreadsCount = replicationPluginConfigurationStorage + .getRequestSendingThreadCount(); ExecutorService executorService = Executors.newFixedThreadPool(requestsSendingThreadsCount); for (int i = 0; i < requestsSendingThreadsCount; i++) { executorService.submit(new Runnable() { @@ -109,18 +100,15 @@ public void run() { } } - private FileBlockingQueue initFileBlockingQueue(ReplicationPluginConfiguration replicationPluginConfiguration) { - BlockingQueue blockingQueue = - new LinkedBlockingQueue<>(replicationPluginConfiguration.getRequestsQueueSize()); - String queueFileName = replicationPluginConfiguration.getQueueDumpFileName(); - FileBlockingQueue retVal = new FileBlockingQueue(blockingQueue, - queueFileName); + private FileBlockingQueue initFileBlockingQueue(ReplicationPluginConfigurationStorage replicationPluginConfigurationStorage) { + String queueFileName = replicationPluginConfigurationStorage.getRequestQueueDumpFileName(); + FileBlockingQueue retVal = fileBlockingQueueFactory.getFileBlockingQueue(); try { File queueFile = new File(queueFileName); if (queueFile.exists()) { - JAXBContext jaxbContext = JAXBContext.newInstance(ArtifactMetaInfoQueueDump.class); + JAXBContext jaxbContext = JAXBContext.newInstance(FileBlockingQueue.ArtifactMetaInfoQueueDump.class); Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); - ArtifactMetaInfoQueueDump unmarshal = (ArtifactMetaInfoQueueDump) unmarshaller.unmarshal(queueFile); + FileBlockingQueue.ArtifactMetaInfoQueueDump unmarshal = (FileBlockingQueue.ArtifactMetaInfoQueueDump) unmarshaller.unmarshal(queueFile); for (ArtifactMetaInfo artifactMetaInfo : unmarshal.getArtifactMetaInfos()) { offerRequest(artifactMetaInfo); } @@ -146,8 +134,10 @@ public void offerRequest(ArtifactMetaInfo artifactMetaInfo) { * @param metaInfo Artifact information */ public void sendRequest(ArtifactMetaInfo metaInfo) { - for (NexusServer server : configurationsManager.getConfiguration().getServers()) { - AsyncWebResource.Builder service = getService(server.getUrl(), server.getUser(), server.getPassword()); + for (ReplicationPluginConfigurationStorage.NexusServer server : replicationPluginConfigurationStorage.getServers()) { + AsyncWebResource.Builder service = + asyncWebResourceBuilderFactory.getAsyncWebResourceBuilder( + server.getUrl(), server.getUser(), server.getPassword()); try { service.post(new ITypeListener() { @Override @@ -180,42 +170,4 @@ public GenericType getGenericType() { } } - /** - * Returns jersey HTTP resource to access to the remote replication servers - * - * @param nexusUrl URL of the remote server - * @param login Username on the remote server - * @param password User's password - * @return Jersey HTTP client - */ - private AsyncWebResource.Builder getService(String nexusUrl, String login, String password) { - Client client = getClient(login, password); - client.setExecutorService(jerseyHttpClientExecutor); - AsyncWebResource webResource = client.asyncResource(UriBuilder.fromUri(nexusUrl).build()); - webResource = webResource.path("service").path("local").path("artifact").path("maven").path("update"); - return webResource.accept(MediaType.APPLICATION_XML_TYPE) - .type(MediaType.APPLICATION_XML_TYPE); - } - - /** - * Creates jersey HTTP client - * - * @param login Username on the remote server - * @param password User's password - * @return HTTP client - */ - private Client getClient(String login, String password) { - ClientConfig config = new DefaultClientConfig(); - config.getProperties().put(ClientConfig.PROPERTY_CONNECT_TIMEOUT, 1000); - config.getProperties().put(ClientConfig.PROPERTY_READ_TIMEOUT, 2000); - Client client = Client.create(config); - client.setExecutorService(jerseyHttpClientExecutor); - if (login != null && !login.isEmpty() && password != null) { - log.debug("Creating HTTP client with authorized HTTPBasicAuthFilter."); - client.addFilter(new HTTPBasicAuthFilter(login, password)); - } else { - log.debug("Creating HTTP client with anonymous HTTPBasicAuthFilter."); - } - return client; - } } diff --git a/src/main/java/com/griddynamics/cd/nrp/internal/uploading/impl/ConfigurationsManagerImpl.java b/src/main/java/com/griddynamics/cd/nrp/internal/uploading/impl/ConfigurationsManagerImpl.java deleted file mode 100644 index 5d4b4be..0000000 --- a/src/main/java/com/griddynamics/cd/nrp/internal/uploading/impl/ConfigurationsManagerImpl.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright 2015, Grid Dynamics International, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.griddynamics.cd.nrp.internal.uploading.impl; - -import com.griddynamics.cd.nrp.internal.model.config.ReplicationPluginConfiguration; -import com.griddynamics.cd.nrp.internal.uploading.ConfigurationsManager; -import org.sonatype.nexus.configuration.application.NexusConfiguration; -import org.sonatype.sisu.goodies.common.ComponentSupport; - -import javax.annotation.PostConstruct; -import javax.inject.Inject; -import javax.inject.Named; -import javax.inject.Singleton; -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBException; -import javax.xml.bind.Unmarshaller; -import java.io.File; - -/** - * Class provides access to plugin configurations - * parsed from {@link ConfigurationsManagerImpl#CONFIG_FILENAME} file - */ -@Singleton -@Named(value = ConfigurationsManagerImpl.ID) -public class ConfigurationsManagerImpl extends ComponentSupport implements ConfigurationsManager { - - public static final String ID = "configurationsManager"; - - /** - * Filename of the XML configuration file - */ - private static final String CONFIG_FILENAME = "replication-plugin.xml"; - - /** - * Bean provides nexus server configurations - */ - private NexusConfiguration nexusConfiguration; - - /** - * DTO contains plugin configurations - */ - private volatile ReplicationPluginConfiguration config; - - @Inject - public ConfigurationsManagerImpl(NexusConfiguration nexusConfiguration) { - this.nexusConfiguration = nexusConfiguration; - } - - /** - * Loads configurations - * from {@link ConfigurationsManagerImpl#CONFIG_FILENAME} file - */ - @PostConstruct - public void init() { - log.trace("Initializing plugin configurations"); - reloadConfigurations(); - } - - /** - * Provides access to plugin configurations DTO - * @return Plugin configurations - */ - @Override - public ReplicationPluginConfiguration getConfiguration() { - if (config == null) { - synchronized (this) { - if (config == null) { - reloadConfigurations(); - } - } - } - return config; - } - - /** - * Reloads {@link ConfigurationsManagerImpl#config} - * from XML plugin configurations file - */ - public void reloadConfigurations() { - File file = getConfigurationFile(); - try { - JAXBContext jaxbContext = JAXBContext.newInstance(ReplicationPluginConfiguration.class); - - Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); - config = (ReplicationPluginConfiguration) jaxbUnmarshaller.unmarshal(file); - } catch (JAXBException e) { - log.error("Can not deserialize xml configuration file: " + file.getAbsolutePath(), e); - } - } - - /** - * Returns plugin configurations XML file - */ - private File getConfigurationFile() { - return new File(nexusConfiguration.getConfigurationDirectory(), CONFIG_FILENAME); - } -} diff --git a/src/main/java/com/griddynamics/cd/nrp/internal/uploading/impl/FileBlockingQueue.java b/src/main/java/com/griddynamics/cd/nrp/internal/uploading/impl/FileBlockingQueue.java index d2ea55b..4be9eed 100644 --- a/src/main/java/com/griddynamics/cd/nrp/internal/uploading/impl/FileBlockingQueue.java +++ b/src/main/java/com/griddynamics/cd/nrp/internal/uploading/impl/FileBlockingQueue.java @@ -2,14 +2,18 @@ import com.google.common.collect.Sets; import com.griddynamics.cd.nrp.internal.model.api.ArtifactMetaInfo; -import com.griddynamics.cd.nrp.internal.model.internal.ArtifactMetaInfoQueueDump; import org.apache.commons.io.FileUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.xml.bind.JAXBContext; import javax.xml.bind.Marshaller; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElementWrapper; +import javax.xml.bind.annotation.XmlRootElement; import java.io.File; +import java.util.HashSet; +import java.util.Set; import java.util.concurrent.BlockingQueue; import java.util.concurrent.TimeUnit; @@ -81,4 +85,25 @@ private synchronized void saveQueueToFile() { } + /** + * DTO Class encapsulates artifact replication queue + */ + @XmlRootElement(name = "artifactMetaInfoBlockingQueueDump") + public static class ArtifactMetaInfoQueueDump { + @XmlElement(name = "artifactMetaInfo") + @XmlElementWrapper(name = "artifactMetaInfos") + private final Set artifactMetaInfos = new HashSet<>(); + + public void addArtifactMetaInfo(ArtifactMetaInfo artifactMetaInfo) { + artifactMetaInfos.add(artifactMetaInfo); + } + public void addAllArtifactMetaInfo(Set artifactMetaInfo) { + artifactMetaInfos.addAll(artifactMetaInfo); + } + + public Set getArtifactMetaInfos() { + return artifactMetaInfos; + } + + } } diff --git a/src/main/java/com/griddynamics/cd/nrp/internal/uploading/impl/UploadEventListenerImpl.java b/src/main/java/com/griddynamics/cd/nrp/internal/uploading/impl/UploadEventListenerImpl.java index 8bad9be..ec1ddcc 100644 --- a/src/main/java/com/griddynamics/cd/nrp/internal/uploading/impl/UploadEventListenerImpl.java +++ b/src/main/java/com/griddynamics/cd/nrp/internal/uploading/impl/UploadEventListenerImpl.java @@ -17,10 +17,10 @@ import com.google.common.eventbus.AllowConcurrentEvents; import com.google.common.eventbus.Subscribe; +import com.griddynamics.cd.nrp.internal.model.config.ReplicationPluginConfigurationStorage; import com.griddynamics.cd.nrp.internal.model.api.ArtifactMetaInfo; import com.griddynamics.cd.nrp.internal.model.api.ArtifactStatus; import com.griddynamics.cd.nrp.internal.uploading.ArtifactUpdateApiClient; -import com.griddynamics.cd.nrp.internal.uploading.ConfigurationsManager; import com.griddynamics.cd.nrp.internal.uploading.UploadEventListener; import org.sonatype.nexus.client.core.subsystem.repository.maven.MavenProxyRepository; import org.sonatype.nexus.proxy.events.RepositoryItemEventStore; @@ -46,17 +46,16 @@ public class UploadEventListenerImpl extends ComponentSupport implements UploadE /** * Provides access to plugin the configurations */ - private ConfigurationsManager configurationsManager; - - private ArtifactUpdateApiClient artifactUpdateApiClient; + private final ArtifactUpdateApiClient artifactUpdateApiClient; + private final ReplicationPluginConfigurationStorage replicationPluginConfigurationStorage; private Map receivedArtifacts = new ConcurrentHashMap<>(); @Inject - public UploadEventListenerImpl(@Named(value = ConfigurationsManagerImpl.ID) ConfigurationsManager configurationsManager, - @Named(value = ArtifactUpdateApiClientImpl.ID) ArtifactUpdateApiClient artifactUpdateApiClient) { - this.configurationsManager = configurationsManager; + public UploadEventListenerImpl(@Named(value = ArtifactUpdateApiClientImpl.ID) ArtifactUpdateApiClient artifactUpdateApiClient, + ReplicationPluginConfigurationStorage replicationPluginConfigurationStorage) { this.artifactUpdateApiClient = artifactUpdateApiClient; + this.replicationPluginConfigurationStorage = replicationPluginConfigurationStorage; } /** @@ -70,7 +69,12 @@ public void onArtifactUploading(RepositoryItemEventStore event) { MavenRepository repo = (MavenRepository) event.getRepository(); Gav gav = repo.getGavCalculator().pathToGav(event.getItemUid().getPath()); if (null != gav) { - ArtifactMetaInfo metaInfo = new ArtifactMetaInfo(configurationsManager.getConfiguration().getMyUrl(), gav.getGroupId(), gav.getArtifactId(), gav.getVersion(), repo.getId()); + ArtifactMetaInfo metaInfo = new ArtifactMetaInfo( + replicationPluginConfigurationStorage.getMasterServerURLPrefix(), + gav.getGroupId(), + gav.getArtifactId(), + gav.getVersion(), + repo.getId()); metaInfo.setClassifier(gav.getClassifier()); metaInfo.setExtension(gav.getExtension()); ArtifactStatus artifactStatus = null; diff --git a/src/main/java/com/griddynamics/cd/nrp/internal/uploading/impl/factories/AsyncWebResourceBuilderFactory.java b/src/main/java/com/griddynamics/cd/nrp/internal/uploading/impl/factories/AsyncWebResourceBuilderFactory.java new file mode 100644 index 0000000..aeec5ea --- /dev/null +++ b/src/main/java/com/griddynamics/cd/nrp/internal/uploading/impl/factories/AsyncWebResourceBuilderFactory.java @@ -0,0 +1,38 @@ +package com.griddynamics.cd.nrp.internal.uploading.impl.factories; + +import com.sun.jersey.api.client.AsyncWebResource; +import com.sun.jersey.api.client.Client; + +import javax.inject.Inject; +import javax.inject.Singleton; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.UriBuilder; + +@Singleton +public class AsyncWebResourceBuilderFactory { + + private final JerseyClientFactory jerseyClientFactory; + + @Inject + public AsyncWebResourceBuilderFactory(JerseyClientFactory jerseyClientFactory) { + this.jerseyClientFactory = jerseyClientFactory; + } + + + /** + * Returns jersey HTTP resource to access to the remote replication servers + * + * @param nexusUrl URL of the remote server + * @param login Username on the remote server + * @param password User's password + * @return Jersey HTTP client + */ + public AsyncWebResource.Builder getAsyncWebResourceBuilder(String nexusUrl, String login, String password) { + Client client = jerseyClientFactory.getClient(login, password); + AsyncWebResource webResource = client.asyncResource(UriBuilder.fromUri(nexusUrl).build()); + webResource = webResource.path("service").path("local").path("artifact").path("maven").path("update"); + return webResource.accept(MediaType.APPLICATION_XML_TYPE) + .type(MediaType.APPLICATION_XML_TYPE); + } + +} diff --git a/src/main/java/com/griddynamics/cd/nrp/internal/uploading/impl/factories/FileBlockingQueueFactory.java b/src/main/java/com/griddynamics/cd/nrp/internal/uploading/impl/factories/FileBlockingQueueFactory.java new file mode 100644 index 0000000..133a889 --- /dev/null +++ b/src/main/java/com/griddynamics/cd/nrp/internal/uploading/impl/factories/FileBlockingQueueFactory.java @@ -0,0 +1,34 @@ +package com.griddynamics.cd.nrp.internal.uploading.impl.factories; + +import com.griddynamics.cd.nrp.internal.model.config.ReplicationPluginConfigurationStorage; +import com.griddynamics.cd.nrp.internal.model.api.ArtifactMetaInfo; +import com.griddynamics.cd.nrp.internal.uploading.impl.FileBlockingQueue; + +import javax.inject.Inject; +import javax.inject.Singleton; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; + +@Singleton +public class FileBlockingQueueFactory { + + private final ReplicationPluginConfigurationStorage + replicationPluginConfigurationStorage; + + @Inject + public FileBlockingQueueFactory(ReplicationPluginConfigurationStorage replicationPluginConfigurationStorage) { + this.replicationPluginConfigurationStorage = replicationPluginConfigurationStorage; + } + + public FileBlockingQueue getFileBlockingQueue() { + BlockingQueue blockingQueue = + new LinkedBlockingQueue<>( + replicationPluginConfigurationStorage.getRequestQueueSize()); + String blockingQueueDumpFileName = + replicationPluginConfigurationStorage.getRequestQueueDumpFileName(); + + return new FileBlockingQueue(blockingQueue, + blockingQueueDumpFileName); + } + +} diff --git a/src/main/java/com/griddynamics/cd/nrp/internal/uploading/impl/factories/JerseyClientFactory.java b/src/main/java/com/griddynamics/cd/nrp/internal/uploading/impl/factories/JerseyClientFactory.java new file mode 100644 index 0000000..ecf9f10 --- /dev/null +++ b/src/main/java/com/griddynamics/cd/nrp/internal/uploading/impl/factories/JerseyClientFactory.java @@ -0,0 +1,61 @@ +package com.griddynamics.cd.nrp.internal.uploading.impl.factories; + +import com.griddynamics.cd.nrp.internal.model.config.ReplicationPluginConfigurationStorage; +import com.sun.jersey.api.client.Client; +import com.sun.jersey.api.client.config.ClientConfig; +import com.sun.jersey.api.client.config.DefaultClientConfig; +import com.sun.jersey.api.client.filter.HTTPBasicAuthFilter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.inject.Inject; +import javax.inject.Singleton; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +@Singleton +public class JerseyClientFactory { + + private Logger log = LoggerFactory.getLogger(JerseyClientFactory.class); + + private ExecutorService executorService; + private final ReplicationPluginConfigurationStorage + replicationPluginConfigurationStorage; + + @Inject + public JerseyClientFactory( + ReplicationPluginConfigurationStorage + replicationPluginConfigurationStorage ) { + this.replicationPluginConfigurationStorage = replicationPluginConfigurationStorage; + + } + + public void onActivate(){ + int requestQueueSize = replicationPluginConfigurationStorage.getRequestQueueSize(); + this.executorService = new ThreadPoolExecutor( + replicationPluginConfigurationStorage.getRequestSendingThreadCount(), + replicationPluginConfigurationStorage.getRequestSendingThreadCount(), + 30, + TimeUnit.SECONDS, + new LinkedBlockingQueue( + requestQueueSize)); + } + + public Client getClient(String login, String password) { + ClientConfig config = new DefaultClientConfig(); + config.getProperties().put(ClientConfig.PROPERTY_CONNECT_TIMEOUT, 1000); + config.getProperties().put(ClientConfig.PROPERTY_READ_TIMEOUT, 2000); + Client client = Client.create(config); + client.setExecutorService(executorService); + if (login != null && !login.isEmpty() && password != null) { + log.debug("Creating HTTP client with authorized HTTPBasicAuthFilter."); + client.addFilter(new HTTPBasicAuthFilter(login, password)); + } else { + log.debug("Creating HTTP client with anonymous HTTPBasicAuthFilter."); + } + return client; + } + +} From e9ab3fc20181490bb0eef396094c62c2b9f800c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Magry=C5=9B?= Date: Thu, 9 Jul 2015 14:42:20 +0200 Subject: [PATCH 2/3] Code review remarks. --- .../ReplicationPluginCapability.java | 9 +- ...ReplicationPluginConfigurationStorage.java | 86 ++++++++++--------- .../uploading/ArtifactUpdateApiClient.java | 2 - .../impl/ArtifactUpdateApiClientImpl.java | 1 - .../impl/factories/JerseyClientFactory.java | 16 ++-- 5 files changed, 60 insertions(+), 54 deletions(-) diff --git a/src/main/java/com/griddynamics/cd/nrp/internal/capabilities/ReplicationPluginCapability.java b/src/main/java/com/griddynamics/cd/nrp/internal/capabilities/ReplicationPluginCapability.java index 0a33537..b18c43d 100644 --- a/src/main/java/com/griddynamics/cd/nrp/internal/capabilities/ReplicationPluginCapability.java +++ b/src/main/java/com/griddynamics/cd/nrp/internal/capabilities/ReplicationPluginCapability.java @@ -2,6 +2,7 @@ import com.griddynamics.cd.nrp.internal.model.config.ReplicationPluginConfigurationStorage; import com.griddynamics.cd.nrp.internal.uploading.ArtifactUpdateApiClient; +import com.griddynamics.cd.nrp.internal.uploading.impl.ArtifactUpdateApiClientImpl; import com.griddynamics.cd.nrp.internal.uploading.impl.factories.JerseyClientFactory; import org.jetbrains.annotations.NonNls; import org.sonatype.nexus.capability.support.CapabilitySupport; @@ -22,13 +23,13 @@ public class ReplicationPluginCapability public static final String NL = System.getProperty("line.separator"); private final ReplicationPluginConfigurationStorage gridRegistry; - private final ArtifactUpdateApiClient artifactUpdateApiClient; + private final ArtifactUpdateApiClientImpl artifactUpdateApiClient; private final JerseyClientFactory jerseyClientFactory; @Inject - public ReplicationPluginCapability(final ReplicationPluginConfigurationStorage replicationPluginConfigurationStorage, - final ArtifactUpdateApiClient artifactUpdateApiClient, - final JerseyClientFactory jerseyClientFactory) { + public ReplicationPluginCapability(ReplicationPluginConfigurationStorage replicationPluginConfigurationStorage, + ArtifactUpdateApiClientImpl artifactUpdateApiClient, + JerseyClientFactory jerseyClientFactory) { this.gridRegistry = checkNotNull(replicationPluginConfigurationStorage); this.artifactUpdateApiClient = artifactUpdateApiClient; this.jerseyClientFactory = jerseyClientFactory; diff --git a/src/main/java/com/griddynamics/cd/nrp/internal/model/config/ReplicationPluginConfigurationStorage.java b/src/main/java/com/griddynamics/cd/nrp/internal/model/config/ReplicationPluginConfigurationStorage.java index 7833313..95ba3fb 100644 --- a/src/main/java/com/griddynamics/cd/nrp/internal/model/config/ReplicationPluginConfigurationStorage.java +++ b/src/main/java/com/griddynamics/cd/nrp/internal/model/config/ReplicationPluginConfigurationStorage.java @@ -12,7 +12,21 @@ import javax.inject.Singleton; import java.util.LinkedHashSet; import java.util.Set; -import java.util.concurrent.atomic.AtomicReference; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * DTO Class for storing plugin's configuration: + * - master server URL prefix + * - request queue size + * - request sending thread count + * - request queue backup file + * - peer servers + *

+ * At first run, the default configuration is being created by ReplicationPluginCapabilitiesBooter, and passed to this class + *

+ * Then every time Nexus is being restarted or plugin's settings changed, ReplicationPluginCapability passes new settings to this class + */ @Named(value = "replicationPluginConfigurationStorage") @Singleton @@ -21,80 +35,68 @@ 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<>(); + private volatile String masterServerURLPrefix = null; + private volatile Integer requestQueueSize = null; + private volatile Integer requestSendingThreadCount = null; + private volatile String requestQueueDumpFileName = null; + private volatile Set servers = null; @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; + checkNotNull(masterServerURLPrefix, "Replication plugin configuration not ready yet!"); + return this.masterServerURLPrefix; } public void setMasterServerURLPrefix(String masterServerURLPrefix) { - this.masterServerURLPrefix.set(masterServerURLPrefix); + checkNotNull(masterServerURLPrefix, "Replication plugin configuration parameter cannot be set to null"); + this.masterServerURLPrefix = 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; + checkNotNull(requestQueueDumpFileName, "Replication plugin configuration not ready yet!"); + return requestQueueDumpFileName; } public void setRequestQueueDumpFileName(String requestQueueDumpFileName) { - this.requestQueueDumpFileName.set(requestQueueDumpFileName); + checkNotNull(requestQueueDumpFileName, "Replication plugin configuration parameter cannot be set to null"); + this.requestQueueDumpFileName = 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; + checkNotNull(servers, "Replication plugin configuration not ready yet!"); + return servers; } public void setServers(Set nexusServers) { - servers.get().clear(); - servers.get().addAll(nexusServers); + checkNotNull(nexusServers, "Replication plugin configuration parameter cannot be set to null"); + servers = new LinkedHashSet<>(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; + checkNotNull(requestSendingThreadCount, "Replication plugin configuration not ready yet!"); + return requestSendingThreadCount; } - public void setRequestSendingThreadCount(int requestSendingThreadCount) { - this.requestSendingThreadCount.set(requestSendingThreadCount); + public void setRequestSendingThreadCount(Integer requestSendingThreadCount) { + checkNotNull(requestSendingThreadCount, "Replication plugin configuration parameter cannot be set to null"); + this.requestSendingThreadCount = 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; + checkNotNull(requestQueueSize, "Replication plugin configuration not ready yet!"); + return requestQueueSize; } - public void setRequestQueueSize(int requestQueueSize) { - this.requestQueueSize.set(requestQueueSize); + public void setRequestQueueSize(Integer requestQueueSize) { + checkNotNull(requestQueueSize, "Replication plugin configuration parameter cannot be set to null"); + this.requestQueueSize = requestQueueSize; logger.info(toString()); } @@ -102,8 +104,8 @@ public void setRequestQueueSize(int requestQueueSize) { public String toString() { return "ReplicationPluginConfigurationStorage{" + "masterServerURLPrefix='" + masterServerURLPrefix + '\'' + - ", requestQueueSize=" + requestQueueSize.get() + - ", requestSendingThreadCount=" + requestSendingThreadCount.get() + + ", requestQueueSize=" + requestQueueSize + + ", requestSendingThreadCount=" + requestSendingThreadCount + ", requestQueueDumpFileName='" + requestQueueDumpFileName + '\'' + ", servers=" + servers + '}'; diff --git a/src/main/java/com/griddynamics/cd/nrp/internal/uploading/ArtifactUpdateApiClient.java b/src/main/java/com/griddynamics/cd/nrp/internal/uploading/ArtifactUpdateApiClient.java index b721b23..5f6087a 100644 --- a/src/main/java/com/griddynamics/cd/nrp/internal/uploading/ArtifactUpdateApiClient.java +++ b/src/main/java/com/griddynamics/cd/nrp/internal/uploading/ArtifactUpdateApiClient.java @@ -18,8 +18,6 @@ import com.griddynamics.cd.nrp.internal.model.api.ArtifactMetaInfo; public interface ArtifactUpdateApiClient { - void onActivate(); - void offerRequest(ArtifactMetaInfo artifactMetaInfo); } diff --git a/src/main/java/com/griddynamics/cd/nrp/internal/uploading/impl/ArtifactUpdateApiClientImpl.java b/src/main/java/com/griddynamics/cd/nrp/internal/uploading/impl/ArtifactUpdateApiClientImpl.java index a0a72b6..d10b912 100644 --- a/src/main/java/com/griddynamics/cd/nrp/internal/uploading/impl/ArtifactUpdateApiClientImpl.java +++ b/src/main/java/com/griddynamics/cd/nrp/internal/uploading/impl/ArtifactUpdateApiClientImpl.java @@ -72,7 +72,6 @@ public ArtifactUpdateApiClientImpl(FileBlockingQueueFactory fileBlockingQueueFac this.replicationPluginConfigurationStorage = replicationPluginConfigurationStorage; } - @Override public void onActivate(){ this.fileBlockingQueue = initFileBlockingQueue(replicationPluginConfigurationStorage); initBackgroundWorkers(replicationPluginConfigurationStorage); diff --git a/src/main/java/com/griddynamics/cd/nrp/internal/uploading/impl/factories/JerseyClientFactory.java b/src/main/java/com/griddynamics/cd/nrp/internal/uploading/impl/factories/JerseyClientFactory.java index ecf9f10..a3824bc 100644 --- a/src/main/java/com/griddynamics/cd/nrp/internal/uploading/impl/factories/JerseyClientFactory.java +++ b/src/main/java/com/griddynamics/cd/nrp/internal/uploading/impl/factories/JerseyClientFactory.java @@ -18,21 +18,20 @@ @Singleton public class JerseyClientFactory { - private Logger log = LoggerFactory.getLogger(JerseyClientFactory.class); - - private ExecutorService executorService; private final ReplicationPluginConfigurationStorage replicationPluginConfigurationStorage; + private Logger log = LoggerFactory.getLogger(JerseyClientFactory.class); + private ExecutorService executorService; @Inject public JerseyClientFactory( ReplicationPluginConfigurationStorage - replicationPluginConfigurationStorage ) { + replicationPluginConfigurationStorage) { this.replicationPluginConfigurationStorage = replicationPluginConfigurationStorage; } - public void onActivate(){ + public void onActivate() { int requestQueueSize = replicationPluginConfigurationStorage.getRequestQueueSize(); this.executorService = new ThreadPoolExecutor( replicationPluginConfigurationStorage.getRequestSendingThreadCount(), @@ -43,6 +42,13 @@ public void onActivate(){ requestQueueSize)); } + /** + * @param login Login to Nexus + * @param password Password to Nexus + * @return Jersey Client for provide login and password with connection timeout set to 1000 ms and read timeout set to 2000 + * This particular values for timeouts were chosen to avoid potential deadlock in case of peer server load + */ + public Client getClient(String login, String password) { ClientConfig config = new DefaultClientConfig(); config.getProperties().put(ClientConfig.PROPERTY_CONNECT_TIMEOUT, 1000); From aa9d244b4b37ef13a2c5e22d123d64d458f70715 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Magry=C5=9B?= Date: Fri, 10 Jul 2015 14:36:54 +0200 Subject: [PATCH 3/3] Change settings window look --- ...licationPluginCapabilityConfiguration.java | 51 ++++-- ...ReplicationPluginCapabilityDescriptor.java | 171 ++++++++++-------- 2 files changed, 128 insertions(+), 94 deletions(-) diff --git a/src/main/java/com/griddynamics/cd/nrp/internal/capabilities/ReplicationPluginCapabilityConfiguration.java b/src/main/java/com/griddynamics/cd/nrp/internal/capabilities/ReplicationPluginCapabilityConfiguration.java index 273ba36..a9e772e 100644 --- a/src/main/java/com/griddynamics/cd/nrp/internal/capabilities/ReplicationPluginCapabilityConfiguration.java +++ b/src/main/java/com/griddynamics/cd/nrp/internal/capabilities/ReplicationPluginCapabilityConfiguration.java @@ -2,32 +2,33 @@ import com.google.common.collect.Maps; import com.griddynamics.cd.nrp.internal.model.config.ReplicationPluginConfigurationStorage; -import org.codehaus.jackson.map.ObjectMapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.Iterator; import java.util.LinkedHashSet; -import java.util.List; import java.util.Map; import java.util.Set; +import static com.google.common.base.Strings.isNullOrEmpty; + public class ReplicationPluginCapabilityConfiguration { 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(ReplicationPluginCapabilityConfiguration.class); - + public static final String SERVER_URL = "server_url"; + public static final String SERVER_LOGIN = "server_user"; + public static final String SERVER_PASSWORD = "server_password"; private final String masterServerURLPrefix; private final int requestQueueSize; private final int requestSendingThreadCount; private final String requestQueueDumpFileName; private final Set nexusServers; + Logger logger = + LoggerFactory.getLogger(ReplicationPluginCapabilityConfiguration.class); public ReplicationPluginCapabilityConfiguration(final Map properties) { this.masterServerURLPrefix = properties.get(MASTER_SERVER_URL_PREFIX); @@ -35,21 +36,24 @@ public ReplicationPluginCapabilityConfiguration(final Map proper 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 servers = (List) objectMapper.readValue(properties.get(SERVERS), Map.class).get("servers"); - for (Map server : servers) { - this.nexusServers.add( - new ReplicationPluginConfigurationStorage.NexusServer( - (String) server.get("url"), - (String) server.get("user"), - (String) server.get("password") - ) - ); + + for (int i = 0; i < 5; i++) { + String serverUrl = properties.get(SERVER_URL + "_" + i); + String serverLogin = properties.get(SERVER_LOGIN + "_" + i); + String serverPassword = properties.get(SERVER_PASSWORD + "_" + i); + + if (isNullOrEmpty(serverUrl) || + isNullOrEmpty(serverLogin) || + isNullOrEmpty(serverPassword)) { + continue; } - } catch (Exception e) { - logger.error(e.getMessage(),e); + ReplicationPluginConfigurationStorage.NexusServer nexusServer = new ReplicationPluginConfigurationStorage.NexusServer( + serverUrl, + serverLogin, + serverPassword + ); + nexusServers.add(nexusServer); } } @@ -59,6 +63,13 @@ public Map asMap() { props.put(REQUESTS_QUEUE_SIZE, String.valueOf(requestQueueSize)); props.put(REQUESTS_SENDING_THREADS_COUNT, String.valueOf(requestSendingThreadCount)); props.put(QUEUE_DUMP_FILE_NAME, requestQueueDumpFileName); + Iterator nexusServerIterator = nexusServers.iterator(); + for (int i = 0; nexusServerIterator.hasNext(); i++) { + ReplicationPluginConfigurationStorage.NexusServer nexusServer = nexusServerIterator.next(); + props.put(SERVER_URL + "_" + i, nexusServer.getUrl()); + props.put(SERVER_LOGIN + "_" + i, nexusServer.getUser()); + props.put(SERVER_PASSWORD + "_" + i, nexusServer.getPassword()); + } return props; } diff --git a/src/main/java/com/griddynamics/cd/nrp/internal/capabilities/ReplicationPluginCapabilityDescriptor.java b/src/main/java/com/griddynamics/cd/nrp/internal/capabilities/ReplicationPluginCapabilityDescriptor.java index d407d22..80ed3bb 100644 --- a/src/main/java/com/griddynamics/cd/nrp/internal/capabilities/ReplicationPluginCapabilityDescriptor.java +++ b/src/main/java/com/griddynamics/cd/nrp/internal/capabilities/ReplicationPluginCapabilityDescriptor.java @@ -1,11 +1,10 @@ package com.griddynamics.cd.nrp.internal.capabilities; -import com.google.common.collect.Lists; import org.sonatype.nexus.capability.support.CapabilityDescriptorSupport; import org.sonatype.nexus.formfields.FormField; import org.sonatype.nexus.formfields.NumberTextFormField; +import org.sonatype.nexus.formfields.PasswordFormField; import org.sonatype.nexus.formfields.StringTextFormField; -import org.sonatype.nexus.formfields.TextAreaFormField; import org.sonatype.nexus.plugins.capabilities.*; import org.sonatype.nexus.plugins.capabilities.support.validator.Validators; import org.sonatype.sisu.goodies.i18n.I18N; @@ -14,6 +13,7 @@ import javax.inject.Inject; import javax.inject.Named; import javax.inject.Singleton; +import java.util.ArrayList; import java.util.List; import java.util.Set; @@ -29,86 +29,60 @@ public class ReplicationPluginCapabilityDescriptor public static final String TYPE_ID = "nexus-replication-plugin"; public static final CapabilityType TYPE = capabilityType(TYPE_ID); - - private static interface Messages - extends MessageBundle { - @DefaultMessage("Nexus Replication Plugin Configuration") - String name(); - - @DefaultMessage("Master server's URL prefix") - String masterServerURLPrefixLabel(); - - @DefaultMessage("Master server's URL prefix (e.g. http://localhost:8081/nexus") - String masterServerURLPrefixHelp(); - - @DefaultMessage("Request queue size") - String requestQueueSizeLabel(); - - @DefaultMessage("Request queue size (default 500)") - String requestQueueSizeHelp(); - - @DefaultMessage("Request sending thread count") - String requestSendingThreadCountLabel(); - - @DefaultMessage("Request sending thread count (default 1)") - String requestSendingThreadCountHelp(); - - @DefaultMessage("Request queue dump file") - String requestQueueDumpFileNameLabel(); - - @DefaultMessage("Request queue dump file (default /tmp/nexus-replication-plugin-queue-backup)") - String requestQueueDumpFileNameHelp(); - - @DefaultMessage("Slave servers (in JSON)") - String serversLabel(); - - @DefaultMessage("Slave servers in JSON, like: {\"servers\":[{\"url\":\"http://localhost:8083/nexus\",\"user\":\"admin\",\"password\":\"admin123\"},{\"url\":\"http://localhost:8082/nexus\",\"user\":\"admin\",\"password\":\"admin123\"}]}") - String serversHelp(); - - } - private static final Messages messages = I18N.create(Messages.class); - private final Validators validators; - private final List formFields; @Inject public ReplicationPluginCapabilityDescriptor(final Validators validators) { this.validators = validators; - this.formFields = Lists.newArrayList( - new StringTextFormField( - ReplicationPluginCapabilityConfiguration.MASTER_SERVER_URL_PREFIX, - messages.masterServerURLPrefixLabel(), - messages.masterServerURLPrefixHelp(), - FormField.OPTIONAL - ).withInitialValue("http://localhost:8081/nexus"), - new NumberTextFormField( - ReplicationPluginCapabilityConfiguration.REQUESTS_QUEUE_SIZE, - messages.requestQueueSizeLabel(), - messages.requestQueueSizeHelp(), - FormField.OPTIONAL - ).withInitialValue(500), - new NumberTextFormField( - ReplicationPluginCapabilityConfiguration.REQUESTS_SENDING_THREADS_COUNT, - messages.requestSendingThreadCountLabel(), - messages.requestSendingThreadCountHelp(), - FormField.OPTIONAL - ).withInitialValue(1), - new StringTextFormField( - ReplicationPluginCapabilityConfiguration.QUEUE_DUMP_FILE_NAME, - messages.requestQueueDumpFileNameLabel(), - messages.requestQueueDumpFileNameHelp(), - FormField.OPTIONAL - ).withInitialValue("/tmp/nexus-replication-plugin-queue-backup"), - new TextAreaFormField( - ReplicationPluginCapabilityConfiguration.SERVERS, - messages.serversLabel(), - messages.serversHelp(), - FormField.OPTIONAL - ).withInitialValue("{\"servers\":[{\"url\":\"http://localhost:8083/nexus\",\"user\":\"admin\",\"password\":\"admin123\"},{\"url\":\"http://localhost:8082/nexus\",\"user\":\"admin\",\"password\":\"admin123\"}]}") - ); + List formFields = new ArrayList<>(); + formFields.add(new StringTextFormField( + ReplicationPluginCapabilityConfiguration.MASTER_SERVER_URL_PREFIX, + messages.masterServerURLPrefixLabel(), + messages.masterServerURLPrefixHelp(), + FormField.OPTIONAL + ).withInitialValue("http://localhost:8081/nexus")); + formFields.add(new NumberTextFormField(ReplicationPluginCapabilityConfiguration.REQUESTS_QUEUE_SIZE, + messages.requestQueueSizeLabel(), + messages.requestQueueSizeHelp(), + FormField.OPTIONAL + ).withInitialValue(500)); + formFields.add(new NumberTextFormField( + ReplicationPluginCapabilityConfiguration.REQUESTS_SENDING_THREADS_COUNT, + messages.requestSendingThreadCountLabel(), + messages.requestSendingThreadCountHelp(), + FormField.OPTIONAL + ).withInitialValue(1)); + formFields.add(new StringTextFormField( + ReplicationPluginCapabilityConfiguration.QUEUE_DUMP_FILE_NAME, + messages.requestQueueDumpFileNameLabel(), + messages.requestQueueDumpFileNameHelp(), + FormField.OPTIONAL + ).withInitialValue("/tmp/nexus-replication-plugin-queue-backup")); + + for (int i = 0; i < 5; i++) { + formFields.add(new StringTextFormField( + ReplicationPluginCapabilityConfiguration.SERVER_URL + "_" + i, + messages.serverUrlLabel() + " (Instance nr " + (i + 1) + ")", + messages.serverUrlHelp(), + FormField.OPTIONAL + ).withInitialValue("")); + formFields.add(new StringTextFormField( + ReplicationPluginCapabilityConfiguration.SERVER_LOGIN + "_" + i, + messages.serverLoginLabel() + " (Instance nr " + (i + 1) + ")", + messages.serverLoginHelp(), + FormField.OPTIONAL + ).withInitialValue("")); + formFields.add(new PasswordFormField( + ReplicationPluginCapabilityConfiguration.SERVER_PASSWORD + "_" + i, + messages.serverPasswordLabel() + " (Instance nr " + (i + 1) + ")", + messages.serverPasswordHelp(), + FormField.OPTIONAL + ).withInitialValue("")); + } + this.formFields = formFields; } @Override @@ -144,4 +118,53 @@ public List formFields() { public Set getTags() { return tags(categoryTag("Grid")); } + + private static interface Messages + extends MessageBundle { + @DefaultMessage("Nexus Replication Plugin Configuration") + String name(); + + @DefaultMessage("Master server's URL prefix") + String masterServerURLPrefixLabel(); + + @DefaultMessage("Master server's URL prefix (e.g. http://localhost:8081/nexus") + String masterServerURLPrefixHelp(); + + @DefaultMessage("Request queue size") + String requestQueueSizeLabel(); + + @DefaultMessage("Request queue size (default 500)") + String requestQueueSizeHelp(); + + @DefaultMessage("Request sending thread count") + String requestSendingThreadCountLabel(); + + @DefaultMessage("Request sending thread count (default 1)") + String requestSendingThreadCountHelp(); + + @DefaultMessage("Request queue dump file") + String requestQueueDumpFileNameLabel(); + + @DefaultMessage("Request queue dump file (default /tmp/nexus-replication-plugin-queue-backup)") + String requestQueueDumpFileNameHelp(); + + @DefaultMessage("Peer server's url") + String serverUrlLabel(); + + @DefaultMessage("Peer server's url (like http://localhost:8083/nexus)") + String serverUrlHelp(); + + @DefaultMessage("Peer server's login") + String serverLoginLabel(); + + @DefaultMessage("Peer server's login (default: admin)") + String serverLoginHelp(); + + @DefaultMessage("Peer server's password") + String serverPasswordLabel(); + + @DefaultMessage("Peer server's password (default: admin123") + String serverPasswordHelp(); + + } }