Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Minor refactoring to address sonar-related issues including:
- Throws declaration should not be redundant (RuntimeException unneeded in
function signature: FcrepoTransactionManager)
- Class Data Abstraction Coupling (FcrepoClient constructor logic moved
into FcrepoHttpClientBuilder class)
- Class Fan Out Complexity (HttpRequestBase instance creation moved to
HttpMethods class)
- Generic exceptions should never be thrown (FcrepoProducer now throws a
TransactionSystemException)
- Public types should be documented (processor.* classes now have full
documentation)
- String literals should not be duplicated (FcrepoClient debug messages
are now more specific)
- FcrepoTransactionManager thrown exceptions are now more specific

Resolves: https://jira.duraspace.org/browse/FCREPO-1397
  • Loading branch information
acoburn authored and Andrew Woods committed Mar 9, 2015
1 parent 8183293 commit e039ef0
Show file tree
Hide file tree
Showing 14 changed files with 171 additions and 96 deletions.
64 changes: 18 additions & 46 deletions src/main/java/org/fcrepo/camel/FcrepoClient.java
Expand Up @@ -15,34 +15,22 @@
*/
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.io.InputStream;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpStatus;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
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.HttpStatus;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
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.slf4j.Logger;

/**
Expand Down Expand Up @@ -75,28 +63,10 @@ public class FcrepoClient {
public FcrepoClient(final String username, final String password, final String host,
final Boolean throwExceptionOnFailure) {

final CredentialsProvider credsProvider = new BasicCredentialsProvider();
AuthScope scope = null;
final FcrepoHttpClientBuilder client = new FcrepoHttpClientBuilder(username, password, host);

this.throwExceptionOnFailure = throwExceptionOnFailure;

if (isBlank(username) || isBlank(password)) {
this.httpclient = HttpClients.createDefault();
} else {
LOGGER.debug("Accessing fcrepo with user credentials");

if (isBlank(host)) {
scope = new AuthScope(AuthScope.ANY);
} else {
scope = new AuthScope(new HttpHost(host));
}
credsProvider.setCredentials(
scope,
new UsernamePasswordCredentials(username, password));
this.httpclient = HttpClients.custom()
.setDefaultCredentialsProvider(credsProvider)
.build();
}
this.httpclient = client.build();
}

/**
Expand All @@ -108,7 +78,7 @@ public FcrepoClient(final String username, final String password, final String h
public FcrepoResponse head(final URI url)
throws FcrepoOperationFailedException {

final HttpHead request = new HttpHead(url);
final HttpRequestBase request = HttpMethods.HEAD.createRequest(url);
final HttpResponse response = executeRequest(request);
final int status = response.getStatusLine().getStatusCode();
final String contentType = getContentTypeHeader(response);
Expand Down Expand Up @@ -139,7 +109,8 @@ public FcrepoResponse head(final URI url)
public FcrepoResponse put(final URI url, final InputStream body, final String contentType)
throws FcrepoOperationFailedException {

final HttpPut request = new HttpPut(url);
final HttpMethods method = HttpMethods.PUT;
final HttpEntityEnclosingRequestBase request = (HttpEntityEnclosingRequestBase)method.createRequest(url);

if (contentType != null) {
request.addHeader(CONTENT_TYPE, contentType);
Expand All @@ -148,7 +119,7 @@ public FcrepoResponse put(final URI url, final InputStream body, final String co
request.setEntity(new InputStreamEntity(body));
}

LOGGER.debug("Fcrepo request headers: {}", request.getAllHeaders());
LOGGER.debug("Fcrepo PUT request headers: {}", request.getAllHeaders());

final HttpResponse response = executeRequest(request);

Expand All @@ -168,12 +139,13 @@ public FcrepoResponse put(final URI url, final InputStream body, final String co
public FcrepoResponse patch(final URI url, final InputStream body)
throws FcrepoOperationFailedException {

final HttpPatch request = new HttpPatch(url);
final HttpMethods method = HttpMethods.PATCH;
final HttpEntityEnclosingRequestBase request = (HttpEntityEnclosingRequestBase)method.createRequest(url);

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

LOGGER.debug("Fcrepo request headers: {}", request.getAllHeaders());
LOGGER.debug("Fcrepo PATCH request headers: {}", request.getAllHeaders());

final HttpResponse response = executeRequest(request);

Expand All @@ -193,7 +165,8 @@ public FcrepoResponse patch(final URI url, final InputStream body)
public FcrepoResponse post(final URI url, final InputStream body, final String contentType)
throws FcrepoOperationFailedException {

final HttpPost request = new HttpPost(url);
final HttpMethods method = HttpMethods.POST;
final HttpEntityEnclosingRequestBase request = (HttpEntityEnclosingRequestBase)method.createRequest(url);

if (contentType != null) {
request.addHeader(CONTENT_TYPE, contentType);
Expand All @@ -202,7 +175,7 @@ public FcrepoResponse post(final URI url, final InputStream body, final String c
request.setEntity(new InputStreamEntity(body));
}

LOGGER.debug("Fcrepo request headers: {}", request.getAllHeaders());
LOGGER.debug("Fcrepo POST request headers: {}", request.getAllHeaders());

final HttpResponse response = executeRequest(request);

Expand All @@ -220,8 +193,7 @@ public FcrepoResponse post(final URI url, final InputStream body, final String c
public FcrepoResponse delete(final URI url)
throws FcrepoOperationFailedException {

final HttpDelete request = new HttpDelete(url);

final HttpRequestBase request = HttpMethods.DELETE.createRequest(url);
final HttpResponse response = executeRequest(request);

LOGGER.debug("Fcrepo DELETE request returned status [{}]", response.getStatusLine().getStatusCode());
Expand All @@ -240,7 +212,7 @@ public FcrepoResponse delete(final URI url)
public FcrepoResponse get(final URI url, final String accept, final String prefer)
throws FcrepoOperationFailedException {

final HttpGet request = new HttpGet(url);
final HttpRequestBase request = HttpMethods.GET.createRequest(url);

if (accept != null) {
request.setHeader("Accept", accept);
Expand All @@ -250,7 +222,7 @@ public FcrepoResponse get(final URI url, final String accept, final String prefe
request.setHeader("Prefer", prefer);
}

LOGGER.debug("Fcrepo request headers: {}", request.getAllHeaders());
LOGGER.debug("Fcrepo GET request headers: {}", request.getAllHeaders());

final HttpResponse response = executeRequest(request);
final int status = response.getStatusLine().getStatusCode();
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/fcrepo/camel/FcrepoConfiguration.java
Expand Up @@ -15,9 +15,9 @@
*/
package org.fcrepo.camel;

