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-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..d15377a39 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; @@ -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() .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/TrellisUtils.java b/trellis-app/src/main/java/org/trellisldp/app/TrellisUtils.java index 5fd0ef45d..b1bb0495d 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; @@ -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; } @@ -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..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 @@ -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,13 @@ 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 javax.inject.Named; + import org.apache.commons.io.IOUtils; import org.apache.commons.rdf.api.Graph; import org.apache.commons.rdf.api.IRI; @@ -67,6 +65,7 @@ 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; @@ -81,21 +80,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 CacheService cache; private final HtmlSerializer htmlSerializer; + private final Set whitelist; + private final Set whitelistDomains; /** * Create a serialization service. @@ -103,36 +103,39 @@ 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, + @Named("TrellisProfileCache") final CacheService 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 CacheService 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..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 @@ -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; @@ -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..47af7af5d 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,9 @@ import java.util.function.Predicate; 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; import org.apache.commons.rdf.api.RDF; @@ -87,7 +90,9 @@ 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, + @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/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 @@ + + +