From 7f19117e0a4f4fe01e310e44337505f297253c71 Mon Sep 17 00:00:00 2001 From: Aaron Coburn Date: Tue, 27 Feb 2018 17:33:24 -0500 Subject: [PATCH 1/2] Add CDI support Resolves #12 There are several changes here: First, this adds an `@Inject` annotation to each CDI-managed bean (unless there is already a no-arg constructor). Second, each package with CDI-managed beans has a `beans.xml` file in the appropriate resources directory. Third, component configuration has been consolidated to use Apache Tamaya. Fourth, constructors have been cleaned up to work better in CDI environments while remaining compatible with non-CDI environments. Fifth, constructors that had been using generic types (e.g. the various cache-related types) now use concrete types. E.g.: CacheService becomes: ProfileCacheService --- build.gradle | 1 + notifications/trellis-amqp/build.gradle | 3 + .../org/trellisldp/amqp/AmqpPublisher.java | 37 ++++++++++-- .../src/main/resources/META-INF/beans.xml | 7 +++ .../trellisldp/amqp/AmqpPublisherTest.java | 9 +++ .../META-INF/javaconfiguration.properties | 2 + notifications/trellis-jms/build.gradle | 3 + .../java/org/trellisldp/jms/JmsPublisher.java | 15 +++-- .../src/main/resources/META-INF/beans.xml | 7 +++ .../org/trellisldp/jms/JmsPublisherTest.java | 2 +- .../META-INF/javaconfiguration.properties | 1 + notifications/trellis-kafka/build.gradle | 3 + .../org/trellisldp/kafka/KafkaPublisher.java | 20 ++++++- .../src/main/resources/META-INF/beans.xml | 7 +++ .../trellisldp/kafka/KafkaPublisherTest.java | 2 +- .../META-INF/javaconfiguration.properties | 1 + .../src/main/resources/META-INF/beans.xml | 7 +++ .../api/AuthorizationCacheService.java | 23 ++++++++ .../trellisldp/api/ProfileCacheService.java | 19 ++++++ trellis-app/build.gradle | 5 +- .../trellisldp/app/TrellisApplication.java | 31 +++++----- .../app/TrellisAuthorizationCache.java | 31 ++++++++++ .../trellisldp/app/TrellisProfileCache.java | 28 +++++++++ .../java/org/trellisldp/app/TrellisUtils.java | 28 ++++++--- .../org/trellisldp/app/TrellisLdpTest.java | 1 + .../trellisldp/app/TrellisMementoTest.java | 2 + .../org/trellisldp/app/TrellisUtilsTest.java | 13 ++-- .../src/main/resources/META-INF/beans.xml | 7 +++ .../src/main/resources/META-INF/beans.xml | 7 +++ .../src/main/resources/META-INF/beans.xml | 7 +++ trellis-file/build.gradle | 3 + .../trellisldp/file/FileBinaryService.java | 25 ++++++-- .../trellisldp/file/FileMementoService.java | 22 +++++-- .../src/main/resources/META-INF/beans.xml | 7 +++ .../file/FileBinaryServiceTest.java | 28 +++++---- .../file/FileMementoServiceTest.java | 25 ++++++-- .../META-INF/javaconfiguration.properties | 2 + trellis-http/build.gradle | 2 + .../http/AgentAuthorizationFilter.java | 19 ++++-- .../http/HttpBasedBinaryService.java | 2 + .../java/org/trellisldp/http/LdpResource.java | 29 +++++++-- .../trellisldp/http/MultipartUploader.java | 16 ++++- .../java/org/trellisldp/http/WebAcFilter.java | 23 ++++++-- .../trellisldp/http/domain/HttpConstants.java | 2 + .../src/main/resources/META-INF/beans.xml | 7 +++ .../http/AgentAuthorizationFilterTest.java | 4 +- .../org/trellisldp/http/CORSResourceTest.java | 2 +- .../trellisldp/http/LdpAdminResourceTest.java | 12 ++-- .../http/LdpForbiddenResourceTest.java | 10 +++- .../http/LdpResourceNoAgentTest.java | 4 +- .../org/trellisldp/http/LdpResourceTest.java | 8 +-- .../http/LdpUnauthorizedResourceTest.java | 7 ++- .../trellisldp/http/LdpUserResourceTest.java | 9 ++- .../org/trellisldp/http/WebACFilterTest.java | 4 +- .../META-INF/javaconfiguration.properties | 1 + .../src/main/resources/META-INF/beans.xml | 7 +++ trellis-io-jena/build.gradle | 3 + .../java/org/trellisldp/io/JenaIOService.java | 59 ++++++++++--------- .../java/org/trellisldp/io/impl/HtmlData.java | 10 ++-- .../trellisldp/io/impl/HtmlSerializer.java | 14 ++--- .../src/main/resources/META-INF/beans.xml | 7 +++ .../java/org/trellisldp/io/IOServiceTest.java | 54 +++++++++-------- trellis-karaf/src/main/resources/features.xml | 9 ++- trellis-namespaces/build.gradle | 3 + .../namespaces/NamespacesJsonContext.java | 23 ++++++-- .../src/main/resources/META-INF/beans.xml | 7 +++ .../namespaces/NamespacesJsonContextTest.java | 23 ++++++-- trellis-triplestore/build.gradle | 1 + .../TriplestoreResourceService.java | 3 + .../src/main/resources/META-INF/beans.xml | 7 +++ trellis-webac/build.gradle | 1 + .../org/trellisldp/webac/WebACService.java | 9 ++- .../src/main/resources/META-INF/beans.xml | 7 +++ .../trellisldp/webac/WebACServiceTest.java | 5 +- 74 files changed, 657 insertions(+), 197 deletions(-) create mode 100644 notifications/trellis-amqp/src/main/resources/META-INF/beans.xml create mode 100644 notifications/trellis-amqp/src/test/resources/META-INF/javaconfiguration.properties create mode 100644 notifications/trellis-jms/src/main/resources/META-INF/beans.xml create mode 100644 notifications/trellis-jms/src/test/resources/META-INF/javaconfiguration.properties create mode 100644 notifications/trellis-kafka/src/main/resources/META-INF/beans.xml create mode 100644 notifications/trellis-kafka/src/test/resources/META-INF/javaconfiguration.properties create mode 100644 trellis-agent/src/main/resources/META-INF/beans.xml create mode 100644 trellis-api/src/main/java/org/trellisldp/api/AuthorizationCacheService.java create mode 100644 trellis-api/src/main/java/org/trellisldp/api/ProfileCacheService.java create mode 100644 trellis-app/src/main/java/org/trellisldp/app/TrellisAuthorizationCache.java create mode 100644 trellis-app/src/main/java/org/trellisldp/app/TrellisProfileCache.java create mode 100644 trellis-audit/src/main/resources/META-INF/beans.xml create mode 100644 trellis-constraint-rules/src/main/resources/META-INF/beans.xml create mode 100644 trellis-event-serialization/src/main/resources/META-INF/beans.xml create mode 100644 trellis-file/src/main/resources/META-INF/beans.xml create mode 100644 trellis-file/src/test/resources/META-INF/javaconfiguration.properties create mode 100644 trellis-http/src/main/resources/META-INF/beans.xml create mode 100644 trellis-http/src/test/resources/META-INF/javaconfiguration.properties create mode 100644 trellis-id/src/main/resources/META-INF/beans.xml create mode 100644 trellis-io-jena/src/main/resources/META-INF/beans.xml create mode 100644 trellis-namespaces/src/main/resources/META-INF/beans.xml create mode 100644 trellis-triplestore/src/main/resources/META-INF/beans.xml create mode 100644 trellis-webac/src/main/resources/META-INF/beans.xml diff --git a/build.gradle b/build.gradle index 990d02759..c1194a857 100644 --- a/build.gradle +++ b/build.gradle @@ -81,6 +81,7 @@ subprojects { mustacheVersion = '0.9.5_1' rabbitMqVersion = '5.1.2' slf4jVersion = '1.7.25' + tamayaVersion = '0.3-incubating' jwtVersion = '0.9.0' jaxbVersion = '2.3.0' diff --git a/notifications/trellis-amqp/build.gradle b/notifications/trellis-amqp/build.gradle index 5b25051bc..fae7a8ade 100644 --- a/notifications/trellis-amqp/build.gradle +++ b/notifications/trellis-amqp/build.gradle @@ -8,12 +8,15 @@ ext { dependencies { api group: 'com.rabbitmq', name: 'amqp-client', version: rabbitMqVersion + api group: 'org.apache.servicemix.bundles', name: 'org.apache.servicemix.bundles.javax-inject', version: javaxInjectVersion api project(':trellis-api') + implementation group: 'org.apache.tamaya', name: 'tamaya-api', version: tamayaVersion implementation group: 'org.slf4j', name: 'slf4j-api', version: slf4jVersion testImplementation group: 'ch.qos.logback', name: 'logback-classic', version: logbackVersion testImplementation group: 'org.apache.commons', name: 'commons-rdf-simple', version: commonsRdfVersion + testImplementation group: 'org.apache.tamaya', name: 'tamaya-core', version: tamayaVersion testImplementation group: 'org.apiguardian', name: 'apiguardian-api', version: apiguardianVersion testImplementation group: 'org.junit.platform', name: 'junit-platform-runner', version: junitPlatformVersion testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: junitVersion diff --git a/notifications/trellis-amqp/src/main/java/org/trellisldp/amqp/AmqpPublisher.java b/notifications/trellis-amqp/src/main/java/org/trellisldp/amqp/AmqpPublisher.java index 4b42bfc10..2457fbc49 100644 --- a/notifications/trellis-amqp/src/main/java/org/trellisldp/amqp/AmqpPublisher.java +++ b/notifications/trellis-amqp/src/main/java/org/trellisldp/amqp/AmqpPublisher.java @@ -23,6 +23,10 @@ import java.io.IOException; import java.util.ServiceLoader; +import javax.inject.Inject; + +import org.apache.tamaya.Configuration; +import org.apache.tamaya.ConfigurationProvider; import org.slf4j.Logger; import org.trellisldp.api.ActivityStreamService; import org.trellisldp.api.Event; @@ -34,6 +38,14 @@ */ public class AmqpPublisher implements EventService { + public static final String AMQP_EXCHANGE_NAME = "trellis.amqp.exchangename"; + + public static final String AMQP_ROUTING_KEY = "trellis.amqp.routingkey"; + + public static final String AMQP_MANDATORY = "trellis.amqp.mandatory"; + + public static final String AMQP_IMMEDIATE = "trellis.amqp.immediate"; + private static final Logger LOGGER = getLogger(AmqpPublisher.class); // TODO - JDK9 ServiceLoader::findFirst @@ -50,7 +62,22 @@ public class AmqpPublisher implements EventService { private final Boolean immediate; /** - * Create a an AMQP publisher. + * Create an AMQP publisher. + * @param channel the channel + */ + @Inject + public AmqpPublisher(final Channel channel) { + this(channel, ConfigurationProvider.getConfiguration()); + } + + private AmqpPublisher(final Channel channel, final Configuration config) { + this(channel, config.get(AMQP_EXCHANGE_NAME), config.get(AMQP_ROUTING_KEY), + config.getOrDefault(AMQP_MANDATORY, Boolean.class, true), + config.getOrDefault(AMQP_IMMEDIATE, Boolean.class, false)); + } + + /** + * Create an AMQP publisher. * @param channel the channel * @param exchangeName the exchange name * @param routingKey the routing key @@ -60,7 +87,7 @@ public AmqpPublisher(final Channel channel, final String exchangeName, final Str } /** - * Create a an AMQP publisher. + * Create an AMQP publisher. * @param channel the channel * @param exchangeName the exchange name * @param routingKey the routing key @@ -69,9 +96,9 @@ public AmqpPublisher(final Channel channel, final String exchangeName, final Str */ public AmqpPublisher(final Channel channel, final String exchangeName, final String routingKey, final Boolean mandatory, final Boolean immediate) { - requireNonNull(channel); - requireNonNull(exchangeName); - requireNonNull(routingKey); + requireNonNull(channel, "AMQP Channel may not be null!"); + requireNonNull(exchangeName, "AMQP exchange name may not be null!"); + requireNonNull(routingKey, "AMQP routing key may not be null!"); this.channel = channel; this.exchangeName = exchangeName; diff --git a/notifications/trellis-amqp/src/main/resources/META-INF/beans.xml b/notifications/trellis-amqp/src/main/resources/META-INF/beans.xml new file mode 100644 index 000000000..1e341328e --- /dev/null +++ b/notifications/trellis-amqp/src/main/resources/META-INF/beans.xml @@ -0,0 +1,7 @@ + + + diff --git a/notifications/trellis-amqp/src/test/java/org/trellisldp/amqp/AmqpPublisherTest.java b/notifications/trellis-amqp/src/test/java/org/trellisldp/amqp/AmqpPublisherTest.java index 4f4c20856..1cdf88eec 100644 --- a/notifications/trellis-amqp/src/test/java/org/trellisldp/amqp/AmqpPublisherTest.java +++ b/notifications/trellis-amqp/src/test/java/org/trellisldp/amqp/AmqpPublisherTest.java @@ -88,6 +88,15 @@ public void testAmqp() throws IOException { any(BasicProperties.class), any(byte[].class)); } + @Test + public void testAmqpConfiguration() throws IOException { + final EventService svc = new AmqpPublisher(mockChannel); + svc.emit(mockEvent); + + verify(mockChannel).basicPublish(eq(exchangeName), eq(queueName), anyBoolean(), anyBoolean(), + any(BasicProperties.class), any(byte[].class)); + } + @Test public void testError() throws IOException { doThrow(IOException.class).when(mockChannel).basicPublish(eq(exchangeName), eq(queueName), diff --git a/notifications/trellis-amqp/src/test/resources/META-INF/javaconfiguration.properties b/notifications/trellis-amqp/src/test/resources/META-INF/javaconfiguration.properties new file mode 100644 index 000000000..2a56266d2 --- /dev/null +++ b/notifications/trellis-amqp/src/test/resources/META-INF/javaconfiguration.properties @@ -0,0 +1,2 @@ +trellis.amqp.exchangename=exchange +trellis.amqp.routingkey=queue diff --git a/notifications/trellis-jms/build.gradle b/notifications/trellis-jms/build.gradle index b1760974e..fbf7e2a17 100644 --- a/notifications/trellis-jms/build.gradle +++ b/notifications/trellis-jms/build.gradle @@ -8,13 +8,16 @@ ext { dependencies { api group: 'javax.jms', name: 'javax.jms-api', version: jmsApiVersion + api group: 'org.apache.servicemix.bundles', name: 'org.apache.servicemix.bundles.javax-inject', version: javaxInjectVersion api project(':trellis-api') + implementation group: 'org.apache.tamaya', name: 'tamaya-api', version: tamayaVersion implementation group: 'org.slf4j', name: 'slf4j-api', version: slf4jVersion testImplementation group: 'ch.qos.logback', name: 'logback-classic', version: logbackVersion testImplementation group: 'org.apache.activemq', name: 'activemq-client', version: activeMqVersion testImplementation group: 'org.apache.commons', name: 'commons-rdf-simple', version: commonsRdfVersion + testImplementation group: 'org.apache.tamaya', name: 'tamaya-core', version: tamayaVersion testImplementation group: 'org.apiguardian', name: 'apiguardian-api', version: apiguardianVersion testImplementation group: 'org.junit.platform', name: 'junit-platform-runner', version: junitPlatformVersion testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: junitVersion diff --git a/notifications/trellis-jms/src/main/java/org/trellisldp/jms/JmsPublisher.java b/notifications/trellis-jms/src/main/java/org/trellisldp/jms/JmsPublisher.java index 8d74069c6..fb064b1f5 100644 --- a/notifications/trellis-jms/src/main/java/org/trellisldp/jms/JmsPublisher.java +++ b/notifications/trellis-jms/src/main/java/org/trellisldp/jms/JmsPublisher.java @@ -19,12 +19,14 @@ import java.util.ServiceLoader; +import javax.inject.Inject; import javax.jms.Connection; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.MessageProducer; import javax.jms.Session; +import org.apache.tamaya.ConfigurationProvider; import org.slf4j.Logger; import org.trellisldp.api.ActivityStreamService; import org.trellisldp.api.Event; @@ -37,6 +39,8 @@ */ public class JmsPublisher implements EventService { + public static final String JMS_QUEUE_NAME = "trellis.jms.queue"; + private static final Logger LOGGER = getLogger(JmsPublisher.class); // TODO - JDK9 ServiceLoader::findFirst @@ -49,11 +53,12 @@ public class JmsPublisher implements EventService { /** * Create a new JMS Publisher. * @param conn the connection - * @param queueName the name of the queue * @throws JMSException when there is a JMS error */ - public JmsPublisher(final Connection conn, final String queueName) throws JMSException { - this(conn.createSession(false, AUTO_ACKNOWLEDGE), queueName); + @Inject + public JmsPublisher(final Connection conn) throws JMSException { + this(conn.createSession(false, AUTO_ACKNOWLEDGE), + ConfigurationProvider.getConfiguration().get(JMS_QUEUE_NAME)); } /** @@ -63,8 +68,8 @@ public JmsPublisher(final Connection conn, final String queueName) throws JMSExc * @throws JMSException when there is a JMS error */ public JmsPublisher(final Session session, final String queueName) throws JMSException { - requireNonNull(session); - requireNonNull(queueName); + requireNonNull(session, "JMS Session may not be null!"); + requireNonNull(queueName, "JMS Queue name may not be null!"); this.session = session; this.producer = session.createProducer(session.createQueue(queueName)); diff --git a/notifications/trellis-jms/src/main/resources/META-INF/beans.xml b/notifications/trellis-jms/src/main/resources/META-INF/beans.xml new file mode 100644 index 000000000..1e341328e --- /dev/null +++ b/notifications/trellis-jms/src/main/resources/META-INF/beans.xml @@ -0,0 +1,7 @@ + + + diff --git a/notifications/trellis-jms/src/test/java/org/trellisldp/jms/JmsPublisherTest.java b/notifications/trellis-jms/src/test/java/org/trellisldp/jms/JmsPublisherTest.java index d560469a2..94ca24fd4 100644 --- a/notifications/trellis-jms/src/test/java/org/trellisldp/jms/JmsPublisherTest.java +++ b/notifications/trellis-jms/src/test/java/org/trellisldp/jms/JmsPublisherTest.java @@ -101,7 +101,7 @@ public void setUp() throws JMSException { @Test public void testJms() throws JMSException { - final EventService svc = new JmsPublisher(mockConnection, queueName); + final EventService svc = new JmsPublisher(mockConnection); svc.emit(mockEvent); verify(mockProducer).send(eq(mockMessage)); diff --git a/notifications/trellis-jms/src/test/resources/META-INF/javaconfiguration.properties b/notifications/trellis-jms/src/test/resources/META-INF/javaconfiguration.properties new file mode 100644 index 000000000..15d715ab7 --- /dev/null +++ b/notifications/trellis-jms/src/test/resources/META-INF/javaconfiguration.properties @@ -0,0 +1 @@ +trellis.jms.queue=queue diff --git a/notifications/trellis-kafka/build.gradle b/notifications/trellis-kafka/build.gradle index b55729b25..9abbdb038 100644 --- a/notifications/trellis-kafka/build.gradle +++ b/notifications/trellis-kafka/build.gradle @@ -8,12 +8,15 @@ ext { dependencies { api group: 'org.apache.servicemix.bundles', name: 'org.apache.servicemix.bundles.kafka-clients', version: kafkaVersion + api group: 'org.apache.servicemix.bundles', name: 'org.apache.servicemix.bundles.javax-inject', version: javaxInjectVersion api project(':trellis-api') + implementation group: 'org.apache.tamaya', name: 'tamaya-api', version: tamayaVersion implementation group: 'org.slf4j', name: 'slf4j-api', version: slf4jVersion testImplementation group: 'ch.qos.logback', name: 'logback-classic', version: logbackVersion testImplementation group: 'org.apache.commons', name: 'commons-rdf-simple', version: commonsRdfVersion + testImplementation group: 'org.apache.tamaya', name: 'tamaya-core', version: tamayaVersion testImplementation group: 'org.apiguardian', name: 'apiguardian-api', version: apiguardianVersion testImplementation group: 'org.junit.platform', name: 'junit-platform-runner', version: junitPlatformVersion testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: junitVersion diff --git a/notifications/trellis-kafka/src/main/java/org/trellisldp/kafka/KafkaPublisher.java b/notifications/trellis-kafka/src/main/java/org/trellisldp/kafka/KafkaPublisher.java index 958d8d491..0ec48f523 100644 --- a/notifications/trellis-kafka/src/main/java/org/trellisldp/kafka/KafkaPublisher.java +++ b/notifications/trellis-kafka/src/main/java/org/trellisldp/kafka/KafkaPublisher.java @@ -18,9 +18,12 @@ import java.util.ServiceLoader; +import javax.inject.Inject; + import org.apache.commons.rdf.api.IRI; import org.apache.kafka.clients.producer.Producer; import org.apache.kafka.clients.producer.ProducerRecord; +import org.apache.tamaya.ConfigurationProvider; import org.slf4j.Logger; import org.trellisldp.api.ActivityStreamService; import org.trellisldp.api.Event; @@ -31,6 +34,8 @@ */ public class KafkaPublisher implements EventService { + public static final String KAFKA_TOPIC = "trellis.kafka.topic"; + private static final Logger LOGGER = getLogger(KafkaPublisher.class); // TODO - JDK9 ServiceLoader::findFirst @@ -42,11 +47,20 @@ public class KafkaPublisher implements EventService { /** * Create a new Kafka Publisher. * @param producer the producer - * @param topicName the name of the topic + */ + @Inject + public KafkaPublisher(final Producer producer) { + this(producer, ConfigurationProvider.getConfiguration().get(KAFKA_TOPIC)); + } + + /** + * Create a new Kafka Publisher. + * @param producer the producer + * @param topicName the name of the kafka topic */ public KafkaPublisher(final Producer producer, final String topicName) { - requireNonNull(producer); - requireNonNull(topicName); + requireNonNull(producer, "Kafka producer may not be null!"); + requireNonNull(topicName, "Kafka topic name may not be null!"); this.producer = producer; this.topicName = topicName; diff --git a/notifications/trellis-kafka/src/main/resources/META-INF/beans.xml b/notifications/trellis-kafka/src/main/resources/META-INF/beans.xml new file mode 100644 index 000000000..1e341328e --- /dev/null +++ b/notifications/trellis-kafka/src/main/resources/META-INF/beans.xml @@ -0,0 +1,7 @@ + + + diff --git a/notifications/trellis-kafka/src/test/java/org/trellisldp/kafka/KafkaPublisherTest.java b/notifications/trellis-kafka/src/test/java/org/trellisldp/kafka/KafkaPublisherTest.java index 5ecb1db4b..ad6ac3fd4 100644 --- a/notifications/trellis-kafka/src/test/java/org/trellisldp/kafka/KafkaPublisherTest.java +++ b/notifications/trellis-kafka/src/test/java/org/trellisldp/kafka/KafkaPublisherTest.java @@ -72,7 +72,7 @@ public void setUp() { @Test public void testKafka() { - final EventService svc = new KafkaPublisher(producer, queueName); + final EventService svc = new KafkaPublisher(producer); svc.emit(mockEvent); final List> records = producer.history(); diff --git a/notifications/trellis-kafka/src/test/resources/META-INF/javaconfiguration.properties b/notifications/trellis-kafka/src/test/resources/META-INF/javaconfiguration.properties new file mode 100644 index 000000000..ad6fcae06 --- /dev/null +++ b/notifications/trellis-kafka/src/test/resources/META-INF/javaconfiguration.properties @@ -0,0 +1 @@ +trellis.kafka.topic=queue diff --git a/trellis-agent/src/main/resources/META-INF/beans.xml b/trellis-agent/src/main/resources/META-INF/beans.xml new file mode 100644 index 000000000..1e341328e --- /dev/null +++ b/trellis-agent/src/main/resources/META-INF/beans.xml @@ -0,0 +1,7 @@ + + + diff --git a/trellis-api/src/main/java/org/trellisldp/api/AuthorizationCacheService.java b/trellis-api/src/main/java/org/trellisldp/api/AuthorizationCacheService.java new file mode 100644 index 000000000..fa5aca5b7 --- /dev/null +++ b/trellis-api/src/main/java/org/trellisldp/api/AuthorizationCacheService.java @@ -0,0 +1,23 @@ +/* + * 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.trellisldp.api; + +import java.util.Set; + +import org.apache.commons.rdf.api.IRI; + +/** + * A cache type for use with authorization data. + */ +public interface AuthorizationCacheService extends CacheService> { } diff --git a/trellis-api/src/main/java/org/trellisldp/api/ProfileCacheService.java b/trellis-api/src/main/java/org/trellisldp/api/ProfileCacheService.java new file mode 100644 index 000000000..9cb5456ff --- /dev/null +++ b/trellis-api/src/main/java/org/trellisldp/api/ProfileCacheService.java @@ -0,0 +1,19 @@ +/* + * 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.trellisldp.api; + +/** + * A cache type for use with JSON-LD profiles. + */ +public interface ProfileCacheService extends CacheService { } diff --git a/trellis-app/build.gradle b/trellis-app/build.gradle index 0f35d6d0d..4586098fb 100644 --- a/trellis-app/build.gradle +++ b/trellis-app/build.gradle @@ -14,10 +14,10 @@ dependencies { compile group: 'io.dropwizard', name: 'dropwizard-metrics', version: dropwizardVersion compile group: 'io.dropwizard', name: 'dropwizard-http2', version: dropwizardVersion compile group: 'io.jsonwebtoken', name: 'jjwt', version: jwtVersion + compile group: 'org.apache.activemq', name: 'activemq-client', version: activeMqVersion + compile group: 'org.apache.commons', name: 'commons-rdf-jena', version: commonsRdfVersion compile group: 'org.apache.jena', name: 'jena-osgi', version: jenaVersion compile group: 'org.apache.jena', name: 'jena-tdb2', version: jenaVersion - compile group: 'org.apache.commons', name: 'commons-rdf-jena', version: commonsRdfVersion - compile group: 'org.apache.activemq', name: 'activemq-client', version: activeMqVersion compile group: 'org.slf4j', name: 'slf4j-api', version: slf4jVersion compile project(":trellis-constraint-rules") @@ -42,6 +42,7 @@ dependencies { testCompile group: 'io.dropwizard', name: 'dropwizard-client', version: dropwizardVersion testCompile group: 'io.dropwizard', name: 'dropwizard-testing', version: dropwizardVersion testCompile group: 'org.apiguardian', name: 'apiguardian-api', version: apiguardianVersion + testImplementation group: 'org.apache.tamaya', name: 'tamaya-core', version: tamayaVersion testImplementation group: 'org.awaitility', name: 'awaitility', version: awaitilityVersion testImplementation group: 'ch.qos.logback', name: 'logback-classic', version: logbackVersion testImplementation group: 'org.junit.platform', name: 'junit-platform-runner', version: junitPlatformVersion diff --git a/trellis-app/src/main/java/org/trellisldp/app/TrellisApplication.java b/trellis-app/src/main/java/org/trellisldp/app/TrellisApplication.java index c88f81acb..88d6ba052 100644 --- a/trellis-app/src/main/java/org/trellisldp/app/TrellisApplication.java +++ b/trellis-app/src/main/java/org/trellisldp/app/TrellisApplication.java @@ -15,7 +15,6 @@ import static com.google.common.cache.CacheBuilder.newBuilder; import static java.util.Arrays.asList; -import static java.util.Collections.emptyList; import static java.util.concurrent.TimeUnit.HOURS; import static org.trellisldp.app.TrellisUtils.getAuthFilters; import static org.trellisldp.app.TrellisUtils.getCorsConfiguration; @@ -31,12 +30,12 @@ import org.apache.jena.rdfconnection.RDFConnection; import org.trellisldp.agent.SimpleAgent; import org.trellisldp.api.BinaryService; -import org.trellisldp.api.CacheService; import org.trellisldp.api.EventService; import org.trellisldp.api.IOService; import org.trellisldp.api.IdentifierService; import org.trellisldp.api.MementoService; import org.trellisldp.api.NamespaceService; +import org.trellisldp.api.ProfileCacheService; import org.trellisldp.app.config.TrellisConfiguration; import org.trellisldp.app.health.RDFConnectionHealthCheck; import org.trellisldp.file.FileBinaryService; @@ -84,28 +83,24 @@ public void run(final TrellisConfiguration config, final RDFConnection rdfConnection = getRDFConnection(config); - final String mementoLocation = config.getMementos(); - - final String baseUrl = config.getBaseUrl(); - final IdentifierService idService = new UUIDGenerator(); - final MementoService mementoService = new FileMementoService(mementoLocation); + final MementoService mementoService = new FileMementoService(config.getMementos()); final TriplestoreResourceService resourceService = new TriplestoreResourceService(rdfConnection, idService, mementoService, notificationService); final NamespaceService namespaceService = new NamespacesJsonContext(config.getNamespaces()); - final BinaryService binaryService = new FileBinaryService(config.getBinaries(), idService, + final BinaryService binaryService = new FileBinaryService(idService, config.getBinaries(), config.getBinaryHierarchyLevels(), config.getBinaryHierarchyLength()); // IO Service - final CacheService profileCache = new TrellisCache<>(newBuilder() + final ProfileCacheService profileCache = new TrellisProfileCache(newBuilder() .maximumSize(config.getJsonld().getCacheSize()) .expireAfterAccess(config.getJsonld().getCacheExpireHours(), HOURS).build()); - final IOService ioService = new JenaIOService(namespaceService, TrellisUtils.getAssetConfiguration(config), - config.getJsonld().getContextWhitelist(), config.getJsonld().getContextDomainWhitelist(), profileCache); + final IOService ioService = new JenaIOService(namespaceService, profileCache, + TrellisUtils.getAssetConfiguration(config)); // Health checks environment.healthChecks().register("rdfconnection", new RDFConnectionHealthCheck(rdfConnection)); @@ -113,17 +108,19 @@ public void run(final TrellisConfiguration config, getAuthFilters(config).ifPresent(filters -> environment.jersey().register(new ChainedAuthFilter<>(filters))); // Resource matchers - environment.jersey() - .register(new LdpResource(resourceService, ioService, binaryService, resourceService, baseUrl)); + environment.jersey().register(new LdpResource(resourceService, ioService, binaryService, resourceService, + config.getBaseUrl())); // Filters - environment.jersey().register(new AgentAuthorizationFilter(new SimpleAgent(), emptyList())); + environment.jersey().register(new AgentAuthorizationFilter(new SimpleAgent())); environment.jersey().register(new CacheControlFilter(config.getCacheMaxAge())); // Authorization - getWebacConfiguration(config).ifPresent(webacCache -> - environment.jersey().register(new WebAcFilter( - asList("Authorization"), new WebACService(resourceService, webacCache)))); + getWebacConfiguration(config).ifPresent(webacCache -> { + final WebAcFilter filter = new WebAcFilter(new WebACService(resourceService, webacCache)); + filter.setChallenges(asList("Authorization")); + environment.jersey().register(filter); + }); // CORS getCorsConfiguration(config).ifPresent(cors -> environment.jersey().register( diff --git a/trellis-app/src/main/java/org/trellisldp/app/TrellisAuthorizationCache.java b/trellis-app/src/main/java/org/trellisldp/app/TrellisAuthorizationCache.java new file mode 100644 index 000000000..90b758ef3 --- /dev/null +++ b/trellis-app/src/main/java/org/trellisldp/app/TrellisAuthorizationCache.java @@ -0,0 +1,31 @@ +/* + * 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.trellisldp.app; + +import com.google.common.cache.Cache; + +import java.util.Set; + +import org.apache.commons.rdf.api.IRI; +import org.trellisldp.api.AuthorizationCacheService; + +/** + * A cache for Authorization data. + */ +class TrellisAuthorizationCache extends TrellisCache> implements AuthorizationCacheService { + + public TrellisAuthorizationCache(final Cache> cache) { + super(cache); + } +} diff --git a/trellis-app/src/main/java/org/trellisldp/app/TrellisProfileCache.java b/trellis-app/src/main/java/org/trellisldp/app/TrellisProfileCache.java new file mode 100644 index 000000000..02070853a --- /dev/null +++ b/trellis-app/src/main/java/org/trellisldp/app/TrellisProfileCache.java @@ -0,0 +1,28 @@ +/* + * 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.trellisldp.app; + +import com.google.common.cache.Cache; + +import org.trellisldp.api.ProfileCacheService; + +/** + * A cache for JSON-LD Profiles. + */ +class TrellisProfileCache extends TrellisCache implements ProfileCacheService { + + public TrellisProfileCache(final Cache cache) { + super(cache); + } +} diff --git a/trellis-app/src/main/java/org/trellisldp/app/TrellisUtils.java b/trellis-app/src/main/java/org/trellisldp/app/TrellisUtils.java index 5fd0ef45d..270aa2530 100644 --- a/trellis-app/src/main/java/org/trellisldp/app/TrellisUtils.java +++ b/trellis-app/src/main/java/org/trellisldp/app/TrellisUtils.java @@ -19,6 +19,7 @@ import static java.util.Optional.ofNullable; import static java.util.concurrent.TimeUnit.SECONDS; import static java.util.stream.Collectors.joining; +import static javax.jms.Session.AUTO_ACKNOWLEDGE; import static org.apache.jena.query.DatasetFactory.createTxnMem; import static org.apache.jena.query.DatasetFactory.wrap; import static org.apache.jena.rdfconnection.RDFConnectionFactory.connect; @@ -27,6 +28,11 @@ import static org.trellisldp.app.config.NotificationsConfiguration.Type.AMQP; import static org.trellisldp.app.config.NotificationsConfiguration.Type.JMS; import static org.trellisldp.app.config.NotificationsConfiguration.Type.KAFKA; +import static org.trellisldp.io.JenaIOService.IO_HTML_CSS; +import static org.trellisldp.io.JenaIOService.IO_HTML_ICON; +import static org.trellisldp.io.JenaIOService.IO_HTML_JS; +import static org.trellisldp.io.JenaIOService.IO_JSONLD_DOMAINS; +import static org.trellisldp.io.JenaIOService.IO_JSONLD_PROFILES; import com.google.common.cache.Cache; import com.rabbitmq.client.ConnectionFactory; @@ -60,7 +66,7 @@ import org.apache.kafka.clients.producer.KafkaProducer; import org.slf4j.Logger; import org.trellisldp.amqp.AmqpPublisher; -import org.trellisldp.api.CacheService; +import org.trellisldp.api.AuthorizationCacheService; import org.trellisldp.api.EventService; import org.trellisldp.api.NoopEventService; import org.trellisldp.app.auth.AnonymousAuthFilter; @@ -85,9 +91,17 @@ final class TrellisUtils { public static Map getAssetConfiguration(final TrellisConfiguration config) { final Map assetMap = new HashMap<>(); - assetMap.put("icon", config.getAssets().getIcon()); - assetMap.put("css", config.getAssets().getCss().stream().map(String::trim).collect(joining(","))); - assetMap.put("js", config.getAssets().getJs().stream().map(String::trim).collect(joining(","))); + assetMap.put(IO_HTML_ICON, config.getAssets().getIcon()); + assetMap.put(IO_HTML_CSS, config.getAssets().getCss().stream().map(String::trim).collect(joining(","))); + assetMap.put(IO_HTML_JS, config.getAssets().getJs().stream().map(String::trim).collect(joining(","))); + if (!config.getJsonld().getContextWhitelist().isEmpty()) { + assetMap.put(IO_JSONLD_PROFILES, config.getJsonld().getContextWhitelist().stream() + .map(String::trim).collect(joining(","))); + } + if (!config.getJsonld().getContextDomainWhitelist().isEmpty()) { + assetMap.put(IO_JSONLD_DOMAINS, config.getJsonld().getContextDomainWhitelist().stream() + .map(String::trim).collect(joining(","))); + } return assetMap; } @@ -123,12 +137,12 @@ public static Optional> getAuthFilters(final TrellisConfigurati return of(filters); } - public static Optional>> getWebacConfiguration(final TrellisConfiguration config) { + public static Optional getWebacConfiguration(final TrellisConfiguration config) { if (config.getAuth().getWebac().getEnabled()) { final Cache> authCache = newBuilder().maximumSize(config.getAuth().getWebac() .getCacheSize()).expireAfterWrite(config.getAuth().getWebac() .getCacheExpireSeconds(), SECONDS).build(); - return of(new TrellisCache<>(authCache)); + return of(new TrellisAuthorizationCache(authCache)); } return empty(); } @@ -203,7 +217,7 @@ private static EventService buildJmsPublisher(final NotificationsConfiguration c LOGGER.info("Connecting to JMS broker at {}", config.getConnectionString()); final Connection jmsConnection = getJmsFactory(config).createConnection(); environment.lifecycle().manage(new AutoCloseableManager(jmsConnection)); - return new JmsPublisher(jmsConnection, config.getTopicName()); + return new JmsPublisher(jmsConnection.createSession(false, AUTO_ACKNOWLEDGE), config.getTopicName()); } private static EventService buildAmqpPublisher(final NotificationsConfiguration config, diff --git a/trellis-app/src/test/java/org/trellisldp/app/TrellisLdpTest.java b/trellis-app/src/test/java/org/trellisldp/app/TrellisLdpTest.java index cb6141397..159d03175 100644 --- a/trellis-app/src/test/java/org/trellisldp/app/TrellisLdpTest.java +++ b/trellis-app/src/test/java/org/trellisldp/app/TrellisLdpTest.java @@ -95,6 +95,7 @@ public class TrellisLdpTest { config("namespaces", resourceFilePath("data/namespaces.json"))); private static final NamespaceService nsSvc = new NamespacesJsonContext(resourceFilePath("data/namespaces.json")); + private static final IOService ioSvc = new JenaIOService(nsSvc); private static final RDF rdf = new JenaRDF(); diff --git a/trellis-app/src/test/java/org/trellisldp/app/TrellisMementoTest.java b/trellis-app/src/test/java/org/trellisldp/app/TrellisMementoTest.java index 8822487ce..5293f357b 100644 --- a/trellis-app/src/test/java/org/trellisldp/app/TrellisMementoTest.java +++ b/trellis-app/src/test/java/org/trellisldp/app/TrellisMementoTest.java @@ -107,6 +107,7 @@ public class TrellisMementoTest { config("namespaces", resourceFilePath("data/namespaces.json"))); private static final NamespaceService nsSvc = new NamespacesJsonContext(resourceFilePath("data/namespaces.json")); + private static final IOService ioSvc = new JenaIOService(nsSvc); private static final RDF rdf = new JenaRDF(); @@ -170,6 +171,7 @@ public static void setUp() { @AfterAll public static void tearDown() { APP.after(); + System.getProperties().remove(NamespacesJsonContext.NAMESPACES_PATH); } @Nested diff --git a/trellis-app/src/test/java/org/trellisldp/app/TrellisUtilsTest.java b/trellis-app/src/test/java/org/trellisldp/app/TrellisUtilsTest.java index 1f381d08d..f86daaaad 100644 --- a/trellis-app/src/test/java/org/trellisldp/app/TrellisUtilsTest.java +++ b/trellis-app/src/test/java/org/trellisldp/app/TrellisUtilsTest.java @@ -23,6 +23,9 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.when; import static org.mockito.MockitoAnnotations.initMocks; +import static org.trellisldp.io.JenaIOService.IO_HTML_CSS; +import static org.trellisldp.io.JenaIOService.IO_HTML_ICON; +import static org.trellisldp.io.JenaIOService.IO_HTML_JS; import com.rabbitmq.client.ConnectionFactory; @@ -79,12 +82,10 @@ public void testGetAssetConfigurations() throws Exception { .build(new File(getClass().getResource("/config1.yml").toURI())); final Map assets = TrellisUtils.getAssetConfiguration(config); - assertEquals(3L, assets.size()); - assertEquals("http://example.org/image.icon", assets.get("icon")); - assertEquals("http://example.org/styles1.css,http://example.org/styles2.css", - assets.get("css")); - assertEquals("http://example.org/scripts1.js,http://example.org/scripts2.js", - assets.get("js")); + assertEquals(4L, assets.size()); + assertEquals("http://example.org/image.icon", assets.get(IO_HTML_ICON)); + assertEquals("http://example.org/styles1.css,http://example.org/styles2.css", assets.get(IO_HTML_CSS)); + assertEquals("http://example.org/scripts1.js,http://example.org/scripts2.js", assets.get(IO_HTML_JS)); } @Test diff --git a/trellis-audit/src/main/resources/META-INF/beans.xml b/trellis-audit/src/main/resources/META-INF/beans.xml new file mode 100644 index 000000000..1e341328e --- /dev/null +++ b/trellis-audit/src/main/resources/META-INF/beans.xml @@ -0,0 +1,7 @@ + + + diff --git a/trellis-constraint-rules/src/main/resources/META-INF/beans.xml b/trellis-constraint-rules/src/main/resources/META-INF/beans.xml new file mode 100644 index 000000000..1e341328e --- /dev/null +++ b/trellis-constraint-rules/src/main/resources/META-INF/beans.xml @@ -0,0 +1,7 @@ + + + diff --git a/trellis-event-serialization/src/main/resources/META-INF/beans.xml b/trellis-event-serialization/src/main/resources/META-INF/beans.xml new file mode 100644 index 000000000..1e341328e --- /dev/null +++ b/trellis-event-serialization/src/main/resources/META-INF/beans.xml @@ -0,0 +1,7 @@ + + + diff --git a/trellis-file/build.gradle b/trellis-file/build.gradle index 70fb5ef60..d75902034 100644 --- a/trellis-file/build.gradle +++ b/trellis-file/build.gradle @@ -8,6 +8,7 @@ ext { dependencies { api group: 'org.apache.commons', name: 'commons-rdf-api', version: commonsRdfVersion + api group: 'org.apache.servicemix.bundles', name: 'org.apache.servicemix.bundles.javax-inject', version: javaxInjectVersion api project(':trellis-api') implementation group: 'commons-codec', name: 'commons-codec', version: commonsCodecVersion @@ -15,10 +16,12 @@ dependencies { implementation group: 'org.apache.commons', name: 'commons-collections4', version: commonsCollectionsVersion implementation group: 'org.apache.commons', name: 'commons-rdf-jena', version: commonsRdfVersion implementation group: 'org.apache.jena', name: 'jena-osgi', version: jenaVersion + implementation group: 'org.apache.tamaya', name: 'tamaya-api', version: tamayaVersion implementation group: 'org.slf4j', name: 'slf4j-api', version: slf4jVersion implementation project(':trellis-vocabulary') testImplementation group: 'ch.qos.logback', name: 'logback-classic', version: logbackVersion + testImplementation group: 'org.apache.tamaya', name: 'tamaya-core', version: tamayaVersion testImplementation group: 'org.apiguardian', name: 'apiguardian-api', version: apiguardianVersion testImplementation group: 'org.junit.platform', name: 'junit-platform-runner', version: junitPlatformVersion testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: junitVersion diff --git a/trellis-file/src/main/java/org/trellisldp/file/FileBinaryService.java b/trellis-file/src/main/java/org/trellisldp/file/FileBinaryService.java index 77157f88e..e56c4a931 100644 --- a/trellis-file/src/main/java/org/trellisldp/file/FileBinaryService.java +++ b/trellis-file/src/main/java/org/trellisldp/file/FileBinaryService.java @@ -47,10 +47,14 @@ import java.util.function.Function; import java.util.function.Supplier; +import javax.inject.Inject; + import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.io.input.BoundedInputStream; import org.apache.commons.lang3.Range; import org.apache.commons.rdf.api.IRI; +import org.apache.tamaya.Configuration; +import org.apache.tamaya.ConfigurationProvider; import org.slf4j.Logger; import org.trellisldp.api.BinaryService; import org.trellisldp.api.IdentifierService; @@ -71,6 +75,10 @@ */ public class FileBinaryService implements BinaryService { + public static final String BINARY_BASE_PATH = "trellis.file.binary.basepath"; + public static final String BINARY_HIERARCHY = "trellis.file.binary.hierarchy"; + public static final String BINARY_LENGTH = "trellis.file.binary.length"; + private static final Logger LOGGER = getLogger(FileBinaryService.class); private static final String SHA = "SHA"; private static final Integer DEFAULT_HIERARCHY = 3; @@ -86,27 +94,34 @@ public class FileBinaryService implements BinaryService { /** * Create a File-based Binary service. * - * @param basePath the base file path * @param idService an identifier service */ - public FileBinaryService(final String basePath, final IdentifierService idService) { - this(basePath, idService, DEFAULT_HIERARCHY, DEFAULT_LENGTH); + @Inject + public FileBinaryService(final IdentifierService idService) { + this(idService, ConfigurationProvider.getConfiguration()); } /** * Create a File-based Binary service. * - * @param basePath the base file path * @param idService an identifier service + * @param basePath the base file path * @param hierarchy the levels of hierarchy * @param length the length of each level of hierarchy */ - public FileBinaryService(final String basePath, final IdentifierService idService, + public FileBinaryService(final IdentifierService idService, final String basePath, final Integer hierarchy, final Integer length) { + requireNonNull(basePath, BINARY_BASE_PATH + " configuration may not be null!"); this.basePath = basePath; this.idSupplier = idService.getSupplier("file:", hierarchy, length); } + private FileBinaryService(final IdentifierService idService, final Configuration config) { + this(idService, config.get(BINARY_BASE_PATH), + config.getOrDefault(BINARY_HIERARCHY, Integer.class, DEFAULT_HIERARCHY), + config.getOrDefault(BINARY_LENGTH, Integer.class, DEFAULT_LENGTH)); + } + @Override public Boolean exists(final IRI identifier) { return getFileFromIdentifier(identifier).filter(File::isFile).isPresent(); diff --git a/trellis-file/src/main/java/org/trellisldp/file/FileMementoService.java b/trellis-file/src/main/java/org/trellisldp/file/FileMementoService.java index 0d49cfa07..2007469d9 100644 --- a/trellis-file/src/main/java/org/trellisldp/file/FileMementoService.java +++ b/trellis-file/src/main/java/org/trellisldp/file/FileMementoService.java @@ -21,6 +21,7 @@ import static java.nio.file.StandardOpenOption.TRUNCATE_EXISTING; import static java.nio.file.StandardOpenOption.WRITE; import static java.util.Collections.emptyList; +import static java.util.Objects.requireNonNull; import static java.util.Optional.of; import static org.slf4j.LoggerFactory.getLogger; @@ -36,9 +37,12 @@ import java.util.Optional; import java.util.stream.Stream; +import javax.inject.Inject; + import org.apache.commons.io.FilenameUtils; import org.apache.commons.rdf.api.IRI; import org.apache.commons.rdf.api.Quad; +import org.apache.tamaya.ConfigurationProvider; import org.slf4j.Logger; import org.trellisldp.api.MementoService; import org.trellisldp.api.Resource; @@ -48,17 +52,27 @@ */ public class FileMementoService implements MementoService { + public static final String MEMENTO_BASE_PATH = "trellis.file.memento.basepath"; + private static final Logger LOGGER = getLogger(FileMementoService.class); private final File directory; /** * Create a file-based memento service. - * - * @param directory the base directory where versions are stored */ - public FileMementoService(final String directory) { - this.directory = new File(directory); + @Inject + public FileMementoService() { + this(ConfigurationProvider.getConfiguration().get(MEMENTO_BASE_PATH)); + } + + /** + * Create a file-based memento service. + * @param path the file path + */ + public FileMementoService(final String path) { + requireNonNull(path, "Memento base path is undefined!"); + this.directory = new File(path); init(); } diff --git a/trellis-file/src/main/resources/META-INF/beans.xml b/trellis-file/src/main/resources/META-INF/beans.xml new file mode 100644 index 000000000..1e341328e --- /dev/null +++ b/trellis-file/src/main/resources/META-INF/beans.xml @@ -0,0 +1,7 @@ + + + diff --git a/trellis-file/src/test/java/org/trellisldp/file/FileBinaryServiceTest.java b/trellis-file/src/test/java/org/trellisldp/file/FileBinaryServiceTest.java index c0757c830..5478366ec 100644 --- a/trellis-file/src/test/java/org/trellisldp/file/FileBinaryServiceTest.java +++ b/trellis-file/src/test/java/org/trellisldp/file/FileBinaryServiceTest.java @@ -42,6 +42,7 @@ import org.apache.commons.rdf.api.IRI; import org.apache.commons.rdf.api.RDF; import org.apache.commons.rdf.simple.SimpleRDF; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.platform.runner.JUnitPlatform; @@ -70,6 +71,11 @@ public class FileBinaryServiceTest { @Mock private InputStream mockInputStream; + @BeforeAll + public static void setUpEverything() { + System.getProperties().setProperty(FileBinaryService.BINARY_BASE_PATH, directory); + } + @BeforeEach public void setUp() { initMocks(this); @@ -77,14 +83,14 @@ public void setUp() { @Test public void testFileExists() { - final BinaryService resolver = new FileBinaryService(directory, idService); + final BinaryService resolver = new FileBinaryService(idService); assertTrue(resolver.exists(file)); assertFalse(resolver.exists(rdf.createIRI("file:fake.txt"))); } @Test public void testFilePurge() { - final BinaryService resolver = new FileBinaryService(directory, idService); + final BinaryService resolver = new FileBinaryService(idService); final IRI fileIRI = rdf.createIRI("file:" + randomFilename()); final InputStream inputStream = new ByteArrayInputStream("Some data".getBytes(UTF_8)); resolver.setContent(fileIRI, inputStream); @@ -95,21 +101,21 @@ public void testFilePurge() { @Test public void testIdSupplier() { - final BinaryService resolver = new FileBinaryService(directory, idService); + final BinaryService resolver = new FileBinaryService(idService); assertTrue(resolver.generateIdentifier().startsWith("file:")); assertNotEquals(resolver.generateIdentifier(), resolver.generateIdentifier()); } @Test public void testFileContent() { - final BinaryService resolver = new FileBinaryService(directory, idService); + final BinaryService resolver = new FileBinaryService(idService); assertTrue(resolver.getContent(file).isPresent()); assertEquals("A test document.\n", resolver.getContent(file).map(this::uncheckedToString).get()); } @Test public void testFileContentSegment() { - final BinaryService resolver = new FileBinaryService(directory, idService); + final BinaryService resolver = new FileBinaryService(idService); final List> range = singletonList(between(1, 5)); assertTrue(resolver.getContent(file, range).isPresent()); assertEquals(" tes", resolver.getContent(file, range).map(this::uncheckedToString).get()); @@ -117,7 +123,7 @@ public void testFileContentSegment() { @Test public void testFileContentSegments() { - final BinaryService resolver = new FileBinaryService(directory, idService); + final BinaryService resolver = new FileBinaryService(idService); final List> ranges = new ArrayList<>(); ranges.add(between(1, 5)); ranges.add(between(8, 10)); @@ -128,7 +134,7 @@ public void testFileContentSegments() { @Test public void testFileContentSegmentBeyond() { - final BinaryService resolver = new FileBinaryService(directory, idService); + final BinaryService resolver = new FileBinaryService(idService); final List> range = singletonList(between(1000, 1005)); assertTrue(resolver.getContent(file, range).isPresent()); assertEquals("", resolver.getContent(file, range).map(this::uncheckedToString).get()); @@ -137,7 +143,7 @@ public void testFileContentSegmentBeyond() { @Test public void testSetFileContent() { final String contents = "A new file"; - final BinaryService resolver = new FileBinaryService(directory, idService); + final BinaryService resolver = new FileBinaryService(idService); final IRI fileIRI = rdf.createIRI("file:" + randomFilename()); final InputStream inputStream = new ByteArrayInputStream(contents.getBytes(UTF_8)); resolver.setContent(fileIRI, inputStream); @@ -147,7 +153,7 @@ public void testSetFileContent() { @Test public void testGetFileContentError() throws IOException { - final BinaryService resolver = new FileBinaryService(directory, idService); + final BinaryService resolver = new FileBinaryService(idService); final IRI fileIRI = rdf.createIRI("file:" + randomFilename()); assertThrows(UncheckedIOException.class, () -> resolver.getContent(fileIRI)); } @@ -155,7 +161,7 @@ public void testGetFileContentError() throws IOException { @Test public void testSetFileContentError() throws IOException { when(mockInputStream.read(any(byte[].class))).thenThrow(new IOException("Expected error")); - final BinaryService resolver = new FileBinaryService(directory, idService); + final BinaryService resolver = new FileBinaryService(idService); final IRI fileIRI = rdf.createIRI("file:" + randomFilename()); assertThrows(UncheckedIOException.class, () -> resolver.setContent(fileIRI, mockInputStream)); } @@ -165,7 +171,7 @@ public void testBase64Digest() throws IOException { final byte[] data = "Some data".getBytes(UTF_8); when(mockInputStream.read(any(), anyInt(), anyInt())).thenThrow(new IOException("Expected Error")); - final BinaryService service = new FileBinaryService(directory, idService); + final BinaryService service = new FileBinaryService(idService); assertEquals(of("W4L4v03yv7DmbMqnMG/QJA=="), service.digest("MD5", new ByteArrayInputStream(data))); assertEquals(of("jXJFPxAHmvPfx/z8QQmx7VXhg58="), service.digest("SHA", new ByteArrayInputStream(data))); assertEquals(of("jXJFPxAHmvPfx/z8QQmx7VXhg58="), service.digest("SHA-1", new ByteArrayInputStream(data))); diff --git a/trellis-file/src/test/java/org/trellisldp/file/FileMementoServiceTest.java b/trellis-file/src/test/java/org/trellisldp/file/FileMementoServiceTest.java index c10ce4bdc..f5fc41433 100644 --- a/trellis-file/src/test/java/org/trellisldp/file/FileMementoServiceTest.java +++ b/trellis-file/src/test/java/org/trellisldp/file/FileMementoServiceTest.java @@ -70,7 +70,10 @@ public void testList() { final File dir = new File(getClass().getResource("/versions").getFile()); assertTrue(dir.exists()); assertTrue(dir.isDirectory()); - final MementoService svc = new FileMementoService(dir.getAbsolutePath()); + + System.getProperties().setProperty(FileMementoService.MEMENTO_BASE_PATH, dir.getAbsolutePath()); + + final MementoService svc = new FileMementoService(); assertEquals(2L, svc.list(identifier).size()); assertTrue(svc.get(identifier, now()).isPresent()); @@ -90,7 +93,10 @@ public void testListNonExistent() { final File dir = new File(getClass().getResource("/versions").getFile()); assertTrue(dir.exists()); assertTrue(dir.isDirectory()); - final MementoService svc = new FileMementoService(dir.getAbsolutePath()); + + System.getProperties().setProperty(FileMementoService.MEMENTO_BASE_PATH, dir.getAbsolutePath()); + + final MementoService svc = new FileMementoService(); assertTrue(svc.list(identifier).isEmpty()); assertFalse(svc.get(identifier, now()).isPresent()); @@ -104,7 +110,10 @@ public void testNewVersionSystem() { assertTrue(dir.isDirectory()); final File versionDir = new File(dir, "versions2"); assertFalse(versionDir.exists()); - final MementoService svc = new FileMementoService(versionDir.getAbsolutePath()); + + System.getProperties().setProperty(FileMementoService.MEMENTO_BASE_PATH, versionDir.getAbsolutePath()); + + final MementoService svc = new FileMementoService(); assertTrue(svc.list(identifier).isEmpty()); final File file = new File(getClass().getResource("/resource.nq").getFile()); @@ -131,7 +140,9 @@ public void testUnwritableVersionSystem() { "/readonly/35/97/1a/f68d4d5afced3770fc13fb8e560dc253/").getFile()); assumeTrue(readonly.setReadOnly()); - final MementoService svc = new FileMementoService(dir.getAbsolutePath()); + System.getProperties().setProperty(FileMementoService.MEMENTO_BASE_PATH, dir.getAbsolutePath()); + + final MementoService svc = new FileMementoService(); assertEquals(2L, svc.list(identifier).size()); final File file = new File(getClass().getResource("/resource.nq").getFile()); assertTrue(file.exists()); @@ -155,9 +166,11 @@ public void testAccessUnreadable() { "/unreadable/35/97/1a/f68d4d5afced3770fc13fb8e560dc253/").getFile()); assumeTrue(unreadable.setReadable(false)); - final MementoService svc = new FileMementoService(dir.getAbsolutePath()); + + System.getProperties().setProperty(FileMementoService.MEMENTO_BASE_PATH, dir.getAbsolutePath()); + + final MementoService svc = new FileMementoService(); assertTrue(svc.list(identifier).isEmpty()); } - } diff --git a/trellis-file/src/test/resources/META-INF/javaconfiguration.properties b/trellis-file/src/test/resources/META-INF/javaconfiguration.properties new file mode 100644 index 000000000..eb98fa8d1 --- /dev/null +++ b/trellis-file/src/test/resources/META-INF/javaconfiguration.properties @@ -0,0 +1,2 @@ +trellis.file.memento.basepath=mementos +trellis.file.binary.basepath=binaries diff --git a/trellis-http/build.gradle b/trellis-http/build.gradle index 139a1f61c..014316f2b 100644 --- a/trellis-http/build.gradle +++ b/trellis-http/build.gradle @@ -17,6 +17,7 @@ dependencies { implementation group: 'commons-codec', name: 'commons-codec', version: commonsCodecVersion implementation group: 'commons-io', name: 'commons-io', version: commonsIoVersion implementation group: 'javax.json', name: 'javax.json-api', version: javaxJsonVersion + implementation group: 'org.apache.tamaya', name: 'tamaya-api', version: tamayaVersion implementation group: 'org.slf4j', name: 'slf4j-api', version: slf4jVersion implementation project(':trellis-vocabulary') @@ -24,6 +25,7 @@ dependencies { testImplementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: jacksonVersion testImplementation group: 'org.apache.commons', name: 'commons-text', version: commonsTextVersion testImplementation group: 'org.apache.commons', name: 'commons-rdf-simple', version: commonsRdfVersion + testImplementation group: 'org.apache.tamaya', name: 'tamaya-core', version: tamayaVersion testImplementation group: 'org.apiguardian', name: 'apiguardian-api', version: apiguardianVersion testImplementation group: 'org.glassfish', name: 'javax.json', version: jsonVersion testImplementation group: 'org.glassfish.jersey.core', name: 'jersey-server', version: jerseyVersion diff --git a/trellis-http/src/main/java/org/trellisldp/http/AgentAuthorizationFilter.java b/trellis-http/src/main/java/org/trellisldp/http/AgentAuthorizationFilter.java index 5a59d6d20..e185ce64a 100644 --- a/trellis-http/src/main/java/org/trellisldp/http/AgentAuthorizationFilter.java +++ b/trellis-http/src/main/java/org/trellisldp/http/AgentAuthorizationFilter.java @@ -20,9 +20,12 @@ import static org.trellisldp.vocabulary.Trellis.AdministratorAgent; import java.io.IOException; +import java.util.HashSet; import java.util.List; +import java.util.Set; import javax.annotation.Priority; +import javax.inject.Inject; import javax.ws.rs.container.ContainerRequestContext; import javax.ws.rs.container.ContainerRequestFilter; import javax.ws.rs.core.SecurityContext; @@ -50,17 +53,25 @@ public class AgentAuthorizationFilter implements ContainerRequestFilter { private static final Logger LOGGER = getLogger(AgentAuthorizationFilter.class); private final AgentService agentService; - private final List adminUsers; + private final Set adminUsers = new HashSet<>(); /** * Create an authorization filter. * * @param agentService the agent service - * @param adminUsers users that should be treated as server administrators */ - public AgentAuthorizationFilter(final AgentService agentService, final List adminUsers) { + @Inject + public AgentAuthorizationFilter(final AgentService agentService) { this.agentService = agentService; - this.adminUsers = adminUsers; + } + + /** + * Set any admin users for the auth filter. + * + * @param adminUsers users that should be treated as server administrators + */ + public void setAdminUsers(final List adminUsers) { + adminUsers.forEach(this.adminUsers::add); } @Override diff --git a/trellis-http/src/main/java/org/trellisldp/http/HttpBasedBinaryService.java b/trellis-http/src/main/java/org/trellisldp/http/HttpBasedBinaryService.java index 3a9873dcf..82acd6f23 100644 --- a/trellis-http/src/main/java/org/trellisldp/http/HttpBasedBinaryService.java +++ b/trellis-http/src/main/java/org/trellisldp/http/HttpBasedBinaryService.java @@ -42,6 +42,7 @@ import java.util.Set; import java.util.function.Function; +import javax.inject.Inject; import javax.ws.rs.client.Client; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; @@ -100,6 +101,7 @@ public HttpBasedBinaryService(final IdentifierService idService) { * @param idService an identifier service * @param client the client */ + @Inject public HttpBasedBinaryService(final IdentifierService idService, final Client client) { requireNonNull(client, "HTTP client may not be null!"); this.idService = idService; diff --git a/trellis-http/src/main/java/org/trellisldp/http/LdpResource.java b/trellis-http/src/main/java/org/trellisldp/http/LdpResource.java index e61210139..0ab2eb298 100644 --- a/trellis-http/src/main/java/org/trellisldp/http/LdpResource.java +++ b/trellis-http/src/main/java/org/trellisldp/http/LdpResource.java @@ -31,6 +31,7 @@ import static org.trellisldp.api.AuditService.none; import static org.trellisldp.api.RDFUtils.TRELLIS_DATA_PREFIX; import static org.trellisldp.api.RDFUtils.getInstance; +import static org.trellisldp.http.domain.HttpConstants.CONFIGURATION_BASE_URL; import static org.trellisldp.http.domain.HttpConstants.TIMEMAP; import static org.trellisldp.http.impl.RdfUtils.ldpResourceTypes; @@ -44,6 +45,7 @@ import java.util.ServiceLoader; import javax.annotation.Priority; +import javax.inject.Inject; import javax.inject.Singleton; import javax.ws.rs.BeanParam; import javax.ws.rs.Consumes; @@ -63,6 +65,7 @@ import org.apache.commons.rdf.api.IRI; import org.apache.commons.rdf.api.RDF; +import org.apache.tamaya.ConfigurationProvider; import org.slf4j.Logger; import org.trellisldp.api.AuditService; import org.trellisldp.api.BinaryService; @@ -121,11 +124,10 @@ public class LdpResource implements ContainerRequestFilter { * @param resourceService the resource service * @param ioService the i/o service * @param binaryService the datastream service - * @param baseUrl a baseUrl value */ public LdpResource(final ResourceService resourceService, final IOService ioService, - final BinaryService binaryService, final String baseUrl) { - this(resourceService, ioService, binaryService, loadFirst(AuditService.class).orElse(none()), baseUrl); + final BinaryService binaryService) { + this(resourceService, ioService, binaryService, loadFirst(AuditService.class).orElse(none())); } /** @@ -134,11 +136,27 @@ public LdpResource(final ResourceService resourceService, final IOService ioServ * @param resourceService the resource service * @param ioService the i/o service * @param binaryService the datastream service - * @param baseUrl a baseUrl value * @param auditService an audit service */ + @Inject public LdpResource(final ResourceService resourceService, final IOService ioService, - final BinaryService binaryService, final AuditService auditService, final String baseUrl) { + final BinaryService binaryService, final AuditService auditService) { + this(resourceService, ioService, binaryService, auditService, + ConfigurationProvider.getConfiguration().get(CONFIGURATION_BASE_URL)); + } + + /** + * Create an LdpResource. + * + * @param resourceService the resource service + * @param ioService the i/o service + * @param binaryService the datastream service + * @param auditService an audit service + * @param baseUrl a base URL + */ + public LdpResource(final ResourceService resourceService, final IOService ioService, + final BinaryService binaryService, final AuditService auditService, + final String baseUrl) { this.baseUrl = baseUrl; this.resourceService = resourceService; this.ioService = ioService; @@ -146,6 +164,7 @@ public LdpResource(final ResourceService resourceService, final IOService ioServ this.auditService = auditService; } + @Override public void filter(final ContainerRequestContext ctx) throws IOException { // Check for a trailing slash. If so, redirect diff --git a/trellis-http/src/main/java/org/trellisldp/http/MultipartUploader.java b/trellis-http/src/main/java/org/trellisldp/http/MultipartUploader.java index f705bd681..5eba77c05 100644 --- a/trellis-http/src/main/java/org/trellisldp/http/MultipartUploader.java +++ b/trellis-http/src/main/java/org/trellisldp/http/MultipartUploader.java @@ -39,6 +39,7 @@ import static org.slf4j.LoggerFactory.getLogger; import static org.trellisldp.api.RDFUtils.TRELLIS_DATA_PREFIX; import static org.trellisldp.api.RDFUtils.getInstance; +import static org.trellisldp.http.domain.HttpConstants.CONFIGURATION_BASE_URL; import static org.trellisldp.http.domain.HttpConstants.UPLOADS; import static org.trellisldp.http.domain.HttpConstants.UPLOAD_PREFIX; import static org.trellisldp.http.impl.RdfUtils.skolemizeQuads; @@ -60,6 +61,7 @@ import java.util.concurrent.ExecutionException; import javax.annotation.Priority; +import javax.inject.Inject; import javax.inject.Singleton; import javax.json.Json; import javax.json.JsonObject; @@ -87,6 +89,7 @@ import org.apache.commons.rdf.api.IRI; import org.apache.commons.rdf.api.RDF; +import org.apache.tamaya.ConfigurationProvider; import org.slf4j.Logger; import org.trellisldp.api.AuditService; import org.trellisldp.api.BinaryService; @@ -124,6 +127,18 @@ public class MultipartUploader implements ContainerRequestFilter, ContainerRespo private final String baseUrl; + /** + * Create a multipart uploader object. + * + * @param resourceService the resource service + * @param binaryService the binary service + */ + @Inject + public MultipartUploader(final ResourceService resourceService, + final BinaryService.MultipartCapable binaryService) { + this(resourceService, binaryService, ConfigurationProvider.getConfiguration().get(CONFIGURATION_BASE_URL)); + } + /** * Create a multipart uploader object. * @@ -133,7 +148,6 @@ public class MultipartUploader implements ContainerRequestFilter, ContainerRespo */ public MultipartUploader(final ResourceService resourceService, final BinaryService.MultipartCapable binaryService, final String baseUrl) { - this.baseUrl = baseUrl; this.resourceService = resourceService; this.binaryService = binaryService; diff --git a/trellis-http/src/main/java/org/trellisldp/http/WebAcFilter.java b/trellis-http/src/main/java/org/trellisldp/http/WebAcFilter.java index 5ad90328f..a1e6d030f 100644 --- a/trellis-http/src/main/java/org/trellisldp/http/WebAcFilter.java +++ b/trellis-http/src/main/java/org/trellisldp/http/WebAcFilter.java @@ -15,7 +15,6 @@ import static java.util.Arrays.asList; import static java.util.Collections.emptyList; -import static java.util.Collections.singletonList; import static java.util.Objects.nonNull; import static javax.ws.rs.Priorities.AUTHORIZATION; import static javax.ws.rs.core.HttpHeaders.LINK; @@ -29,11 +28,13 @@ import static org.trellisldp.http.domain.HttpConstants.SESSION_PROPERTY; import java.io.IOException; +import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import javax.annotation.Priority; +import javax.inject.Inject; import javax.ws.rs.ForbiddenException; import javax.ws.rs.NotAllowedException; import javax.ws.rs.NotAuthorizedException; @@ -67,7 +68,7 @@ public class WebAcFilter implements ContainerRequestFilter, ContainerResponseFil private static final Logger LOGGER = getLogger(WebAcFilter.class); private final AccessControlService accessService; - private final List challenges; + private final List challenges = new ArrayList<>(); private static final Set readable = new HashSet<>(asList("GET", "HEAD", "OPTIONS")); private static final Set writable = new HashSet<>(asList("PUT", "PATCH", "DELETE")); private static final Set appendable = new HashSet<>(asList("POST")); @@ -75,12 +76,24 @@ public class WebAcFilter implements ContainerRequestFilter, ContainerResponseFil /** * Create a new WebAc-based auth filter. * - * @param challenges the challenges * @param accessService the access service */ - public WebAcFilter(final List challenges, final AccessControlService accessService) { + @Inject + public WebAcFilter(final AccessControlService accessService) { this.accessService = accessService; - this.challenges = challenges.isEmpty() ? singletonList(BASIC_AUTH) : challenges; + challenges.add(BASIC_AUTH); + } + + /** + * Set the auth challenges. + * + * @param challenges the auth challenges + */ + public void setChallenges(final List challenges) { + if (!challenges.isEmpty()) { + this.challenges.clear(); + challenges.forEach(this.challenges::add); + } } @Override diff --git a/trellis-http/src/main/java/org/trellisldp/http/domain/HttpConstants.java b/trellis-http/src/main/java/org/trellisldp/http/domain/HttpConstants.java index cfa24a654..ee633e7f8 100644 --- a/trellis-http/src/main/java/org/trellisldp/http/domain/HttpConstants.java +++ b/trellis-http/src/main/java/org/trellisldp/http/domain/HttpConstants.java @@ -43,6 +43,8 @@ public final class HttpConstants { public static final String APPLICATION_LINK_FORMAT = "application/link-format"; + public static final String CONFIGURATION_BASE_URL = "trellis.http.baseUrl"; + public static final String EXT = "ext"; public static final String DIGEST = "Digest"; diff --git a/trellis-http/src/main/resources/META-INF/beans.xml b/trellis-http/src/main/resources/META-INF/beans.xml new file mode 100644 index 000000000..1e341328e --- /dev/null +++ b/trellis-http/src/main/resources/META-INF/beans.xml @@ -0,0 +1,7 @@ + + + diff --git a/trellis-http/src/test/java/org/trellisldp/http/AgentAuthorizationFilterTest.java b/trellis-http/src/test/java/org/trellisldp/http/AgentAuthorizationFilterTest.java index 69e2e6067..dc83bdb10 100644 --- a/trellis-http/src/test/java/org/trellisldp/http/AgentAuthorizationFilterTest.java +++ b/trellis-http/src/test/java/org/trellisldp/http/AgentAuthorizationFilterTest.java @@ -72,8 +72,8 @@ public void setUp() { @Test public void testFilterMissingAgent() throws Exception { when(mockPrincipal.getName()).thenReturn(""); - final AgentAuthorizationFilter filter = new AgentAuthorizationFilter(mockAgentService, emptyList()); - + final AgentAuthorizationFilter filter = new AgentAuthorizationFilter(mockAgentService); + filter.setAdminUsers(emptyList()); filter.filter(mockContext); verify(mockContext).setProperty(eq(SESSION_PROPERTY), sessionArgument.capture()); assertEquals(Trellis.AnonymousAgent, sessionArgument.getValue().getAgent()); diff --git a/trellis-http/src/test/java/org/trellisldp/http/CORSResourceTest.java b/trellis-http/src/test/java/org/trellisldp/http/CORSResourceTest.java index 89d1dde28..8a055ec44 100644 --- a/trellis-http/src/test/java/org/trellisldp/http/CORSResourceTest.java +++ b/trellis-http/src/test/java/org/trellisldp/http/CORSResourceTest.java @@ -164,7 +164,7 @@ public Application configure() { final String origin = baseUri.substring(0, baseUri.length() - 1); final ResourceConfig config = new ResourceConfig(); - config.register(new LdpResource(mockResourceService, ioService, mockBinaryService, BASE_URL)); + config.register(new LdpResource(mockResourceService, ioService, mockBinaryService)); config.register(new CrossOriginResourceSharingFilter(asList("*"), asList("PATCH", "POST", "PUT"), asList("Link", "Content-Type", "Accept", "Accept-Datetime"), emptyList(), false, 0)); diff --git a/trellis-http/src/test/java/org/trellisldp/http/LdpAdminResourceTest.java b/trellis-http/src/test/java/org/trellisldp/http/LdpAdminResourceTest.java index d1d0880d9..bd7dcf13f 100644 --- a/trellis-http/src/test/java/org/trellisldp/http/LdpAdminResourceTest.java +++ b/trellis-http/src/test/java/org/trellisldp/http/LdpAdminResourceTest.java @@ -14,7 +14,6 @@ package org.trellisldp.http; import static java.util.Arrays.asList; -import static java.util.Collections.emptyList; import static org.mockito.MockitoAnnotations.initMocks; import javax.ws.rs.core.Application; @@ -34,12 +33,15 @@ public Application configure() { final String baseUri = getBaseUri().toString(); final String origin = baseUri.substring(0, baseUri.length() - 1); + final AgentAuthorizationFilter agentFilter = new AgentAuthorizationFilter(mockAgentService); + agentFilter.setAdminUsers(asList("testUser")); + final ResourceConfig config = new ResourceConfig(); - config.register(new LdpResource(mockResourceService, ioService, mockBinaryService, mockAuditService, BASE_URL)); + config.register(new LdpResource(mockResourceService, ioService, mockBinaryService, mockAuditService)); config.register(new TestAuthenticationFilter("testUser", "")); - config.register(new WebAcFilter(emptyList(), mockAccessControlService)); - config.register(new AgentAuthorizationFilter(mockAgentService, asList("testUser"))); - config.register(new MultipartUploader(mockResourceService, mockBinaryResolver, BASE_URL)); + config.register(new WebAcFilter(mockAccessControlService)); + config.register(agentFilter); + config.register(new MultipartUploader(mockResourceService, mockBinaryResolver)); config.register(new CacheControlFilter(86400)); config.register(new CrossOriginResourceSharingFilter(asList(origin), asList("PATCH", "POST", "PUT"), diff --git a/trellis-http/src/test/java/org/trellisldp/http/LdpForbiddenResourceTest.java b/trellis-http/src/test/java/org/trellisldp/http/LdpForbiddenResourceTest.java index 9124d6946..7e1ada2e7 100644 --- a/trellis-http/src/test/java/org/trellisldp/http/LdpForbiddenResourceTest.java +++ b/trellis-http/src/test/java/org/trellisldp/http/LdpForbiddenResourceTest.java @@ -33,6 +33,7 @@ import static org.trellisldp.api.RDFUtils.TRELLIS_DATA_PREFIX; import static org.trellisldp.api.RDFUtils.getInstance; import static org.trellisldp.http.domain.HttpConstants.APPLICATION_LINK_FORMAT; +import static org.trellisldp.http.domain.HttpConstants.CONFIGURATION_BASE_URL; import static org.trellisldp.http.domain.RdfMediaType.APPLICATION_N_TRIPLES_TYPE; import static org.trellisldp.http.domain.RdfMediaType.APPLICATION_SPARQL_UPDATE_TYPE; @@ -119,12 +120,15 @@ public Application configure() { initMocks(this); BASE_URL = getBaseUri().toString(); + System.getProperties().setProperty(CONFIGURATION_BASE_URL, BASE_URL); final ResourceConfig config = new ResourceConfig(); config.register(new TestAuthenticationFilter("testUser", "group")); - config.register(new AgentAuthorizationFilter(mockAgentService, emptyList())); - config.register(new WebAcFilter(emptyList(), mockAccessControlService)); - config.register(new LdpResource(mockResourceService, ioService, mockBinaryService, null)); + config.register(new AgentAuthorizationFilter(mockAgentService)); + config.register(new WebAcFilter(mockAccessControlService)); + config.register(new LdpResource(mockResourceService, ioService, mockBinaryService)); + System.getProperties().remove(CONFIGURATION_BASE_URL); + return config; } diff --git a/trellis-http/src/test/java/org/trellisldp/http/LdpResourceNoAgentTest.java b/trellis-http/src/test/java/org/trellisldp/http/LdpResourceNoAgentTest.java index c544427e4..7b68a5347 100644 --- a/trellis-http/src/test/java/org/trellisldp/http/LdpResourceNoAgentTest.java +++ b/trellis-http/src/test/java/org/trellisldp/http/LdpResourceNoAgentTest.java @@ -35,8 +35,8 @@ public Application configure() { final String origin = baseUri.substring(0, baseUri.length() - 1); final ResourceConfig config = new ResourceConfig(); - config.register(new LdpResource(mockResourceService, ioService, mockBinaryService, mockAuditService, BASE_URL)); - config.register(new MultipartUploader(mockResourceService, mockBinaryResolver, BASE_URL)); + config.register(new LdpResource(mockResourceService, ioService, mockBinaryService, mockAuditService)); + config.register(new MultipartUploader(mockResourceService, mockBinaryResolver)); config.register(new CacheControlFilter(86400)); config.register(new CrossOriginResourceSharingFilter(asList(origin), asList("PATCH", "POST", "PUT"), asList("Link", "Content-Type", "Accept-Datetime"), diff --git a/trellis-http/src/test/java/org/trellisldp/http/LdpResourceTest.java b/trellis-http/src/test/java/org/trellisldp/http/LdpResourceTest.java index b5bd5adbe..6ade3d0a3 100644 --- a/trellis-http/src/test/java/org/trellisldp/http/LdpResourceTest.java +++ b/trellis-http/src/test/java/org/trellisldp/http/LdpResourceTest.java @@ -14,7 +14,6 @@ package org.trellisldp.http; import static java.util.Arrays.asList; -import static java.util.Collections.emptyList; import static org.mockito.MockitoAnnotations.initMocks; import javax.ws.rs.core.Application; @@ -35,9 +34,10 @@ public Application configure() { final String origin = baseUri.substring(0, baseUri.length() - 1); final ResourceConfig config = new ResourceConfig(); - config.register(new LdpResource(mockResourceService, ioService, mockBinaryService, mockAuditService, BASE_URL)); - config.register(new AgentAuthorizationFilter(mockAgentService, emptyList())); - config.register(new MultipartUploader(mockResourceService, mockBinaryResolver, BASE_URL)); + + config.register(new LdpResource(mockResourceService, ioService, mockBinaryService, mockAuditService)); + config.register(new AgentAuthorizationFilter(mockAgentService)); + config.register(new MultipartUploader(mockResourceService, mockBinaryResolver)); config.register(new CacheControlFilter(86400)); config.register(new CrossOriginResourceSharingFilter(asList(origin), asList("PATCH", "POST", "PUT"), asList("Link", "Content-Type", "Accept-Datetime"), diff --git a/trellis-http/src/test/java/org/trellisldp/http/LdpUnauthorizedResourceTest.java b/trellis-http/src/test/java/org/trellisldp/http/LdpUnauthorizedResourceTest.java index 7e04c480e..e051b65df 100644 --- a/trellis-http/src/test/java/org/trellisldp/http/LdpUnauthorizedResourceTest.java +++ b/trellis-http/src/test/java/org/trellisldp/http/LdpUnauthorizedResourceTest.java @@ -117,10 +117,13 @@ public Application configure() { // Junit runner doesn't seem to work very well with JerseyTest initMocks(this); + final WebAcFilter webacFilter = new WebAcFilter(mockAccessControlService); + webacFilter.setChallenges(asList(BASIC_AUTH, DIGEST_AUTH)); + final ResourceConfig config = new ResourceConfig(); - config.register(new LdpResource(mockResourceService, ioService, mockBinaryService, "http://example.org/")); + config.register(new LdpResource(mockResourceService, ioService, mockBinaryService)); config.register(new TestAuthenticationFilter("testUser", "group")); - config.register(new WebAcFilter(asList(BASIC_AUTH, DIGEST_AUTH), mockAccessControlService)); + config.register(webacFilter); config.register(new CrossOriginResourceSharingFilter(asList(origin), asList("PATCH", "POST", "PUT"), asList("Link", "Content-Type", "Accept", "Accept-Datetime"), diff --git a/trellis-http/src/test/java/org/trellisldp/http/LdpUserResourceTest.java b/trellis-http/src/test/java/org/trellisldp/http/LdpUserResourceTest.java index 9d00117d3..e0827f4a9 100644 --- a/trellis-http/src/test/java/org/trellisldp/http/LdpUserResourceTest.java +++ b/trellis-http/src/test/java/org/trellisldp/http/LdpUserResourceTest.java @@ -14,7 +14,6 @@ package org.trellisldp.http; import static java.util.Arrays.asList; -import static java.util.Collections.emptyList; import static org.mockito.MockitoAnnotations.initMocks; import javax.ws.rs.core.Application; @@ -36,11 +35,11 @@ public Application configure() { final String origin = baseUri.substring(0, baseUri.length() - 1); final ResourceConfig config = new ResourceConfig(); - config.register(new LdpResource(mockResourceService, ioService, mockBinaryService, mockAuditService, BASE_URL)); + config.register(new LdpResource(mockResourceService, ioService, mockBinaryService, mockAuditService)); config.register(new TestAuthenticationFilter("testUser", "group")); - config.register(new WebAcFilter(emptyList(), mockAccessControlService)); - config.register(new AgentAuthorizationFilter(mockAgentService, emptyList())); - config.register(new MultipartUploader(mockResourceService, mockBinaryResolver, BASE_URL)); + config.register(new WebAcFilter(mockAccessControlService)); + config.register(new AgentAuthorizationFilter(mockAgentService)); + config.register(new MultipartUploader(mockResourceService, mockBinaryResolver)); config.register(new CacheControlFilter(86400)); config.register(new CrossOriginResourceSharingFilter(asList(origin), asList("PATCH", "POST", "PUT"), asList("Link", "Content-Type", "Accept-Datetime"), diff --git a/trellis-http/src/test/java/org/trellisldp/http/WebACFilterTest.java b/trellis-http/src/test/java/org/trellisldp/http/WebACFilterTest.java index c21828470..29b07b654 100644 --- a/trellis-http/src/test/java/org/trellisldp/http/WebACFilterTest.java +++ b/trellis-http/src/test/java/org/trellisldp/http/WebACFilterTest.java @@ -89,7 +89,7 @@ public void setUp() { public void testFilterUnknownMethod() throws Exception { when(mockContext.getMethod()).thenReturn("FOO"); - final WebAcFilter filter = new WebAcFilter(emptyList(), mockAccessControlService); + final WebAcFilter filter = new WebAcFilter(mockAccessControlService); assertThrows(NotAllowedException.class, () -> filter.filter(mockContext)); } @@ -100,7 +100,7 @@ public void testFilterAppend() throws Exception { when(mockContext.getMethod()).thenReturn("POST"); when(mockAccessControlService.getAccessModes(any(IRI.class), any(Session.class))).thenReturn(modes); - final WebAcFilter filter = new WebAcFilter(emptyList(), mockAccessControlService); + final WebAcFilter filter = new WebAcFilter(mockAccessControlService); modes.add(ACL.Append); filter.filter(mockContext); diff --git a/trellis-http/src/test/resources/META-INF/javaconfiguration.properties b/trellis-http/src/test/resources/META-INF/javaconfiguration.properties new file mode 100644 index 000000000..ded5d6da5 --- /dev/null +++ b/trellis-http/src/test/resources/META-INF/javaconfiguration.properties @@ -0,0 +1 @@ +trellis.http.baseUrl=http://example.org/ diff --git a/trellis-id/src/main/resources/META-INF/beans.xml b/trellis-id/src/main/resources/META-INF/beans.xml new file mode 100644 index 000000000..1e341328e --- /dev/null +++ b/trellis-id/src/main/resources/META-INF/beans.xml @@ -0,0 +1,7 @@ + + + diff --git a/trellis-io-jena/build.gradle b/trellis-io-jena/build.gradle index d2b6a0562..6863c63b9 100644 --- a/trellis-io-jena/build.gradle +++ b/trellis-io-jena/build.gradle @@ -8,15 +8,18 @@ ext { dependencies { api group: 'org.apache.commons', name: 'commons-rdf-api', version: commonsRdfVersion + api group: 'org.apache.servicemix.bundles', name: 'org.apache.servicemix.bundles.javax-inject', version: javaxInjectVersion api project(':trellis-api') implementation group: 'org.apache.commons', name: 'commons-rdf-jena', version: commonsRdfVersion implementation group: 'org.apache.jena', name: 'jena-osgi', version: jenaVersion implementation group: 'org.apache.servicemix.bundles', name: 'org.apache.servicemix.bundles.mustache-compiler', version: mustacheVersion + implementation group: 'org.apache.tamaya', name: 'tamaya-api', version: tamayaVersion implementation group: 'org.slf4j', name: 'slf4j-api', version: slf4jVersion implementation project(':trellis-vocabulary') testImplementation group: 'ch.qos.logback', name: 'logback-classic', version: logbackVersion + testImplementation group: 'org.apache.tamaya', name: 'tamaya-core', version: tamayaVersion testImplementation group: 'org.apiguardian', name: 'apiguardian-api', version: apiguardianVersion testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: junitVersion testImplementation group: 'org.junit.platform', name: 'junit-platform-runner', version: junitPlatformVersion diff --git a/trellis-io-jena/src/main/java/org/trellisldp/io/JenaIOService.java b/trellis-io-jena/src/main/java/org/trellisldp/io/JenaIOService.java index 0a6bc7b71..d8db82837 100644 --- a/trellis-io-jena/src/main/java/org/trellisldp/io/JenaIOService.java +++ b/trellis-io-jena/src/main/java/org/trellisldp/io/JenaIOService.java @@ -14,15 +14,11 @@ package org.trellisldp.io; import static java.nio.charset.StandardCharsets.UTF_8; -import static java.util.Collections.emptySet; -import static java.util.Collections.unmodifiableMap; -import static java.util.Collections.unmodifiableSet; +import static java.util.Arrays.stream; import static java.util.Objects.nonNull; import static java.util.Objects.requireNonNull; import static java.util.Optional.ofNullable; -import static java.util.stream.Collectors.toMap; import static java.util.stream.Collectors.toSet; -import static java.util.stream.Stream.of; import static org.apache.commons.rdf.api.RDFSyntax.RDFA; import static org.apache.jena.graph.Factory.createDefaultGraph; import static org.apache.jena.riot.Lang.JSONLD; @@ -38,11 +34,12 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.util.AbstractMap.SimpleEntry; import java.util.Map; import java.util.Set; import java.util.stream.Stream; +import javax.inject.Inject; + import org.apache.commons.io.IOUtils; import org.apache.commons.rdf.api.Graph; import org.apache.commons.rdf.api.IRI; @@ -67,10 +64,11 @@ import org.apache.jena.sparql.core.DatasetGraph; import org.apache.jena.sparql.core.DatasetGraphFactory; import org.apache.jena.update.UpdateException; +import org.apache.tamaya.ConfigurationProvider; import org.slf4j.Logger; -import org.trellisldp.api.CacheService; import org.trellisldp.api.IOService; import org.trellisldp.api.NamespaceService; +import org.trellisldp.api.ProfileCacheService; import org.trellisldp.api.RuntimeTrellisException; import org.trellisldp.io.impl.HtmlSerializer; @@ -81,21 +79,22 @@ */ public class JenaIOService implements IOService { + public static final String IO_HTML_CSS = "trellis.io.html.css"; + public static final String IO_HTML_JS = "trellis.io.html.js"; + public static final String IO_HTML_TEMPLATE = "trellis.io.html.template"; + public static final String IO_HTML_ICON = "trellis.io.html.icon"; + public static final String IO_JSONLD_PROFILES = "trellis.io.jsonld.profiles"; + public static final String IO_JSONLD_DOMAINS = "trellis.io.jsonld.domains"; + private static final Logger LOGGER = getLogger(JenaIOService.class); private static final JenaRDF rdf = new JenaRDF(); - private static final Map defaultProperties = unmodifiableMap(of( - new SimpleEntry<>("icon", "//www.trellisldp.org/assets/img/trellis.png"), - new SimpleEntry<>("css", "//www.trellisldp.org/assets/css/trellis.css")) - .collect(toMap(Map.Entry::getKey, Map.Entry::getValue))); - - private final Set whitelist; - private final Set whitelistDomains; - private final CacheService cache; - private final NamespaceService nsService; + private final ProfileCacheService cache; private final HtmlSerializer htmlSerializer; + private final Set whitelist; + private final Set whitelistDomains; /** * Create a serialization service. @@ -103,36 +102,38 @@ public class JenaIOService implements IOService { * @param namespaceService the namespace service */ public JenaIOService(final NamespaceService namespaceService) { - this(namespaceService, defaultProperties); + this(namespaceService, null, ConfigurationProvider.getConfiguration().getProperties()); } /** * Create a serialization service. * * @param namespaceService the namespace service - * @param properties additional properties for the HTML view + * @param cache a cache for custom JSON-LD profile resolution */ - public JenaIOService(final NamespaceService namespaceService, final Map properties) { - this(namespaceService, properties, emptySet(), emptySet(), null); + @Inject + public JenaIOService(final NamespaceService namespaceService, final ProfileCacheService cache) { + this(namespaceService, cache, ConfigurationProvider.getConfiguration().getProperties()); } /** * Create a serialization service. * * @param namespaceService the namespace service - * @param properties additional properties for the HTML view - * @param whitelist a whitelist of JSON-LD profiles - * @param whitelistDomains a whitelist of domains for use with JSON-LD profiles * @param cache a cache for custom JSON-LD profile resolution + * @param properties additional properties for the serialization service */ - public JenaIOService(final NamespaceService namespaceService, final Map properties, - final Set whitelist, final Set whitelistDomains, final CacheService cache) { + public JenaIOService(final NamespaceService namespaceService, final ProfileCacheService cache, + final Map properties) { this.nsService = namespaceService; - this.htmlSerializer = new HtmlSerializer(namespaceService, - properties.getOrDefault("template", "org/trellisldp/io/resource.mustache"), properties); - this.whitelist = unmodifiableSet(whitelist); - this.whitelistDomains = unmodifiableSet(whitelistDomains); this.cache = cache; + + this.htmlSerializer = new HtmlSerializer(namespaceService, properties); + + this.whitelist = stream(properties.getOrDefault(IO_JSONLD_PROFILES, "").split(",")).map(String::trim) + .filter(x -> !x.isEmpty()).collect(toSet()); + this.whitelistDomains = stream(properties.getOrDefault(IO_JSONLD_DOMAINS, "").split(",")).map(String::trim) + .filter(x -> !x.isEmpty()).collect(toSet()); } @Override diff --git a/trellis-io-jena/src/main/java/org/trellisldp/io/impl/HtmlData.java b/trellis-io-jena/src/main/java/org/trellisldp/io/impl/HtmlData.java index a8b9c7549..7790ef869 100644 --- a/trellis-io-jena/src/main/java/org/trellisldp/io/impl/HtmlData.java +++ b/trellis-io-jena/src/main/java/org/trellisldp/io/impl/HtmlData.java @@ -80,8 +80,8 @@ public List getTriples() { * @return a list of any CSS documents */ public List getCss() { - return stream(properties.getOrDefault("css", "").split(",")) - .map(String::trim).filter(x -> x.length() > 0).collect(toList()); + return stream(properties.getOrDefault("trellis.io.html.css", "//www.trellisldp.org/assets/css/trellis.css") + .split(",")).map(String::trim).filter(x -> !x.isEmpty()).collect(toList()); } /** @@ -90,7 +90,7 @@ public List getCss() { * @return the location of an icon, if one exists */ public String getIcon() { - return properties.get("icon"); + return properties.getOrDefault("trellis.io.html.icon", "//www.trellisldp.org/assets/img/trellis.png"); } /** @@ -99,8 +99,8 @@ public String getIcon() { * @return a list of JS documents */ public List getJs() { - return stream(properties.getOrDefault("js", "").split(",")) - .map(String::trim).filter(x -> x.length() > 0).collect(toList()); + return stream(properties.getOrDefault("trellis.io.html.js", "").split(",")) + .map(String::trim).filter(x -> !x.isEmpty()).collect(toList()); } /** diff --git a/trellis-io-jena/src/main/java/org/trellisldp/io/impl/HtmlSerializer.java b/trellis-io-jena/src/main/java/org/trellisldp/io/impl/HtmlSerializer.java index 443bdb4be..df5a73c1f 100644 --- a/trellis-io-jena/src/main/java/org/trellisldp/io/impl/HtmlSerializer.java +++ b/trellis-io-jena/src/main/java/org/trellisldp/io/impl/HtmlSerializer.java @@ -50,18 +50,14 @@ public class HtmlSerializer { * Create a ResourceView object. * * @param namespaceService a namespace service - * @param template the template name * @param properties additional HTML-related properties, e.g. URLs for icon, css, js */ - public HtmlSerializer(final NamespaceService namespaceService, final String template, - final Map properties) { + public HtmlSerializer(final NamespaceService namespaceService, final Map properties) { this.namespaceService = namespaceService; - final File tpl = new File(template); - if (tpl.exists()) { - this.template = mf.compile(template); - } else { - this.template = mf.compile(getReader(template), template); - } + final String templatePath = properties.getOrDefault("trellis.io.html.template", + "org/trellisldp/io/resource.mustache"); + final File tpl = new File(templatePath); + this.template = tpl.exists() ? mf.compile(templatePath) : mf.compile(getReader(templatePath), templatePath); this.properties = properties; } diff --git a/trellis-io-jena/src/main/resources/META-INF/beans.xml b/trellis-io-jena/src/main/resources/META-INF/beans.xml new file mode 100644 index 000000000..1e341328e --- /dev/null +++ b/trellis-io-jena/src/main/resources/META-INF/beans.xml @@ -0,0 +1,7 @@ + + + diff --git a/trellis-io-jena/src/test/java/org/trellisldp/io/IOServiceTest.java b/trellis-io-jena/src/test/java/org/trellisldp/io/IOServiceTest.java index e80ecc08b..d5cad15b6 100644 --- a/trellis-io-jena/src/test/java/org/trellisldp/io/IOServiceTest.java +++ b/trellis-io-jena/src/test/java/org/trellisldp/io/IOServiceTest.java @@ -14,8 +14,6 @@ package org.trellisldp.io; import static java.nio.charset.StandardCharsets.UTF_8; -import static java.util.Collections.emptySet; -import static java.util.Collections.singleton; import static java.util.Optional.empty; import static java.util.stream.Stream.of; import static org.apache.commons.rdf.api.RDFSyntax.JSONLD; @@ -44,6 +42,11 @@ import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.when; import static org.mockito.MockitoAnnotations.initMocks; +import static org.trellisldp.io.JenaIOService.IO_HTML_CSS; +import static org.trellisldp.io.JenaIOService.IO_HTML_ICON; +import static org.trellisldp.io.JenaIOService.IO_HTML_TEMPLATE; +import static org.trellisldp.io.JenaIOService.IO_JSONLD_DOMAINS; +import static org.trellisldp.io.JenaIOService.IO_JSONLD_PROFILES; import static org.trellisldp.vocabulary.JSONLD.compacted; import static org.trellisldp.vocabulary.JSONLD.expanded; import static org.trellisldp.vocabulary.JSONLD.flattened; @@ -75,9 +78,9 @@ import org.junit.platform.runner.JUnitPlatform; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.trellisldp.api.CacheService; import org.trellisldp.api.IOService; import org.trellisldp.api.NamespaceService; +import org.trellisldp.api.ProfileCacheService; import org.trellisldp.api.RuntimeTrellisException; /** @@ -99,7 +102,7 @@ public class IOServiceTest { private OutputStream mockOutputStream; @Mock - private CacheService mockCache; + private ProfileCacheService mockCache; @Mock private RDFSyntax mockSyntax; @@ -113,16 +116,21 @@ public void setUp() { namespaces.put("rdf", RDF.uri); final Map properties = new HashMap<>(); - properties.put("icon", "//www.trellisldp.org/assets/img/trellis.png"); - properties.put("css", "//www.trellisldp.org/assets/css/trellis.css"); + properties.put(IO_HTML_ICON, "//www.trellisldp.org/assets/img/trellis.png"); + properties.put(IO_HTML_CSS, "//www.trellisldp.org/assets/css/trellis.css"); + properties.put(IO_JSONLD_PROFILES, "http://www.w3.org/ns/anno.jsonld"); + properties.put(IO_JSONLD_DOMAINS, "http://www.trellisldp.org/ns/"); - service = new JenaIOService(mockNamespaceService, properties, - singleton("http://www.w3.org/ns/anno.jsonld"), singleton("http://www.trellisldp.org/ns/"), mockCache); + service = new JenaIOService(mockNamespaceService, mockCache, properties); - service2 = new JenaIOService(mockNamespaceService, properties, emptySet(), - singleton("http://www.w3.org/ns/"), mockCache); + final Map properties2 = new HashMap<>(); + properties.forEach(properties2::put); + properties2.remove(IO_JSONLD_PROFILES); + properties2.put(IO_JSONLD_DOMAINS, "http://www.w3.org/ns/"); + service2 = new JenaIOService(mockNamespaceService, mockCache, properties2); - service3 = new JenaIOService(mockNamespaceService); + final Map properties3 = new HashMap<>(); + service3 = new JenaIOService(mockNamespaceService, mockCache, properties3); when(mockNamespaceService.getNamespaces()).thenReturn(namespaces); when(mockNamespaceService.getPrefix(eq("http://purl.org/dc/terms/"))).thenReturn(Optional.of("dc")); @@ -215,12 +223,12 @@ public void testJsonLdCustomUnrecognizedSerializer() throws UnsupportedEncodingE @Test public void testJsonLdNullCache() throws UnsupportedEncodingException { final Map properties = new HashMap<>(); - properties.put("icon", "//www.trellisldp.org/assets/img/trellis.png"); - properties.put("css", "//www.trellisldp.org/assets/css/trellis.css"); + properties.put(IO_HTML_ICON, "//www.trellisldp.org/assets/img/trellis.png"); + properties.put(IO_HTML_CSS, "//www.trellisldp.org/assets/css/trellis.css"); + properties.put(IO_JSONLD_DOMAINS, "http://www.w3.org/ns/"); final ByteArrayOutputStream out = new ByteArrayOutputStream(); - final IOService myservice = new JenaIOService(null, properties, emptySet(), - singleton("http://www.w3.org/ns/"), null); + final IOService myservice = new JenaIOService(null, null, properties); myservice.write(getTriples(), out, JSONLD, rdf.createIRI("http://www.w3.org/ns/anno.jsonld")); final String output = out.toString("UTF-8"); assertTrue(output.contains("\"http://purl.org/dc/terms/title\":[{\"@value\":\"A title\"}]")); @@ -363,11 +371,11 @@ public void testHtmlSerializer2() { @Test public void testHtmlSerializer3() { final Map properties = new HashMap<>(); - properties.put("icon", "//www.trellisldp.org/assets/img/trellis.png"); - properties.put("css", "//www.trellisldp.org/assets/css/trellis.css"); - properties.put("template", "/resource-test.mustache"); + properties.put(IO_HTML_ICON, "//www.trellisldp.org/assets/img/trellis.png"); + properties.put(IO_HTML_CSS, "//www.trellisldp.org/assets/css/trellis.css"); + properties.put(IO_HTML_TEMPLATE, "/resource-test.mustache"); - final IOService service4 = new JenaIOService(mockNamespaceService, properties); + final IOService service4 = new JenaIOService(mockNamespaceService, mockCache, properties); final ByteArrayOutputStream out = new ByteArrayOutputStream(); service.write(getComplexTriples(), out, RDFA, rdf.createIRI("http://example.org/")); @@ -384,11 +392,11 @@ public void testHtmlSerializer3() { @Test public void testHtmlSerializer4() throws Exception { final Map properties = new HashMap<>(); - properties.put("icon", "//www.trellisldp.org/assets/img/trellis.png"); - properties.put("css", "//www.trellisldp.org/assets/css/trellis.css"); - properties.put("template", getClass().getResource("/resource-test.mustache").toURI().getPath()); + properties.put(IO_HTML_ICON, "//www.trellisldp.org/assets/img/trellis.png"); + properties.put(IO_HTML_CSS, "//www.trellisldp.org/assets/css/trellis.css"); + properties.put(IO_HTML_TEMPLATE, getClass().getResource("/resource-test.mustache").toURI().getPath()); - final IOService service4 = new JenaIOService(mockNamespaceService, properties); + final IOService service4 = new JenaIOService(mockNamespaceService, mockCache, properties); final ByteArrayOutputStream out = new ByteArrayOutputStream(); service.write(getComplexTriples(), out, RDFA, rdf.createIRI("http://example.org/")); diff --git a/trellis-karaf/src/main/resources/features.xml b/trellis-karaf/src/main/resources/features.xml index dc6f54f26..50e7b624d 100644 --- a/trellis-karaf/src/main/resources/features.xml +++ b/trellis-karaf/src/main/resources/features.xml @@ -42,6 +42,7 @@ mvn:org.apache.commons/commons-collections4/${commonsCollectionsVersion} mvn:org.apache.commons/commons-rdf-api/${commonsRdfVersion} + mvn:org.apache.tamaya/tamaya-api/${tamayaVersion} mvn:commons-codec/commons-codec/${commonsCodecVersion} mvn:org.trellisldp/trellis-file/${project.version} @@ -87,6 +88,7 @@ mvn:javax.json/javax.json-api/${javaxJsonVersion} mvn:javax.ws.rs/javax.ws.rs-api/${jaxrsVersion} mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.javax-inject/${javaxInjectVersion} + mvn:org.apache.tamaya/tamaya-api/${tamayaVersion} mvn:org.apache.aries.spifly/org.apache.aries.spifly.dynamic.bundle/${spiflyVersion} @@ -108,8 +110,9 @@ trellis-api trellis-vocabulary - mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.mustache-compiler/${mustacheVersion} mvn:com.google.guava/guava/${guavaVersion} + mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.mustache-compiler/${mustacheVersion} + mvn:org.apache.tamaya/tamaya-api/${tamayaVersion} mvn:org.trellisldp/trellis-io-jena/${project.version} @@ -122,6 +125,7 @@ mvn:com.fasterxml.jackson.core/jackson-core/${jacksonVersion} mvn:com.fasterxml.jackson.core/jackson-databind/${jacksonVersion} mvn:com.fasterxml.jackson.core/jackson-annotations/${jacksonVersion} + mvn:org.apache.tamaya/tamaya-api/${tamayaVersion} mvn:org.trellisldp/trellis-namespaces/${project.version} @@ -179,6 +183,7 @@ trellis-api mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.kafka-clients/${kafkaVersion} + mvn:org.apache.tamaya/tamaya-api/${tamayaVersion} mvn:org.apache.aries.spifly/org.apache.aries.spifly.dynamic.bundle/${spiflyVersion} mvn:org.trellisldp/trellis-kafka/${project.version} @@ -190,6 +195,7 @@ trellis-api mvn:com.rabbitmq/amqp-client/${rabbitMqVersion} + mvn:org.apache.tamaya/tamaya-api/${tamayaVersion} mvn:org.apache.aries.spifly/org.apache.aries.spifly.dynamic.bundle/${spiflyVersion} mvn:org.trellisldp/trellis-amqp/${project.version} @@ -203,6 +209,7 @@ mvn:javax.jms/javax.jms-api/${jmsApiVersion} mvn:org.apache.aries.spifly/org.apache.aries.spifly.dynamic.bundle/${spiflyVersion} + mvn:org.apache.tamaya/tamaya-api/${tamayaVersion} mvn:org.trellisldp/trellis-jms/${project.version} diff --git a/trellis-namespaces/build.gradle b/trellis-namespaces/build.gradle index e8033a790..a540fbb0a 100644 --- a/trellis-namespaces/build.gradle +++ b/trellis-namespaces/build.gradle @@ -8,11 +8,14 @@ ext { dependencies { api project(':trellis-api') + api group: 'org.apache.servicemix.bundles', name: 'org.apache.servicemix.bundles.javax-inject', version: javaxInjectVersion implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: jacksonVersion implementation group: 'org.slf4j', name: 'slf4j-api', version: slf4jVersion + implementation group: 'org.apache.tamaya', name: 'tamaya-api', version: tamayaVersion testImplementation group: 'ch.qos.logback', name: 'logback-classic', version: logbackVersion + testImplementation group: 'org.apache.tamaya', name: 'tamaya-core', version: tamayaVersion testImplementation group: 'org.apiguardian', name: 'apiguardian-api', version: apiguardianVersion testImplementation group: 'org.junit.platform', name: 'junit-platform-runner', version: junitPlatformVersion testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: junitVersion diff --git a/trellis-namespaces/src/main/java/org/trellisldp/namespaces/NamespacesJsonContext.java b/trellis-namespaces/src/main/java/org/trellisldp/namespaces/NamespacesJsonContext.java index 0900166ab..cb39c8b2c 100644 --- a/trellis-namespaces/src/main/java/org/trellisldp/namespaces/NamespacesJsonContext.java +++ b/trellis-namespaces/src/main/java/org/trellisldp/namespaces/NamespacesJsonContext.java @@ -29,6 +29,9 @@ import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; +import javax.inject.Inject; + +import org.apache.tamaya.ConfigurationProvider; import org.slf4j.Logger; import org.trellisldp.api.NamespaceService; @@ -39,6 +42,8 @@ */ public class NamespacesJsonContext implements NamespaceService { + public static final String NAMESPACES_PATH = "trellis.namespaces.path"; + private static final Logger LOGGER = getLogger(NamespacesJsonContext.class); private static final ObjectMapper MAPPER = new ObjectMapper(); @@ -48,13 +53,21 @@ public class NamespacesJsonContext implements NamespaceService { /** * Create a JSON-based Namespace service. - * @param filePath the file path */ - public NamespacesJsonContext(final String filePath) { - requireNonNull(filePath, "The filePath may not be null!"); + @Inject + public NamespacesJsonContext() { + this(ConfigurationProvider.getConfiguration().get(NAMESPACES_PATH)); + } + + /** + * Create a JSON-based Namespace service. + * @param path the path to the JSON file + */ + public NamespacesJsonContext(final String path) { + requireNonNull(path, "Namespace path may not be empty!"); - this.filePath = filePath; - this.data = read(filePath); + this.filePath = path; + this.data = read(path); init(); } diff --git a/trellis-namespaces/src/main/resources/META-INF/beans.xml b/trellis-namespaces/src/main/resources/META-INF/beans.xml new file mode 100644 index 000000000..1e341328e --- /dev/null +++ b/trellis-namespaces/src/main/resources/META-INF/beans.xml @@ -0,0 +1,7 @@ + + + diff --git a/trellis-namespaces/src/test/java/org/trellisldp/namespaces/NamespacesJsonContextTest.java b/trellis-namespaces/src/test/java/org/trellisldp/namespaces/NamespacesJsonContextTest.java index ea02e6cd9..afb840849 100644 --- a/trellis-namespaces/src/test/java/org/trellisldp/namespaces/NamespacesJsonContextTest.java +++ b/trellis-namespaces/src/test/java/org/trellisldp/namespaces/NamespacesJsonContextTest.java @@ -50,32 +50,44 @@ public static void cleanUp() throws IOException { @Test public void testReadFromJson() { final URL res = NamespacesJsonContext.class.getResource(nsDoc); - final NamespacesJsonContext svc = new NamespacesJsonContext(res.getPath()); + System.getProperties().setProperty(NamespacesJsonContext.NAMESPACES_PATH, res.getPath()); + final NamespacesJsonContext svc = new NamespacesJsonContext(); assertEquals(2, svc.getNamespaces().size()); assertEquals(LDP, svc.getNamespace("ldp").get()); assertEquals("ldp", svc.getPrefix(LDP).get()); + System.getProperties().remove(NamespacesJsonContext.NAMESPACES_PATH); } @Test public void testReadError() { final URL res = NamespacesJsonContext.class.getResource("/thisIsNot.json"); - assertThrows(UncheckedIOException.class, () -> new NamespacesJsonContext(res.getPath())); + System.getProperties().setProperty(NamespacesJsonContext.NAMESPACES_PATH, res.getPath()); + + assertThrows(UncheckedIOException.class, () -> new NamespacesJsonContext()); + System.getProperties().remove(NamespacesJsonContext.NAMESPACES_PATH); } @Test public void testWriteError() throws Exception { final URL res = NamespacesJsonContext.class.getResource("/readonly.json"); - final NamespacesJsonContext svc = new NamespacesJsonContext(res.getPath()); + + System.getProperties().setProperty(NamespacesJsonContext.NAMESPACES_PATH, res.getPath()); + + final NamespacesJsonContext svc = new NamespacesJsonContext(); final File file = new File(res.toURI()); assumeTrue(file.setWritable(false)); assertThrows(UncheckedIOException.class, () -> svc.setPrefix("ex", "http://example.com/")); + System.getProperties().remove(NamespacesJsonContext.NAMESPACES_PATH); } @Test public void testWriteToJson() { final File file = new File(NamespacesJsonContext.class.getResource(nsDoc).getPath()); final String filename = file.getParent() + "/" + randomFilename(); - final NamespacesJsonContext svc1 = new NamespacesJsonContext(filename); + + System.getProperties().setProperty(NamespacesJsonContext.NAMESPACES_PATH, filename); + + final NamespacesJsonContext svc1 = new NamespacesJsonContext(); assertEquals(15, svc1.getNamespaces().size()); assertFalse(svc1.getNamespace("jsonld").isPresent()); assertFalse(svc1.getPrefix(JSONLD).isPresent()); @@ -84,10 +96,11 @@ public void testWriteToJson() { assertEquals(JSONLD, svc1.getNamespace("jsonld").get()); assertEquals("jsonld", svc1.getPrefix(JSONLD).get()); - final NamespacesJsonContext svc2 = new NamespacesJsonContext(filename); + final NamespacesJsonContext svc2 = new NamespacesJsonContext(); assertEquals(16, svc2.getNamespaces().size()); assertEquals(JSONLD, svc2.getNamespace("jsonld").get()); assertFalse(svc2.setPrefix("jsonld", JSONLD)); + System.getProperties().remove(NamespacesJsonContext.NAMESPACES_PATH); } private static String randomFilename() { diff --git a/trellis-triplestore/build.gradle b/trellis-triplestore/build.gradle index e304e390c..2697407b2 100644 --- a/trellis-triplestore/build.gradle +++ b/trellis-triplestore/build.gradle @@ -8,6 +8,7 @@ ext { dependencies { api group: 'org.apache.commons', name: 'commons-rdf-api', version: commonsRdfVersion + api group: 'org.apache.servicemix.bundles', name: 'org.apache.servicemix.bundles.javax-inject', version: javaxInjectVersion api project(':trellis-api') implementation group: 'org.apache.commons', name: 'commons-rdf-jena', version: commonsRdfVersion diff --git a/trellis-triplestore/src/main/java/org/trellisldp/triplestore/TriplestoreResourceService.java b/trellis-triplestore/src/main/java/org/trellisldp/triplestore/TriplestoreResourceService.java index 86c2dddb7..eaee03d7e 100644 --- a/trellis-triplestore/src/main/java/org/trellisldp/triplestore/TriplestoreResourceService.java +++ b/trellis-triplestore/src/main/java/org/trellisldp/triplestore/TriplestoreResourceService.java @@ -51,6 +51,8 @@ import java.util.function.Supplier; import java.util.stream.Stream; +import javax.inject.Inject; + import org.apache.commons.lang3.Range; import org.apache.commons.rdf.api.Dataset; import org.apache.commons.rdf.api.IRI; @@ -120,6 +122,7 @@ public class TriplestoreResourceService extends DefaultAuditService implements R * @param mementoService a service for memento resources * @param eventService an event service */ + @Inject public TriplestoreResourceService(final RDFConnection rdfConnection, final IdentifierService identifierService, final MementoService mementoService, final EventService eventService) { requireNonNull(rdfConnection, "RDFConnection may not be null!"); diff --git a/trellis-triplestore/src/main/resources/META-INF/beans.xml b/trellis-triplestore/src/main/resources/META-INF/beans.xml new file mode 100644 index 000000000..1e341328e --- /dev/null +++ b/trellis-triplestore/src/main/resources/META-INF/beans.xml @@ -0,0 +1,7 @@ + + + diff --git a/trellis-webac/build.gradle b/trellis-webac/build.gradle index 46fdc2135..1152ded8e 100644 --- a/trellis-webac/build.gradle +++ b/trellis-webac/build.gradle @@ -9,6 +9,7 @@ ext { dependencies { api group: 'org.apache.commons', name: 'commons-rdf-api', version: commonsRdfVersion + api group: 'org.apache.servicemix.bundles', name: 'org.apache.servicemix.bundles.javax-inject', version: javaxInjectVersion api project(':trellis-api') implementation group: 'org.slf4j', name: 'slf4j-api', version: slf4jVersion diff --git a/trellis-webac/src/main/java/org/trellisldp/webac/WebACService.java b/trellis-webac/src/main/java/org/trellisldp/webac/WebACService.java index c3f04d22f..86a59b81c 100644 --- a/trellis-webac/src/main/java/org/trellisldp/webac/WebACService.java +++ b/trellis-webac/src/main/java/org/trellisldp/webac/WebACService.java @@ -30,6 +30,8 @@ import java.util.function.Predicate; import java.util.stream.Stream; +import javax.inject.Inject; + import org.apache.commons.rdf.api.Graph; import org.apache.commons.rdf.api.IRI; import org.apache.commons.rdf.api.RDF; @@ -37,7 +39,7 @@ import org.apache.commons.rdf.api.Triple; import org.slf4j.Logger; import org.trellisldp.api.AccessControlService; -import org.trellisldp.api.CacheService; +import org.trellisldp.api.AuthorizationCacheService; import org.trellisldp.api.Resource; import org.trellisldp.api.ResourceService; import org.trellisldp.api.RuntimeTrellisException; @@ -70,7 +72,7 @@ public class WebACService implements AccessControlService { } private final ResourceService resourceService; - private final CacheService> cache; + private final AuthorizationCacheService cache; /** * Create a WebAC-based authorization service. @@ -87,7 +89,8 @@ public WebACService(final ResourceService resourceService) { * @param resourceService the resource service * @param cache a cache (may be null if caching is not desired) */ - public WebACService(final ResourceService resourceService, final CacheService> cache) { + @Inject + public WebACService(final ResourceService resourceService, final AuthorizationCacheService cache) { requireNonNull(resourceService, "A non-null ResourceService must be provided!"); this.resourceService = resourceService; this.cache = cache; diff --git a/trellis-webac/src/main/resources/META-INF/beans.xml b/trellis-webac/src/main/resources/META-INF/beans.xml new file mode 100644 index 000000000..1e341328e --- /dev/null +++ b/trellis-webac/src/main/resources/META-INF/beans.xml @@ -0,0 +1,7 @@ + + + diff --git a/trellis-webac/src/test/java/org/trellisldp/webac/WebACServiceTest.java b/trellis-webac/src/test/java/org/trellisldp/webac/WebACServiceTest.java index 252a52a40..10b71674e 100644 --- a/trellis-webac/src/test/java/org/trellisldp/webac/WebACServiceTest.java +++ b/trellis-webac/src/test/java/org/trellisldp/webac/WebACServiceTest.java @@ -25,7 +25,6 @@ import static org.trellisldp.vocabulary.RDF.type; import java.util.Optional; -import java.util.Set; import java.util.function.Function; import java.util.stream.Stream; @@ -40,7 +39,7 @@ import org.mockito.Mockito; import org.mockito.stubbing.OngoingStubbing; import org.trellisldp.api.AccessControlService; -import org.trellisldp.api.CacheService; +import org.trellisldp.api.AuthorizationCacheService; import org.trellisldp.api.Resource; import org.trellisldp.api.ResourceService; import org.trellisldp.api.Session; @@ -65,7 +64,7 @@ public class WebACServiceTest { private Session mockSession; @Mock - private CacheService> mockCache; + private AuthorizationCacheService mockCache; @Mock private Resource mockResource, mockChildResource, mockParentResource, mockRootResource, From bbf358069e2800b3164ea9f66eae9d03769c45cf Mon Sep 17 00:00:00 2001 From: Aaron Coburn Date: Wed, 7 Mar 2018 09:20:28 -0500 Subject: [PATCH 2/2] Use named qualifiers for CDI injection --- .../api/AuthorizationCacheService.java | 23 -------------- .../trellisldp/api/ProfileCacheService.java | 19 ------------ .../trellisldp/app/TrellisApplication.java | 4 +-- .../app/TrellisAuthorizationCache.java | 31 ------------------- .../trellisldp/app/TrellisProfileCache.java | 28 ----------------- .../java/org/trellisldp/app/TrellisUtils.java | 6 ++-- .../java/org/trellisldp/io/JenaIOService.java | 10 +++--- .../java/org/trellisldp/io/IOServiceTest.java | 4 +-- .../org/trellisldp/webac/WebACService.java | 8 +++-- .../trellisldp/webac/WebACServiceTest.java | 5 +-- 10 files changed, 21 insertions(+), 117 deletions(-) delete mode 100644 trellis-api/src/main/java/org/trellisldp/api/AuthorizationCacheService.java delete mode 100644 trellis-api/src/main/java/org/trellisldp/api/ProfileCacheService.java delete mode 100644 trellis-app/src/main/java/org/trellisldp/app/TrellisAuthorizationCache.java delete mode 100644 trellis-app/src/main/java/org/trellisldp/app/TrellisProfileCache.java diff --git a/trellis-api/src/main/java/org/trellisldp/api/AuthorizationCacheService.java b/trellis-api/src/main/java/org/trellisldp/api/AuthorizationCacheService.java deleted file mode 100644 index fa5aca5b7..000000000 --- a/trellis-api/src/main/java/org/trellisldp/api/AuthorizationCacheService.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * 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.trellisldp.api; - -import java.util.Set; - -import org.apache.commons.rdf.api.IRI; - -/** - * A cache type for use with authorization data. - */ -public interface AuthorizationCacheService extends CacheService> { } diff --git a/trellis-api/src/main/java/org/trellisldp/api/ProfileCacheService.java b/trellis-api/src/main/java/org/trellisldp/api/ProfileCacheService.java deleted file mode 100644 index 9cb5456ff..000000000 --- a/trellis-api/src/main/java/org/trellisldp/api/ProfileCacheService.java +++ /dev/null @@ -1,19 +0,0 @@ -/* - * 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.trellisldp.api; - -/** - * A cache type for use with JSON-LD profiles. - */ -public interface ProfileCacheService extends CacheService { } diff --git a/trellis-app/src/main/java/org/trellisldp/app/TrellisApplication.java b/trellis-app/src/main/java/org/trellisldp/app/TrellisApplication.java index 88d6ba052..d15377a39 100644 --- a/trellis-app/src/main/java/org/trellisldp/app/TrellisApplication.java +++ b/trellis-app/src/main/java/org/trellisldp/app/TrellisApplication.java @@ -30,12 +30,12 @@ import org.apache.jena.rdfconnection.RDFConnection; import org.trellisldp.agent.SimpleAgent; import org.trellisldp.api.BinaryService; +import org.trellisldp.api.CacheService; import org.trellisldp.api.EventService; import org.trellisldp.api.IOService; import org.trellisldp.api.IdentifierService; import org.trellisldp.api.MementoService; import org.trellisldp.api.NamespaceService; -import org.trellisldp.api.ProfileCacheService; import org.trellisldp.app.config.TrellisConfiguration; import org.trellisldp.app.health.RDFConnectionHealthCheck; import org.trellisldp.file.FileBinaryService; @@ -96,7 +96,7 @@ public void run(final TrellisConfiguration config, config.getBinaryHierarchyLevels(), config.getBinaryHierarchyLength()); // IO Service - final ProfileCacheService profileCache = new TrellisProfileCache(newBuilder() + final CacheService profileCache = new TrellisCache<>(newBuilder() .maximumSize(config.getJsonld().getCacheSize()) .expireAfterAccess(config.getJsonld().getCacheExpireHours(), HOURS).build()); final IOService ioService = new JenaIOService(namespaceService, profileCache, diff --git a/trellis-app/src/main/java/org/trellisldp/app/TrellisAuthorizationCache.java b/trellis-app/src/main/java/org/trellisldp/app/TrellisAuthorizationCache.java deleted file mode 100644 index 90b758ef3..000000000 --- a/trellis-app/src/main/java/org/trellisldp/app/TrellisAuthorizationCache.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * 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.trellisldp.app; - -import com.google.common.cache.Cache; - -import java.util.Set; - -import org.apache.commons.rdf.api.IRI; -import org.trellisldp.api.AuthorizationCacheService; - -/** - * A cache for Authorization data. - */ -class TrellisAuthorizationCache extends TrellisCache> implements AuthorizationCacheService { - - public TrellisAuthorizationCache(final Cache> cache) { - super(cache); - } -} diff --git a/trellis-app/src/main/java/org/trellisldp/app/TrellisProfileCache.java b/trellis-app/src/main/java/org/trellisldp/app/TrellisProfileCache.java deleted file mode 100644 index 02070853a..000000000 --- a/trellis-app/src/main/java/org/trellisldp/app/TrellisProfileCache.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * 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.trellisldp.app; - -import com.google.common.cache.Cache; - -import org.trellisldp.api.ProfileCacheService; - -/** - * A cache for JSON-LD Profiles. - */ -class TrellisProfileCache extends TrellisCache implements ProfileCacheService { - - public TrellisProfileCache(final Cache cache) { - super(cache); - } -} diff --git a/trellis-app/src/main/java/org/trellisldp/app/TrellisUtils.java b/trellis-app/src/main/java/org/trellisldp/app/TrellisUtils.java index 270aa2530..b1bb0495d 100644 --- a/trellis-app/src/main/java/org/trellisldp/app/TrellisUtils.java +++ b/trellis-app/src/main/java/org/trellisldp/app/TrellisUtils.java @@ -66,7 +66,7 @@ import org.apache.kafka.clients.producer.KafkaProducer; import org.slf4j.Logger; import org.trellisldp.amqp.AmqpPublisher; -import org.trellisldp.api.AuthorizationCacheService; +import org.trellisldp.api.CacheService; import org.trellisldp.api.EventService; import org.trellisldp.api.NoopEventService; import org.trellisldp.app.auth.AnonymousAuthFilter; @@ -137,12 +137,12 @@ public static Optional> getAuthFilters(final TrellisConfigurati return of(filters); } - public static Optional getWebacConfiguration(final TrellisConfiguration config) { + public static Optional>> getWebacConfiguration(final TrellisConfiguration config) { if (config.getAuth().getWebac().getEnabled()) { final Cache> authCache = newBuilder().maximumSize(config.getAuth().getWebac() .getCacheSize()).expireAfterWrite(config.getAuth().getWebac() .getCacheExpireSeconds(), SECONDS).build(); - return of(new TrellisAuthorizationCache(authCache)); + return of(new TrellisCache<>(authCache)); } return empty(); } diff --git a/trellis-io-jena/src/main/java/org/trellisldp/io/JenaIOService.java b/trellis-io-jena/src/main/java/org/trellisldp/io/JenaIOService.java index d8db82837..5cf23e687 100644 --- a/trellis-io-jena/src/main/java/org/trellisldp/io/JenaIOService.java +++ b/trellis-io-jena/src/main/java/org/trellisldp/io/JenaIOService.java @@ -39,6 +39,7 @@ import java.util.stream.Stream; import javax.inject.Inject; +import javax.inject.Named; import org.apache.commons.io.IOUtils; import org.apache.commons.rdf.api.Graph; @@ -66,9 +67,9 @@ import org.apache.jena.update.UpdateException; import org.apache.tamaya.ConfigurationProvider; import org.slf4j.Logger; +import org.trellisldp.api.CacheService; import org.trellisldp.api.IOService; import org.trellisldp.api.NamespaceService; -import org.trellisldp.api.ProfileCacheService; import org.trellisldp.api.RuntimeTrellisException; import org.trellisldp.io.impl.HtmlSerializer; @@ -91,7 +92,7 @@ public class JenaIOService implements IOService { private static final JenaRDF rdf = new JenaRDF(); private final NamespaceService nsService; - private final ProfileCacheService cache; + private final CacheService cache; private final HtmlSerializer htmlSerializer; private final Set whitelist; private final Set whitelistDomains; @@ -112,7 +113,8 @@ public JenaIOService(final NamespaceService namespaceService) { * @param cache a cache for custom JSON-LD profile resolution */ @Inject - public JenaIOService(final NamespaceService namespaceService, final ProfileCacheService cache) { + public JenaIOService(final NamespaceService namespaceService, + @Named("TrellisProfileCache") final CacheService cache) { this(namespaceService, cache, ConfigurationProvider.getConfiguration().getProperties()); } @@ -123,7 +125,7 @@ public JenaIOService(final NamespaceService namespaceService, final ProfileCache * @param cache a cache for custom JSON-LD profile resolution * @param properties additional properties for the serialization service */ - public JenaIOService(final NamespaceService namespaceService, final ProfileCacheService cache, + public JenaIOService(final NamespaceService namespaceService, final CacheService cache, final Map properties) { this.nsService = namespaceService; this.cache = cache; diff --git a/trellis-io-jena/src/test/java/org/trellisldp/io/IOServiceTest.java b/trellis-io-jena/src/test/java/org/trellisldp/io/IOServiceTest.java index d5cad15b6..62e151528 100644 --- a/trellis-io-jena/src/test/java/org/trellisldp/io/IOServiceTest.java +++ b/trellis-io-jena/src/test/java/org/trellisldp/io/IOServiceTest.java @@ -78,9 +78,9 @@ import org.junit.platform.runner.JUnitPlatform; import org.junit.runner.RunWith; import org.mockito.Mock; +import org.trellisldp.api.CacheService; import org.trellisldp.api.IOService; import org.trellisldp.api.NamespaceService; -import org.trellisldp.api.ProfileCacheService; import org.trellisldp.api.RuntimeTrellisException; /** @@ -102,7 +102,7 @@ public class IOServiceTest { private OutputStream mockOutputStream; @Mock - private ProfileCacheService mockCache; + private CacheService mockCache; @Mock private RDFSyntax mockSyntax; diff --git a/trellis-webac/src/main/java/org/trellisldp/webac/WebACService.java b/trellis-webac/src/main/java/org/trellisldp/webac/WebACService.java index 86a59b81c..47af7af5d 100644 --- a/trellis-webac/src/main/java/org/trellisldp/webac/WebACService.java +++ b/trellis-webac/src/main/java/org/trellisldp/webac/WebACService.java @@ -31,6 +31,7 @@ import java.util.stream.Stream; import javax.inject.Inject; +import javax.inject.Named; import org.apache.commons.rdf.api.Graph; import org.apache.commons.rdf.api.IRI; @@ -39,7 +40,7 @@ import org.apache.commons.rdf.api.Triple; import org.slf4j.Logger; import org.trellisldp.api.AccessControlService; -import org.trellisldp.api.AuthorizationCacheService; +import org.trellisldp.api.CacheService; import org.trellisldp.api.Resource; import org.trellisldp.api.ResourceService; import org.trellisldp.api.RuntimeTrellisException; @@ -72,7 +73,7 @@ public class WebACService implements AccessControlService { } private final ResourceService resourceService; - private final AuthorizationCacheService cache; + private final CacheService> cache; /** * Create a WebAC-based authorization service. @@ -90,7 +91,8 @@ public WebACService(final ResourceService resourceService) { * @param cache a cache (may be null if caching is not desired) */ @Inject - public WebACService(final ResourceService resourceService, final AuthorizationCacheService cache) { + public WebACService(final ResourceService resourceService, + @Named("TrellisAuthorizationCache") final CacheService> cache) { requireNonNull(resourceService, "A non-null ResourceService must be provided!"); this.resourceService = resourceService; this.cache = cache; diff --git a/trellis-webac/src/test/java/org/trellisldp/webac/WebACServiceTest.java b/trellis-webac/src/test/java/org/trellisldp/webac/WebACServiceTest.java index 10b71674e..252a52a40 100644 --- a/trellis-webac/src/test/java/org/trellisldp/webac/WebACServiceTest.java +++ b/trellis-webac/src/test/java/org/trellisldp/webac/WebACServiceTest.java @@ -25,6 +25,7 @@ import static org.trellisldp.vocabulary.RDF.type; import java.util.Optional; +import java.util.Set; import java.util.function.Function; import java.util.stream.Stream; @@ -39,7 +40,7 @@ import org.mockito.Mockito; import org.mockito.stubbing.OngoingStubbing; import org.trellisldp.api.AccessControlService; -import org.trellisldp.api.AuthorizationCacheService; +import org.trellisldp.api.CacheService; import org.trellisldp.api.Resource; import org.trellisldp.api.ResourceService; import org.trellisldp.api.Session; @@ -64,7 +65,7 @@ public class WebACServiceTest { private Session mockSession; @Mock - private AuthorizationCacheService mockCache; + private CacheService> mockCache; @Mock private Resource mockResource, mockChildResource, mockParentResource, mockRootResource,