import org.apache.camel.RuntimeCamelException;
import org.apache.camel.spi.UriParam;
import org.apache.camel.spi.UriParams;
import org.apache.camel.RuntimeCamelException;
import org.springframework.transaction.PlatformTransactionManager;

/**
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/fcrepo/camel/FcrepoEndpoint.java
Expand Up @@ -21,8 +21,8 @@
import org.apache.camel.Processor;
import org.apache.camel.Producer;
import org.apache.camel.RuntimeCamelException;
import org.apache.camel.api.management.ManagedResource;
import org.apache.camel.api.management.ManagedAttribute;
import org.apache.camel.api.management.ManagedResource;
import org.apache.camel.impl.DefaultEndpoint;
import org.apache.camel.spi.UriEndpoint;
import org.springframework.transaction.PlatformTransactionManager;
Expand Down
88 changes: 88 additions & 0 deletions src/main/java/org/fcrepo/camel/FcrepoHttpClientBuilder.java
@@ -0,0 +1,88 @@
/**
* Copyright 2015 DuraSpace, 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 org.fcrepo.camel;

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

import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.slf4j.Logger;

/**
* A utility class for building an httpclient for interacting with a Fedora repository
*
* @author Aaron Coburn
* @since March 9, 2015
*/
public class FcrepoHttpClientBuilder {

private String username;

private String password;

private String host;

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

/**
* Create a FcrepoHttpClientBuilder object with which it is possible to create
* an HttpClient object
*
* @param username an optional username for authentication
* @param password an optional password for authentication
* @param host an optional realm for authentication
*/
public FcrepoHttpClientBuilder(final String username, final String password, final String host) {
this.username = username;
this.password = password;
this.host = host;
}

/**
* Build an HttpClient
*
* @return an HttpClient
*/
public CloseableHttpClient build() {

if (isBlank(username) || isBlank(password)) {
return HttpClients.createDefault();
} else {
LOGGER.debug("Accessing fcrepo with user credentials");

final CredentialsProvider credsProvider = new BasicCredentialsProvider();
AuthScope scope = null;

if (isBlank(host)) {
scope = new AuthScope(AuthScope.ANY);
} else {
scope = new AuthScope(new HttpHost(host));
}
credsProvider.setCredentials(
scope,
new UsernamePasswordCredentials(username, password));
return HttpClients.custom()
.setDefaultCredentialsProvider(credsProvider)
.build();
}
}
}
8 changes: 5 additions & 3 deletions src/main/java/org/fcrepo/camel/FcrepoProducer.java
Expand Up @@ -18,9 +18,9 @@
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.slf4j.LoggerFactory.getLogger;

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

