Skip to content

Commit

Permalink
Add more unit tests, increasing overall coverage
Browse files Browse the repository at this point in the history
- Add tests for fedoraResponse class
- Clean up camel exceptions

Partial resolution of: https://www.pivotaltracker.com/story/show/82225792
  • Loading branch information
acoburn authored and Andrew Woods committed Nov 14, 2014
1 parent 1e9bc59 commit 2b26e0d
Show file tree
Hide file tree
Showing 9 changed files with 300 additions and 68 deletions.
67 changes: 36 additions & 31 deletions src/main/java/org/fcrepo/camel/FedoraClient.java
Expand Up @@ -16,29 +16,31 @@
package org.fcrepo.camel;

import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.ws.rs.core.Link;

import org.apache.camel.component.http4.HttpOperationFailedException;
import org.apache.http.HttpStatus;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpHead;
import org.apache.http.client.methods.HttpPatch;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.InputStreamEntity;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
Expand All @@ -54,6 +56,10 @@
*/
public class FedoraClient {

private static final String DESCRIBED_BY = "describedby";

private static final String CONTENT_TYPE = "Content-Type";

private CloseableHttpClient httpclient;

private volatile Boolean throwExceptionOnFailure = true;
Expand Down Expand Up @@ -88,25 +94,24 @@ public FedoraClient(final String username, final String password, final String h
/**
* Stop the client
*/
public void stop() throws ClientProtocolException, IOException {
public void stop() throws IOException {
this.httpclient.close();
}

/**
* Make a HEAD response
*/
public FedoraResponse head(final URI url)
throws ClientProtocolException, IOException, HttpOperationFailedException {
throws IOException, HttpOperationFailedException {

final HttpHead request = new HttpHead(url);
final HttpResponse response = httpclient.execute(request);
final int status = response.getStatusLine().getStatusCode();
final String contentType = getContentTypeHeader(response);

if ((status >= 200 && status < 300) || !this.throwExceptionOnFailure) {
final HttpEntity entity = response.getEntity();
if ((status >= HttpStatus.SC_OK && status < HttpStatus.SC_BAD_REQUEST) || !this.throwExceptionOnFailure) {
URI describedBy = null;
final ArrayList<URI> links = getLinkHeaders(response, "describedby");
final List<URI> links = getLinkHeaders(response, DESCRIBED_BY);
if (links.size() == 1) {
describedBy = links.get(0);
}
Expand All @@ -119,22 +124,22 @@ public FedoraResponse head(final URI url)
/**
* Make a PUT request
*/
public FedoraResponse put(final URI url, final String body, final String contentType)
throws ClientProtocolException, IOException, HttpOperationFailedException {
public FedoraResponse put(final URI url, final InputStream body, final String contentType)
throws IOException, HttpOperationFailedException {

final HttpPut request = new HttpPut(url);
if (contentType != null) {
request.addHeader("Content-Type", contentType);
request.addHeader(CONTENT_TYPE, contentType);
}
if (body != null) {
request.setEntity(new StringEntity(body));
request.setEntity(new InputStreamEntity(body));
}

final HttpResponse response = httpclient.execute(request);
final int status = response.getStatusLine().getStatusCode();
final String contentTypeHeader = getContentTypeHeader(response);

if ((status >= 200 && status < 300) || !this.throwExceptionOnFailure) {
if ((status >= HttpStatus.SC_OK && status < HttpStatus.SC_BAD_REQUEST) || !this.throwExceptionOnFailure) {
final HttpEntity entity = response.getEntity();
return new FedoraResponse(url, status, contentTypeHeader, null,
entity != null ? EntityUtils.toString(entity) : null);
Expand All @@ -146,20 +151,20 @@ public FedoraResponse put(final URI url, final String body, final String content
/**
* Make a PATCH request
*/
public FedoraResponse patch(final URI url, final String body)
throws ClientProtocolException, IOException, HttpOperationFailedException {
public FedoraResponse patch(final URI url, final InputStream body)
throws IOException, HttpOperationFailedException {

final HttpPatch request = new HttpPatch(url);
request.addHeader("Content-Type", "application/sparql-update");
request.addHeader(CONTENT_TYPE, "application/sparql-update");
if (body != null) {
request.setEntity(new StringEntity(body));
request.setEntity(new InputStreamEntity(body));
}

final HttpResponse response = httpclient.execute(request);
final int status = response.getStatusLine().getStatusCode();
final String contentType = getContentTypeHeader(response);

if ((status >= 200 && status < 300) || !this.throwExceptionOnFailure) {
if ((status >= HttpStatus.SC_OK && status < HttpStatus.SC_BAD_REQUEST) || !this.throwExceptionOnFailure) {
final HttpEntity entity = response.getEntity();
return new FedoraResponse(url, status, contentType, null,
entity != null ? EntityUtils.toString(entity) : null);
Expand All @@ -171,20 +176,20 @@ public FedoraResponse patch(final URI url, final String body)
/**
* Make a POST request
*/
public FedoraResponse post(final URI url, final String body, final String contentType)
throws ClientProtocolException, IOException, HttpOperationFailedException {
public FedoraResponse post(final URI url, final InputStream body, final String contentType)
throws IOException, HttpOperationFailedException {

final HttpPost request = new HttpPost(url);
request.addHeader("Content-Type", contentType);
request.addHeader(CONTENT_TYPE, contentType);
if (body != null) {
request.setEntity(new StringEntity(body));
request.setEntity(new InputStreamEntity(body));
}

final HttpResponse response = httpclient.execute(request);
final int status = response.getStatusLine().getStatusCode();
final String contentTypeHeader = getContentTypeHeader(response);

if ((status >= 200 && status < 300) || !this.throwExceptionOnFailure) {
if ((status >= HttpStatus.SC_OK && status < HttpStatus.SC_BAD_REQUEST) || !this.throwExceptionOnFailure) {
final HttpEntity entity = response.getEntity();
return new FedoraResponse(url, status, contentTypeHeader, null,
entity != null ? EntityUtils.toString(entity) : null);
Expand All @@ -197,14 +202,14 @@ public FedoraResponse post(final URI url, final String body, final String conten
* Make a DELETE request
*/
public FedoraResponse delete(final URI url)
throws ClientProtocolException, IOException, HttpOperationFailedException {
throws IOException, HttpOperationFailedException {

final HttpDelete request = new HttpDelete(url);
final HttpResponse response = httpclient.execute(request);
final int status = response.getStatusLine().getStatusCode();
final String contentType = getContentTypeHeader(response);

if ((status >= 200 && status < 300) || !this.throwExceptionOnFailure) {
if ((status >= HttpStatus.SC_OK && status < HttpStatus.SC_BAD_REQUEST) || !this.throwExceptionOnFailure) {
final HttpEntity entity = response.getEntity();
return new FedoraResponse(url, status, contentType, null,
entity != null ? EntityUtils.toString(entity) : null);
Expand All @@ -217,7 +222,7 @@ public FedoraResponse delete(final URI url)
* Make a GET request
*/
public FedoraResponse get(final URI url, final String accept)
throws ClientProtocolException, IOException, HttpOperationFailedException {
throws IOException, HttpOperationFailedException {

final HttpGet request = new HttpGet(url);

Expand All @@ -229,10 +234,10 @@ public FedoraResponse get(final URI url, final String accept)
final int status = response.getStatusLine().getStatusCode();
final String contentType = getContentTypeHeader(response);

if ((status >= 200 && status < 300) || !this.throwExceptionOnFailure) {
if ((status >= HttpStatus.SC_OK && status < HttpStatus.SC_BAD_REQUEST) || !this.throwExceptionOnFailure) {
final HttpEntity entity = response.getEntity();
URI describedBy = null;
final ArrayList<URI> links = getLinkHeaders(response, "describedby");
final List<URI> links = getLinkHeaders(response, DESCRIBED_BY);
if (links.size() == 1) {
describedBy = links.get(0);
}
Expand All @@ -255,7 +260,7 @@ public FedoraResponse get(final URI url, final String accept)
final HttpEntity entity = response.getEntity();
String locationValue = null;

if (locationHeader != null && (status >= 300 && status < 400)) {
if (locationHeader != null && status < HttpStatus.SC_BAD_REQUEST) {
locationValue = locationHeader.getValue();
}

Expand Down Expand Up @@ -286,7 +291,7 @@ protected static Map<String, String> extractResponseHeaders(final Header[] respo
* Extract the content-type header value
*/
protected static String getContentTypeHeader(final HttpResponse response) {
final Header[] contentTypes = response.getHeaders("Content-Type");
final Header[] contentTypes = response.getHeaders(CONTENT_TYPE);
if (contentTypes != null && contentTypes.length > 0) {
return contentTypes[0].getValue();
} else {
Expand All @@ -297,8 +302,8 @@ protected static String getContentTypeHeader(final HttpResponse response) {
/**
* Extract any Link headers
*/
protected static ArrayList<URI> getLinkHeaders(final HttpResponse response, final String relationship) {
final ArrayList<URI> uris = new ArrayList<URI>();
protected static List<URI> getLinkHeaders(final HttpResponse response, final String relationship) {
final List<URI> uris = new ArrayList<URI>();
final Header[] links = response.getHeaders("Link");
if (links != null) {
for (Header header: links) {
Expand Down
41 changes: 19 additions & 22 deletions src/main/java/org/fcrepo/camel/FedoraProducer.java
Expand Up @@ -28,8 +28,9 @@
import static org.fcrepo.jms.headers.DefaultMessageFactory.IDENTIFIER_HEADER_NAME;
import static org.slf4j.LoggerFactory.getLogger;

import java.io.IOException;
import java.net.URI;
import java.io.IOException;
import java.io.InputStream;

import org.apache.camel.Exchange;
import org.apache.camel.Message;
Expand All @@ -46,7 +47,6 @@
* @since October 20, 2014
*/
public class FedoraProducer extends DefaultProducer {

private static final Logger LOGGER = getLogger(FedoraProducer.class);

private volatile FedoraEndpoint endpoint;
Expand All @@ -65,7 +65,6 @@ public FedoraProducer(final FedoraEndpoint endpoint) {
* Define how message exchanges are processed.
*
* @param exchange the InOut message exchange
* @throws IOException
* @throws HttpOperationFailedException
*/
@Override
Expand All @@ -84,25 +83,19 @@ public void process(final Exchange exchange) throws HttpOperationFailedException

LOGGER.debug("Fcrepo Request [{}] with method [{}]", url, method);

FedoraResponse headResponse;
FedoraResponse response;

switch (method) {
case PATCH:
headResponse = client.head(create(url));
if (headResponse.getLocation() != null) {
response = client.patch(headResponse.getLocation(), in.getBody(String.class));
} else {
response = client.patch(create(url), in.getBody(String.class));
}
response = client.patch(getMetadataUri(client, url), in.getBody(InputStream.class));
exchange.getIn().setBody(response.getBody());
break;
case PUT:
response = client.put(create(url), in.getBody(String.class), contentType);
response = client.put(create(url), in.getBody(InputStream.class), contentType);
exchange.getIn().setBody(response.getBody());
break;
case POST:
response = client.post(create(url), in.getBody(String.class), contentType);
response = client.post(create(url), in.getBody(InputStream.class), contentType);
exchange.getIn().setBody(response.getBody());
break;
case DELETE:
Expand All @@ -115,23 +108,27 @@ public void process(final Exchange exchange) throws HttpOperationFailedException
break;
case GET:
default:
if (endpoint.getMetadata()) {
headResponse = client.head(create(url));
if (headResponse.getLocation() != null) {
response = client.get(headResponse.getLocation(), accept);
} else {
response = client.get(create(url), accept);
}
} else {
response = client.get(create(url), null);
}
response = client.get(endpoint.getMetadata() ? getMetadataUri(client, url) : create(url), accept);
exchange.getIn().setBody(response.getBody());
exchange.getIn().setHeader("Content-Type", response.getContentType());
}
exchange.getIn().setHeader(HTTP_RESPONSE_CODE, response.getStatusCode());
client.stop();
}

/**
*
*/
protected URI getMetadataUri(final FedoraClient client, final String url)
throws HttpOperationFailedException, IOException {
final FedoraResponse headResponse = client.head(create(url));
if (headResponse.getLocation() != null) {
return headResponse.getLocation();
} else {
return create(url);
}
}

/**
* Given an exchange, determine which HTTP method to use. Basically, use GET unless the value of the
* Exchange.HTTP_METHOD header is defined. Unlike the http4: component, the request does not use POST if there is
Expand Down
Expand Up @@ -34,6 +34,7 @@
import com.hp.hpl.jena.rdf.model.StmtIterator;

import java.io.InputStream;
import java.io.IOException;
import java.util.Set;
import java.util.HashSet;
import java.util.List;
Expand All @@ -50,19 +51,17 @@ public class SparqlDeleteProcessor implements Processor {
/**
* Define how the message should be processed.
*/
public void process(final Exchange exchange) throws Exception {
public void process(final Exchange exchange) throws IOException {

final Message in = exchange.getIn();
final Model model = createDefaultModel().read(in.getBody(InputStream.class), null);
final StmtIterator triples = model.listStatements();
String subject = null;

if (in.getHeader(FCREPO_BASE_URL) != null) {
subject = in.getHeader(FCREPO_BASE_URL, String.class);
} else if (in.getHeader(BASE_URL_HEADER_NAME) != null) {
subject = in.getHeader(BASE_URL_HEADER_NAME, String.class);
} else {
throw new Exception("No baseURL header available!");
throw new IOException("No baseURL header available!");
}

if (in.getHeader(FCREPO_IDENTIFIER) != null) {
Expand All @@ -71,6 +70,9 @@ public void process(final Exchange exchange) throws Exception {
subject += in.getHeader(IDENTIFIER_HEADER_NAME);
}

final Model model = createDefaultModel().read(in.getBody(InputStream.class), null);
final StmtIterator triples = model.listStatements();

// build list of triples to delete
final Set<String> uris = new HashSet<String>();
while ( triples.hasNext() ) {
Expand Down
Expand Up @@ -23,9 +23,11 @@
import static org.fcrepo.jms.headers.DefaultMessageFactory.BASE_URL_HEADER_NAME;
import static org.fcrepo.jms.headers.DefaultMessageFactory.IDENTIFIER_HEADER_NAME;

import org.apache.camel.Processor;
import org.apache.camel.Exchange;
import org.apache.camel.Message;
import org.apache.camel.Processor;

import java.io.IOException;

/**
* Represents a Processor class that formulates a Sparql DESCRIBE query
Expand All @@ -45,18 +47,17 @@ public class SparqlDescribeProcessor implements Processor {
/**
* Define how this message should be processed
*/
public void process(final Exchange exchange) throws Exception {
public void process(final Exchange exchange) throws IOException {

final Message in = exchange.getIn();

String subject = null;

if (in.getHeader(FCREPO_BASE_URL) != null) {
subject = in.getHeader(FCREPO_BASE_URL, String.class);
} else if (in.getHeader(BASE_URL_HEADER_NAME) != null) {
subject = in.getHeader(BASE_URL_HEADER_NAME, String.class);
} else {
throw new Exception("No baseURL header available!");
throw new IOException("No baseURL header available!");
}

if (in.getHeader(FCREPO_IDENTIFIER) != null) {
Expand Down

0 comments on commit 2b26e0d

Please sign in to comment.