diff --git a/.gitignore b/.gitignore
index 7cc9f3f2..c4f45f5f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,3 +7,5 @@
workbench.xmi
target
build
+.DS_Store
+bin/
diff --git a/build.gradle b/build.gradle
index 077f7ae3..94192029 100644
--- a/build.gradle
+++ b/build.gradle
@@ -87,8 +87,7 @@ subprojects {
checkstyle {
configFile = rootProject.file('gradle/checkstyle/checkstyle.xml')
configProperties.checkstyleConfigDir = rootProject.file('gradle/checkstyle')
- /* eventually, we should change this to fail builds on errors */
- ignoreFailures true
+ ignoreFailures false
}
license {
diff --git a/islandora-http-client/build.gradle b/islandora-http-client/build.gradle
new file mode 100644
index 00000000..20a4fbb6
--- /dev/null
+++ b/islandora-http-client/build.gradle
@@ -0,0 +1,34 @@
+apply plugin: 'osgi'
+
+description = 'Islandora CLAW HTTP Client'
+
+dependencies {
+ compile group: 'org.apache.httpcomponents', name: 'httpclient-osgi', version: '4.5.3'
+
+ testCompile group: 'junit', name: 'junit', version:'4.12'
+}
+
+jar {
+ manifest {
+ description project.description
+ docURL project.docURL
+ vendor project.vendor
+ license project.license
+
+ instruction 'Import-Package',
+ 'org.apache.http,' +
+ 'org.apache.http.protocol,' +
+ 'org.apache.http.message,' +
+ 'org.apache.http.impl.client,' +
+ 'org.apache.http.client,' +
+ defaultOsgiImports
+ instruction 'Export-Package', 'ca.islandora.alpaca.http.client'
+ }
+}
+
+artifacts {
+ archives (file('build/cfg/main/ca.islandora.alpaca.http.client.cfg')) {
+ classifier 'configuration'
+ type 'cfg'
+ }
+}
diff --git a/islandora-http-client/src/main/cfg/ca.islandora.alpaca.http.client.cfg b/islandora-http-client/src/main/cfg/ca.islandora.alpaca.http.client.cfg
new file mode 100644
index 00000000..06cf1bb0
--- /dev/null
+++ b/islandora-http-client/src/main/cfg/ca.islandora.alpaca.http.client.cfg
@@ -0,0 +1,3 @@
+# The static token value to be used for authentication by the HttpClient available as an OSGi service for
+# other services to use against the Fedora repository
+token.value=islandora
diff --git a/islandora-http-client/src/main/java/ca/islandora/alpaca/http/client/StaticTokenRequestInterceptor.java b/islandora-http-client/src/main/java/ca/islandora/alpaca/http/client/StaticTokenRequestInterceptor.java
new file mode 100644
index 00000000..84657836
--- /dev/null
+++ b/islandora-http-client/src/main/java/ca/islandora/alpaca/http/client/StaticTokenRequestInterceptor.java
@@ -0,0 +1,85 @@
+/*
+ * Licensed to Islandora Foundation under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * The Islandora Foundation licenses this file to you under the MIT License.
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/MIT
+ *
+ * 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 ca.islandora.alpaca.http.client;
+
+import static java.util.Objects.requireNonNull;
+
+import org.apache.http.Header;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpRequestInterceptor;
+import org.apache.http.client.HttpClient;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.message.BasicHeader;
+import org.apache.http.protocol.HttpContext;
+
+/**
+ * Adds a single authentication header to any request that does not
+ * already have at least one authentication header.
+ *
+ * @author ajs6f
+ *
+ */
+public class StaticTokenRequestInterceptor implements HttpRequestInterceptor {
+
+ public static final String AUTH_HEADER = "Authorization";
+
+ private Header header;
+
+ /**
+ * Default constructor
+ */
+ public StaticTokenRequestInterceptor() {
+ }
+
+ /**
+ * @param token the authentication token to use
+ */
+ public StaticTokenRequestInterceptor(final String token) {
+ this.header = makeHeader(token);
+ }
+
+ /**
+ * @param token the authentication token to use
+ */
+ public void setToken(final String token) {
+ this.header = makeHeader(token);
+ }
+
+ private static Header makeHeader(final String token) {
+ return new BasicHeader(AUTH_HEADER, "Bearer " + requireNonNull(token, "Token must not be null!"));
+ }
+
+ @Override
+ public void process(final HttpRequest request, final HttpContext context) {
+ // we do not inject if auth headers present
+ if (request.getFirstHeader(AUTH_HEADER) == null) {
+ request.addHeader(header);
+ }
+ }
+
+ /**
+ * Convenience factory method.
+ *
+ * @param interceptor the interceptor to use, presumably an instance of {@link StaticTokenRequestInterceptor}
+ * @return a default-configuration {@link HttpClient} that is wrapped with this interceptor
+ */
+ public static HttpClient defaultClient(final StaticTokenRequestInterceptor interceptor) {
+ return HttpClientBuilder.create().addInterceptorFirst(interceptor).build();
+ }
+}
diff --git a/islandora-http-client/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/islandora-http-client/src/main/resources/OSGI-INF/blueprint/blueprint.xml
new file mode 100644
index 00000000..ee156b74
--- /dev/null
+++ b/islandora-http-client/src/main/resources/OSGI-INF/blueprint/blueprint.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/islandora-http-client/src/test/java/ca/islandora/alpaca/http/client/StaticTokenRequestInterceptorTest.java b/islandora-http-client/src/test/java/ca/islandora/alpaca/http/client/StaticTokenRequestInterceptorTest.java
new file mode 100644
index 00000000..d5556c12
--- /dev/null
+++ b/islandora-http-client/src/test/java/ca/islandora/alpaca/http/client/StaticTokenRequestInterceptorTest.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to Islandora Foundation under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * The Islandora Foundation licenses this file to you under the MIT License.
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/MIT
+ *
+ * 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 ca.islandora.alpaca.http.client;
+
+import static ca.islandora.alpaca.http.client.StaticTokenRequestInterceptor.AUTH_HEADER;
+
+import org.apache.http.Header;
+import org.apache.http.HttpRequest;
+import org.apache.http.client.methods.HttpGet;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * @author ajs6f
+ *
+ */
+public class StaticTokenRequestInterceptorTest extends Assert {
+
+ @Test
+ public void shouldInjectHeaderWhenNoAuthHeadersPresent() {
+ final StaticTokenRequestInterceptor testInterceptor = new StaticTokenRequestInterceptor("testToken");
+ final HttpRequest request = new HttpGet();
+ testInterceptor.process(request, null);
+ final Header[] authHeaders = request.getHeaders(AUTH_HEADER);
+ assertEquals("Should only be one auth header!", 1, authHeaders.length);
+ assertEquals("Wrong value for header!", "Bearer testToken", authHeaders[0].getValue());
+ }
+
+ @Test
+ public void shouldNotInjectHeaderWhenAuthHeadersPresent() {
+ final StaticTokenRequestInterceptor testInterceptor = new StaticTokenRequestInterceptor();
+ testInterceptor.setToken("testToken");
+ final HttpRequest request = new HttpGet();
+ request.addHeader(AUTH_HEADER, "fake header");
+ testInterceptor.process(request, null);
+ final Header[] authHeaders = request.getHeaders(AUTH_HEADER);
+ assertEquals("Should only be one auth header!", 1, authHeaders.length);
+ assertEquals("Wrong value for header!", "fake header", authHeaders[0].getValue());
+ }
+}
diff --git a/karaf/src/main/resources/features.xml b/karaf/src/main/resources/features.xml
index e4c572cf..58a275a1 100644
--- a/karaf/src/main/resources/features.xml
+++ b/karaf/src/main/resources/features.xml
@@ -30,5 +30,15 @@
mvn:ca.islandora.alpaca/islandora-connector-broadcast/${project.version}/cfg/configuration
+
+
+
+ mvn:org.apache.httpcomponents/httpcore-osgi/4.4.6
+ mvn:org.apache.httpcomponents/httpclient-osgi/4.5.3
+ mvn:ca.islandora.alpaca/islandora-http-client/${project.version}
+
+ mvn:ca.islandora.alpaca/islandora-http-client/${project.version}/cfg/configuration
+
+
diff --git a/settings.gradle b/settings.gradle
index e05f19d0..abfbcf98 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -1,7 +1,9 @@
include ':islandora-karaf'
include ':islandora-indexing-triplestore'
include ':islandora-connector-broadcast'
+include ':islandora-http-client'
project(':islandora-karaf').projectDir = "$rootDir/karaf" as File
project(':islandora-indexing-triplestore').projectDir = "$rootDir/islandora-indexing-triplestore" as File
project(':islandora-connector-broadcast').projectDir = "$rootDir/islandora-connector-broadcast" as File
+project(':islandora-http-client').projectDir = "$rootDir/islandora-http-client" as File