import org.apache.camel.Exchange;
import org.apache.camel.Message;
Expand All @@ -30,6 +30,7 @@
import org.apache.camel.util.IOHelper;
import org.slf4j.Logger;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.TransactionSystemException;
import org.springframework.transaction.support.DefaultTransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
Expand Down Expand Up @@ -85,7 +86,8 @@ protected void doInTransactionWithoutResult(final TransactionStatus status) {
try {
doRequest(exchange, tx.getSessionId());
} catch (FcrepoOperationFailedException ex) {
throw new RuntimeException("Error executing fcrepo request in transaction: ", ex);
throw new TransactionSystemException(
"Error executing fcrepo request in transaction: ", ex);
}
}
});
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/fcrepo/camel/FcrepoResponse.java
Expand Up @@ -15,8 +15,8 @@
*/
package org.fcrepo.camel;

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

/**
* Represents a response from a fedora repository using a {@link FcrepoClient}.
Expand Down
8 changes: 4 additions & 4 deletions src/main/java/org/fcrepo/camel/FcrepoTransactionManager.java
Expand Up @@ -23,6 +23,7 @@
import org.slf4j.Logger;
import org.springframework.transaction.CannotCreateTransactionException;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionSystemException;
import org.springframework.transaction.support.AbstractPlatformTransactionManager;
import org.springframework.transaction.support.DefaultTransactionStatus;

Expand Down Expand Up @@ -127,8 +128,7 @@ public String getAuthHost() {
}

@Override
protected void doBegin(final Object transaction, final TransactionDefinition definition)
throws CannotCreateTransactionException {
protected void doBegin(final Object transaction, final TransactionDefinition definition) {
final FcrepoResponse response;
final InputStream is = null;
final String contentType = null;
Expand Down Expand Up @@ -160,7 +160,7 @@ protected void doCommit(final DefaultTransactionStatus status) {
getClient().post(URI.create(baseUrl + "/" + tx.getSessionId() + "/fcr:tx/fcr:commit"), is, contentType);
} catch (FcrepoOperationFailedException ex) {
LOGGER.debug("Transaction commit failed: ", ex);
throw new CannotCreateTransactionException("Could not commit fcrepo transaction");
throw new TransactionSystemException("Could not commit fcrepo transaction");
} finally {
tx.setSessionId(null);
}
Expand All @@ -174,7 +174,7 @@ protected void doRollback(final DefaultTransactionStatus status) {
getClient().post(URI.create(baseUrl + "/" + tx.getSessionId() + "/fcr:tx/fcr:rollback"), null, null);
} catch (FcrepoOperationFailedException ex) {
LOGGER.debug("Transaction rollback failed: ", ex);
throw new CannotCreateTransactionException("Could not rollback fcrepo transaction");
throw new TransactionSystemException("Could not rollback fcrepo transaction");
} finally {
tx.setSessionId(null);
}
Expand Down
17 changes: 17 additions & 0 deletions src/main/java/org/fcrepo/camel/HttpMethods.java
Expand Up @@ -15,6 +15,9 @@
*/
package org.fcrepo.camel;

import java.net.URI;

import org.apache.camel.RuntimeCamelException;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import org.apache.http.client.methods.HttpGet;
Expand Down Expand Up @@ -48,4 +51,18 @@ public enum HttpMethods {
this.clazz = clazz;
entity = HttpEntityEnclosingRequestBase.class.isAssignableFrom(clazz);
}

/**
* Instantiate a new HttpRequst object from the method type
*
* @param url the URI that is part of the request
* @return an instance of the corresponding request class
*/
public HttpRequestBase createRequest(final URI url) {
try {
return clazz.getDeclaredConstructor(URI.class).newInstance(url);
} catch (ReflectiveOperationException ex) {
throw new RuntimeCamelException(ex);
}
}
}
Expand Up @@ -20,8 +20,8 @@
import org.apache.camel.Message;
import org.apache.clerezza.rdf.core.UriRef;
import org.apache.commons.lang3.StringUtils;
import org.fcrepo.camel.JmsHeaders;
import org.fcrepo.camel.FcrepoHeaders;
import org.fcrepo.camel.JmsHeaders;

/**
* Utility functions for fcrepo processor classes
Expand Down

0 comments on commit e039ef0

Please sign in to comment.