Skip to content

Commit

Permalink
Implement automated tests for plugin API HTTP Client
Browse files Browse the repository at this point in the history
Implement automated tests for plugin API HTTP resource
Add Mockito and Power Mock dependency
Implement automated tests for ConfigurationsManager. Implement additional tests for HTTP Client and HTTP resource
Exclude artifacts forbidden by maven enforce plugin
  • Loading branch information
gd-tmagrys committed Jul 2, 2015
1 parent af01346 commit 50b1883
Show file tree
Hide file tree
Showing 14 changed files with 578 additions and 73 deletions.
25 changes: 25 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,31 @@
<artifactId>lombok</artifactId>
<version>1.16.4</version>
</dependency>

<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>1.10.19</version>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<version>1.6.2</version>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/**
Expand All @@ -36,26 +36,24 @@
public class ReplicationPluginConfiguration {
@XmlElement(name = "server")
@XmlElementWrapper(name = "servers")
private final Set<NexusServer> servers = new HashSet<>();
private final Set<NexusServer> 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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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<Runnable>(
configurationsManager.getConfiguration().getRequestsQueueSize())
);
initBackgroundWorkers(configurationsManager);
}

Expand All @@ -95,12 +87,8 @@ public void run() {
}

private FileBlockingQueue initFileBlockingQueue(ConfigurationsManager configurationsManager) {
BlockingQueue<ArtifactMetaInfo> 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()) {
Expand Down Expand Up @@ -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<RestResponse>() {
@Override
Expand Down Expand Up @@ -166,40 +156,4 @@ public GenericType<RestResponse> 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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ public ConfigurationsManagerImpl(NexusConfiguration nexusConfiguration) {
@PostConstruct
public void init() {
log.trace("Initializing plugin configurations");
reloadConfigurations();
reloadConfigurations(CONFIG_FILENAME);
}

/**
Expand All @@ -78,7 +78,7 @@ public ReplicationPluginConfiguration getConfiguration() {
if (config == null) {
synchronized (this) {
if (config == null) {
reloadConfigurations();
reloadConfigurations(CONFIG_FILENAME);
}
}
}
Expand All @@ -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);

Expand All @@ -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);
}
}
Original file line number Diff line number Diff line change
@@ -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);
}

}
Original file line number Diff line number Diff line change
@@ -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<ArtifactMetaInfo> blockingQueue =
new LinkedBlockingQueue<>(configurationsManager.
getConfiguration().getRequestsQueueSize());
String blockingQueueDumpFileName = configurationsManager.getConfiguration().getQueueDumpFileName();

return new FileBlockingQueue(blockingQueue,
blockingQueueDumpFileName);
}

}
Original file line number Diff line number Diff line change
@@ -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<Runnable>(
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;
}

}
Loading

0 comments on commit 50b1883

Please sign in to comment.