Skip to content

Commit

Permalink
Remove dependency on camel-http4
Browse files Browse the repository at this point in the history
- Add unit tests for new classes
- Remove code duplication, as per sonar

Resolves: https://jira.duraspace.org/browse/FCREPO-1278
  • Loading branch information
acoburn authored and Andrew Woods committed Jan 9, 2015
1 parent 3ad67c8 commit 1d164a1
Show file tree
Hide file tree
Showing 9 changed files with 338 additions and 207 deletions.
13 changes: 7 additions & 6 deletions pom.xml
Expand Up @@ -100,12 +100,6 @@
<version>${camel.version}</version>
</dependency>

<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-http4</artifactId>
<version>${camel.version}</version>
</dependency>

<dependency>
<groupId>org.apache.clerezza</groupId>
<artifactId>rdf.core</artifactId>
Expand Down Expand Up @@ -175,6 +169,13 @@
<version>${camel.version}</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-http4</artifactId>
<version>${camel.version}</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.apache.camel</groupId>
Expand Down
154 changes: 59 additions & 95 deletions src/main/java/org/fcrepo/camel/FcrepoClient.java
Expand Up @@ -16,18 +16,16 @@
package org.fcrepo.camel;

import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.slf4j.LoggerFactory.getLogger;

import java.io.InputStream;
import java.io.IOException;
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.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
Expand All @@ -42,11 +40,12 @@
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.client.methods.HttpRequestBase;
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;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;

/**
* Represents a client to interact with Fedora's HTTP API.
Expand All @@ -64,6 +63,8 @@ public class FcrepoClient {

private Boolean throwExceptionOnFailure = true;

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

/**
* Create a FcrepoClient with a set of authentication values.
* @param username the username for the repository
Expand Down Expand Up @@ -96,22 +97,15 @@ public FcrepoClient(final String username, final String password, final String h
}
}

/**
* Stop the client
*/
public void stop() throws IOException {
this.httpclient.close();
}

/**
* Make a HEAD response
* @param url the URL of the resource to check
*/
public FcrepoResponse head(final URI url)
throws IOException, HttpOperationFailedException {
throws FcrepoOperationFailedException {

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

Expand All @@ -123,7 +117,8 @@ public FcrepoResponse head(final URI url)
}
return new FcrepoResponse(url, status, contentType, describedBy, null);
} else {
throw buildHttpOperationFailedException(url, response);
throw new FcrepoOperationFailedException(url, status,
response.getStatusLine().getReasonPhrase());
}
}

