diff --git a/pom.xml b/pom.xml
index de10428..9061665 100644
--- a/pom.xml
+++ b/pom.xml
@@ -146,6 +146,31 @@
lombok
1.16.4
+
+
+ org.mockito
+ mockito-core
+ 1.10.19
+ test
+
+
+ org.hamcrest
+ hamcrest-core
+
+
+
+
+ org.powermock
+ powermock-api-mockito
+ 1.6.2
+ test
+
+
+ org.mockito
+ mockito-all
+
+
+
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
index 4d78ae0..b683ff4 100644
--- 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
@@ -15,7 +15,9 @@
*/
package com.griddynamics.cd.nrp.internal.model.config;
-import lombok.*;
+import lombok.NoArgsConstructor;
+import lombok.NonNull;
+import lombok.RequiredArgsConstructor;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
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
index 47a4feb..9251883 100644
--- 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
@@ -24,7 +24,7 @@
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.LinkedHashSet;
import java.util.Set;
/**
@@ -36,26 +36,24 @@
public class ReplicationPluginConfiguration {
@XmlElement(name = "server")
@XmlElementWrapper(name = "servers")
- private final Set servers = new HashSet<>();
+ private final Set servers = new LinkedHashSet<>();
@Getter
@NonNull
@XmlAttribute(name = "myUrl")
private String myUrl;
+ @Getter
@XmlAttribute(name = "requestsQueueSize")
private Integer requestsQueueSize = 500;
@XmlAttribute(name = "requestsSendingThreadsCount")
private Integer requestsSendingThreadsCount = 1;
@XmlAttribute(name = "queueDumpFileName")
+ @NonNull
private String queueDumpFileName;
public void addServer(NexusServer server) {
servers.add(server);
}
- public Integer getRequestsQueueSize() {
- return requestsQueueSize;
- }
-
public String getQueueDumpFileName() {
return queueDumpFileName;
}
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 52cf9bf..57b1131 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
@@ -16,25 +16,21 @@
package com.griddynamics.cd.nrp.internal.uploading.impl;
import com.griddynamics.cd.nrp.internal.model.api.ArtifactMetaInfo;
-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.model.internal.ArtifactMetaInfoQueueDump;
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;
@@ -50,25 +46,21 @@ public class ArtifactUpdateApiClientImpl extends ComponentSupport implements Art
* Provides access to the plugin configurations
*/
private final ConfigurationsManager configurationsManager;
-
+ private final FileBlockingQueueFactory fileBlockingQueueFactory;
+ private final AsyncWebResourceBuilderFactory asyncWebResourceBuilderFactory;
/**
* ExecutorService shares between clients. All treads are created in the same executor
*/
- private final ExecutorService jerseyHttpClientExecutor;
private final FileBlockingQueue fileBlockingQueue;
@Inject
- public ArtifactUpdateApiClientImpl(ConfigurationsManager configurationsManager) {
+ public ArtifactUpdateApiClientImpl(ConfigurationsManager configurationsManager,
+ FileBlockingQueueFactory fileBlockingQueueFactory,
+ AsyncWebResourceBuilderFactory asyncWebResourceBuilderFactory) {
this.configurationsManager = configurationsManager;
+ this.fileBlockingQueueFactory = fileBlockingQueueFactory;
+ this.asyncWebResourceBuilderFactory = asyncWebResourceBuilderFactory;
this.fileBlockingQueue = initFileBlockingQueue(configurationsManager);
- this.jerseyHttpClientExecutor = new ThreadPoolExecutor(
- configurationsManager.getConfiguration().getRequestsSendingThreadsCount(),
- configurationsManager.getConfiguration().getRequestsSendingThreadsCount(),
- 30,
- TimeUnit.SECONDS,
- new LinkedBlockingQueue(
- configurationsManager.getConfiguration().getRequestsQueueSize())
- );
initBackgroundWorkers(configurationsManager);
}
@@ -95,12 +87,8 @@ public void run() {
}
private FileBlockingQueue initFileBlockingQueue(ConfigurationsManager configurationsManager) {
- BlockingQueue blockingQueue =
- new LinkedBlockingQueue<>(configurationsManager.
- getConfiguration().getRequestsQueueSize());
String blockingQueueDumpFileName = configurationsManager.getConfiguration().getQueueDumpFileName();
- FileBlockingQueue retVal = new FileBlockingQueue(blockingQueue,
- blockingQueueDumpFileName);
+ FileBlockingQueue retVal = fileBlockingQueueFactory.getFileBlockingQueue();
try {
File blockingQueueInputFile = new File(blockingQueueDumpFileName);
if (blockingQueueInputFile.exists()) {
@@ -133,7 +121,9 @@ public void offerRequest(ArtifactMetaInfo artifactMetaInfo) {
*/
public void sendRequest(ArtifactMetaInfo metaInfo) {
for (NexusServer server : configurationsManager.getConfiguration().getServers()) {
- AsyncWebResource.Builder service = getService(server.getUrl(), server.getUser(), server.getPassword());
+ AsyncWebResource.Builder service =
+ asyncWebResourceBuilderFactory.getAsyncWebResourceBuilder(
+ server.getUrl(), server.getUser(), server.getPassword());
try {
service.post(new ITypeListener() {
@Override
@@ -166,40 +156,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();
- 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
index 5d4b4be..4dc835b 100644
--- 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
@@ -66,7 +66,7 @@ public ConfigurationsManagerImpl(NexusConfiguration nexusConfiguration) {
@PostConstruct
public void init() {
log.trace("Initializing plugin configurations");
- reloadConfigurations();
+ reloadConfigurations(CONFIG_FILENAME);
}
/**
@@ -78,7 +78,7 @@ public ReplicationPluginConfiguration getConfiguration() {
if (config == null) {
synchronized (this) {
if (config == null) {
- reloadConfigurations();
+ reloadConfigurations(CONFIG_FILENAME);
}
}
}
@@ -89,8 +89,8 @@ public ReplicationPluginConfiguration getConfiguration() {
* Reloads {@link ConfigurationsManagerImpl#config}
* from XML plugin configurations file
*/
- public void reloadConfigurations() {
- File file = getConfigurationFile();
+ public void reloadConfigurations(String filename) {
+ File file = getConfigurationFile(filename);
try {
JAXBContext jaxbContext = JAXBContext.newInstance(ReplicationPluginConfiguration.class);
@@ -104,7 +104,7 @@ public void reloadConfigurations() {
/**
* Returns plugin configurations XML file
*/
- private File getConfigurationFile() {
- return new File(nexusConfiguration.getConfigurationDirectory(), CONFIG_FILENAME);
+ private File getConfigurationFile(String filename) {
+ return new File(nexusConfiguration.getConfigurationDirectory(), filename);
}
}
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..c76343a
--- /dev/null
+++ b/src/main/java/com/griddynamics/cd/nrp/internal/uploading/impl/factories/FileBlockingQueueFactory.java
@@ -0,0 +1,32 @@
+package com.griddynamics.cd.nrp.internal.uploading.impl.factories;
+
+import com.griddynamics.cd.nrp.internal.model.api.ArtifactMetaInfo;
+import com.griddynamics.cd.nrp.internal.uploading.ConfigurationsManager;
+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 ConfigurationsManager configurationsManager;
+
+ @Inject
+ public FileBlockingQueueFactory(ConfigurationsManager configurationsManager) {
+ this.configurationsManager = configurationsManager;
+ }
+
+ public FileBlockingQueue getFileBlockingQueue() {
+ BlockingQueue blockingQueue =
+ new LinkedBlockingQueue<>(configurationsManager.
+ getConfiguration().getRequestsQueueSize());
+ String blockingQueueDumpFileName = configurationsManager.getConfiguration().getQueueDumpFileName();
+
+ 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..f02a657
--- /dev/null
+++ b/src/main/java/com/griddynamics/cd/nrp/internal/uploading/impl/factories/JerseyClientFactory.java
@@ -0,0 +1,49 @@
+package com.griddynamics.cd.nrp.internal.uploading.impl.factories;
+
+import com.griddynamics.cd.nrp.internal.uploading.ConfigurationsManager;
+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 final ExecutorService executorService;
+
+ @Inject
+ public JerseyClientFactory(ConfigurationsManager configurationsManager) {
+ this.executorService = new ThreadPoolExecutor(
+ configurationsManager.getConfiguration().getRequestsSendingThreadsCount(),
+ configurationsManager.getConfiguration().getRequestsSendingThreadsCount(),
+ 30,
+ TimeUnit.SECONDS,
+ new LinkedBlockingQueue(
+ configurationsManager.getConfiguration().getRequestsQueueSize()));
+ }
+
+ public Client getClient(String login, String password) {
+ ClientConfig config = new DefaultClientConfig();
+ 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;
+ }
+
+}
diff --git a/src/test/java/com/griddynamics/cd/nrp/internal/rest/ArtifactUpdatePlexusResourceTest.java b/src/test/java/com/griddynamics/cd/nrp/internal/rest/ArtifactUpdatePlexusResourceTest.java
new file mode 100644
index 0000000..bf82a85
--- /dev/null
+++ b/src/test/java/com/griddynamics/cd/nrp/internal/rest/ArtifactUpdatePlexusResourceTest.java
@@ -0,0 +1,157 @@
+package com.griddynamics.cd.nrp.internal.rest;
+
+import com.griddynamics.cd.nrp.internal.model.api.ArtifactMetaInfo;
+import com.griddynamics.cd.nrp.internal.model.api.RestResponse;
+import com.thoughtworks.xstream.XStream;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.restlet.data.Request;
+import org.restlet.resource.ResourceException;
+import org.sonatype.nexus.proxy.maven.ArtifactStoreHelper;
+import org.sonatype.nexus.proxy.maven.ArtifactStoreRequest;
+import org.sonatype.nexus.proxy.maven.maven2.M2Repository;
+import org.sonatype.nexus.proxy.registry.RepositoryRegistry;
+import org.sonatype.nexus.proxy.repository.Repository;
+import org.sonatype.plexus.rest.resource.PathProtectionDescriptor;
+
+import java.util.ArrayList;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.*;
+
+@RunWith(MockitoJUnitRunner.class)
+public class ArtifactUpdatePlexusResourceTest {
+
+ private final String REQUEST_URI = "/artifact/maven/update";
+ private final ArrayList repositories = new ArrayList<>();
+ ArtifactStoreRequest artifactStoreRequestMock = mock(ArtifactStoreRequest.class);
+
+ private ArtifactUpdatePlexusResource artifactUpdatePlexusResource;
+ private ArtifactMetaInfo artifactMetaInfo;
+
+ @Before
+ public void setUp() throws Exception {
+ artifactUpdatePlexusResource = spy(new ArtifactUpdatePlexusResource() {
+ @Override
+ protected RepositoryRegistry getRepositoryRegistry() {
+// ArtifactStoreHelper artifactStoreHelper = mock(ArtifactStoreHelper.class);
+// ArrayList repositories = new ArrayList<>();
+// M2Repository repository = mock(M2Repository.class);
+// when(repository.getRemoteUrl()).thenReturn("http://localhost:8081/nexus/content/repositories/snapshots/");
+// when(repository.getId()).thenReturn("replica-1");
+// when(repository.getArtifactStoreHelper()).thenReturn(artifactStoreHelper);
+// repositories.add(repository);
+ RepositoryRegistry repositoryRegistry = mock(RepositoryRegistry.class);
+ when(repositoryRegistry.getRepositories()).thenReturn(repositories);
+ return repositoryRegistry;
+ }
+
+ @Override
+ protected ArtifactStoreRequest getResourceStoreRequest(Request request, boolean localOnly, boolean remoteOnly, String repositoryId, String g, String a, String v, String p, String c, String e) throws ResourceException {
+ return artifactStoreRequestMock;
+ }
+ });
+ artifactMetaInfo = new ArtifactMetaInfo("http://localhost:8081/nexus", "com.griddynamics.cd", "nexus-replication-plugin", "1.0", "snapshots");
+ artifactMetaInfo.setExtension("jar");
+ }
+
+ @After
+ public void tearDown() {
+ repositories.clear();
+ }
+
+ @Test
+ public void testGetResourceUri() throws Exception {
+ assertEquals(artifactUpdatePlexusResource.getResourceUri(), REQUEST_URI);
+ }
+
+ @Test
+ public void testGetResourceProtection() throws Exception {
+ PathProtectionDescriptor resourceProtection = artifactUpdatePlexusResource.getResourceProtection();
+ assertEquals("Incorrect request URI in security configuration", resourceProtection.getPathPattern(), REQUEST_URI);
+ assertEquals("Incorrect permissions for API", resourceProtection.getFilterExpression(), "authcBasic,perms[nexus:artifact]");
+ }
+
+ @Test
+ public void testGetPayloadInstance() throws Exception {
+ Object instance = artifactUpdatePlexusResource.getPayloadInstance();
+ assertNotNull(REQUEST_URI + " resource should be configured to return ArtifactMetaInfo as request body DTO. Method returns null.", instance);
+ assertTrue(REQUEST_URI + " resource should be configured to return ArtifactMetaInfo as request body DTO. Method returns incorrect type.", instance instanceof ArtifactMetaInfo);
+ }
+
+ @Test
+ public void testConfigureXStream() throws Exception {
+ XStream xstream = mock(XStream.class);
+ artifactUpdatePlexusResource.configureXStream(xstream);
+ Mockito.verify(xstream, Mockito.times(1)).processAnnotations(ArtifactMetaInfo.class);
+ Mockito.verify(xstream, Mockito.times(1)).processAnnotations(RestResponse.class);
+ }
+
+ @Test
+ public void testPostForEmptyRepositoriesList() throws Exception {
+ // Mocks initialization
+ Request request = mock(Request.class);
+
+ // Tested method invocation
+ RestResponse response = (RestResponse) artifactUpdatePlexusResource.post(null, request, null, artifactMetaInfo);
+ // Asserts
+ assertEquals("Method should return message that no proxies found", response.getMessage(), "No proxies for this artifact.");
+ assertFalse("Method should return error status because of no proxies found", response.isSuccess());
+ }
+
+ @Test
+ public void testPostForOneRepositoryList() throws Exception {
+ // Init mocks
+ ArtifactStoreHelper artifactStoreHelper = mock(ArtifactStoreHelper.class);
+ Request request = new Request();
+
+ M2Repository repository = mock(M2Repository.class);
+ when(repository.getRemoteUrl()).thenReturn("http://localhost:8081/nexus/content/repositories/snapshots/");
+ when(repository.getId()).thenReturn("replica-1");
+ when(repository.getArtifactStoreHelper()).thenReturn(artifactStoreHelper);
+ repositories.add(repository);
+ // Tested method invocation
+ RestResponse response = (RestResponse) artifactUpdatePlexusResource.post(null, request, null, artifactMetaInfo);
+ // Asserts
+ Mockito.verify(artifactStoreHelper, Mockito.times(1)).retrieveArtifact(artifactStoreRequestMock);
+ Assert.assertEquals("Request should return that artifact is resolved", "Artifact is resolved.", response.getMessage());
+ Assert.assertTrue("Request should be success.", response.isSuccess());
+ }
+
+ @Test
+ public void testPostForTwoMatchedRepositories() throws Exception {
+ // Init mocks
+ ArtifactStoreHelper artifactStoreHelper = mock(ArtifactStoreHelper.class);
+
+ M2Repository repository = mock(M2Repository.class);
+ when(repository.getRemoteUrl()).thenReturn("http://localhost:8081/nexus/content/repositories/snapshots/");
+ when(repository.getId()).thenReturn("replica-1");
+ when(repository.getArtifactStoreHelper()).thenReturn(artifactStoreHelper);
+ repositories.add(repository);
+
+ repository = mock(M2Repository.class);
+ when(repository.getRemoteUrl()).thenReturn("http://localhost:8081/nexus/content/repositories/snapshots/");
+ when(repository.getId()).thenReturn("replica-2");
+ when(repository.getArtifactStoreHelper()).thenReturn(artifactStoreHelper);
+ repositories.add(repository);
+
+ repository = mock(M2Repository.class);
+ when(repository.getRemoteUrl()).thenReturn("http://localhost:8085/nexus/content/repositories/releases/");
+ when(repository.getId()).thenReturn("replica-3");
+ when(repository.getArtifactStoreHelper()).thenReturn(artifactStoreHelper);
+ repositories.add(repository);
+
+ Request request = new Request();
+ // Tested method invocation
+ RestResponse response = (RestResponse) artifactUpdatePlexusResource.post(null, request, null, artifactMetaInfo);
+ // Asserts
+ Mockito.verify(artifactStoreHelper, Mockito.times(2)).retrieveArtifact(artifactStoreRequestMock);
+ Assert.assertEquals("Request should return that artifact is resolved", "Artifact is resolved.", response.getMessage());
+ Assert.assertTrue("Request should be success.", response.isSuccess());
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/com/griddynamics/cd/nrp/internal/uploading/impl/ArtifactUpdateApiClientImplTest.java b/src/test/java/com/griddynamics/cd/nrp/internal/uploading/impl/ArtifactUpdateApiClientImplTest.java
new file mode 100644
index 0000000..8e75af1
--- /dev/null
+++ b/src/test/java/com/griddynamics/cd/nrp/internal/uploading/impl/ArtifactUpdateApiClientImplTest.java
@@ -0,0 +1,137 @@
+package com.griddynamics.cd.nrp.internal.uploading.impl;
+
+
+import com.griddynamics.cd.nrp.internal.model.api.ArtifactMetaInfo;
+import com.griddynamics.cd.nrp.internal.model.config.NexusServer;
+import com.griddynamics.cd.nrp.internal.model.config.ReplicationPluginConfiguration;
+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.async.ITypeListener;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+
+import java.util.List;
+import java.util.concurrent.LinkedBlockingQueue;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.*;
+
+@RunWith(MockitoJUnitRunner.class)
+public class ArtifactUpdateApiClientImplTest {
+
+ private AwaitableFIleBlockingQueue awaitableFIleBlockingQueue;
+ @Mock
+ private ConfigurationsManager configurationsManagerMock;
+ @Mock
+ private FileBlockingQueueFactory fileBlockingQueueFactory;
+ @Mock
+ private AsyncWebResourceBuilderFactory asyncWebResourceBuilderFactoryMock;
+ @Mock
+ AsyncWebResource.Builder asyncWebResourceBuilderMock;
+
+ private ArtifactUpdateApiClient underTest;
+
+ @Before
+ public void setUp() {
+ NexusServer nexusServer = new NexusServer("http://mock:8082","admin","admin123");
+ NexusServer nexusServer2 = new NexusServer("http://mock:8083", "admin2", "admin456");
+ awaitableFIleBlockingQueue = new AwaitableFIleBlockingQueue(
+ new LinkedBlockingQueue(), "/tmp/queueDumpForTests",
+ 2
+ );
+ ReplicationPluginConfiguration replicationPluginConfiguration =
+ new ReplicationPluginConfiguration("http://mock:8081","/tmp/queueDumpForTests");
+ replicationPluginConfiguration.addServer(nexusServer);
+ replicationPluginConfiguration.addServer(nexusServer2);
+ when(configurationsManagerMock.getConfiguration()).thenReturn(replicationPluginConfiguration);
+ when(fileBlockingQueueFactory.getFileBlockingQueue()).thenReturn(awaitableFIleBlockingQueue);
+ when(asyncWebResourceBuilderFactoryMock.getAsyncWebResourceBuilder(
+ anyString(), anyString(), anyString())).
+ thenReturn(asyncWebResourceBuilderMock);
+ underTest = new ArtifactUpdateApiClientImpl(
+ configurationsManagerMock,
+ fileBlockingQueueFactory,
+ asyncWebResourceBuilderFactoryMock);
+ }
+
+ @After
+ public void tearDown() {
+ underTest = null;
+ }
+
+ @Test
+ public void testOfferRequest() throws InterruptedException {
+ ArtifactMetaInfo artifactMetaInfo = new ArtifactMetaInfo(
+ "http://mock:8081",
+ "com.griddynamics",
+ "nexus-replication-status",
+ "1.0-SNAPSHOT",
+ "local-master-nexus"
+ );
+ ArtifactMetaInfo artifactMetaInfo2 = new ArtifactMetaInfo(
+ "http://mock:8081",
+ "com.griddynamics",
+ "nexus-replication-status",
+ "2.0-SNAPSHOT",
+ "local-master-nexus"
+ );
+ underTest.offerRequest(artifactMetaInfo);
+ underTest.offerRequest(artifactMetaInfo2);
+ awaitableFIleBlockingQueue.await();
+
+ ArgumentCaptor urlCaptor = ArgumentCaptor.forClass(String.class);
+ ArgumentCaptor loginCaptor = ArgumentCaptor.forClass(String.class);
+ ArgumentCaptor passwordCaptor = ArgumentCaptor.forClass(String.class);
+
+ verify(asyncWebResourceBuilderFactoryMock, times(4)).
+ getAsyncWebResourceBuilder(urlCaptor.capture(), loginCaptor.capture(), passwordCaptor.capture());
+
+ List allUrls = urlCaptor.getAllValues();
+ List allLogins = loginCaptor.getAllValues();
+ List allpasswowrds = passwordCaptor.getAllValues();
+
+ assertEquals(4, allUrls.size());
+ assertEquals("http://mock:8082", allUrls.get(0));
+ assertEquals("http://mock:8083", allUrls.get(1));
+ assertEquals("http://mock:8082", allUrls.get(2));
+ assertEquals("http://mock:8083", allUrls.get(3));
+
+ assertEquals(4, allLogins.size());
+ assertEquals("admin", allLogins.get(0));
+ assertEquals("admin2", allLogins.get(1));
+ assertEquals("admin", allLogins.get(2));
+ assertEquals("admin2", allLogins.get(3));
+
+ assertEquals(4, allpasswowrds.size());
+ assertEquals("admin123", allpasswowrds.get(0));
+ assertEquals("admin456", allpasswowrds.get(1));
+ assertEquals("admin123", allpasswowrds.get(2));
+ assertEquals("admin456", allpasswowrds.get(3));
+
+ ArgumentCaptor iTypeListenerArgumentCaptor = ArgumentCaptor.forClass(ITypeListener.class);
+
+ ArgumentCaptor artifactMetaInfoArgumentCaptor =
+ ArgumentCaptor.forClass(ArtifactMetaInfo.class);
+
+ verify(asyncWebResourceBuilderMock,times(4)).post(
+ iTypeListenerArgumentCaptor.capture(),
+ artifactMetaInfoArgumentCaptor.capture());
+
+
+ assertEquals(artifactMetaInfo,artifactMetaInfoArgumentCaptor.getAllValues().get(0));
+ assertEquals(artifactMetaInfo,artifactMetaInfoArgumentCaptor.getAllValues().get(1));
+ assertEquals(artifactMetaInfo2,artifactMetaInfoArgumentCaptor.getAllValues().get(2));
+ assertEquals(artifactMetaInfo2,artifactMetaInfoArgumentCaptor.getAllValues().get(3));
+
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/com/griddynamics/cd/nrp/internal/uploading/impl/AwaitableFIleBlockingQueue.java b/src/test/java/com/griddynamics/cd/nrp/internal/uploading/impl/AwaitableFIleBlockingQueue.java
new file mode 100644
index 0000000..0241ea4
--- /dev/null
+++ b/src/test/java/com/griddynamics/cd/nrp/internal/uploading/impl/AwaitableFIleBlockingQueue.java
@@ -0,0 +1,30 @@
+package com.griddynamics.cd.nrp.internal.uploading.impl;
+
+import com.griddynamics.cd.nrp.internal.model.api.ArtifactMetaInfo;
+
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.CountDownLatch;
+
+public class AwaitableFIleBlockingQueue extends FileBlockingQueue{
+
+ private final CountDownLatch countDownLatch;
+
+ public AwaitableFIleBlockingQueue(BlockingQueue blockingQueue,
+ String blockingQueueDumpFileName,
+ int n) {
+ super(blockingQueue, blockingQueueDumpFileName);
+ this.countDownLatch = new CountDownLatch(n);
+ }
+
+ @Override
+ public ArtifactMetaInfo take() throws InterruptedException {
+ ArtifactMetaInfo retVal = super.take();
+ countDownLatch.countDown();
+ return retVal;
+ }
+
+ public void await() throws InterruptedException {
+ countDownLatch.await();
+ }
+
+}
diff --git a/src/test/java/com/griddynamics/cd/nrp/internal/uploading/impl/ConfigurationsManagerImplTest.java b/src/test/java/com/griddynamics/cd/nrp/internal/uploading/impl/ConfigurationsManagerImplTest.java
new file mode 100644
index 0000000..276348c
--- /dev/null
+++ b/src/test/java/com/griddynamics/cd/nrp/internal/uploading/impl/ConfigurationsManagerImplTest.java
@@ -0,0 +1,58 @@
+package com.griddynamics.cd.nrp.internal.uploading.impl;
+
+import com.griddynamics.cd.nrp.internal.model.config.NexusServer;
+import com.griddynamics.cd.nrp.internal.model.config.ReplicationPluginConfiguration;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.sonatype.nexus.configuration.application.NexusConfiguration;
+
+import java.io.File;
+import java.net.URL;
+import java.util.Iterator;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+@RunWith(MockitoJUnitRunner.class)
+public class ConfigurationsManagerImplTest {
+
+ private final String FIRST_CONFIGURATION_FILE = "replication-plugin.xml";
+ private final String SECOND_CONFIGURATION_FILE = "replication-plugin-2.xml";
+
+ @Test
+ public void testGetConfiguration() throws Exception {
+ NexusConfiguration nexusConfiguration = mock(NexusConfiguration.class);
+ URL configFile = getClass().getClassLoader().getResource(FIRST_CONFIGURATION_FILE);
+ when(nexusConfiguration.getConfigurationDirectory()).thenReturn(new File(configFile.getFile()).getParentFile());
+ ConfigurationsManagerImpl configurationsManager = spy(new ConfigurationsManagerImpl(nexusConfiguration));
+
+ ReplicationPluginConfiguration configuration = configurationsManager.getConfiguration();
+ Assert.assertEquals("My url was written incorrectly", "http://localhost:8081/nexus", configuration.getMyUrl());
+ Assert.assertEquals("Incorrect count of servers", 1, configuration.getServers().size());
+ Iterator iterator = configuration.getServers().iterator();
+ if (iterator.hasNext()) {
+ NexusServer nexusServer = iterator.next();
+ Assert.assertEquals("Server url was written incorrectly", "http://localhost:8083/nexus", nexusServer.getUrl());
+ Assert.assertEquals("User was written incorrectly", "admin", nexusServer.getUser());
+ Assert.assertEquals("Password was written incorrectly", "admin123", nexusServer.getPassword());
+ }
+ }
+
+ @Test
+ public void testReloadConfigurations() throws Exception {
+ NexusConfiguration nexusConfiguration = mock(NexusConfiguration.class);
+ URL configFile = getClass().getClassLoader().getResource(FIRST_CONFIGURATION_FILE);
+ when(nexusConfiguration.getConfigurationDirectory()).thenReturn(new File(configFile.getFile()).getParentFile());
+ ConfigurationsManagerImpl configurationsManager = spy(new ConfigurationsManagerImpl(nexusConfiguration));
+
+ ReplicationPluginConfiguration configuration = configurationsManager.getConfiguration();
+ Assert.assertEquals("First file should contain one nexus server only", 1, configuration.getServers().size());
+
+ configurationsManager.reloadConfigurations(SECOND_CONFIGURATION_FILE);
+ configuration = configurationsManager.getConfiguration();
+ Assert.assertEquals("Second file should contain two nexus servers", 2, configuration.getServers().size());
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/replication-plugin-2.xml b/src/test/resources/replication-plugin-2.xml
new file mode 100644
index 0000000..4bfa8d6
--- /dev/null
+++ b/src/test/resources/replication-plugin-2.xml
@@ -0,0 +1,15 @@
+
+
+
+
+ http://localhost:8083/nexus
+ admin
+ admin123
+
+
+ http://localhost:8083/nexus2
+ admin2
+ admin123
+
+
+
diff --git a/src/test/resources/replication-plugin.xml b/src/test/resources/replication-plugin.xml
new file mode 100644
index 0000000..95d9854
--- /dev/null
+++ b/src/test/resources/replication-plugin.xml
@@ -0,0 +1,10 @@
+
+
+
+
+ http://localhost:8083/nexus
+ admin
+ admin123
+
+
+