Expand All @@ -134,27 +129,18 @@ public FcrepoResponse head(final URI url)
* @param contentType the MIMEType of the resource
*/
public FcrepoResponse put(final URI url, final InputStream body, final String contentType)
throws IOException, HttpOperationFailedException {
throws FcrepoOperationFailedException {

final HttpPut request = new HttpPut(url);

if (contentType != null) {
request.addHeader(CONTENT_TYPE, contentType);
}
if (body != null) {
request.setEntity(new InputStreamEntity(body));
}

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

if ((status >= HttpStatus.SC_OK && status < HttpStatus.SC_BAD_REQUEST) || !this.throwExceptionOnFailure) {
final HttpEntity entity = response.getEntity();
return new FcrepoResponse(url, status, contentTypeHeader, null,
entity != null ? entity.getContent() : null);
} else {
throw buildHttpOperationFailedException(url, response);
}
return fcrepoGenericResponse(url, executeRequest(request), throwExceptionOnFailure);
}

/**
Expand All @@ -164,22 +150,14 @@ public FcrepoResponse put(final URI url, final InputStream body, final String co
* @param body the body to be sent to the repository
*/
public FcrepoResponse patch(final URI url, final InputStream body)
throws IOException, HttpOperationFailedException {
throws FcrepoOperationFailedException {

final HttpPatch request = new HttpPatch(url);

request.addHeader(CONTENT_TYPE, "application/sparql-update");
request.setEntity(new InputStreamEntity(body));

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

if ((status >= HttpStatus.SC_OK && status < HttpStatus.SC_BAD_REQUEST) || !this.throwExceptionOnFailure) {
final HttpEntity entity = response.getEntity();
return new FcrepoResponse(url, status, contentType, null, entity != null ? entity.getContent() : null);
} else {
throw buildHttpOperationFailedException(url, response);
}
return fcrepoGenericResponse(url, executeRequest(request), throwExceptionOnFailure);
}

/**
Expand All @@ -189,45 +167,28 @@ public FcrepoResponse patch(final URI url, final InputStream body)
* @param contentType the Content-Type of the body
*/
public FcrepoResponse post(final URI url, final InputStream body, final String contentType)
throws IOException, HttpOperationFailedException {
throws FcrepoOperationFailedException {

final HttpPost request = new HttpPost(url);

request.addHeader(CONTENT_TYPE, contentType);
if (body != null) {
request.setEntity(new InputStreamEntity(body));
}

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

if ((status >= HttpStatus.SC_OK && status < HttpStatus.SC_BAD_REQUEST) || !this.throwExceptionOnFailure) {
final HttpEntity entity = response.getEntity();
return new FcrepoResponse(url, status, contentTypeHeader, null,
entity != null ? entity.getContent() : null);
} else {
throw buildHttpOperationFailedException(url, response);
}
return fcrepoGenericResponse(url, executeRequest(request), throwExceptionOnFailure);
}

/**
* Make a DELETE request
* @param url the URL of the resource to delete
*/
public FcrepoResponse delete(final URI url)
throws IOException, HttpOperationFailedException {
throws FcrepoOperationFailedException {

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 >= HttpStatus.SC_OK && status < HttpStatus.SC_BAD_REQUEST) || !this.throwExceptionOnFailure) {
final HttpEntity entity = response.getEntity();
return new FcrepoResponse(url, status, contentType, null, entity != null ? entity.getContent() : null);
} else {
throw buildHttpOperationFailedException(url, response);
}
return fcrepoGenericResponse(url, executeRequest(request), throwExceptionOnFailure);
}

/**
Expand All @@ -236,7 +197,7 @@ public FcrepoResponse delete(final URI url)
* @param accept the requested MIMEType of the resource to be retrieved
*/
public FcrepoResponse get(final URI url, final String accept, final String prefer)
throws IOException, HttpOperationFailedException {
throws FcrepoOperationFailedException {

final HttpGet request = new HttpGet(url);

Expand All @@ -248,69 +209,74 @@ public FcrepoResponse get(final URI url, final String accept, final String prefe
request.setHeader("Prefer", prefer);
}

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

if ((status >= HttpStatus.SC_OK && status < HttpStatus.SC_BAD_REQUEST) || !this.throwExceptionOnFailure) {
final HttpEntity entity = response.getEntity();
URI describedBy = null;
final List<URI> links = getLinkHeaders(response, DESCRIBED_BY);
if (links.size() == 1) {
describedBy = links.get(0);
}
return new FcrepoResponse(url, status, contentType, describedBy,
entity != null ? entity.getContent() : null);
getEntityContent(response));
} else {
throw buildHttpOperationFailedException(url, response);
throw new FcrepoOperationFailedException(url, status,
response.getStatusLine().getReasonPhrase());
}
}

/**
* Build a HttpOperationFailedException object from an http response
* @param url the URL of the request
* @param response the HTTP response
* Execute the HTTP request
*/
protected static HttpOperationFailedException
buildHttpOperationFailedException(final URI url, final HttpResponse response)
throws IOException {
private HttpResponse executeRequest(final HttpRequestBase request) throws FcrepoOperationFailedException {
try {
return httpclient.execute(request);
} catch (IOException ex) {
LOGGER.debug("HTTP Operation failed: ", ex);
throw new FcrepoOperationFailedException(request.getURI(), -1, ex.getMessage());
}
}

/**
* Handle the general case with responses.
*/
private FcrepoResponse fcrepoGenericResponse(final URI url, final HttpResponse response,
final Boolean throwExceptionOnFailure) throws FcrepoOperationFailedException {
final int status = response.getStatusLine().getStatusCode();
final Header locationHeader = response.getFirstHeader("location");
final HttpEntity entity = response.getEntity();
String locationValue = null;
final String contentTypeHeader = getContentTypeHeader(response);

if (locationHeader != null) {
locationValue = locationHeader.getValue();
if ((status >= HttpStatus.SC_OK && status < HttpStatus.SC_BAD_REQUEST) || !throwExceptionOnFailure) {
return new FcrepoResponse(url, status, contentTypeHeader, null, getEntityContent(response));
} else {
throw new FcrepoOperationFailedException(url, status,
response.getStatusLine().getReasonPhrase());
}

return new HttpOperationFailedException(url.toString(), status,
response.getStatusLine().getReasonPhrase(),
locationValue,
extractResponseHeaders(response.getAllHeaders()),
entity != null ? EntityUtils.toString(entity) : null);
}


/**
* Extract the response headers into a Map
* Extract the response body as an input stream
*/
protected static Map<String, String> extractResponseHeaders(final Header[] responseHeaders) {
if (responseHeaders == null) {
private static InputStream getEntityContent(final HttpResponse response) {
try {
final HttpEntity entity = response.getEntity();
if (entity == null) {
return null;
} else {
return entity.getContent();
}
} catch (IOException ex) {
LOGGER.debug("Unable to extract HttpEntity response into an InputStream: ", ex);
return null;
}

final Map<String, String> answer = new HashMap<String, String>();
for (Header header : responseHeaders) {
answer.put(header.getName(), header.getValue());
}

return answer;
}

/**
* Extract the content-type header value
*/
protected static String getContentTypeHeader(final HttpResponse response) {
private static String getContentTypeHeader(final HttpResponse response) {
final Header[] contentTypes = response.getHeaders(CONTENT_TYPE);
if (contentTypes.length > 0) {
return contentTypes[0].getValue();
Expand All @@ -322,7 +288,7 @@ protected static String getContentTypeHeader(final HttpResponse response) {
/**
* Extract any Link headers
*/
protected static List<URI> getLinkHeaders(final HttpResponse response, final String relationship) {
private static List<URI> getLinkHeaders(final HttpResponse response, final String relationship) {
final List<URI> uris = new ArrayList<URI>();
final Header[] links = response.getHeaders("Link");
for (Header header: links) {
Expand All @@ -333,6 +299,4 @@ protected static List<URI> getLinkHeaders(final HttpResponse response, final Str
}
return uris;
}


}

0 comments on commit 1d164a1

Please sign in to comment.