├── .gitattributes ├── NOTICE ├── fcrepo-audit-triplestore ├── src │ ├── test │ │ ├── resources │ │ │ ├── passwd │ │ │ ├── logback-test.xml │ │ │ ├── event_delete_binary.json │ │ │ ├── event_audit_update.json │ │ │ ├── event_delete_resource.json │ │ │ └── event_audit_resource.json │ │ └── java │ │ │ └── org │ │ │ └── fcrepo │ │ │ └── camel │ │ │ └── audit │ │ │ └── triplestore │ │ │ ├── RouteDisabledTest.java │ │ │ ├── integration │ │ │ └── RouteAuthTestIT.java │ │ │ └── RouteTest.java │ └── main │ │ └── java │ │ └── org │ │ └── fcrepo │ │ └── camel │ │ └── audit │ │ └── triplestore │ │ ├── AuditHeaders.java │ │ ├── EventRouter.java │ │ └── FcrepoAuditTriplestoreConfig.java └── pom.xml ├── fcrepo-indexing-triplestore └── src │ ├── test │ ├── resources │ │ ├── passwd │ │ ├── jetty-users.properties │ │ ├── indexable.ttl │ │ ├── container.nt │ │ ├── container.rdf │ │ ├── logback-test.xml │ │ ├── indexable.rdf │ │ ├── event_delete_resource.json │ │ └── event.json │ └── java │ │ └── org │ │ └── fcrepo │ │ └── camel │ │ └── indexing │ │ └── triplestore │ │ └── integration │ │ └── RouteDeleteIT.java │ └── main │ └── java │ └── org │ └── fcrepo │ └── camel │ └── indexing │ └── triplestore │ ├── FcrepoTripleStoreIndexingConfig.java │ └── TriplestoreRouter.java ├── .dockerignore ├── docker └── entrypoint.sh ├── fcrepo-camel-toolbox-app ├── src │ └── main │ │ ├── resources │ │ ├── app.properties │ │ └── logback.xml │ │ └── java │ │ └── org │ │ └── fcrepo │ │ └── camel │ │ └── toolbox │ │ └── app │ │ ├── AppConfig.java │ │ ├── AppVersionProvider.java │ │ └── Driver.java └── pom.xml ├── fcrepo-fixity └── src │ ├── test │ ├── resources │ │ ├── binary.txt │ │ ├── jetty-users.properties │ │ ├── container.rdf │ │ ├── logback-test.xml │ │ ├── fixity.rdf │ │ └── fixityFailure.rdf │ └── java │ │ └── org │ │ └── fcrepo │ │ └── camel │ │ └── fixity │ │ ├── RouteDisabledTest.java │ │ ├── RouteTest.java │ │ └── integration │ │ └── RouteIT.java │ └── main │ └── java │ └── org │ └── fcrepo │ └── camel │ └── fixity │ ├── FixityRouter.java │ └── FcrepoFixityConfig.java ├── fcrepo-indexing-solr ├── src │ ├── main │ │ ├── resources │ │ │ └── org │ │ │ │ └── fcrepo │ │ │ │ └── camel │ │ │ │ └── indexing │ │ │ │ └── solr │ │ │ │ ├── delete.mustache │ │ │ │ └── default_transform.xsl │ │ └── java │ │ │ └── org │ │ │ └── fcrepo │ │ │ └── camel │ │ │ └── indexing │ │ │ └── solr │ │ │ └── FcrepoSolrIndexingConfig.java │ └── test │ │ └── resources │ │ ├── indexable.ttl │ │ ├── container.rdf │ │ ├── logback-test.xml │ │ ├── indexable.rdf │ │ └── event_delete_resource.json └── pom.xml ├── fcrepo-reindexing └── src │ ├── test │ ├── resources │ │ ├── jetty-users.properties │ │ ├── logback-test.xml │ │ ├── indexable.rdf │ │ └── indexable.nt │ └── java │ │ └── org │ │ └── fcrepo │ │ └── camel │ │ └── reindexing │ │ ├── integration │ │ └── RouteIT.java │ │ └── RestProcessorTest.java │ └── main │ ├── java │ └── org │ │ └── fcrepo │ │ └── camel │ │ └── reindexing │ │ ├── ReindexingHeaders.java │ │ ├── FcrepoReindexingConfig.java │ │ └── RestProcessor.java │ └── resources │ └── org │ └── fcrepo │ └── camel │ └── reindexing │ └── usage.mustache ├── fcrepo-service-camel └── src │ ├── test │ ├── resources │ │ ├── jetty-users.properties │ │ ├── logback-test.xml │ │ └── OSGI-INF │ │ │ └── blueprint │ │ │ └── blueprint-test.xml │ └── java │ │ └── org │ │ └── fcrepo │ │ └── camel │ │ └── service │ │ └── RouteIT.java │ └── main │ ├── cfg │ └── org.fcrepo.camel.service.cfg │ └── java │ └── org │ └── fcrepo │ └── camel │ └── service │ └── FcrepoCamelConfig.java ├── fcrepo-service-activemq └── src │ ├── test │ ├── resources │ │ ├── jetty-users.properties │ │ ├── logback-test.xml │ │ └── OSGI-INF │ │ │ └── blueprint │ │ │ └── blueprint-test.xml │ └── java │ │ └── org │ │ └── fcrepo │ │ └── camel │ │ └── service │ │ └── activemq │ │ └── RouteIT.java │ └── main │ ├── cfg │ └── org.fcrepo.camel.service.activemq.cfg │ ├── java │ └── org │ │ └── fcrepo │ │ └── camel │ │ └── activemq │ │ └── ActiveMQConfig.java │ └── resources │ └── OSGI-INF │ └── blueprint │ └── blueprint.xml ├── fcrepo-http-forwarding ├── src │ ├── main │ │ ├── resources │ │ │ └── org │ │ │ │ └── fcrepo │ │ │ │ └── camel │ │ │ │ └── httpforwarding │ │ │ │ └── httpMessage.mustache │ │ └── java │ │ │ └── org │ │ │ └── fcrepo │ │ │ └── camel │ │ │ └── httpforwarding │ │ │ ├── FcrepoHttpForwardingConfig.java │ │ │ └── HttpRouter.java │ └── test │ │ └── java │ │ └── org │ │ └── fcrepo │ │ └── camel │ │ └── httpforwarding │ │ ├── integration │ │ ├── TestUtils.java │ │ ├── RouteDeleteIT.java │ │ └── RouteUpdateIT.java │ │ ├── RouteValidationTest.java │ │ └── RouteTest.java └── pom.xml ├── src └── site │ ├── markdown │ └── index.md.vm │ └── site.xml ├── docker-compose ├── camel-toolbox-config │ └── configuration.properties └── docker-compose.yml ├── .gitignore ├── Dockerfile ├── fcrepo-camel-common ├── src │ ├── main │ │ └── java │ │ │ └── org │ │ │ └── fcrepo │ │ │ └── camel │ │ │ └── common │ │ │ ├── config │ │ │ ├── ConditionOnPropertyTrue.java │ │ │ ├── ConditionOnPropertyFalse.java │ │ │ ├── ConditionOnProperty.java │ │ │ └── BasePropsConfig.java │ │ │ ├── helpers │ │ │ └── BasicAuth.java │ │ │ └── processor │ │ │ ├── DockerRunningProcessor.java │ │ │ └── AddBasicAuthProcessor.java │ └── test │ │ └── java │ │ └── org │ │ └── fcrepo │ │ └── camel │ │ └── common │ │ └── TestTracer.java └── pom.xml └── .github ├── PULL_REQUEST_TEMPLATE.md └── workflows └── build.yml /.gitattributes: -------------------------------------------------------------------------------- 1 | * -text 2 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | Fedora Camel Toolbox 2 | Copyright 2013-2021 Lyrasis 3 | -------------------------------------------------------------------------------- /fcrepo-audit-triplestore/src/test/resources/passwd: -------------------------------------------------------------------------------- 1 | admin: password -------------------------------------------------------------------------------- /fcrepo-indexing-triplestore/src/test/resources/passwd: -------------------------------------------------------------------------------- 1 | admin: password -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | .git 2 | .github 3 | .idea 4 | .project 5 | .settings 6 | -------------------------------------------------------------------------------- /docker/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | exec java ${JAVA_OPTIONS} -jar /usr/local/fcrepo-camel-toolbox/driver.jar "$@" 4 | -------------------------------------------------------------------------------- /fcrepo-camel-toolbox-app/src/main/resources/app.properties: -------------------------------------------------------------------------------- 1 | app.version=${project.version} 2 | app.revision=${buildNumber} 3 | -------------------------------------------------------------------------------- /fcrepo-fixity/src/test/resources/binary.txt: -------------------------------------------------------------------------------- 1 | The apparition of these faces in the crowd; 2 | Petals on a wet, black bough. 3 | -------------------------------------------------------------------------------- /fcrepo-fixity/src/test/resources/jetty-users.properties: -------------------------------------------------------------------------------- 1 | testuser: testpass,fedoraUser 2 | testuser2: testpass,fedoraUser 3 | fedoraAdmin: fedoraAdmin,fedoraAdmin 4 | -------------------------------------------------------------------------------- /fcrepo-indexing-solr/src/main/resources/org/fcrepo/camel/indexing/solr/delete.mustache: -------------------------------------------------------------------------------- 1 | { 2 | "delete" : { 3 | "id" : "{{headers.CamelFcrepoUri}}" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /fcrepo-reindexing/src/test/resources/jetty-users.properties: -------------------------------------------------------------------------------- 1 | testuser: testpass,fedoraUser 2 | testuser2: testpass,fedoraUser 3 | fedoraAdmin: fedoraAdmin,fedoraAdmin 4 | -------------------------------------------------------------------------------- /fcrepo-service-camel/src/test/resources/jetty-users.properties: -------------------------------------------------------------------------------- 1 | testuser: testpass,fedoraUser 2 | testuser2: testpass,fedoraUser 3 | fedoraAdmin: fedoraAdmin,fedoraAdmin 4 | -------------------------------------------------------------------------------- /fcrepo-service-activemq/src/test/resources/jetty-users.properties: -------------------------------------------------------------------------------- 1 | testuser: testpass,fedoraUser 2 | testuser2: testpass,fedoraUser 3 | fedoraAdmin: fedoraAdmin,fedoraAdmin 4 | -------------------------------------------------------------------------------- /fcrepo-indexing-triplestore/src/test/resources/jetty-users.properties: -------------------------------------------------------------------------------- 1 | testuser: testpass,fedoraUser 2 | testuser2: testpass,fedoraUser 3 | fedoraAdmin: fedoraAdmin,fedoraAdmin 4 | -------------------------------------------------------------------------------- /fcrepo-http-forwarding/src/main/resources/org/fcrepo/camel/httpforwarding/httpMessage.mustache: -------------------------------------------------------------------------------- 1 | { 2 | "id" : "{{headers.CamelFcrepoUri}}", 3 | "type" : "{{headers.CamelFcrepoEventType}}" 4 | } 5 | -------------------------------------------------------------------------------- /fcrepo-service-camel/src/main/cfg/org.fcrepo.camel.service.cfg: -------------------------------------------------------------------------------- 1 | # The baseUrl for the fedora repository. 2 | fcrepo.baseUrl=http://localhost:8080/fcrepo/rest 3 | 4 | # If authentication is enabled on the Fedora repository, add appropriate values here 5 | fcrepo.authUsername= 6 | fcrepo.authPassword= 7 | fcrepo.authHost= 8 | -------------------------------------------------------------------------------- /fcrepo-service-activemq/src/main/cfg/org.fcrepo.camel.service.activemq.cfg: -------------------------------------------------------------------------------- 1 | # The JMS connection URI, used for connecting to a local or remote ActiveMQ broker. 2 | jms.brokerUrl=tcp://localhost:61616 3 | 4 | # If authentication is enabled on the activemq broker, add appropriate values here 5 | jms.username= 6 | jms.password= 7 | -------------------------------------------------------------------------------- /fcrepo-indexing-solr/src/test/resources/indexable.ttl: -------------------------------------------------------------------------------- 1 | PREFIX ldp: 2 | PREFIX fedora: 3 | PREFIX indexing: 4 | PREFIX dc: 5 | 6 | <> a indexing:Indexable ; 7 | dc:title "Indexable Object" . 8 | -------------------------------------------------------------------------------- /src/site/markdown/index.md.vm: -------------------------------------------------------------------------------- 1 | ${project.description} 2 | 3 | ## About 4 | 5 | This is the automatically generated documentation for Fedora 4 Camel Toolbox. 6 | 7 | You're probably looking for the [javadocs](apidocs/index.html). 8 | 9 | Otherwise, all of the hand-written, community documentation is on the 10 | [wiki](https://wiki.duraspace.org/display/FF/). 11 | 12 | 13 | ## Usage 14 | 15 | -------------------------------------------------------------------------------- /fcrepo-indexing-triplestore/src/test/resources/indexable.ttl: -------------------------------------------------------------------------------- 1 | PREFIX ldp: 2 | PREFIX fedora: 3 | PREFIX indexing: 4 | PREFIX dc: 5 | 6 | <> a indexing:Indexable ; 7 | dc:title "Indexable Object & Value" ; 8 | indexing:hasIndexingTransformation "default" . 9 | -------------------------------------------------------------------------------- /docker-compose/camel-toolbox-config/configuration.properties: -------------------------------------------------------------------------------- 1 | fcrepo.baseUrl=http://fcrepo:8080/fcrepo/rest 2 | fcrepo.authHost=fcrepo 3 | 4 | jms.brokerUrl=tcp://fcrepo:61616 5 | 6 | solr.indexing.enabled=true 7 | solr.baseUrl=http://solr:8983/solr/fcrepo 8 | solr.fcrepo.defaultTransform=org/fcrepo/camel/indexing/solr/default_transform.xsl 9 | 10 | triplestore.indexing.enabled=true 11 | triplestore.baseUrl=http://fuseki:3030/fcrepo 12 | 13 | reindexing.rest.host=0.0.0.0 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | fcrepo4-data/ 3 | ldcache/ 4 | *transaction.log 5 | *~ 6 | 7 | # Eclipse files 8 | **/.settings 9 | **/.classpath 10 | **/.checkstyle 11 | **/.project 12 | 13 | # Mobile Tools for Java (J2ME) 14 | .mtj.tmp/ 15 | 16 | # Package Files # 17 | *.jar 18 | *.war 19 | *.ear 20 | 21 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 22 | hs_err_pid* 23 | 24 | # maven target directories 25 | target/ 26 | 27 | # intellij 28 | .idea/ 29 | *.iml 30 | -------------------------------------------------------------------------------- /fcrepo-fixity/src/test/resources/container.rdf: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM maven:3-eclipse-temurin-11 AS build 2 | 3 | WORKDIR /build 4 | 5 | COPY . ./ 6 | 7 | # Build with maven, if fcrepo-camel-toolbox-app-*-driver.jar does not exist: 8 | RUN [ -e "fcrepo-camel-toolbox-app/target/"fcrepo-camel-toolbox-app-*-driver.jar ] || mvn clean package 9 | 10 | FROM eclipse-temurin:11-jre AS app 11 | 12 | WORKDIR /usr/local/fcrepo-camel-toolbox 13 | 14 | COPY --from=build "/build/fcrepo-camel-toolbox-app/target/fcrepo-camel-toolbox-app-*-driver.jar" ./driver.jar 15 | 16 | COPY docker/entrypoint.sh ./ 17 | RUN chmod a+x ./entrypoint.sh 18 | 19 | ENTRYPOINT ["./entrypoint.sh"] 20 | -------------------------------------------------------------------------------- /fcrepo-service-activemq/src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | %p %d{HH:mm:ss.SSS} \(%c{0}\) %m%n 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /fcrepo-service-camel/src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | %p %d{HH:mm:ss.SSS} \(%c{0}\) %m%n 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /fcrepo-camel-toolbox-app/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | %p %d{HH:mm:ss.SSS} [%thread] \(%c{0}\) %m%n 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /fcrepo-audit-triplestore/src/main/java/org/fcrepo/camel/audit/triplestore/AuditHeaders.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The contents of this file are subject to the license and copyright 3 | * detailed in the LICENSE and NOTICE files at the root of the source 4 | * tree. 5 | */ 6 | package org.fcrepo.camel.audit.triplestore; 7 | 8 | /** 9 | * @author acoburn 10 | */ 11 | public final class AuditHeaders { 12 | 13 | public static final String EVENT_BASE_URI = "CamelAuditEventBaseUri"; 14 | 15 | public static final String EVENT_URI = "CamelAuditEventUri"; 16 | 17 | private AuditHeaders() { 18 | // prevent instantiation 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /fcrepo-indexing-triplestore/src/test/resources/container.nt: -------------------------------------------------------------------------------- 1 | . 2 | . 3 | . 4 | . 5 | "This & That" . 6 | -------------------------------------------------------------------------------- /fcrepo-indexing-solr/src/test/resources/container.rdf: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /fcrepo-indexing-triplestore/src/test/resources/container.rdf: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /fcrepo-camel-toolbox-app/src/main/java/org/fcrepo/camel/toolbox/app/AppConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The contents of this file are subject to the license and copyright 3 | * detailed in the LICENSE and NOTICE files at the root of the source 4 | * tree. 5 | */ 6 | 7 | package org.fcrepo.camel.toolbox.app; 8 | 9 | 10 | import org.apache.camel.spring.javaconfig.CamelConfiguration; 11 | import org.springframework.context.annotation.ComponentScan; 12 | import org.springframework.context.annotation.Configuration; 13 | 14 | /** 15 | * A configuration class for the application 16 | * 17 | * @author dbernstein 18 | */ 19 | @Configuration 20 | @ComponentScan(basePackages = {"org.fcrepo.camel"}) 21 | public class AppConfig extends CamelConfiguration { 22 | 23 | 24 | } 25 | -------------------------------------------------------------------------------- /docker-compose/docker-compose.yml: -------------------------------------------------------------------------------- 1 | services: 2 | fcrepo: 3 | image: fcrepo/fcrepo:6-tomcat9 4 | ports: 5 | - "8080:8080" 6 | environment: 7 | CATALINA_OPTS: "-Dfcrepo.jms.baseUrl=http://fcrepo:8080" 8 | 9 | solr: 10 | image: solr:8 11 | ports: 12 | - "8983:8983" 13 | command: 14 | - solr-precreate 15 | - fcrepo 16 | 17 | fuseki: 18 | image: atomgraph/fuseki 19 | ports: 20 | - "3030:3030" 21 | command: 22 | - --mem 23 | - /fcrepo 24 | 25 | camel-toolbox: 26 | image: fcrepo/fcrepo-camel-toolbox:latest 27 | volumes: 28 | - "./camel-toolbox-config:/config" 29 | ports: 30 | - "9080:9080" 31 | command: 32 | - -c 33 | - "/config/configuration.properties" 34 | -------------------------------------------------------------------------------- /fcrepo-camel-common/src/main/java/org/fcrepo/camel/common/config/ConditionOnPropertyTrue.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The contents of this file are subject to the license and copyright 3 | * detailed in the LICENSE and NOTICE files at the root of the source 4 | * tree. 5 | */ 6 | 7 | package org.fcrepo.camel.common.config; 8 | 9 | /** 10 | * This condition enables a bean/configuration when the specified property is true 11 | * 12 | * Implementations must provide a no-arg constructor. 13 | * 14 | * @author pwinckles 15 | */ 16 | public abstract class ConditionOnPropertyTrue extends org.fcrepo.camel.common.config.ConditionOnProperty { 17 | 18 | public ConditionOnPropertyTrue(final String name, final boolean defaultValue) { 19 | super(name, true, defaultValue, Boolean.class); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /fcrepo-camel-common/src/main/java/org/fcrepo/camel/common/config/ConditionOnPropertyFalse.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The contents of this file are subject to the license and copyright 3 | * detailed in the LICENSE and NOTICE files at the root of the source 4 | * tree. 5 | */ 6 | 7 | package org.fcrepo.camel.common.config; 8 | 9 | /** 10 | * This condition enables a bean/configuration when the specified property is false 11 | * 12 | * Implementations must provide a no-arg constructor. 13 | * 14 | * @author pwinckles 15 | */ 16 | public abstract class ConditionOnPropertyFalse extends org.fcrepo.camel.common.config.ConditionOnProperty { 17 | 18 | public ConditionOnPropertyFalse(final String name, final boolean defaultValue) { 19 | super(name, false, defaultValue, Boolean.class); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /fcrepo-reindexing/src/main/java/org/fcrepo/camel/reindexing/ReindexingHeaders.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The contents of this file are subject to the license and copyright 3 | * detailed in the LICENSE and NOTICE files at the root of the source 4 | * tree. 5 | */ 6 | package org.fcrepo.camel.reindexing; 7 | 8 | /** 9 | * A class defining header values for the indexing routes 10 | * 11 | * @author acoburn 12 | * @since May 22, 2015 13 | */ 14 | public final class ReindexingHeaders { 15 | public static final String REINDEXING_PORT = "CamelReindexingPort"; 16 | public static final String REINDEXING_PREFIX = "CamelReindexingPrefix"; 17 | public static final String REINDEXING_RECIPIENTS = "CamelReindexingRecipients"; 18 | public static final String REINDEXING_HOST = "CamelReindexingHost"; 19 | 20 | private ReindexingHeaders() { 21 | // prevent instantiation 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /fcrepo-fixity/src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | %p %d{HH:mm:ss.SSS} \(%c{0}\) %m%n 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /fcrepo-camel-common/src/main/java/org/fcrepo/camel/common/helpers/BasicAuth.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The contents of this file are subject to the license and copyright 3 | * detailed in the LICENSE and NOTICE files at the root of the source 4 | * tree. 5 | */ 6 | 7 | package org.fcrepo.camel.common.helpers; 8 | 9 | import java.util.Base64; 10 | 11 | /** 12 | * Helper class to generate a Basic Auth Header 13 | * 14 | * @author Thomas Bernhart 15 | * @since 2021-10-11 16 | */ 17 | public final class BasicAuth { 18 | 19 | public static final String BASIC_AUTH_HEADER = "Authorization"; 20 | 21 | private BasicAuth() { 22 | //intentionally left blank 23 | } 24 | public static final String generateBasicAuthHeader(final String username, final String password) { 25 | return "Basic " + Base64.getEncoder() 26 | .encodeToString((username + ":" + password).getBytes()); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /fcrepo-audit-triplestore/src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | %p %d{HH:mm:ss.SSS} \(%c{0}\) %m%n 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /fcrepo-indexing-solr/src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | %p %d{HH:mm:ss.SSS} \(%c{0}\) %m%n 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /fcrepo-service-camel/src/test/resources/OSGI-INF/blueprint/blueprint-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /fcrepo-reindexing/src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | %p %d{HH:mm:ss.SSS} \(%c{0}\) %m%n 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /fcrepo-indexing-triplestore/src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | %p %d{HH:mm:ss.SSS} \(%c{0}\) %m%n 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /fcrepo-indexing-triplestore/src/test/resources/indexable.rdf: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | default 15 | 16 | 17 | -------------------------------------------------------------------------------- /fcrepo-indexing-solr/src/test/resources/indexable.rdf: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /fcrepo-service-activemq/src/test/resources/OSGI-INF/blueprint/blueprint-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /fcrepo-camel-toolbox-app/src/main/java/org/fcrepo/camel/toolbox/app/AppVersionProvider.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The contents of this file are subject to the license and copyright 3 | * detailed in the LICENSE and NOTICE files at the root of the source 4 | * tree. 5 | */ 6 | package org.fcrepo.camel.toolbox.app; 7 | 8 | import picocli.CommandLine; 9 | 10 | import java.util.Properties; 11 | 12 | /** 13 | * @author dbernstein 14 | */ 15 | class AppVersionProvider implements CommandLine.IVersionProvider { 16 | @Override 17 | public String[] getVersion() throws Exception { 18 | try { 19 | final var is = AppVersionProvider.class.getResourceAsStream("/app.properties"); 20 | final var appProps = new Properties(); 21 | appProps.load(is); 22 | return new String[]{appProps.get("app.version") + " r." + appProps.get("app.revision")}; 23 | } catch (final Exception ex) { 24 | ex.printStackTrace(); 25 | throw new RuntimeException("This should never happen"); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /fcrepo-service-camel/src/main/java/org/fcrepo/camel/service/FcrepoCamelConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The contents of this file are subject to the license and copyright 3 | * detailed in the LICENSE and NOTICE files at the root of the source 4 | * tree. 5 | */ 6 | package org.fcrepo.camel.service; 7 | 8 | import org.fcrepo.camel.FcrepoComponent; 9 | import org.fcrepo.camel.common.config.BasePropsConfig; 10 | import org.springframework.context.annotation.Bean; 11 | import org.springframework.context.annotation.Configuration; 12 | 13 | /** 14 | * @author dbernstein 15 | */ 16 | @Configuration 17 | public class FcrepoCamelConfig extends BasePropsConfig { 18 | 19 | @Bean("fcrepo") 20 | public FcrepoComponent fcrepoComponent() { 21 | final var fcrepoComponent = new FcrepoComponent(); 22 | fcrepoComponent.setBaseUrl(getFcrepoBaseUrl()); 23 | fcrepoComponent.setAuthUsername(getFcrepoUsername()); 24 | fcrepoComponent.setAuthPassword(getFcrepoPassword()); 25 | fcrepoComponent.setAuthHost(getFcrepoAuthHost()); 26 | return fcrepoComponent; 27 | } 28 | 29 | } 30 | 31 | -------------------------------------------------------------------------------- /fcrepo-indexing-solr/src/main/resources/org/fcrepo/camel/indexing/solr/default_transform.xsl: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /fcrepo-audit-triplestore/src/test/resources/event_delete_binary.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "urn:uuid:3c834a8f-5638-4412-aa4b-35ea80416a13", 3 | "type" : [ 4 | "http://www.w3.org/ns/prov#Activity" , 5 | "https://www.w3.org/ns/activitystreams#Delete" ], 6 | "name": "delete resource", 7 | "published": "2016-05-19T17:17:42-04:00Z", 8 | "actor": [{ 9 | "type": ["Person"], 10 | "id": "info:fedora/fedoraAdmin" 11 | }, { 12 | "type": ["Application"], 13 | "name": "CLAW client/1.0" 14 | }], 15 | 16 | "object" : { 17 | "id" : "http://localhost/rest/file1" , 18 | "type" : [ 19 | "http://www.w3.org/ns/prov#Entity" , 20 | "http://fedora.info/definitions/v4/repository#Resource" , 21 | "http://fedora.info/definitions/v4/repository#Binary" , 22 | "http://www.w3.org/ns/ldp#NonRDFSource" ], 23 | "isPartOf" : "http://localhost/rest" 24 | }, 25 | 26 | "@context": ["https://www.w3.org/ns/activitystreams", { 27 | "prov": "http://www.w3.org/ns/prov#", 28 | "dcterms": "http://purl.org/dc/terms/", 29 | "type": "@type", 30 | "id": "@id", 31 | "isPartOf": { 32 | "@id": "dcterms:isPartOf", 33 | "@type": "@id" 34 | } 35 | }] 36 | } -------------------------------------------------------------------------------- /fcrepo-audit-triplestore/src/test/resources/event_audit_update.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "urn:uuid:3c834a8f-5638-4412-aa4b-35ea80416a12", 3 | "type" : [ 4 | "http://www.w3.org/ns/prov#Activity" , 5 | "https://www.w3.org/ns/activitystreams#Update" ], 6 | "name": "update resource", 7 | "published": "2016-05-19T17:17:41-04:00Z", 8 | "actor": [{ 9 | "type": ["Person"], 10 | "id": "info:fedora/fedoraAdmin" 11 | }, { 12 | "type": ["Application"], 13 | "name": "CLAW client/1.0" 14 | }], 15 | 16 | "object" : { 17 | "id" : "http://localhost/rest/audit" , 18 | "type" : [ 19 | "http://www.w3.org/ns/prov#Entity" , 20 | "http://fedora.info/definitions/v4/repository#Resource" , 21 | "http://fedora.info/definitions/v4/repository#Container" , 22 | "http://www.w3.org/ns/ldp#RDFSource", 23 | "http://www.w3.org/ns/ldp#BasicContainer" ], 24 | "isPartOf" : "http://localhost/rest" 25 | }, 26 | 27 | "@context": ["https://www.w3.org/ns/activitystreams", { 28 | "prov": "http://www.w3.org/ns/prov#", 29 | "dcterms": "http://purl.org/dc/terms/", 30 | "type": "@type", 31 | "id": "@id", 32 | "isPartOf": { 33 | "@id": "dcterms:isPartOf", 34 | "@type": "@id" 35 | } 36 | }] 37 | } -------------------------------------------------------------------------------- /fcrepo-audit-triplestore/src/test/resources/event_delete_resource.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "urn:uuid:3c834a8f-5638-4412-aa4b-35ea80416a14", 3 | "type" : [ 4 | "http://www.w3.org/ns/prov#Activity" , 5 | "https://www.w3.org/ns/activitystreams#Delete" ], 6 | "name": "delete resource", 7 | "published": "2016-05-19T17:17:43-04:00Z", 8 | "actor": [{ 9 | "type": ["Person"], 10 | "id": "info:fedora/fedoraAdmin" 11 | }, { 12 | "type": ["Application"], 13 | "name": "CLAW client/1.0" 14 | }], 15 | 16 | "object" : { 17 | "id" : "http://localhost/rest/auditions/1234" , 18 | "type" : [ 19 | "http://www.w3.org/ns/prov#Entity" , 20 | "http://fedora.info/definitions/v4/repository#Resource" , 21 | "http://fedora.info/definitions/v4/repository#Container" , 22 | "http://www.w3.org/ns/ldp#RDFSource", 23 | "http://www.w3.org/ns/ldp#BasicContainer" ], 24 | "isPartOf" : "http://localhost/rest" 25 | }, 26 | 27 | "@context": ["https://www.w3.org/ns/activitystreams", { 28 | "prov": "http://www.w3.org/ns/prov#", 29 | "dcterms": "http://purl.org/dc/terms/", 30 | "type": "@type", 31 | "id": "@id", 32 | "isPartOf": { 33 | "@id": "dcterms:isPartOf", 34 | "@type": "@id" 35 | } 36 | }] 37 | } -------------------------------------------------------------------------------- /fcrepo-indexing-triplestore/src/test/resources/event_delete_resource.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "urn:uuid:3c834a8f-5638-4412-aa4b-35ea80416a18", 3 | "type" : [ 4 | "http://www.w3.org/ns/prov#Activity" , 5 | "https://www.w3.org/ns/activitystreams#Delete" ], 6 | "name": "delete resource", 7 | "published": "2016-05-19T17:17:43-04:00Z", 8 | "actor": [{ 9 | "type": ["Person"], 10 | "id": "info:fedora/fedoraAdmin" 11 | }, { 12 | "type": ["Application"], 13 | "name": "CLAW client/1.0" 14 | }], 15 | 16 | "object" : { 17 | "id" : "http://localhost/rest/some/resource" , 18 | "type" : [ 19 | "http://www.w3.org/ns/prov#Entity" , 20 | "http://fedora.info/definitions/v4/repository#Resource" , 21 | "http://fedora.info/definitions/v4/repository#Container" , 22 | "http://www.w3.org/ns/ldp#RDFSource", 23 | "http://www.w3.org/ns/ldp#BasicContainer" ], 24 | "isPartOf" : "http://localhost/rest" 25 | }, 26 | 27 | "@context": ["https://www.w3.org/ns/activitystreams", { 28 | "prov": "http://www.w3.org/ns/prov#", 29 | "dcterms": "http://purl.org/dc/terms/", 30 | "type": "@type", 31 | "id": "@id", 32 | "isPartOf": { 33 | "@id": "dcterms:isPartOf", 34 | "@type": "@id" 35 | } 36 | }] 37 | } -------------------------------------------------------------------------------- /fcrepo-audit-triplestore/src/test/resources/event_audit_resource.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "urn:uuid:3c834a8f-5638-4412-aa4b-35ea80416a11", 3 | "type" : [ 4 | "http://www.w3.org/ns/prov#Activity" , 5 | "https://www.w3.org/ns/activitystreams#Create" ], 6 | "name": "create resource", 7 | "published": "2016-05-19T17:17:40-04:00Z", 8 | "actor": [{ 9 | "type": ["Person"], 10 | "id": "info:fedora/fedoraAdmin" 11 | }, { 12 | "type": ["Application"], 13 | "name": "CLAW client/1.0" 14 | }], 15 | 16 | "object" : { 17 | "id" : "http://localhost/rest/audit/1234" , 18 | "type" : [ 19 | "http://www.w3.org/ns/prov#Entity" , 20 | "http://fedora.info/definitions/v4/repository#Resource" , 21 | "http://fedora.info/definitions/v4/repository#Container" , 22 | "http://www.w3.org/ns/ldp#RDFSource", 23 | "http://www.w3.org/ns/ldp#BasicContainer" ], 24 | "isPartOf" : "http://localhost/rest" 25 | }, 26 | 27 | "@context": ["https://www.w3.org/ns/activitystreams", { 28 | "prov": "http://www.w3.org/ns/prov#", 29 | "dcterms": "http://purl.org/dc/terms/", 30 | "type": "@type", 31 | "id": "@id", 32 | "isPartOf": { 33 | "@id": "dcterms:isPartOf", 34 | "@type": "@id" 35 | } 36 | }] 37 | } 38 | 39 | -------------------------------------------------------------------------------- /fcrepo-camel-common/src/test/java/org/fcrepo/camel/common/TestTracer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The contents of this file are subject to the license and copyright 3 | * detailed in the LICENSE and NOTICE files at the root of the source 4 | * tree. 5 | */ 6 | package org.fcrepo.camel.common; 7 | 8 | import org.apache.camel.impl.engine.DefaultTracer; 9 | import org.slf4j.Logger; 10 | 11 | /** 12 | * A test tracer for logging camel routes under our control. 13 | * @author whikloj 14 | * 15 | * To use, before adapting the context add camelContext.setTracer(new TestTracer(logger)); 16 | * i.e. 17 | * final Logger LOGGER = LoggerFactory.getLogger(FcrepoSolrIndexer.class); 18 | * camelContext.setTracer(new TestTracer(LOGGER)); 19 | * final var context = camelContext.adapt(ModelCamelContext.class); 20 | * AdviceWith.adviceWith(context, "FcrepoSolrIndexer", a -%lt; { 21 | */ 22 | public class TestTracer extends DefaultTracer { 23 | private final Logger LOGGER; 24 | 25 | public TestTracer(final Logger logger) { 26 | super(); 27 | this.LOGGER = logger; 28 | this.setTracePattern("%-4.4s [%-20.20s] [%-40.40s]"); 29 | } 30 | 31 | @Override 32 | protected void dumpTrace(final String out) { 33 | LOGGER.info(out); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /fcrepo-indexing-solr/src/test/resources/event_delete_resource.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "urn:uuid:3c834a8f-5638-4412-aa4b-35ea80416a18", 3 | "type" : [ 4 | "http://www.w3.org/ns/prov#Activity" , 5 | "https://www.w3.org/ns/activitystreams#Delete" ], 6 | "name": "delete resource", 7 | "published": "2016-05-19T17:17:39-04:00Z", 8 | "actor": [{ 9 | "type": ["Person"], 10 | "id": "info:fedora/fedoraAdmin" 11 | }, { 12 | "type": ["Application"], 13 | "name": "CLAW client/1.0" 14 | }], 15 | 16 | 17 | "object" : { 18 | "id" : "http://localhost/rest/auditions/1234" , 19 | "isPartOf" : "http://localhost/rest" , 20 | "type" : [ 21 | "http://www.w3.org/ns/prov#Entity" , 22 | "http://fedora.info/definitions/v4/repository#Resource" , 23 | "http://fedora.info/definitions/v4/repository#Container" , 24 | "http://www.w3.org/ns/ldp#RDFSource", 25 | "http://www.w3.org/ns/ldp#BasicContainer", 26 | "http://example.org/CustomType" ] 27 | }, 28 | 29 | "@context": ["https://www.w3.org/ns/activitystreams", { 30 | "prov": "http://www.w3.org/ns/prov#", 31 | "dcterms": "http://purl.org/dc/terms/", 32 | "type": "@type", 33 | "id": "@id", 34 | "isPartOf": { 35 | "@id": "dcterms:isPartOf", 36 | "@type": "@id" 37 | } 38 | }] 39 | } 40 | -------------------------------------------------------------------------------- /fcrepo-reindexing/src/test/resources/indexable.rdf: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /fcrepo-camel-common/src/main/java/org/fcrepo/camel/common/processor/DockerRunningProcessor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The contents of this file are subject to the license and copyright 3 | * detailed in the LICENSE and NOTICE files at the root of the source 4 | * tree. 5 | */ 6 | package org.fcrepo.camel.common.processor; 7 | 8 | import org.apache.camel.Exchange; 9 | import org.apache.camel.Processor; 10 | 11 | import java.nio.file.Path; 12 | 13 | /** 14 | * Processor for determining if the application is currently running in 15 | * a Docker environment. Adds a header `CamelDockerRunning` of type boolean 16 | * to the exchange headers. 17 | * 18 | * WARNING 19 | * Checks for existence of /.dockerenv in the filesystem. Note that the presence 20 | * of this file is not documented and that this check might not work in the future. 21 | * 22 | * See ... 23 | * 24 | * @author Ralf Claussnitzer 25 | */ 26 | public class DockerRunningProcessor implements Processor { 27 | 28 | public static final String DOCKER_RUNNING = "CamelDockerRunning"; 29 | 30 | @Override 31 | public void process(final Exchange exchange) throws Exception { 32 | final boolean dockerenvExists = Path.of("/.dockerenv").toFile().exists(); 33 | exchange.getMessage().setHeader(DOCKER_RUNNING, dockerenvExists); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /fcrepo-fixity/src/test/resources/fixity.rdf: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | SUCCESS 17 | 18 | 1636261 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /fcrepo-fixity/src/test/resources/fixityFailure.rdf: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | FAILURE 17 | 18 | 1636261 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /fcrepo-camel-common/src/main/java/org/fcrepo/camel/common/processor/AddBasicAuthProcessor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The contents of this file are subject to the license and copyright 3 | * detailed in the LICENSE and NOTICE files at the root of the source 4 | * tree. 5 | */ 6 | 7 | package org.fcrepo.camel.common.processor; 8 | 9 | import org.apache.camel.Exchange; 10 | import org.apache.camel.Processor; 11 | import org.apache.commons.lang3.StringUtils; 12 | 13 | import static org.fcrepo.camel.common.helpers.BasicAuth.BASIC_AUTH_HEADER; 14 | import static org.fcrepo.camel.common.helpers.BasicAuth.generateBasicAuthHeader; 15 | 16 | /** 17 | * A processor for adding a basic auth header when username is present. 18 | * @author dbernstein 19 | */ 20 | public class AddBasicAuthProcessor implements Processor { 21 | 22 | private final String username; 23 | private final String password; 24 | 25 | /** 26 | * Constructor 27 | * @param username The username 28 | * @param password The password 29 | */ 30 | public AddBasicAuthProcessor(final String username, final String password) { 31 | this.username = username; 32 | this.password = password; 33 | } 34 | @Override 35 | public void process(final Exchange exchange) throws Exception { 36 | if (!StringUtils.isBlank(this.username)) { 37 | exchange.getIn().setHeader(BASIC_AUTH_HEADER, 38 | generateBasicAuthHeader(this.username, this.password)); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/site/site.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | org.apache.maven.skins 10 | maven-fluido-skin 11 | 1.3.0 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | false 37 | width: 80%; 38 | true 39 | true 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | **The title of this pull-request should be a brief description of what the pull-request fixes/improves/changes. Ideally 50 characters or less.** 2 | * * * 3 | 4 | **JIRA Ticket**: (link) 5 | 6 | * Other Relevant Links (Mailing list discussion, related pull requests, etc.) 7 | 8 | # What does this Pull Request do? 9 | A brief description of what the intended result of the PR will be and/or what problem it solves. 10 | 11 | # What's new? 12 | A in-depth description of the changes made by this PR. Technical details and possible side effects. 13 | 14 | Example: 15 | * Changes x feature to such that y 16 | * Added x 17 | * Removed y 18 | 19 | # How should this be tested? 20 | 21 | A description of what steps someone could take to: 22 | * Reproduce the problem you are fixing (if applicable) 23 | * Test that the Pull Request does what is intended. 24 | * Please be as detailed as possible. 25 | * Good testing instructions help get your PR completed faster. 26 | 27 | 28 | # Additional Notes: 29 | Any additional information that you think would be helpful when reviewing this PR. 30 | 31 | Example: 32 | * Does this change require documentation to be updated? 33 | * Does this change add any new dependencies? 34 | * Does this change require any other modifications to be made to the repository (ie. Regeneration activity, etc.)? 35 | * Could this change impact execution of existing code? 36 | 37 | # Interested parties 38 | Tag (@ mention) interested parties or, if unsure, @fcrepo/committers 39 | -------------------------------------------------------------------------------- /fcrepo-reindexing/src/main/resources/org/fcrepo/camel/reindexing/usage.mustache: -------------------------------------------------------------------------------- 1 | Fedora Reindexing Service {{#headers.CamelDockerRunning}}(Running in Docker){{/headers.CamelDockerRunning}} 2 | 3 | Configured Fedora Location: {{headers.CamelFcrepoBaseUrl}} 4 | Configured REST endpoint: {{headers.CamelReindexingHost}}:{{headers.CamelReindexingPort}}{{headers.CamelReindexingPrefix}} 5 | 6 | You can POST to the defined re-indexing endpoint, and it 7 | will begin to traverse the Fedora repository at that point, 8 | sending "re-indexing" hints to the specified services 9 | (there are no default services defined). 10 | 11 | {{#headers.CamelDockerRunning}} 12 | Note: The mentioned hostname and port might not work on your host machine when running 13 | Camel Toolbox as Docker container. You can usually access the reindexing service on 14 | localhost:9080 when you docker-compose. 15 | 16 | {{/headers.CamelDockerRunning}} 17 | For example: 18 | 19 | curl -XPOST {{headers.CamelReindexingHost}}:{{headers.CamelReindexingPort}}{{headers.CamelReindexingPrefix}}/objects \ 20 | -d "CamelReindexingRecipients=broker:queue:solr.reindex,broker:queue:fixity,queingservice:queue:triplestore.reindex" 21 | 22 | Or (as JSON) 23 | 24 | curl -XPOST {{headers.CamelReindexingHost}}:{{headers.CamelReindexingPort}}{{headers.CamelReindexingPrefix}}/objects -H"Content-Type: application/json" \ 25 | -d '["broker:queue:solr.reindex","broker:queue:fixity","broker:queue:triplestore.reindex"]' 26 | 27 | This will reindex both Solr and the external triplestore, 28 | starting at the /objects node in fedora. 29 | -------------------------------------------------------------------------------- /fcrepo-indexing-triplestore/src/test/resources/event.json: -------------------------------------------------------------------------------- 1 | { 2 | "@context" : { 3 | "prov" : "http://www.w3.org/ns/prov#" , 4 | "foaf" : "http://xmlns.com/foaf/0.1/" , 5 | "dcterms" : "http://purl.org/dc/terms/" , 6 | "xsd" : "http://www.w3.org/2001/XMLSchema#" , 7 | 8 | "type" : "@type" , 9 | "id" : "@id" , 10 | 11 | "atTime" : { "@id" : "prov:atTime", "@type" : "xsd:dateTime" } , 12 | "identifier" : { "@id" : "dcterms:identifier" , "@type" : "@id" } , 13 | "isPartOf" : { "@id" : "dcterms:isPartOf", "@type" : "@id" } , 14 | "name" : { "@id" : "foaf:name", "@type" : "xsd:string" } , 15 | "wasAttributedTo" : { "@id" : "prov:wasAttributedTo", "@type" : "@id" } , 16 | "wasGeneratedBy" : { "@id" : "prov:wasGeneratedBy", "@type" : "@id" } 17 | } , 18 | 19 | "id" : "http://localhost/rest/path/to/resource" , 20 | "type" : [ 21 | "http://www.w3.org/ns/prov#Entity" , 22 | "http://fedora.info/definitions/v4/repository#Resource" , 23 | "http://fedora.info/definitions/v4/repository#Container" ] , 24 | "isPartOf" : "http://localhost/rest" , 25 | "wasGeneratedBy" : { 26 | "type" : [ 27 | "http://www.w3.org/ns/prov#Activity" , 28 | "http://fedora.info/definitions/v4/event#ResourceCreation" ] , 29 | "identifier" : "urn:uuid:3c834a8f-5638-4412-aa4b-35ea80416a18" , 30 | "atTime" : "2016-05-19T17:17:39-04:00Z" } , 31 | "wasAttributedTo" : [ 32 | { "type" : "http://www.w3.org/ns/prov#Person" , 33 | "name" : "fedo raAdmin" }, 34 | { "type" : "http://www.w3.org/ns/prov#SoftwareAgent" , 35 | "name" : "CLAW client/1.0" } ] 36 | } 37 | -------------------------------------------------------------------------------- /fcrepo-reindexing/src/test/resources/indexable.nt: -------------------------------------------------------------------------------- 1 | . 2 | . 3 | . 4 | . 5 | . 6 | . 7 | . 8 | . 9 | . 10 | . 11 | . 12 | . 13 | -------------------------------------------------------------------------------- /fcrepo-camel-common/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | fcrepo-camel-toolbox 5 | org.fcrepo.camel 6 | 6.3.0-SNAPSHOT 7 | 8 | 4.0.0 9 | 10 | fcrepo-camel-common 11 | jar 12 | 13 | 14 | org.springframework 15 | spring-context 16 | 17 | 18 | org.apache.camel 19 | camel-core 20 | 21 | 22 | org.apache.commons 23 | commons-lang3 24 | 25 | 26 | 27 | org.slf4j 28 | slf4j-api 29 | 30 | 31 | 32 | 33 | 34 | 35 | org.apache.maven.plugins 36 | maven-checkstyle-plugin 37 | 38 | 39 | org.apache.maven.plugins 40 | maven-jar-plugin 41 | 42 | 43 | 44 | test-jar 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /fcrepo-fixity/src/test/java/org/fcrepo/camel/fixity/RouteDisabledTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The contents of this file are subject to the license and copyright 3 | * detailed in the LICENSE and NOTICE files at the root of the source 4 | * tree. 5 | */ 6 | package org.fcrepo.camel.fixity; 7 | 8 | import org.apache.camel.CamelContext; 9 | import org.apache.camel.spring.javaconfig.CamelConfiguration; 10 | import org.junit.BeforeClass; 11 | import org.junit.Test; 12 | import org.junit.runner.RunWith; 13 | import org.springframework.beans.factory.annotation.Autowired; 14 | import org.springframework.context.annotation.ComponentScan; 15 | import org.springframework.context.annotation.Configuration; 16 | import org.springframework.test.annotation.DirtiesContext; 17 | import org.springframework.test.context.ContextConfiguration; 18 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 19 | import org.springframework.test.context.support.AnnotationConfigContextLoader; 20 | 21 | import static org.junit.Assert.assertNull; 22 | 23 | /** 24 | * Test that the route can be disabled. 25 | * 26 | * @author dbernstein 27 | * @since 2021-10-01 28 | */ 29 | @RunWith(SpringJUnit4ClassRunner.class) 30 | @ContextConfiguration(classes = {RouteDisabledTest.ContextConfig.class}, loader = AnnotationConfigContextLoader.class) 31 | public class RouteDisabledTest { 32 | 33 | @Autowired 34 | private CamelContext camelContext; 35 | 36 | @Autowired(required = false) 37 | private FcrepoFixityConfig config; 38 | 39 | @BeforeClass 40 | public static void beforeClass() { 41 | System.setProperty("fixity.enabled", "false"); 42 | } 43 | 44 | @DirtiesContext 45 | @Test 46 | public void testFixityDisabled() throws Exception { 47 | assertNull("fixity config should be null", config); 48 | } 49 | 50 | @Configuration 51 | @ComponentScan(resourcePattern = "**/Fcrepo*.class") 52 | static class ContextConfig extends CamelConfiguration { 53 | } 54 | 55 | } 56 | 57 | -------------------------------------------------------------------------------- /fcrepo-audit-triplestore/src/test/java/org/fcrepo/camel/audit/triplestore/RouteDisabledTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The contents of this file are subject to the license and copyright 3 | * detailed in the LICENSE and NOTICE files at the root of the source 4 | * tree. 5 | */ 6 | package org.fcrepo.camel.audit.triplestore; 7 | 8 | import org.apache.camel.CamelContext; 9 | import org.apache.camel.spring.javaconfig.CamelConfiguration; 10 | import org.junit.BeforeClass; 11 | import org.junit.Test; 12 | import org.junit.runner.RunWith; 13 | import org.springframework.beans.factory.annotation.Autowired; 14 | import org.springframework.context.annotation.ComponentScan; 15 | import org.springframework.context.annotation.Configuration; 16 | import org.springframework.test.annotation.DirtiesContext; 17 | import org.springframework.test.context.ContextConfiguration; 18 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 19 | import org.springframework.test.context.support.AnnotationConfigContextLoader; 20 | 21 | import static org.junit.Assert.assertNull; 22 | 23 | /** 24 | * Test that the route can be disabled. 25 | * 26 | * @author dbernstein 27 | * @since 2021-10-01 28 | */ 29 | @RunWith(SpringJUnit4ClassRunner.class) 30 | @ContextConfiguration(classes = {RouteDisabledTest.ContextConfig.class}, loader = AnnotationConfigContextLoader.class) 31 | public class RouteDisabledTest { 32 | 33 | @Autowired 34 | private CamelContext camelContext; 35 | 36 | @Autowired(required = false) 37 | private FcrepoAuditTriplestoreConfig config; 38 | 39 | @BeforeClass 40 | public static void beforeClass() { 41 | System.setProperty("audit.enabled", "false"); 42 | } 43 | 44 | @DirtiesContext 45 | @Test 46 | public void testFixityDisabled() throws Exception { 47 | assertNull("audit config should be null", config); 48 | } 49 | 50 | @Configuration 51 | @ComponentScan(resourcePattern = "**/Fcrepo*.class") 52 | static class ContextConfig extends CamelConfiguration { 53 | } 54 | 55 | } 56 | 57 | -------------------------------------------------------------------------------- /fcrepo-camel-common/src/main/java/org/fcrepo/camel/common/config/ConditionOnProperty.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The contents of this file are subject to the license and copyright 3 | * detailed in the LICENSE and NOTICE files at the root of the source 4 | * tree. 5 | */ 6 | 7 | package org.fcrepo.camel.common.config; 8 | 9 | import org.slf4j.Logger; 10 | import org.slf4j.LoggerFactory; 11 | import org.springframework.context.annotation.ConditionContext; 12 | import org.springframework.context.annotation.ConfigurationCondition; 13 | import org.springframework.core.type.AnnotatedTypeMetadata; 14 | 15 | import java.util.Objects; 16 | 17 | /** 18 | * This condition enables a bean/configuration when the specified property matches the expected value 19 | * 20 | * Implementations must provide a no-arg constructor. 21 | * 22 | * @author pwinckles 23 | */ 24 | public abstract class ConditionOnProperty implements ConfigurationCondition { 25 | 26 | private static final Logger LOGGER = 27 | LoggerFactory.getLogger(org.fcrepo.camel.common.config.ConditionOnProperty.class); 28 | 29 | private final String name; 30 | private final T expected; 31 | private final T defaultValue; 32 | private final Class clazz; 33 | 34 | public ConditionOnProperty(final String name, final T expected, final T defaultValue, final Class clazz) { 35 | this.name = name; 36 | this.expected = expected; 37 | this.defaultValue = defaultValue; 38 | this.clazz = clazz; 39 | } 40 | 41 | @Override 42 | public boolean matches(final ConditionContext context, final AnnotatedTypeMetadata metadata) { 43 | LOGGER.debug("Prop {}: {}", name, context.getEnvironment().getProperty(name)); 44 | return Objects.equals(expected, context.getEnvironment().getProperty(name, clazz, defaultValue)); 45 | } 46 | 47 | @Override 48 | public ConfigurationPhase getConfigurationPhase() { 49 | // This forces spring to not evaluate these conditions until after it has loaded other @Configuration classes, 50 | // ensuring that the properties have been loaded. 51 | return ConfigurationPhase.REGISTER_BEAN; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /fcrepo-reindexing/src/main/java/org/fcrepo/camel/reindexing/FcrepoReindexingConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The contents of this file are subject to the license and copyright 3 | * detailed in the LICENSE and NOTICE files at the root of the source 4 | * tree. 5 | */ 6 | package org.fcrepo.camel.reindexing; 7 | 8 | import org.apache.camel.builder.RouteBuilder; 9 | import org.fcrepo.camel.common.config.BasePropsConfig; 10 | import org.fcrepo.camel.common.config.ConditionOnPropertyTrue; 11 | import org.slf4j.Logger; 12 | import org.slf4j.LoggerFactory; 13 | import org.springframework.beans.factory.annotation.Value; 14 | import org.springframework.context.annotation.Bean; 15 | import org.springframework.context.annotation.Conditional; 16 | import org.springframework.context.annotation.Configuration; 17 | 18 | /** 19 | * A configuration class for the re-indexer service 20 | * 21 | * @author dbernstein 22 | */ 23 | 24 | @Configuration 25 | @Conditional(FcrepoReindexingConfig.ReindexingEnabled.class) 26 | public class FcrepoReindexingConfig extends BasePropsConfig { 27 | 28 | private static final Logger LOGGER = LoggerFactory.getLogger(FcrepoReindexingConfig.class); 29 | static final String REINDEXING_ENABLED = "reindexing.enabled"; 30 | 31 | static class ReindexingEnabled extends ConditionOnPropertyTrue { 32 | ReindexingEnabled() { 33 | super(FcrepoReindexingConfig.REINDEXING_ENABLED, true); 34 | } 35 | } 36 | 37 | @Value("${reindexing.stream:broker:queue:reindexing}") 38 | private String reindexingStream; 39 | 40 | @Value("${reindexing.rest.prefix:/reindexing}") 41 | private String restPrefix; 42 | 43 | @Value("${reindexing.rest.host:localhost}") 44 | private String restHost; 45 | 46 | @Value("${reindexing.rest.port:9080}") 47 | private int restPort; 48 | 49 | 50 | public String getReindexingStream() { 51 | return reindexingStream; 52 | } 53 | 54 | public String getRestPrefix() { 55 | return restPrefix; 56 | } 57 | 58 | public String getRestHost() { 59 | return restHost; 60 | } 61 | 62 | public int getRestPort() { 63 | return restPort; 64 | } 65 | 66 | @Bean 67 | public RouteBuilder reindexingRoute() { 68 | return new ReindexingRouter(); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /fcrepo-camel-common/src/main/java/org/fcrepo/camel/common/config/BasePropsConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The contents of this file are subject to the license and copyright 3 | * detailed in the LICENSE and NOTICE files at the root of the source 4 | * tree. 5 | */ 6 | 7 | package org.fcrepo.camel.common.config; 8 | 9 | import org.springframework.beans.factory.annotation.Value; 10 | import org.springframework.context.annotation.PropertySource; 11 | import org.springframework.context.annotation.PropertySources; 12 | 13 | 14 | /** 15 | * A base class for property configs 16 | * 17 | * @author dbernstein 18 | */ 19 | @PropertySources({ 20 | @PropertySource(value = BasePropsConfig.DEFAULT_FCREPO_CAMEL_TOOLBOX_CONFIG_FILE_PROP_SOURCE, 21 | ignoreResourceNotFound = true), 22 | @PropertySource(value = BasePropsConfig.FCREPO_CAMEL_CONFIG_FILE_PROP_SOURCE, ignoreResourceNotFound = true) 23 | }) 24 | public abstract class BasePropsConfig { 25 | 26 | public static final String FCREPO_CAMEL_TOOLBOX_HOME_PROPERTY = "fcrepo-camel-toolbox.home"; 27 | public static final String DEFAULT_FCREPO_HOME_VALUE = "fcrepo-camel-toolbox-home"; 28 | public static final String DEFAULT_FCREPO_CAMEL_TOOLBOX_CONFIG_FILE_PROP_SOURCE = 29 | "file:${" + FCREPO_CAMEL_TOOLBOX_HOME_PROPERTY + ":" + DEFAULT_FCREPO_HOME_VALUE + 30 | "}/config/fcrepo-camel-toolbox.properties"; 31 | public static final String FCREPO_CAMEL_CONFIG_FILE_PROPERTY = "fcrepo.camel.toolbox.config.file"; 32 | public static final String FCREPO_CAMEL_CONFIG_FILE_PROP_SOURCE = 33 | "file:${" + FCREPO_CAMEL_CONFIG_FILE_PROPERTY + "}"; 34 | 35 | @Value("${error.maxRedeliveries:10}") 36 | private int maxRedeliveries; 37 | 38 | @Value("${fcrepo.baseUrl:http://localhost:8080/fcrepo/rest}") 39 | private String fcrepoBaseUrl; 40 | 41 | @Value("${fcrepo.authUsername:fedoraAdmin}") 42 | private String fcrepoUsername; 43 | 44 | @Value("${fcrepo.authPassword:fedoraAdmin}") 45 | private String fcrepoPassword; 46 | 47 | @Value("${fcrepo.authHost:localhost}") 48 | private String fcrepoAuthHost; 49 | 50 | public int getMaxRedeliveries() { 51 | return maxRedeliveries; 52 | } 53 | 54 | public String getFcrepoBaseUrl() { 55 | return fcrepoBaseUrl; 56 | } 57 | 58 | public String getFcrepoUsername() { 59 | return fcrepoUsername; 60 | } 61 | 62 | public String getFcrepoPassword() { 63 | return fcrepoPassword; 64 | } 65 | 66 | public String getFcrepoAuthHost() { 67 | return fcrepoAuthHost; 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /fcrepo-service-activemq/src/main/java/org/fcrepo/camel/activemq/ActiveMQConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The contents of this file are subject to the license and copyright 3 | * detailed in the LICENSE and NOTICE files at the root of the source 4 | * tree. 5 | */ 6 | package org.fcrepo.camel.activemq; 7 | 8 | import org.apache.activemq.ActiveMQConnectionFactory; 9 | import org.apache.activemq.pool.PooledConnectionFactory; 10 | import org.apache.camel.component.activemq.ActiveMQComponent; 11 | import org.apache.camel.component.jms.JmsConfiguration; 12 | import org.fcrepo.camel.common.config.BasePropsConfig; 13 | import org.springframework.beans.factory.annotation.Value; 14 | import org.springframework.context.annotation.Bean; 15 | import org.springframework.context.annotation.Configuration; 16 | 17 | import javax.jms.ConnectionFactory; 18 | 19 | /** 20 | * @author dbernstein 21 | */ 22 | @Configuration 23 | public class ActiveMQConfig extends BasePropsConfig { 24 | @Value("${jms.brokerUrl:tcp://localhost:61616}") 25 | private String jmsBrokerUrl; 26 | 27 | @Value("${jms.username:#{null}}") 28 | private String jmsUsername; 29 | 30 | @Value("${jms.password:#{null}}") 31 | private String jmsPasword; 32 | 33 | @Value("${jms.connections:10}") 34 | private int jmsConnections; 35 | 36 | @Value("${jms.consumers:1}") 37 | private int jmsConsumers; 38 | 39 | 40 | @Bean 41 | public ActiveMQConnectionFactory connectionFactory() { 42 | final var connectionFactory = new ActiveMQConnectionFactory(); 43 | connectionFactory.setBrokerURL(jmsBrokerUrl); 44 | connectionFactory.setUserName(jmsUsername); 45 | connectionFactory.setPassword(jmsPasword); 46 | return connectionFactory; 47 | } 48 | 49 | @Bean 50 | public ConnectionFactory pooledConnectionFactory(final ActiveMQConnectionFactory connectionFactory) { 51 | final var pooledConnectionFactory = new PooledConnectionFactory(); 52 | pooledConnectionFactory.setMaxConnections(jmsConnections); 53 | pooledConnectionFactory.setConnectionFactory(connectionFactory); 54 | return pooledConnectionFactory; 55 | } 56 | 57 | @Bean 58 | public JmsConfiguration jmsConfiguration(final PooledConnectionFactory connectionFactory) { 59 | final var configuration = new JmsConfiguration(); 60 | configuration.setConcurrentConsumers(jmsConsumers); 61 | configuration.setConnectionFactory(connectionFactory); 62 | return configuration; 63 | } 64 | 65 | @Bean("broker") 66 | public ActiveMQComponent activeMQComponent(final JmsConfiguration jmsConfiguration) { 67 | final var component = new ActiveMQComponent(); 68 | component.setConfiguration(jmsConfiguration); 69 | return component; 70 | } 71 | } 72 | 73 | -------------------------------------------------------------------------------- /fcrepo-service-activemq/src/main/resources/OSGI-INF/blueprint/blueprint.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /fcrepo-http-forwarding/src/main/java/org/fcrepo/camel/httpforwarding/FcrepoHttpForwardingConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The contents of this file are subject to the license and copyright 3 | * detailed in the LICENSE and NOTICE files at the root of the source 4 | * tree. 5 | */ 6 | package org.fcrepo.camel.httpforwarding; 7 | 8 | import org.apache.camel.builder.RouteBuilder; 9 | import org.apache.camel.component.http.HttpComponent; 10 | import org.fcrepo.camel.common.config.BasePropsConfig; 11 | import org.fcrepo.camel.common.config.ConditionOnPropertyTrue; 12 | import org.springframework.beans.factory.annotation.Value; 13 | import org.springframework.context.annotation.Bean; 14 | import org.springframework.context.annotation.Conditional; 15 | import org.springframework.context.annotation.Configuration; 16 | 17 | /** 18 | * A configuration class for the Http Indexer service 19 | * 20 | * @author Geoff Scholl 21 | * @author Demian Katz 22 | */ 23 | @Configuration 24 | @Conditional(FcrepoHttpForwardingConfig.HttpForwardingingEnabled.class) 25 | public class FcrepoHttpForwardingConfig extends BasePropsConfig { 26 | 27 | static final String HTTP_FORWARDING_ENABLED = "http.enabled"; 28 | 29 | static class HttpForwardingingEnabled extends ConditionOnPropertyTrue { 30 | HttpForwardingingEnabled() { 31 | super(FcrepoHttpForwardingConfig.HTTP_FORWARDING_ENABLED, false); 32 | } 33 | } 34 | 35 | @Value("${http.input.stream:broker:topic:fedora}") 36 | private String inputStream; 37 | 38 | @Value("${http.reindex.stream:broker:queue:http.reindex}") 39 | private String reindexStream; 40 | 41 | @Value("${http.filter.containers:http://localhost:8080/fcrepo/rest/audit}") 42 | private String filterContainers; 43 | 44 | @Value("${http.baseUrl:}") 45 | private String httpBaseUrl; 46 | 47 | @Value("${http.authUsername:}") 48 | private String httpAuthUsername; 49 | 50 | @Value("${http.authPassword:}") 51 | private String httpAuthPassword; 52 | 53 | public String getInputStream() { 54 | return inputStream; 55 | } 56 | 57 | public String getReindexStream() { 58 | return reindexStream; 59 | } 60 | 61 | public String getFilterContainers() { 62 | return filterContainers; 63 | } 64 | 65 | public String getHttpBaseUrl() { 66 | return httpBaseUrl; 67 | } 68 | 69 | public String getHttpAuthUsername() { 70 | return httpAuthUsername; 71 | } 72 | 73 | public String getHttpAuthPassword() { 74 | return httpAuthPassword; 75 | } 76 | 77 | 78 | @Bean(name = "http") 79 | public HttpComponent http() { 80 | return new HttpComponent(); 81 | } 82 | 83 | @Bean(name = "https") 84 | public HttpComponent https() { 85 | return new HttpComponent(); 86 | } 87 | 88 | @Bean 89 | public RouteBuilder httpRoute() { 90 | return new HttpRouter(); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /fcrepo-reindexing/src/main/java/org/fcrepo/camel/reindexing/RestProcessor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The contents of this file are subject to the license and copyright 3 | * detailed in the LICENSE and NOTICE files at the root of the source 4 | * tree. 5 | */ 6 | package org.fcrepo.camel.reindexing; 7 | 8 | import static java.lang.String.join; 9 | import static org.apache.camel.Exchange.CONTENT_TYPE; 10 | import static org.apache.camel.Exchange.HTTP_RESPONSE_CODE; 11 | import static org.fcrepo.camel.reindexing.ReindexingHeaders.REINDEXING_RECIPIENTS; 12 | import static org.slf4j.LoggerFactory.getLogger; 13 | 14 | import java.util.HashSet; 15 | import java.util.Iterator; 16 | import java.util.Set; 17 | 18 | import com.fasterxml.jackson.core.JsonProcessingException; 19 | import com.fasterxml.jackson.databind.JsonNode; 20 | import com.fasterxml.jackson.databind.ObjectMapper; 21 | 22 | import org.apache.camel.Exchange; 23 | import org.apache.camel.Message; 24 | import org.apache.camel.Processor; 25 | import org.slf4j.Logger; 26 | 27 | /** 28 | * A processor that converts the REST uri into the 29 | * identifying path for an fcrepo node. 30 | * 31 | * This assumes that the `rest.prefix` value is stored 32 | * in the CamelFcrepoRestPrefix header. 33 | * 34 | * @author Aaron Coburn 35 | */ 36 | public class RestProcessor implements Processor { 37 | 38 | private static final Logger LOGGER = getLogger(RestProcessor.class); 39 | 40 | private static final int BAD_REQUEST = 400; 41 | 42 | private static final ObjectMapper MAPPER = new ObjectMapper(); 43 | 44 | /** 45 | * Convert the incoming REST request into the correct 46 | * Fcrepo header fields. 47 | * 48 | * @param exchange the current message exchange 49 | */ 50 | public void process(final Exchange exchange) throws Exception { 51 | final Message in = exchange.getIn(); 52 | 53 | final String contentType = in.getHeader(CONTENT_TYPE, "", String.class); 54 | final String body = in.getBody(String.class); 55 | final Set endpoints = new HashSet<>(); 56 | 57 | for (final String s : in.getHeader(REINDEXING_RECIPIENTS, "", String.class).split(",")) { 58 | endpoints.add(s.trim()); 59 | } 60 | 61 | if (contentType.equals("application/json") && body != null && !body.trim().isEmpty()) { 62 | try { 63 | final JsonNode root = MAPPER.readTree(body); 64 | final Iterator ite = root.elements(); 65 | while (ite.hasNext()) { 66 | final JsonNode n = ite.next(); 67 | endpoints.add(n.asText()); 68 | } 69 | } catch (JsonProcessingException e) { 70 | LOGGER.debug("Invalid JSON", e); 71 | in.setHeader(HTTP_RESPONSE_CODE, BAD_REQUEST); 72 | in.setBody("Invalid JSON"); 73 | } 74 | } 75 | in.setHeader(REINDEXING_RECIPIENTS, join(",", endpoints)); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /fcrepo-fixity/src/main/java/org/fcrepo/camel/fixity/FixityRouter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The contents of this file are subject to the license and copyright 3 | * detailed in the LICENSE and NOTICE files at the root of the source 4 | * tree. 5 | */ 6 | package org.fcrepo.camel.fixity; 7 | 8 | import org.apache.camel.LoggingLevel; 9 | import org.apache.camel.builder.RouteBuilder; 10 | import org.apache.camel.support.builder.Namespaces; 11 | import org.apache.jena.vocabulary.RDF; 12 | import org.slf4j.Logger; 13 | import org.springframework.beans.factory.annotation.Autowired; 14 | 15 | import static org.slf4j.LoggerFactory.getLogger; 16 | 17 | /** 18 | * A content router for checking fixity of Binary resources. 19 | * 20 | * @author Aaron Coburn 21 | * @since 2015-06-18 22 | */ 23 | public class FixityRouter extends RouteBuilder { 24 | 25 | private static final Logger LOGGER = getLogger(FixityRouter.class); 26 | 27 | private static final String REPOSITORY = "http://fedora.info/definitions/v4/repository#"; 28 | 29 | @Autowired 30 | private FcrepoFixityConfig config; 31 | 32 | /** 33 | * Configure the message route workflow. 34 | */ 35 | public void configure() throws Exception { 36 | final Namespaces ns = new Namespaces("rdf", RDF.uri); 37 | ns.add("premis", "http://www.loc.gov/premis/rdf/v1#"); 38 | 39 | /** 40 | * A generic error handler (specific to this RouteBuilder) 41 | */ 42 | onException(Exception.class) 43 | .maximumRedeliveries(config.getMaxRedeliveries()) 44 | .log("Index Routing Error: ${routeId}"); 45 | 46 | /** 47 | * Handle fixity events 48 | */ 49 | from(config.getInputStream()) 50 | .routeId("FcrepoFixity") 51 | .to("fcrepo:" + config.getFcrepoBaseUrl() + "?preferInclude=ServerManged&accept=application/rdf+xml") 52 | .filter().xpath( 53 | "/rdf:RDF/rdf:Description/rdf:type" + 54 | "[@rdf:resource='" + REPOSITORY + "Binary']", ns) 55 | .log(LoggingLevel.INFO, LOGGER, 56 | "Checking Fixity for ${headers[CamelFcrepoUri]}") 57 | .delay(simple(String.valueOf(config.getFixityDelay()))) 58 | .to("fcrepo:" + config.getFcrepoBaseUrl() + "?fixity=true&accept=application/rdf+xml") 59 | .choice() 60 | .when().xpath( 61 | "/rdf:RDF/rdf:Description/premis:hasEventOutcome" + 62 | "[text()='SUCCESS']", ns) 63 | .log(LoggingLevel.INFO, LOGGER, 64 | "Fixity success on ${headers[CamelFcrepoUri]}") 65 | .to(config.getFixitySuccess()) 66 | .otherwise() 67 | .log(LoggingLevel.WARN, LOGGER, 68 | "Fixity error on ${headers[CamelFcrepoUri]}") 69 | .to(config.getFixityFailure()); 70 | 71 | LOGGER.info("FixityRouter configured"); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /fcrepo-audit-triplestore/src/main/java/org/fcrepo/camel/audit/triplestore/EventRouter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The contents of this file are subject to the license and copyright 3 | * detailed in the LICENSE and NOTICE files at the root of the source 4 | * tree. 5 | */ 6 | package org.fcrepo.camel.audit.triplestore; 7 | 8 | import org.apache.camel.LoggingLevel; 9 | import org.apache.camel.builder.RouteBuilder; 10 | import org.fcrepo.camel.common.processor.AddBasicAuthProcessor; 11 | import org.fcrepo.camel.processor.EventProcessor; 12 | import org.slf4j.Logger; 13 | import org.springframework.beans.factory.annotation.Autowired; 14 | 15 | import static java.util.stream.Collectors.toList; 16 | import static org.apache.camel.builder.PredicateBuilder.in; 17 | import static org.apache.camel.builder.PredicateBuilder.not; 18 | import static org.apache.camel.builder.PredicateBuilder.or; 19 | import static org.fcrepo.camel.FcrepoHeaders.FCREPO_URI; 20 | import static org.fcrepo.camel.processor.ProcessorUtils.tokenizePropertyPlaceholder; 21 | import static org.slf4j.LoggerFactory.getLogger; 22 | 23 | /** 24 | * A content router for handling JMS events. 25 | * 26 | * @author Aaron Coburn 27 | * @author escowles 28 | */ 29 | public class EventRouter extends RouteBuilder { 30 | 31 | private static final Logger LOGGER = getLogger(EventRouter.class); 32 | 33 | @Autowired 34 | private FcrepoAuditTriplestoreConfig config; 35 | 36 | /** 37 | * Configure the message route workflow. 38 | */ 39 | public void configure() throws Exception { 40 | 41 | /** 42 | * A generic error handler (specific to this RouteBuilder) 43 | */ 44 | onException(Exception.class) 45 | .maximumRedeliveries(config.getMaxRedeliveries()) 46 | .log("Event Routing Error: ${routeId}"); 47 | 48 | /** 49 | * Process a message. 50 | */ 51 | from(config.getInputStream()) 52 | .routeId("AuditFcrepoRouter") 53 | .process(new EventProcessor()) 54 | .filter(not(in(tokenizePropertyPlaceholder(getContext(), config.getFilterContainers(), ",").stream() 55 | .map(uri -> or( 56 | header(FCREPO_URI).startsWith(constant(uri + "/")), 57 | header(FCREPO_URI).isEqualTo(constant(uri)))) 58 | .collect(toList())))) 59 | .to("direct:event"); 60 | 61 | from("direct:event") 62 | .routeId("AuditEventRouter") 63 | .setHeader(AuditHeaders.EVENT_BASE_URI, simple(config.getEventBaseUri())) 64 | .process(new AuditSparqlProcessor()) 65 | .log(LoggingLevel.INFO, "org.fcrepo.camel.audit", 66 | "Audit Event: ${headers.CamelFcrepoUri} :: ${headers[CamelAuditEventUri]}") 67 | .process(new AddBasicAuthProcessor(this.config.getTriplestoreAuthUsername(), 68 | this.config.getTriplestoreAuthPassword())) 69 | .to(config.getTriplestoreBaseUrl() + "?useSystemProperties=true"); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /fcrepo-audit-triplestore/src/main/java/org/fcrepo/camel/audit/triplestore/FcrepoAuditTriplestoreConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The contents of this file are subject to the license and copyright 3 | * detailed in the LICENSE and NOTICE files at the root of the source 4 | * tree. 5 | */ 6 | package org.fcrepo.camel.audit.triplestore; 7 | 8 | import org.apache.camel.builder.RouteBuilder; 9 | import org.apache.camel.component.http.HttpComponent; 10 | import org.fcrepo.camel.common.config.BasePropsConfig; 11 | import org.fcrepo.camel.common.config.ConditionOnPropertyTrue; 12 | import org.slf4j.Logger; 13 | import org.slf4j.LoggerFactory; 14 | import org.springframework.beans.factory.annotation.Value; 15 | import org.springframework.context.annotation.Bean; 16 | import org.springframework.context.annotation.Conditional; 17 | import org.springframework.context.annotation.Configuration; 18 | 19 | /** 20 | * A configuration class for the audit triplestore service 21 | * 22 | * @author dbernstein 23 | */ 24 | @Configuration 25 | @Conditional({FcrepoAuditTriplestoreConfig.AuditTriplestoreEnabled.class}) 26 | public class FcrepoAuditTriplestoreConfig extends BasePropsConfig { 27 | 28 | private static final Logger LOGGER = LoggerFactory.getLogger(FcrepoAuditTriplestoreConfig.class); 29 | static final String AUDIT_ENABLED = "audit.enabled"; 30 | 31 | static class AuditTriplestoreEnabled extends ConditionOnPropertyTrue { 32 | AuditTriplestoreEnabled() { 33 | super(FcrepoAuditTriplestoreConfig.AUDIT_ENABLED, false); 34 | } 35 | } 36 | 37 | @Value("${audit.input.stream:broker:topic:fedora}") 38 | private String inputStream; 39 | 40 | @Value("${audit.event.baseUri:http://example.com/event}") 41 | private String eventBaseUri; 42 | 43 | @Value("${audit.triplestore.baseUrl:http://localhost:3030/fuseki/test/update}") 44 | private String triplestoreBaseUrl; 45 | 46 | @Value("${audit.triplestore.authUsername:}") 47 | private String triplestoreAuthUsername; 48 | 49 | @Value("${audit.triplestore.authPassword:}") 50 | private String tripleStoreAuthPassword; 51 | 52 | @Value("${audit.filter.containers:http://localhost:8080/fcrepo/rest/audit}") 53 | private String filterContainers; 54 | 55 | @Bean(name = "http") 56 | public HttpComponent http() { 57 | return new HttpComponent(); 58 | } 59 | 60 | @Bean(name = "https") 61 | public HttpComponent https() { 62 | return new HttpComponent(); 63 | } 64 | 65 | @Bean 66 | public RouteBuilder route() { 67 | return new EventRouter(); 68 | } 69 | 70 | public String getTriplestoreBaseUrl() { 71 | return triplestoreBaseUrl; 72 | } 73 | 74 | public String getTriplestoreAuthPassword() { 75 | return tripleStoreAuthPassword; 76 | } 77 | 78 | public String getTriplestoreAuthUsername() { 79 | return triplestoreAuthUsername; 80 | } 81 | 82 | public String getFilterContainers() { 83 | return filterContainers; 84 | } 85 | 86 | public String getEventBaseUri() { 87 | return eventBaseUri; 88 | } 89 | 90 | public String getInputStream() { 91 | return inputStream; 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a Java project with Maven 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven 3 | 4 | name: Build 5 | 6 | on: 7 | push: 8 | branches: 9 | - "**" 10 | pull_request: 11 | branches: [ main ] 12 | 13 | jobs: 14 | build: 15 | runs-on: ${{ matrix.os }} 16 | continue-on-error: ${{ matrix.experimental }} 17 | strategy: 18 | fail-fast: false 19 | matrix: 20 | os: [ubuntu-latest, windows-latest] 21 | java: [ '11' ] 22 | experimental: [ false ] 23 | # JDK 17 build testing. Allowed to fail as marked experimental 24 | include: 25 | - java: 17 26 | os: ubuntu-latest 27 | experimental: true 28 | steps: 29 | - name: Git support longpaths 30 | run: git config --global core.longpaths true 31 | - name: Checkout 32 | uses: actions/checkout@v4 33 | - name: Set up JDK 11 34 | uses: actions/setup-java@v4 35 | with: 36 | distribution: 'temurin' 37 | java-version: ${{ matrix.java }} 38 | cache: 'maven' 39 | - name: Build with Maven 40 | run: mvn -B -U clean install 41 | 42 | deploy: 43 | if: github.ref == 'refs/heads/main' 44 | needs: [build] 45 | runs-on: ubuntu-latest 46 | steps: 47 | - name: Git support longpaths 48 | run: git config --global core.longpaths true 49 | - name: Checkout fcrepo 50 | uses: actions/checkout@v4 51 | - name: Set up JDK 11 52 | uses: actions/setup-java@v4 53 | with: 54 | java-version: 11 55 | distribution: 'temurin' 56 | server-id: sonatype-nexus-snapshots 57 | server-username: MAVEN_USERNAME 58 | server-password: MAVEN_PASSWORD 59 | # https://github.com/actions/setup-java/issues/43 60 | gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }} 61 | gpg-passphrase: GPG_PASSPHRASE 62 | - name: Publish package 63 | run: mvn -U -B -DskipTests=true deploy 64 | env: 65 | MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }} 66 | MAVEN_PASSWORD: ${{ secrets.OSSRH_TOKEN }} 67 | GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} 68 | - name: Deploy Docker image 69 | env: 70 | DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} 71 | DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} 72 | DOCKER_PLATFORMS: linux/arm64,linux/amd64 73 | run: | 74 | FCREPO_CAMEL_TOOLBOX_VERSION=$(mvn org.apache.maven.plugins:maven-help-plugin:3.2.0:evaluate -Dexpression=project.version -q -DforceStdout) 75 | echo "authenticating with dockerhub" 76 | docker login -u "$DOCKER_USERNAME" -p "$DOCKER_PASSWORD" 77 | echo "Building and pushing tags 'fcrepo/fcrepo-camel-toolbox' and 'fcrepo/fcrepo-camel-toolbox:${FCREPO_CAMEL_TOOLBOX_VERSION}' ..." 78 | docker buildx create --use 79 | docker buildx build --platform=${DOCKER_PLATFORMS} --push --tag="fcrepo/fcrepo-camel-toolbox" --tag="fcrepo/fcrepo-camel-toolbox:${FCREPO_CAMEL_TOOLBOX_VERSION}" . 80 | echo "Build and push complete" 81 | -------------------------------------------------------------------------------- /fcrepo-fixity/src/main/java/org/fcrepo/camel/fixity/FcrepoFixityConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The contents of this file are subject to the license and copyright 3 | * detailed in the LICENSE and NOTICE files at the root of the source 4 | * tree. 5 | */ 6 | package org.fcrepo.camel.fixity; 7 | 8 | import org.apache.camel.builder.RouteBuilder; 9 | import org.apache.camel.component.http.HttpComponent; 10 | import org.fcrepo.camel.common.config.BasePropsConfig; 11 | import org.fcrepo.camel.common.config.ConditionOnPropertyTrue; 12 | import org.slf4j.Logger; 13 | import org.slf4j.LoggerFactory; 14 | import org.springframework.beans.factory.annotation.Value; 15 | import org.springframework.context.annotation.Bean; 16 | import org.springframework.context.annotation.Conditional; 17 | import org.springframework.context.annotation.Configuration; 18 | 19 | /** 20 | * A configuration class for the Fixity service 21 | * 22 | * @author dbernstein 23 | */ 24 | @Configuration 25 | @Conditional({FcrepoFixityConfig.FixityEnabled.class}) 26 | public class FcrepoFixityConfig extends BasePropsConfig { 27 | 28 | private static final Logger LOGGER = LoggerFactory.getLogger(FcrepoFixityConfig.class); 29 | static final String FIXITY_ENABLED = "fixity.enabled"; 30 | 31 | static class FixityEnabled extends ConditionOnPropertyTrue { 32 | FixityEnabled() { 33 | super(FcrepoFixityConfig.FIXITY_ENABLED, false); 34 | } 35 | } 36 | 37 | @Value("${fixity.input.stream:broker:queue:fixity}") 38 | private String inputStream; 39 | 40 | 41 | @Value("${fixity.delay:0}") 42 | private long fixityDelay; 43 | 44 | @Value("${fixity.failure:file:/tmp/?fileName=fixityErrors.log&fileExist=Append}") 45 | private String fixityFailure; 46 | 47 | 48 | @Value("${fixity.success:mock:fixity.success}") 49 | private String fixitySuccess; 50 | 51 | /** 52 | * The jms message stream for the fixity service 53 | * @return 54 | */ 55 | public String getInputStream() { 56 | return inputStream; 57 | } 58 | 59 | /** 60 | * Because fixity checking can put a significant load on a server, it can be convenient 61 | * to introduce a delay between each fixity check. That delay is measured in milliseconds. 62 | */ 63 | public long getFixityDelay() { 64 | return fixityDelay; 65 | } 66 | 67 | /** 68 | * It is also possible to trigger an action on success (by default, this is a no-op): 69 | */ 70 | public String getFixitySuccess() { 71 | return fixitySuccess; 72 | } 73 | 74 | /** 75 | * Most importantly, it is possible to configure what should happen when a fixity check fails. 76 | * In the default example below, the fixity output is written to a file in `/tmp/fixityErrors.log`. But this can 77 | * be changed to send a message to an email address (`fixity.failure=smtp:admin@example.org?subject=Fixity`) 78 | * or use just about any other camel component. 79 | */ 80 | public String getFixityFailure() { 81 | return fixityFailure; 82 | } 83 | 84 | @Bean(name = "http") 85 | public HttpComponent http() { 86 | return new HttpComponent(); 87 | } 88 | 89 | @Bean(name = "https") 90 | public HttpComponent https() { 91 | return new HttpComponent(); 92 | } 93 | 94 | @Bean 95 | public RouteBuilder fixityRoute() { 96 | return new FixityRouter(); 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /fcrepo-camel-toolbox-app/src/main/java/org/fcrepo/camel/toolbox/app/Driver.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The contents of this file are subject to the license and copyright 3 | * detailed in the LICENSE and NOTICE files at the root of the source 4 | * tree. 5 | */ 6 | 7 | package org.fcrepo.camel.toolbox.app; 8 | 9 | import org.slf4j.Logger; 10 | import org.springframework.context.annotation.AnnotationConfigApplicationContext; 11 | import picocli.CommandLine; 12 | 13 | import java.nio.file.Path; 14 | import java.util.concurrent.Callable; 15 | import java.util.concurrent.CountDownLatch; 16 | 17 | import static org.fcrepo.camel.common.config.BasePropsConfig.FCREPO_CAMEL_CONFIG_FILE_PROPERTY; 18 | import static org.slf4j.LoggerFactory.getLogger; 19 | 20 | //TODO pull in version and git revision from generated property file 21 | 22 | /** 23 | * The command line tool entry point and parameter definitions 24 | * 25 | * @author dbernstein 26 | */ 27 | @CommandLine.Command(name = "fcrepo-camel-toolbox", 28 | mixinStandardHelpOptions = true, sortOptions = false, 29 | versionProvider = AppVersionProvider.class) 30 | public class Driver implements Callable { 31 | 32 | private static final Logger LOGGER = getLogger(Driver.class); 33 | 34 | 35 | @CommandLine.Option(names = {"--config", "-c"}, required = false, order = 1, 36 | description = "The path to the configuration file") 37 | private Path configurationFilePath; 38 | 39 | @Override 40 | public Integer call() { 41 | 42 | if (configurationFilePath != null) { 43 | System.setProperty(FCREPO_CAMEL_CONFIG_FILE_PROPERTY, configurationFilePath.toFile().getAbsolutePath()); 44 | } 45 | final var appContext = new AnnotationConfigApplicationContext("org.fcrepo.camel"); 46 | final var countdownLatch = new CountDownLatch(1); 47 | 48 | Runtime.getRuntime().addShutdownHook(new Thread(() -> { 49 | LOGGER.info("Shutting down fcrepo-camel-toolbox..."); 50 | appContext.stop(); 51 | countdownLatch.countDown(); 52 | })); 53 | appContext.start(); 54 | LOGGER.info("fcrepo-camel-toolbox started."); 55 | try { 56 | countdownLatch.await(); 57 | } catch (final InterruptedException e) { 58 | // Ignore error because we are exiting anyways. 59 | return 1; 60 | } 61 | return 0; 62 | } 63 | 64 | /** 65 | * @param args Command line arguments 66 | */ 67 | public static void main(final String[] args) { 68 | final Driver driver = new Driver(); 69 | final CommandLine cmd = new CommandLine(driver); 70 | cmd.setExecutionExceptionHandler(new AppExceptionHandler(driver)); 71 | cmd.execute(args); 72 | } 73 | 74 | private static class AppExceptionHandler implements CommandLine.IExecutionExceptionHandler { 75 | 76 | private final Driver driver; 77 | 78 | AppExceptionHandler(final Driver driver) { 79 | this.driver = driver; 80 | } 81 | 82 | @Override 83 | public int handleExecutionException( 84 | final Exception ex, 85 | final CommandLine commandLine, 86 | final CommandLine.ParseResult parseResult) { 87 | commandLine.getErr().println(ex.getMessage()); 88 | ex.printStackTrace(commandLine.getErr()); 89 | commandLine.usage(commandLine.getErr()); 90 | return commandLine.getCommandSpec().exitCodeOnExecutionException(); 91 | } 92 | } 93 | 94 | } 95 | -------------------------------------------------------------------------------- /fcrepo-indexing-solr/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 4.0.0 5 | 6 | 7 | fcrepo-camel-toolbox 8 | org.fcrepo.camel 9 | 6.3.0-SNAPSHOT 10 | 11 | 12 | fcrepo-indexing-solr 13 | jar 14 | 15 | Fedora Indexing Service with a Solr backend 16 | Camel-based indexing service for Solr 17 | 18 | 19 | 20 | 21 | 22 | 23 | org.apache.camel 24 | camel-core 25 | 26 | 27 | 28 | org.apache.camel 29 | camel-spring-javaconfig 30 | 31 | 32 | 33 | org.apache.camel 34 | camel-http 35 | 36 | 37 | 38 | org.apache.camel 39 | camel-mustache 40 | 41 | 42 | 43 | org.fcrepo.camel 44 | fcrepo-camel 45 | 46 | 47 | 48 | org.fcrepo.client 49 | fcrepo-java-client 50 | 51 | 52 | 53 | ${project.parent.groupId} 54 | fcrepo-camel-common 55 | ${project.parent.version} 56 | 57 | 58 | 59 | 60 | org.slf4j 61 | slf4j-api 62 | 63 | 64 | ch.qos.logback 65 | logback-classic 66 | 67 | 68 | 69 | 70 | org.apache.camel 71 | camel-test-spring 72 | 73 | 74 | 75 | ${project.parent.groupId} 76 | fcrepo-camel-common 77 | ${project.parent.version} 78 | test 79 | test-jar 80 | 81 | 82 | commons-io 83 | commons-io 84 | test 85 | 86 | 87 | 88 | xerces 89 | xercesImpl 90 | 91 | 92 | 93 | 94 | 95 | install 96 | 97 | 98 | 99 | 100 | org.apache.maven.plugins 101 | maven-compiler-plugin 102 | 103 | 104 | 105 | org.apache.maven.plugins 106 | maven-checkstyle-plugin 107 | 108 | 109 | 110 | org.apache.maven.plugins 111 | maven-resources-plugin 112 | 113 | 114 | 115 | 116 | 117 | 118 | -------------------------------------------------------------------------------- /fcrepo-indexing-triplestore/src/main/java/org/fcrepo/camel/indexing/triplestore/FcrepoTripleStoreIndexingConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The contents of this file are subject to the license and copyright 3 | * detailed in the LICENSE and NOTICE files at the root of the source 4 | * tree. 5 | */ 6 | package org.fcrepo.camel.indexing.triplestore; 7 | 8 | import org.apache.camel.builder.RouteBuilder; 9 | import org.apache.camel.component.http.HttpComponent; 10 | import org.fcrepo.camel.common.config.BasePropsConfig; 11 | import org.fcrepo.camel.common.config.ConditionOnPropertyTrue; 12 | import org.springframework.beans.factory.annotation.Value; 13 | import org.springframework.context.annotation.Bean; 14 | import org.springframework.context.annotation.Conditional; 15 | import org.springframework.context.annotation.Configuration; 16 | 17 | /** 18 | * A configuration class for the triplestore Indexing service 19 | * 20 | * @author dbernstein 21 | */ 22 | @Configuration 23 | @Conditional(FcrepoTripleStoreIndexingConfig.TriplestoreIndexingEnabled.class) 24 | public class FcrepoTripleStoreIndexingConfig extends BasePropsConfig { 25 | 26 | static final String TRIPLESTORE_INDEXING_ENABLED = "triplestore.indexing.enabled"; 27 | 28 | static class TriplestoreIndexingEnabled extends ConditionOnPropertyTrue { 29 | TriplestoreIndexingEnabled() { 30 | super(FcrepoTripleStoreIndexingConfig.TRIPLESTORE_INDEXING_ENABLED, false); 31 | } 32 | } 33 | 34 | @Value("${triplestore.input.stream:broker:topic:fedora}") 35 | private String inputStream; 36 | 37 | @Value("${triplestore.reindex.stream:broker:queue:triplestore.reindex}") 38 | private String reindexStream; 39 | 40 | @Value("${triplestore.indexing.predicate:false}") 41 | private boolean indexingPredicate; 42 | 43 | @Value("${triplestore.namedGraph:}") 44 | private String namedGraph; 45 | 46 | @Value("${triplestore.filter.containers:http://localhost:8080/fcrepo/rest/audit}") 47 | private String filterContainers; 48 | 49 | @Value("${triplestore.prefer.include:}") 50 | private String preferInclude; 51 | 52 | @Value("${triplestore.prefer.omit:http://www.w3.org/ns/ldp#PreferContainment}") 53 | private String preferOmit; 54 | 55 | @Value("${triplestore.baseUrl:http://localhost:8080/fuseki/test/update}") 56 | private String triplestoreBaseUrl; 57 | 58 | @Value("${triplestore.authUsername:}") 59 | private String triplestoreAuthUsername; 60 | 61 | @Value("${triplestore.authPassword:}") 62 | private String triplestoreAuthPassword; 63 | 64 | public String getInputStream() { 65 | return inputStream; 66 | } 67 | 68 | public String getReindexStream() { 69 | return reindexStream; 70 | } 71 | 72 | public boolean isIndexingPredicate() { 73 | return indexingPredicate; 74 | } 75 | 76 | public String getNamedGraph() { 77 | return namedGraph; 78 | } 79 | 80 | public String getFilterContainers() { 81 | return filterContainers; 82 | } 83 | 84 | public String getPreferInclude() { 85 | return preferInclude; 86 | } 87 | 88 | public String getPreferOmit() { 89 | return preferOmit; 90 | } 91 | 92 | public String getTriplestoreBaseUrl() { 93 | return triplestoreBaseUrl; 94 | } 95 | 96 | public String getTriplestoreAuthUsername() { 97 | return triplestoreAuthUsername; 98 | } 99 | 100 | public String getTriplestoreAuthPassword() { 101 | return triplestoreAuthPassword; 102 | } 103 | 104 | @Bean(name = "http") 105 | public HttpComponent http() { 106 | return new HttpComponent(); 107 | } 108 | 109 | @Bean(name = "https") 110 | public HttpComponent https() { 111 | return new HttpComponent(); 112 | } 113 | 114 | @Bean 115 | public RouteBuilder tripleStoreRoute() { 116 | return new TriplestoreRouter(); 117 | } 118 | 119 | } 120 | -------------------------------------------------------------------------------- /fcrepo-indexing-solr/src/main/java/org/fcrepo/camel/indexing/solr/FcrepoSolrIndexingConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The contents of this file are subject to the license and copyright 3 | * detailed in the LICENSE and NOTICE files at the root of the source 4 | * tree. 5 | */ 6 | package org.fcrepo.camel.indexing.solr; 7 | 8 | import org.apache.camel.builder.RouteBuilder; 9 | import org.apache.camel.component.http.HttpComponent; 10 | import org.fcrepo.camel.common.config.BasePropsConfig; 11 | import org.fcrepo.camel.common.config.ConditionOnPropertyTrue; 12 | import org.slf4j.Logger; 13 | import org.slf4j.LoggerFactory; 14 | import org.springframework.beans.factory.annotation.Value; 15 | import org.springframework.context.annotation.Bean; 16 | import org.springframework.context.annotation.Conditional; 17 | import org.springframework.context.annotation.Configuration; 18 | 19 | /** 20 | * A configuration class for the Solr Indexer service 21 | * 22 | * @author dbernstein 23 | */ 24 | @Configuration 25 | @Conditional(FcrepoSolrIndexingConfig.SolrIndexingEnabled.class) 26 | public class FcrepoSolrIndexingConfig extends BasePropsConfig { 27 | 28 | private static final Logger LOGGER = LoggerFactory.getLogger(FcrepoSolrIndexingConfig.class); 29 | static final String SOLR_INDEXING_ENABLED = "solr.indexing.enabled"; 30 | 31 | static class SolrIndexingEnabled extends ConditionOnPropertyTrue { 32 | SolrIndexingEnabled() { 33 | super(FcrepoSolrIndexingConfig.SOLR_INDEXING_ENABLED, false); 34 | } 35 | } 36 | 37 | @Value("${solr.fcrepo.checkHasIndexingTransformation:true}") 38 | private boolean checkHasIndexingTransformation; 39 | 40 | @Value("${solr.fcrepo.defaultTransform:org/fcrepo/camel/indexing/solr/default_transform.xsl}") 41 | private String defaultTransform; 42 | 43 | @Value("${solr.input.stream:broker:topic:fedora}") 44 | private String inputStream; 45 | 46 | @Value("${solr.reindex.stream:broker:queue:solr.reindex}") 47 | private String reindexStream; 48 | 49 | @Value("${solr.commitWithin:10000}") 50 | private long commitWithin; 51 | 52 | @Value("${solr.indexing.predicate:false}") 53 | private boolean indexingPredicate; 54 | 55 | @Value("${solr.filter.containers:http://localhost:8080/fcrepo/rest/audit}") 56 | private String filterContainers; 57 | 58 | @Value("${solr.baseUrl:http://localhost:8983/solr/collection1}") 59 | private String solrBaseUrl; 60 | 61 | @Value("${solr.username:}") 62 | private String solrUsername; 63 | 64 | @Value("${solr.password:}") 65 | private String solrPassword; 66 | 67 | @Value("${solr.include.containment:false}") 68 | private boolean includeContainment; 69 | 70 | public boolean isCheckHasIndexingTransformation() { 71 | return checkHasIndexingTransformation; 72 | } 73 | 74 | public String getDefaultTransform() { 75 | return defaultTransform; 76 | } 77 | 78 | public String getInputStream() { 79 | return inputStream; 80 | } 81 | 82 | public String getReindexStream() { 83 | return reindexStream; 84 | } 85 | 86 | public long getCommitWithin() { 87 | return commitWithin; 88 | } 89 | 90 | public boolean isIndexingPredicate() { 91 | return indexingPredicate; 92 | } 93 | 94 | public String getFilterContainers() { 95 | return filterContainers; 96 | } 97 | 98 | public String getSolrBaseUrl() { 99 | return solrBaseUrl; 100 | } 101 | 102 | public String getSolrUsername() { 103 | return solrUsername; 104 | } 105 | 106 | public String getSolrPassword() { 107 | return solrPassword; 108 | } 109 | public boolean isIncludeContainment() { 110 | return includeContainment; 111 | } 112 | 113 | @Bean(name = "http") 114 | public HttpComponent http() { 115 | return new HttpComponent(); 116 | } 117 | 118 | @Bean(name = "https") 119 | public HttpComponent https() { 120 | return new HttpComponent(); 121 | } 122 | 123 | @Bean 124 | public RouteBuilder solrRoute() { 125 | return new SolrRouter(); 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /fcrepo-audit-triplestore/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 4.0.0 5 | 6 | 7 | org.fcrepo.camel 8 | fcrepo-camel-toolbox 9 | 6.3.0-SNAPSHOT 10 | 11 | 12 | fcrepo-audit-triplestore 13 | jar 14 | 15 | Fedora Audit System with a Triplestore backend 16 | Camel-based audit system built with a triplestore backend 17 | 18 | 19 | 20 | 21 | ${project.parent.groupId} 22 | fcrepo-camel-common 23 | ${project.parent.version} 24 | 25 | 26 | 27 | org.apache.camel 28 | camel-core 29 | 30 | 31 | 32 | org.apache.camel 33 | camel-spring-javaconfig 34 | 35 | 36 | 37 | org.apache.camel 38 | camel-spring 39 | 40 | 41 | 42 | org.springframework 43 | spring-context 44 | 45 | 46 | 47 | org.apache.camel 48 | camel-http 49 | 50 | 51 | 52 | org.fcrepo.camel 53 | fcrepo-camel 54 | 55 | 56 | org.apache.jena 57 | jena-core 58 | 59 | 60 | 61 | 62 | org.slf4j 63 | slf4j-api 64 | 65 | 66 | ch.qos.logback 67 | logback-classic 68 | 69 | 70 | 71 | 72 | 73 | org.apache.camel 74 | camel-test-spring 75 | 76 | 77 | 78 | org.apache.jena 79 | jena-fuseki-main 80 | test 81 | 82 | 83 | 84 | org.apache.commons 85 | commons-lang3 86 | test 87 | 88 | 89 | 90 | ${project.parent.groupId} 91 | fcrepo-service-activemq 92 | ${project.parent.version} 93 | test 94 | 95 | 96 | 97 | 98 | 99 | install 100 | 101 | 102 | 103 | org.apache.maven.plugins 104 | maven-checkstyle-plugin 105 | 106 | 107 | 108 | org.apache.maven.plugins 109 | maven-compiler-plugin 110 | 111 | 112 | 113 | 114 | org.codehaus.mojo 115 | build-helper-maven-plugin 116 | 117 | 118 | fuseki.dynamic.test.port 119 | 120 | 121 | 122 | 123 | 124 | org.apache.maven.plugins 125 | maven-failsafe-plugin 126 | 127 | ${jacoco.agent.it.arg} 128 | 129 | ${fuseki.dynamic.test.port} 130 | 131 | 132 | 133 | 134 | 135 | 136 | -------------------------------------------------------------------------------- /fcrepo-http-forwarding/src/test/java/org/fcrepo/camel/httpforwarding/integration/TestUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The contents of this file are subject to the license and copyright 3 | * detailed in the LICENSE and NOTICE files at the root of the source 4 | * tree. 5 | */ 6 | package org.fcrepo.camel.httpforwarding.integration; 7 | 8 | import org.apache.camel.Exchange; 9 | import org.apache.http.client.methods.HttpPost; 10 | import org.apache.http.entity.StringEntity; 11 | import org.apache.http.impl.client.CloseableHttpClient; 12 | import org.apache.http.impl.client.HttpClients; 13 | import org.fcrepo.client.FcrepoClient; 14 | 15 | import static org.fcrepo.client.FcrepoClient.client; 16 | 17 | /** 18 | * Utility functions for the integration tests 19 | * 20 | * @author acoburn 21 | * @since 2015-04-21 22 | */ 23 | public class TestUtils { 24 | 25 | private static String FEDORA_USERNAME = "fedoraAdmin"; 26 | private static String FEDORA_PASSWORD = "fedoraAdmin"; 27 | 28 | /** 29 | * Get an event for a given URL 30 | * 31 | * @param subject the URL 32 | * @param eventType the event type 33 | * @return the event message as JSON 34 | */ 35 | public static String getEvent(final String subject, final String eventType) { 36 | return "{\n" + 37 | "\"id\": \"urn:uuid:3c834a8f-5638-4412-aa4b-35ea80416a18\", \n" + 38 | "\"type\" : [ \"http://www.w3.org/ns/prov#Activity\" ,\n" + 39 | " \"" + eventType + "\" ],\n" + 40 | "\"name\": \"resource event\",\n" + 41 | " \"published\": \"2016-05-19T17:17:43-04:00Z\",\n" + 42 | " \"actor\": [{\n" + 43 | " \"type\": [\"Person\"],\n" + 44 | " \"id\": \"info:fedora/fedoraAdmin\"\n" + 45 | "}, {\n" + 46 | " \"type\": [\"Application\"],\n" + 47 | " \"name\": \"CLAW client/1.0\"\n" + 48 | "}],\n" + 49 | " \n" + 50 | "\"object\" : {\n" + 51 | " \"id\" : \"" + subject + "\" ,\n" + 52 | " \"type\" : [\n" + 53 | " \"http://www.w3.org/ns/prov#Entity\" ,\n" + 54 | " \"http://fedora.info/definitions/v4/repository#Resource\" ,\n" + 55 | " \"http://fedora.info/definitions/v4/repository#Container\" ,\n" + 56 | " \"http://www.w3.org/ns/ldp#RDFSource\",\n" + 57 | " \"http://www.w3.org/ns/ldp#BasicContainer\" ],\n" + 58 | " \"isPartOf\" : \"http://localhost/rest\"\n" + 59 | "},\n" + 60 | " \n" + 61 | "\"@context\": [\"https://www.w3.org/ns/activitystreams\", {\n" + 62 | " \"prov\": \"http://www.w3.org/ns/prov#\",\n" + 63 | " \"dcterms\": \"http://purl.org/dc/terms/\",\n" + 64 | " \"type\": \"@type\",\n" + 65 | " \"id\": \"@id\",\n" + 66 | " \"isPartOf\": {\n" + 67 | " \"@id\": \"dcterms:isPartOf\",\n" + 68 | " \"@type\": \"@id\"\n" + 69 | "}}]\n" + 70 | "}"; 71 | } 72 | 73 | /** 74 | * Post data to the provided URL 75 | * 76 | * @param url string containing URL 77 | * @param content string containing data 78 | * @param mimeType string containing MIMe type of content 79 | * @throws Exception in the event of an HTTP client failure 80 | */ 81 | public static void httpPost(final String url, final String content, final String mimeType) throws Exception { 82 | final CloseableHttpClient httpClient = HttpClients.createDefault(); 83 | final HttpPost post = new HttpPost(url); 84 | post.addHeader(Exchange.CONTENT_TYPE, mimeType); 85 | post.setEntity(new StringEntity(content)); 86 | httpClient.execute(post); 87 | } 88 | 89 | /** 90 | * Create a new FcrepoClient instance with authentication. 91 | * @return the newly created client 92 | */ 93 | public static FcrepoClient createClient() { 94 | return client().throwExceptionOnFailure() 95 | .authScope("localhost") 96 | .credentials(FEDORA_USERNAME, FEDORA_PASSWORD).build(); 97 | } 98 | 99 | private TestUtils() { 100 | // prevent instantiation 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /fcrepo-http-forwarding/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 4.0.0 5 | 6 | 7 | fcrepo-camel-toolbox 8 | org.fcrepo.camel 9 | 6.3.0-SNAPSHOT 10 | 11 | 12 | fcrepo-http-forwarding 13 | jar 14 | 15 | Fedora Http Message Forwarding Service 16 | Camel-based HTTP forwarding service 17 | 18 | 19 | 20 | 21 | 22 | 23 | org.apache.camel 24 | camel-core 25 | 26 | 27 | 28 | org.apache.camel 29 | camel-spring-javaconfig 30 | 31 | 32 | 33 | org.apache.camel 34 | camel-http 35 | 36 | 37 | 38 | org.fcrepo.camel 39 | fcrepo-camel 40 | 41 | 42 | 43 | org.fcrepo.client 44 | fcrepo-java-client 45 | 46 | 47 | 48 | org.apache.camel 49 | camel-mustache 50 | 51 | 52 | 53 | ${project.parent.groupId} 54 | fcrepo-camel-common 55 | ${project.parent.version} 56 | 57 | 58 | 59 | 60 | org.slf4j 61 | slf4j-api 62 | 63 | 64 | ch.qos.logback 65 | logback-classic 66 | 67 | 68 | 69 | 70 | org.apache.camel 71 | camel-test-spring 72 | 73 | 74 | 75 | commons-io 76 | commons-io 77 | test 78 | 79 | 80 | 81 | com.github.tomakehurst 82 | wiremock-jre8 83 | 2.35.1 84 | test 85 | 86 | 87 | 88 | org.apache.camel 89 | camel-activemq 90 | test 91 | 92 | 93 | 94 | xerces 95 | xercesImpl 96 | 97 | 98 | 99 | 100 | 101 | install 102 | 103 | 104 | 105 | 106 | org.apache.maven.plugins 107 | maven-compiler-plugin 108 | 109 | 110 | 111 | org.apache.maven.plugins 112 | maven-checkstyle-plugin 113 | 114 | 115 | 116 | org.apache.maven.plugins 117 | maven-resources-plugin 118 | 119 | 120 | 121 | 122 | 123 | org.codehaus.mojo 124 | build-helper-maven-plugin 125 | 126 | 127 | mockserver.dynamic.test.port 128 | 129 | 130 | 131 | 132 | 133 | 134 | org.apache.maven.plugins 135 | maven-failsafe-plugin 136 | 137 | ${jacoco.agent.it.arg} 138 | 139 | ${mockserver.dynamic.test.port} 140 | 141 | 142 | 143 | 144 | 145 | 146 | -------------------------------------------------------------------------------- /fcrepo-http-forwarding/src/main/java/org/fcrepo/camel/httpforwarding/HttpRouter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The contents of this file are subject to the license and copyright 3 | * detailed in the LICENSE and NOTICE files at the root of the source 4 | * tree. 5 | */ 6 | package org.fcrepo.camel.httpforwarding; 7 | 8 | import org.apache.camel.LoggingLevel; 9 | import org.apache.camel.builder.RouteBuilder; 10 | import org.fcrepo.camel.common.processor.AddBasicAuthProcessor; 11 | import org.apache.camel.support.builder.Namespaces; 12 | import org.fcrepo.camel.processor.EventProcessor; 13 | import org.slf4j.Logger; 14 | import org.springframework.beans.factory.annotation.Autowired; 15 | 16 | import static org.apache.camel.builder.PredicateBuilder.in; 17 | import static org.apache.camel.builder.PredicateBuilder.not; 18 | import static org.apache.camel.builder.PredicateBuilder.or; 19 | import static org.fcrepo.camel.FcrepoHeaders.FCREPO_URI; 20 | import static java.util.stream.Collectors.toList; 21 | import static org.fcrepo.camel.processor.ProcessorUtils.tokenizePropertyPlaceholder; 22 | 23 | import static org.apache.camel.Exchange.CONTENT_TYPE; 24 | import static org.apache.camel.Exchange.HTTP_METHOD; 25 | import static org.fcrepo.camel.FcrepoHeaders.FCREPO_EVENT_TYPE; 26 | import static org.slf4j.LoggerFactory.getLogger; 27 | 28 | /** 29 | * A content router for handling JMS events. 30 | * 31 | * @author Geoff Scholl 32 | * @author Demian Katz 33 | */ 34 | public class HttpRouter extends RouteBuilder { 35 | 36 | private static final Logger LOGGER = getLogger(HttpRouter.class); 37 | 38 | @Autowired 39 | private FcrepoHttpForwardingConfig config; 40 | 41 | /** 42 | * Configure the message route workflow. 43 | */ 44 | public void configure() throws Exception { 45 | 46 | final Namespaces ns = new Namespaces("rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#"); 47 | ns.add("indexing", "http://fedora.info/definitions/v4/indexing#"); 48 | ns.add("ldp", "http://www.w3.org/ns/ldp#"); 49 | 50 | /* 51 | * A generic error handler (specific to this RouteBuilder) 52 | */ 53 | onException(Exception.class) 54 | .maximumRedeliveries(config.getMaxRedeliveries()) 55 | .log("Index Routing Error: ${routeId}"); 56 | 57 | /* 58 | * route a message to the proper queue 59 | */ 60 | from(config.getInputStream()) 61 | .routeId("FcrepoHttpRouter") 62 | .process(new EventProcessor()) 63 | .log(LoggingLevel.TRACE, "Received message from Fedora routing to index.http") 64 | .to("direct:add.type.to.http.message"); 65 | 66 | /* 67 | * Handle re-index events 68 | */ 69 | from(config.getReindexStream()) 70 | .routeId("FcrepoHttpReindex") 71 | .to("direct:add.type.to.http.message"); 72 | 73 | /* 74 | * Add event type header to message; we want to use the header.org.fcrepo.jms.eventtype 75 | * value when it is available. If it is unset, that likely indicates a reindex operation, 76 | * in which case we should default to an Update. 77 | */ 78 | from("direct:add.type.to.http.message") 79 | .routeId("FcrepoHttpAddType") 80 | .choice() 81 | .when(simple("${header.org.fcrepo.jms.eventtype}")) 82 | .setHeader(FCREPO_EVENT_TYPE).simple("${header.org.fcrepo.jms.eventtype}") 83 | .to("direct:send.to.http") 84 | .otherwise() 85 | .setHeader(FCREPO_EVENT_TYPE).constant("https://www.w3.org/ns/activitystreams#Update") 86 | .to("direct:send.to.http"); 87 | 88 | /* 89 | * Forward message to Http 90 | */ 91 | from("direct:send.to.http").routeId("FcrepoHttpSend") 92 | .filter(not(in(tokenizePropertyPlaceholder(getContext(), config.getFilterContainers(), ",").stream() 93 | .map(uri -> or( 94 | header(FCREPO_URI).startsWith(constant(uri + "/")), 95 | header(FCREPO_URI).isEqualTo(constant(uri)))) 96 | .collect(toList())))) 97 | .log(LoggingLevel.INFO, LOGGER, "sending ${headers[CamelFcrepoUri]} to http endpoint...") 98 | .to("mustache:org/fcrepo/camel/httpforwarding/httpMessage.mustache") 99 | .setHeader(HTTP_METHOD).constant("POST") 100 | .setHeader(CONTENT_TYPE).constant("application/json") 101 | .process(new AddBasicAuthProcessor(config.getHttpAuthUsername(), config.getHttpAuthPassword())) 102 | .to(config.getHttpBaseUrl().isEmpty() ? "direct:http.baseurl.missing" : config.getHttpBaseUrl()); 103 | 104 | /* 105 | * Stop the route if configuration is incomplete. 106 | */ 107 | from("direct:http.baseurl.missing") 108 | .routeId("FcrepoHttpBaseUrlMissing") 109 | .log(LoggingLevel.ERROR, LOGGER, "Cannot forward HTTP message because http.baseUrl property is empty.") 110 | .stop(); 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /fcrepo-audit-triplestore/src/test/java/org/fcrepo/camel/audit/triplestore/integration/RouteAuthTestIT.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The contents of this file are subject to the license and copyright 3 | * detailed in the LICENSE and NOTICE files at the root of the source 4 | * tree. 5 | */ 6 | package org.fcrepo.camel.audit.triplestore.integration; 7 | 8 | import org.apache.camel.CamelContext; 9 | import org.apache.camel.Produce; 10 | import org.apache.camel.ProducerTemplate; 11 | import org.apache.camel.builder.AdviceWith; 12 | import org.apache.camel.component.mock.MockEndpoint; 13 | import org.apache.camel.model.ModelCamelContext; 14 | import org.apache.camel.spring.javaconfig.CamelConfiguration; 15 | import org.apache.jena.atlas.web.AuthScheme; 16 | import org.apache.jena.fuseki.main.FusekiServer; 17 | import org.apache.jena.query.Dataset; 18 | import org.apache.jena.query.DatasetFactory; 19 | import org.junit.After; 20 | import org.junit.Before; 21 | import org.junit.BeforeClass; 22 | import org.junit.Test; 23 | import org.junit.runner.RunWith; 24 | import org.slf4j.Logger; 25 | import org.springframework.beans.factory.annotation.Autowired; 26 | import org.springframework.context.annotation.ComponentScan; 27 | import org.springframework.context.annotation.Configuration; 28 | import org.springframework.test.annotation.DirtiesContext; 29 | import org.springframework.test.context.ContextConfiguration; 30 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 31 | import org.springframework.test.context.support.AnnotationConfigContextLoader; 32 | 33 | import static java.lang.Integer.parseInt; 34 | import static org.apache.camel.util.ObjectHelper.loadResourceAsStream; 35 | import static org.slf4j.LoggerFactory.getLogger; 36 | 37 | /** 38 | * Test routing against a triple store with basic authentication 39 | * 40 | * @author Andy Pfister 41 | * @since 2015-04-10 42 | */ 43 | @RunWith(SpringJUnit4ClassRunner.class) 44 | @ContextConfiguration(loader = AnnotationConfigContextLoader.class) 45 | public class RouteAuthTestIT { 46 | 47 | final private Logger logger = getLogger(RouteAuthTestIT.class); 48 | 49 | private static FusekiServer server = null; 50 | 51 | @Produce("direct:start") 52 | protected ProducerTemplate template; 53 | 54 | @Autowired 55 | private CamelContext camelContext; 56 | 57 | private static final String baseURL = "http://localhost/rest"; 58 | private static final String auditContainer = "/audit"; 59 | 60 | private static final String FUSEKI_PORT = System.getProperty( 61 | "fuseki.dynamic.test.port", "8080" 62 | ); 63 | 64 | @BeforeClass 65 | public static void beforeClass() { 66 | System.setProperty("audit.input.stream", "seda:foo"); 67 | System.setProperty("audit.filter.containers", baseURL + auditContainer); 68 | System.setProperty("audit.enabled", "true"); 69 | 70 | System.setProperty("audit.triplestore.baseUrl", "http://localhost:" + FUSEKI_PORT + "/fuseki/test/update"); 71 | System.setProperty("audit.triplestore.authUsername", "admin"); 72 | System.setProperty("audit.triplestore.authPassword", "password"); 73 | } 74 | 75 | @After 76 | public void tearDownFuseki() throws Exception { 77 | logger.info("Stopping EmbeddedFusekiServer"); 78 | server.stop(); 79 | } 80 | 81 | @Before 82 | public void setUpFuseki() throws Exception { 83 | logger.info("Starting EmbeddedFusekiServer on port {}", FUSEKI_PORT); 84 | final Dataset ds = DatasetFactory.createTxnMem(); 85 | server = FusekiServer.create() 86 | .verbose(true) 87 | .port(parseInt(FUSEKI_PORT)) 88 | .contextPath("/fuseki") 89 | .add("/test", ds, true) 90 | .passwordFile("src/test/resources/passwd") 91 | .auth(AuthScheme.BASIC) 92 | .build(); 93 | server.start(); 94 | } 95 | 96 | @DirtiesContext 97 | @Test 98 | public void testBasicAuthFusekiShouldReceiveMessages() throws Exception { 99 | final String fusekiEndpoint = "mock:http:localhost:" + FUSEKI_PORT + "/fuseki/test/update"; 100 | final var context = camelContext.adapt(ModelCamelContext.class); 101 | 102 | AdviceWith.adviceWith(context, "AuditFcrepoRouter", a -> { 103 | a.replaceFromWith("direct:start"); 104 | }); 105 | 106 | AdviceWith.adviceWith(context, "AuditEventRouter", a -> { 107 | a.mockEndpoints("*"); 108 | }); 109 | 110 | final var fusekiMockEndpoint = MockEndpoint.resolve(camelContext, fusekiEndpoint); 111 | fusekiMockEndpoint.expectedMessageCount(2); 112 | fusekiMockEndpoint.setAssertPeriod(5000); 113 | 114 | template.sendBody(loadResourceAsStream("event_delete_binary.json")); 115 | template.sendBody(loadResourceAsStream("event_delete_resource.json")); 116 | 117 | MockEndpoint.assertIsSatisfied(fusekiMockEndpoint); 118 | } 119 | 120 | @Configuration 121 | @ComponentScan(basePackages = "org.fcrepo.camel.audit") 122 | static class ContextConfig extends CamelConfiguration { 123 | 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /fcrepo-camel-toolbox-app/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | fcrepo-camel-toolbox 5 | org.fcrepo.camel 6 | 6.3.0-SNAPSHOT 7 | 8 | 4.0.0 9 | 10 | fcrepo-camel-toolbox-app 11 | 12 | 13 | 14 | 15 | ${project.parent.groupId} 16 | fcrepo-service-camel 17 | ${project.parent.version} 18 | 19 | 20 | 21 | 22 | ${project.parent.groupId} 23 | fcrepo-service-activemq 24 | ${project.parent.version} 25 | 26 | 27 | 28 | ${project.parent.groupId} 29 | fcrepo-indexing-solr 30 | ${project.parent.version} 31 | 32 | 33 | 34 | ${project.parent.groupId} 35 | fcrepo-http-forwarding 36 | ${project.parent.version} 37 | 38 | 39 | 40 | ${project.parent.groupId} 41 | fcrepo-reindexing 42 | ${project.parent.version} 43 | 44 | 45 | 46 | ${project.parent.groupId} 47 | fcrepo-indexing-triplestore 48 | ${project.parent.version} 49 | 50 | 51 | 52 | ${project.parent.groupId} 53 | fcrepo-fixity 54 | ${project.parent.version} 55 | 56 | 57 | 58 | ${project.parent.groupId} 59 | fcrepo-audit-triplestore 60 | ${project.parent.version} 61 | 62 | 63 | 64 | org.apache.camel 65 | camel-spring-javaconfig 66 | 67 | 68 | 69 | info.picocli 70 | picocli 71 | 4.5.2 72 | 73 | 74 | 75 | org.apache.httpcomponents 76 | httpclient 77 | 78 | 79 | commons-codec 80 | commons-codec 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | src/main/resources 90 | true 91 | 92 | 93 | 94 | 95 | 96 | org.apache.maven.plugins 97 | maven-checkstyle-plugin 98 | 99 | 100 | 101 | org.apache.maven.plugins 102 | maven-shade-plugin 103 | 3.2.1 104 | 105 | 106 | package 107 | 108 | shade 109 | 110 | 111 | true 112 | driver 113 | 114 | 115 | 116 | org.fcrepo.camel.toolbox.app.Driver 117 | 118 | 119 | META-INF/services/org/apache/camel/TypeConverterLoader 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | org.codehaus.mojo 129 | buildnumber-maven-plugin 130 | 1.3 131 | 132 | 133 | validate 134 | 135 | create 136 | 137 | 138 | 139 | 140 | false 141 | false 142 | 5 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | -------------------------------------------------------------------------------- /fcrepo-audit-triplestore/src/test/java/org/fcrepo/camel/audit/triplestore/RouteTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The contents of this file are subject to the license and copyright 3 | * detailed in the LICENSE and NOTICE files at the root of the source 4 | * tree. 5 | */ 6 | package org.fcrepo.camel.audit.triplestore; 7 | 8 | import org.apache.camel.CamelContext; 9 | import org.apache.camel.EndpointInject; 10 | import org.apache.camel.Exchange; 11 | import org.apache.camel.Produce; 12 | import org.apache.camel.ProducerTemplate; 13 | import org.apache.camel.builder.AdviceWith; 14 | import org.apache.camel.component.mock.MockEndpoint; 15 | import org.apache.camel.model.ModelCamelContext; 16 | import org.apache.camel.spring.javaconfig.CamelConfiguration; 17 | import org.junit.BeforeClass; 18 | import org.junit.Test; 19 | import org.junit.runner.RunWith; 20 | import org.springframework.beans.factory.annotation.Autowired; 21 | import org.springframework.context.annotation.ComponentScan; 22 | import org.springframework.context.annotation.Configuration; 23 | import org.springframework.test.annotation.DirtiesContext; 24 | import org.springframework.test.context.ContextConfiguration; 25 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 26 | import org.springframework.test.context.support.AnnotationConfigContextLoader; 27 | 28 | import static org.apache.camel.component.mock.MockEndpoint.assertIsSatisfied; 29 | import static org.apache.camel.util.ObjectHelper.loadResourceAsStream; 30 | import static org.fcrepo.camel.audit.triplestore.AuditSparqlProcessor.AUDIT; 31 | import static org.fcrepo.camel.audit.triplestore.AuditSparqlProcessor.PREMIS; 32 | import static org.junit.Assert.assertTrue; 33 | 34 | /** 35 | * Test the route workflow. 36 | * 37 | * @author escowles 38 | * @author Aaron Coburn 39 | * @author dbernstein 40 | * @since 2015-04-10 41 | */ 42 | @RunWith(SpringJUnit4ClassRunner.class) 43 | @ContextConfiguration(classes = {RouteTest.ContextConfig.class}, loader = AnnotationConfigContextLoader.class) 44 | public class RouteTest { 45 | 46 | @EndpointInject("mock:result") 47 | protected MockEndpoint resultEndpoint; 48 | 49 | @Produce("direct:start") 50 | protected ProducerTemplate template; 51 | 52 | @Autowired 53 | private CamelContext camelContext; 54 | 55 | private static final String baseURL = "http://localhost/rest"; 56 | private static final String fileID = "/file1"; 57 | private static final String auditContainer = "/audit"; 58 | 59 | 60 | @BeforeClass 61 | public static void beforeClass() { 62 | System.setProperty("audit.input.stream", "seda:foo"); 63 | System.setProperty("audit.filter.containers", baseURL + auditContainer); 64 | System.setProperty("audit.enabled", "true"); 65 | } 66 | 67 | @DirtiesContext 68 | @Test 69 | public void testWithoutJms() throws Exception { 70 | 71 | final var context = camelContext.adapt(ModelCamelContext.class); 72 | 73 | AdviceWith.adviceWith(context, "AuditFcrepoRouter", a -> { 74 | a.replaceFromWith("direct:start"); 75 | }); 76 | 77 | AdviceWith.adviceWith(context, "AuditEventRouter", a -> { 78 | a.mockEndpointsAndSkip("http*"); 79 | a.weaveAddLast().to("mock:result"); 80 | }); 81 | 82 | resultEndpoint.expectedMessageCount(2); 83 | resultEndpoint.expectedHeaderReceived(Exchange.CONTENT_TYPE, "application/x-www-form-urlencoded"); 84 | resultEndpoint.expectedHeaderReceived(Exchange.HTTP_METHOD, "POST"); 85 | resultEndpoint.expectedHeaderReceived(AuditHeaders.EVENT_BASE_URI, "http://example.com/event"); 86 | 87 | template.sendBody(loadResourceAsStream("event_delete_binary.json")); 88 | template.sendBody(loadResourceAsStream("event_delete_resource.json")); 89 | 90 | assertIsSatisfied(resultEndpoint); 91 | final String body = (String) resultEndpoint.assertExchangeReceived(0).getIn().getBody(); 92 | assertTrue("Event type not found!", 93 | body.contains("<" + PREMIS + "hasEventType> <" + AUDIT + "contentRemoval>")); 94 | assertTrue("Object link not found!", 95 | body.contains("<" + PREMIS + "hasEventRelatedObject> <" + baseURL + fileID + ">")); 96 | } 97 | 98 | @DirtiesContext 99 | @Test 100 | public void testFilterContainersWithoutJms() throws Exception { 101 | 102 | final var context = camelContext.adapt(ModelCamelContext.class); 103 | 104 | resultEndpoint.expectedMessageCount(0); 105 | resultEndpoint.setAssertPeriod(1000); 106 | 107 | AdviceWith.adviceWith(context, "AuditFcrepoRouter", a -> { 108 | a.replaceFromWith("direct:start"); 109 | }); 110 | 111 | AdviceWith.adviceWith(context, "AuditEventRouter", a -> { 112 | a.mockEndpointsAndSkip("http*"); 113 | a.weaveAddLast().to("mock:result"); 114 | }); 115 | 116 | //send events that should be filtered 117 | template.sendBody(loadResourceAsStream("event_audit_resource.json")); 118 | template.sendBody(loadResourceAsStream("event_audit_update.json")); 119 | 120 | assertIsSatisfied(resultEndpoint); 121 | } 122 | 123 | @Configuration 124 | @ComponentScan(basePackages = "org.fcrepo.camel.audit") 125 | static class ContextConfig extends CamelConfiguration { 126 | 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /fcrepo-service-activemq/src/test/java/org/fcrepo/camel/service/activemq/RouteIT.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The contents of this file are subject to the license and copyright 3 | * detailed in the LICENSE and NOTICE files at the root of the source 4 | * tree. 5 | */ 6 | package org.fcrepo.camel.service.activemq; 7 | 8 | import org.apache.camel.CamelContext; 9 | import org.apache.camel.EndpointInject; 10 | import org.apache.camel.ServiceStatus; 11 | import org.apache.camel.builder.RouteBuilder; 12 | import org.apache.camel.component.mock.MockEndpoint; 13 | import org.apache.camel.spring.javaconfig.CamelConfiguration; 14 | import org.apache.http.HttpResponse; 15 | import org.apache.http.auth.AuthScope; 16 | import org.apache.http.auth.UsernamePasswordCredentials; 17 | import org.apache.http.client.methods.HttpPost; 18 | import org.apache.http.impl.client.BasicCredentialsProvider; 19 | import org.apache.http.impl.client.CloseableHttpClient; 20 | import org.apache.http.impl.client.HttpClients; 21 | import org.apache.http.util.EntityUtils; 22 | import org.fcrepo.camel.processor.EventProcessor; 23 | import org.junit.BeforeClass; 24 | import org.junit.Test; 25 | import org.junit.runner.RunWith; 26 | import org.slf4j.Logger; 27 | import org.springframework.beans.factory.annotation.Autowired; 28 | import org.springframework.context.annotation.Bean; 29 | import org.springframework.context.annotation.ComponentScan; 30 | import org.springframework.context.annotation.Configuration; 31 | import org.springframework.test.context.ContextConfiguration; 32 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 33 | import org.springframework.test.context.support.AnnotationConfigContextLoader; 34 | 35 | import java.io.IOException; 36 | import java.util.ArrayList; 37 | import java.util.List; 38 | import java.util.concurrent.TimeUnit; 39 | 40 | import static org.apache.camel.component.mock.MockEndpoint.assertIsSatisfied; 41 | import static org.apache.http.HttpStatus.SC_CREATED; 42 | import static org.fcrepo.camel.FcrepoHeaders.FCREPO_URI; 43 | import static org.junit.Assert.assertEquals; 44 | import static org.slf4j.LoggerFactory.getLogger; 45 | 46 | /** 47 | * Test the route workflow. 48 | * 49 | * @author Aaron Coburn 50 | * @since 2016-05-04 51 | */ 52 | @RunWith(SpringJUnit4ClassRunner.class) 53 | @ContextConfiguration(classes = {ContextConfig.class}, loader = AnnotationConfigContextLoader.class) 54 | public class RouteIT { 55 | private static final Logger LOGGER = getLogger(RouteIT.class); 56 | private static String FEDORA_USERNAME = "fedoraAdmin"; 57 | private static String FEDORA_PASSWORD = "fedoraAdmin"; 58 | 59 | @EndpointInject("mock:result") 60 | protected MockEndpoint resultEndpoint; 61 | 62 | @Autowired 63 | private CamelContext camelContext; 64 | 65 | @BeforeClass 66 | public static void beforeClass() { 67 | final String jmsPort = System.getProperty("fcrepo.dynamic.jms.port", "61616"); 68 | System.setProperty("jms.brokerUrl", "tcp://localhost:" + jmsPort); 69 | } 70 | 71 | @Test 72 | public void testQueuingService() throws Exception { 73 | assertEquals(ServiceStatus.Started, camelContext.getStatus()); 74 | final String webPort = System.getProperty("fcrepo.dynamic.test.port", "8080"); 75 | final String baseUrl = "http://localhost:" + webPort + "/fcrepo/rest"; 76 | 77 | resultEndpoint.reset(); 78 | 79 | final String url1 = post(baseUrl); 80 | final String url2 = post(baseUrl); 81 | 82 | final List expectedIds = new ArrayList<>(); 83 | expectedIds.add(url1); 84 | expectedIds.add(url2); 85 | 86 | // expectedMessageCount is set to the number of elements passed to the below function, 87 | // so we need to account for them all or the test stops and just checks the ones we have. 88 | resultEndpoint.expectedHeaderValuesReceivedInAnyOrder(FCREPO_URI, expectedIds); 89 | resultEndpoint.await(500, TimeUnit.MILLISECONDS); 90 | 91 | assertIsSatisfied(resultEndpoint); 92 | } 93 | 94 | private String post(final String url) { 95 | final BasicCredentialsProvider provider = new BasicCredentialsProvider(); 96 | provider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(FEDORA_USERNAME, FEDORA_PASSWORD)); 97 | final CloseableHttpClient httpclient = HttpClients.custom().setDefaultCredentialsProvider(provider).build(); 98 | try { 99 | final HttpPost httppost = new HttpPost(url); 100 | final HttpResponse response = httpclient.execute(httppost); 101 | assertEquals(SC_CREATED, response.getStatusLine().getStatusCode()); 102 | return EntityUtils.toString(response.getEntity(), "UTF-8"); 103 | } catch (final IOException ex) { 104 | LOGGER.debug("Unable to extract HttpEntity response into an InputStream: ", ex); 105 | return ""; 106 | } 107 | } 108 | } 109 | 110 | @Configuration 111 | @ComponentScan("org.fcrepo.camel") 112 | class ContextConfig extends CamelConfiguration { 113 | 114 | @Bean 115 | public RouteBuilder route() { 116 | return new RouteBuilder() { 117 | public void configure() throws Exception { 118 | from("broker:topic:fedora") 119 | .process(new EventProcessor()) 120 | .to("mock:result"); 121 | } 122 | }; 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /fcrepo-service-camel/src/test/java/org/fcrepo/camel/service/RouteIT.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The contents of this file are subject to the license and copyright 3 | * detailed in the LICENSE and NOTICE files at the root of the source 4 | * tree. 5 | */ 6 | package org.fcrepo.camel.service; 7 | 8 | import org.apache.camel.EndpointInject; 9 | import org.apache.camel.Produce; 10 | import org.apache.camel.ProducerTemplate; 11 | import org.apache.camel.builder.RouteBuilder; 12 | import org.apache.camel.component.mock.MockEndpoint; 13 | import org.apache.camel.spring.javaconfig.CamelConfiguration; 14 | import org.apache.http.HttpResponse; 15 | import org.apache.http.auth.AuthScope; 16 | import org.apache.http.auth.UsernamePasswordCredentials; 17 | import org.apache.http.client.methods.HttpPost; 18 | import org.apache.http.impl.client.BasicCredentialsProvider; 19 | import org.apache.http.impl.client.CloseableHttpClient; 20 | import org.apache.http.impl.client.HttpClients; 21 | import org.apache.http.util.EntityUtils; 22 | import org.fcrepo.camel.processor.EventProcessor; 23 | import org.junit.BeforeClass; 24 | import org.junit.Test; 25 | import org.junit.runner.RunWith; 26 | import org.slf4j.Logger; 27 | import org.springframework.context.annotation.Bean; 28 | import org.springframework.context.annotation.ComponentScan; 29 | import org.springframework.context.annotation.Configuration; 30 | import org.springframework.test.context.ContextConfiguration; 31 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 32 | import org.springframework.test.context.support.AnnotationConfigContextLoader; 33 | 34 | import java.io.IOException; 35 | import java.util.HashMap; 36 | import java.util.Map; 37 | 38 | import static org.apache.camel.component.mock.MockEndpoint.assertIsSatisfied; 39 | import static org.apache.http.HttpStatus.SC_CREATED; 40 | import static org.fcrepo.camel.FcrepoHeaders.FCREPO_BASE_URL; 41 | import static org.fcrepo.camel.FcrepoHeaders.FCREPO_IDENTIFIER; 42 | import static org.junit.Assert.assertEquals; 43 | import static org.slf4j.LoggerFactory.getLogger; 44 | 45 | /** 46 | * Test the route workflow. 47 | * 48 | * @author Aaron Coburn 49 | * @since 2016-07-21 50 | */ 51 | @RunWith(SpringJUnit4ClassRunner.class) 52 | @ContextConfiguration(classes = {ContextConfig.class}, loader = AnnotationConfigContextLoader.class) 53 | public class RouteIT { 54 | 55 | private static final Logger LOGGER = getLogger(RouteIT.class); 56 | 57 | private static String FEDORA_USERNAME = "fedoraAdmin"; 58 | private static String FEDORA_PASSWORD = "fedoraAdmin"; 59 | private static String FEDORA_BASE_URL = ""; 60 | @EndpointInject("mock:result") 61 | protected MockEndpoint resultEndpoint; 62 | 63 | @Produce("direct:start") 64 | protected ProducerTemplate template; 65 | 66 | @BeforeClass 67 | public static void beforeClass() { 68 | System.setProperty("fcrepo.authUsername", FEDORA_USERNAME); 69 | System.setProperty("fcrepo.authPassword", FEDORA_PASSWORD); 70 | final String fcrepoPort = System.getProperty("fcrepo.dynamic.test.port", "8080"); 71 | FEDORA_BASE_URL = "http://localhost:" + fcrepoPort + "/fcrepo/rest"; 72 | System.setProperty("fcrepo.baseUrl", FEDORA_BASE_URL); 73 | } 74 | 75 | @Test 76 | public void testFcrepoService() throws Exception { 77 | final String webPort = System.getProperty("fcrepo.dynamic.test.port", "8080"); 78 | 79 | final String baseUrl = "http://localhost:" + webPort + "/fcrepo/rest"; 80 | final String url1 = post(baseUrl).replace(baseUrl, ""); 81 | final String url2 = post(baseUrl).replace(baseUrl, ""); 82 | 83 | final Map headers = new HashMap<>(); 84 | headers.put(FCREPO_BASE_URL, baseUrl); 85 | headers.put(FCREPO_IDENTIFIER, url1); 86 | template.sendBodyAndHeaders(null, headers); 87 | 88 | headers.put(FCREPO_IDENTIFIER, url2); 89 | template.sendBodyAndHeaders(null, headers); 90 | 91 | resultEndpoint.expectedMessageCount(2); 92 | assertIsSatisfied(resultEndpoint); 93 | } 94 | 95 | private String post(final String url) { 96 | try { 97 | final BasicCredentialsProvider provider = new BasicCredentialsProvider(); 98 | provider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(FEDORA_USERNAME, FEDORA_PASSWORD)); 99 | final CloseableHttpClient httpclient = HttpClients.custom().setDefaultCredentialsProvider(provider).build(); 100 | 101 | final HttpPost httppost = new HttpPost(url); 102 | final HttpResponse response = httpclient.execute(httppost); 103 | assertEquals(SC_CREATED, response.getStatusLine().getStatusCode()); 104 | return EntityUtils.toString(response.getEntity(), "UTF-8"); 105 | } catch (IOException ex) { 106 | LOGGER.debug("Unable to extract HttpEntity response into an InputStream: ", ex); 107 | return ""; 108 | } 109 | } 110 | 111 | 112 | } 113 | 114 | @Configuration 115 | @ComponentScan("org.fcrepo.camel") 116 | class ContextConfig extends CamelConfiguration { 117 | @Bean 118 | public RouteBuilder route() { 119 | return new RouteBuilder() { 120 | public void configure() throws Exception { 121 | from("direct:start") 122 | .process(new EventProcessor()) 123 | .to("fcrepo:localhost/rest") 124 | .to("mock:result"); 125 | } 126 | }; 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /fcrepo-fixity/src/test/java/org/fcrepo/camel/fixity/RouteTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The contents of this file are subject to the license and copyright 3 | * detailed in the LICENSE and NOTICE files at the root of the source 4 | * tree. 5 | */ 6 | package org.fcrepo.camel.fixity; 7 | 8 | import org.apache.camel.CamelContext; 9 | import org.apache.camel.EndpointInject; 10 | import org.apache.camel.Produce; 11 | import org.apache.camel.ProducerTemplate; 12 | import org.apache.camel.builder.AdviceWith; 13 | import org.apache.camel.component.mock.MockEndpoint; 14 | import org.apache.camel.model.ModelCamelContext; 15 | import org.apache.camel.spring.javaconfig.CamelConfiguration; 16 | import org.apache.commons.io.IOUtils; 17 | import org.junit.BeforeClass; 18 | import org.junit.Test; 19 | import org.junit.runner.RunWith; 20 | import org.springframework.beans.factory.annotation.Autowired; 21 | import org.springframework.context.annotation.ComponentScan; 22 | import org.springframework.context.annotation.Configuration; 23 | import org.springframework.test.context.ContextConfiguration; 24 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 25 | import org.springframework.test.context.support.AnnotationConfigContextLoader; 26 | 27 | import static org.apache.camel.component.mock.MockEndpoint.assertIsSatisfied; 28 | import static org.apache.camel.util.ObjectHelper.loadResourceAsStream; 29 | import static org.fcrepo.camel.FcrepoHeaders.FCREPO_URI; 30 | 31 | /** 32 | * Test the route workflow. 33 | * 34 | * @author Aaron Coburn 35 | * @since 2015-06-18 36 | */ 37 | @RunWith(SpringJUnit4ClassRunner.class) 38 | @ContextConfiguration(classes = {RouteTest.ContextConfig.class}, loader = AnnotationConfigContextLoader.class) 39 | public class RouteTest { 40 | 41 | private static final long ASSERT_PERIOD_MS = 5000; 42 | @EndpointInject("mock:result") 43 | protected MockEndpoint resultEndpoint; 44 | 45 | @Produce("direct:start") 46 | protected ProducerTemplate template; 47 | 48 | private static final String baseURL = "http://localhost/rest"; 49 | private static final String identifier = "/file1"; 50 | 51 | @Autowired 52 | private CamelContext camelContext; 53 | 54 | @Autowired 55 | private FcrepoFixityConfig config; 56 | 57 | @BeforeClass 58 | public static void beforeClass() { 59 | System.setProperty("fixity.failure", "mock:failure"); 60 | System.setProperty("fixity.success", "mock:success"); 61 | System.setProperty("fixity.input.stream", "seda:foo"); 62 | System.setProperty("fixity.enabled", "true"); 63 | 64 | } 65 | 66 | @Test 67 | public void testBinaryFixitySuccess() throws Exception { 68 | 69 | final var context = camelContext.adapt(ModelCamelContext.class); 70 | AdviceWith.adviceWith(context, "FcrepoFixity", a -> { 71 | a.replaceFromWith("direct:start"); 72 | a.mockEndpointsAndSkip("fcrepo:*"); 73 | }); 74 | 75 | final var failureEndpoint = MockEndpoint.resolve(camelContext, config.getFixityFailure()); 76 | failureEndpoint.expectedMessageCount(0); 77 | failureEndpoint.setAssertPeriod(ASSERT_PERIOD_MS); 78 | final var successEndpoint = MockEndpoint.resolve(camelContext, config.getFixitySuccess()); 79 | successEndpoint.expectedMessageCount(1); 80 | 81 | final String body = IOUtils.toString(loadResourceAsStream("fixity.rdf"), "UTF-8"); 82 | template.sendBodyAndHeader(body, FCREPO_URI, baseURL + identifier); 83 | 84 | assertIsSatisfied(failureEndpoint, successEndpoint); 85 | } 86 | 87 | @Test 88 | public void testBinaryFixityFailure() throws Exception { 89 | final var context = camelContext.adapt(ModelCamelContext.class); 90 | AdviceWith.adviceWith(context, "FcrepoFixity", a -> { 91 | a.replaceFromWith("direct:start"); 92 | a.mockEndpointsAndSkip("fcrepo:*"); 93 | }); 94 | 95 | final var failureEndpoint = MockEndpoint.resolve(camelContext, "mock:failure"); 96 | failureEndpoint.expectedMessageCount(1); 97 | final var successEndpoint = MockEndpoint.resolve(camelContext, "mock:success"); 98 | successEndpoint.expectedMessageCount(0); 99 | successEndpoint.setAssertPeriod(ASSERT_PERIOD_MS); 100 | 101 | final String body = IOUtils.toString(loadResourceAsStream("fixityFailure.rdf"), "UTF-8"); 102 | template.sendBodyAndHeader(body, FCREPO_URI, baseURL + identifier); 103 | 104 | assertIsSatisfied(failureEndpoint, successEndpoint); 105 | } 106 | 107 | @Test 108 | public void testNonBinary() throws Exception { 109 | final var context = camelContext.adapt(ModelCamelContext.class); 110 | AdviceWith.adviceWith(context, "FcrepoFixity", a -> { 111 | a.replaceFromWith("direct:start"); 112 | a.mockEndpointsAndSkip("fcrepo:*"); 113 | }); 114 | 115 | final var failureEndpoint = MockEndpoint.resolve(camelContext, "mock:failure"); 116 | failureEndpoint.expectedMessageCount(0); 117 | failureEndpoint.setAssertPeriod(ASSERT_PERIOD_MS); 118 | final var successEndpoint = MockEndpoint.resolve(camelContext, "mock:success"); 119 | successEndpoint.expectedMessageCount(0); 120 | successEndpoint.setAssertPeriod(ASSERT_PERIOD_MS); 121 | 122 | final String body = IOUtils.toString(loadResourceAsStream("container.rdf"), "UTF-8"); 123 | template.sendBodyAndHeader(body, FCREPO_URI, baseURL + identifier); 124 | assertIsSatisfied(failureEndpoint, successEndpoint); 125 | } 126 | 127 | @Configuration 128 | @ComponentScan(resourcePattern = "**/Fcrepo*.class") 129 | static class ContextConfig extends CamelConfiguration { 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /fcrepo-fixity/src/test/java/org/fcrepo/camel/fixity/integration/RouteIT.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The contents of this file are subject to the license and copyright 3 | * detailed in the LICENSE and NOTICE files at the root of the source 4 | * tree. 5 | */ 6 | package org.fcrepo.camel.fixity.integration; 7 | 8 | import org.apache.camel.CamelContext; 9 | import org.apache.camel.EndpointInject; 10 | import org.apache.camel.Produce; 11 | import org.apache.camel.ProducerTemplate; 12 | import org.apache.camel.builder.AdviceWith; 13 | import org.apache.camel.component.mock.MockEndpoint; 14 | import org.apache.camel.model.ModelCamelContext; 15 | import org.apache.camel.spring.javaconfig.CamelConfiguration; 16 | import org.apache.camel.support.builder.Namespaces; 17 | import org.apache.commons.codec.digest.DigestUtils; 18 | import org.apache.jena.vocabulary.RDF; 19 | import org.fcrepo.camel.fixity.FcrepoFixityConfig; 20 | import org.fcrepo.client.FcrepoClient; 21 | import org.fcrepo.client.FcrepoResponse; 22 | import org.junit.BeforeClass; 23 | import org.junit.Test; 24 | import org.junit.runner.RunWith; 25 | import org.slf4j.Logger; 26 | import org.slf4j.LoggerFactory; 27 | import org.springframework.beans.factory.annotation.Autowired; 28 | import org.springframework.context.annotation.ComponentScan; 29 | import org.springframework.context.annotation.Configuration; 30 | import org.springframework.test.context.ContextConfiguration; 31 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 32 | import org.springframework.test.context.support.AnnotationConfigContextLoader; 33 | 34 | import java.net.URI; 35 | 36 | import static junit.framework.TestCase.assertTrue; 37 | import static org.apache.camel.component.mock.MockEndpoint.assertIsSatisfied; 38 | import static org.apache.camel.util.ObjectHelper.loadResourceAsStream; 39 | import static org.fcrepo.camel.FcrepoHeaders.FCREPO_URI; 40 | import static org.fcrepo.client.FcrepoClient.client; 41 | 42 | /** 43 | * Test the route workflow. 44 | * 45 | * @author Aaron Coburn 46 | * @since 2015-06-18 47 | */ 48 | @RunWith(SpringJUnit4ClassRunner.class) 49 | @ContextConfiguration(classes = {RouteIT.ContextConfig.class}, loader = AnnotationConfigContextLoader.class) 50 | public class RouteIT { 51 | private static Logger LOGGER = LoggerFactory.getLogger(RouteIT.class); 52 | private static final String REPOSITORY = "http://fedora.info/definitions/v4/repository#"; 53 | 54 | private static String FEDORA_USERNAME = "fedoraAdmin"; 55 | private static String FEDORA_PASSWORD = "fedoraAdmin"; 56 | 57 | private static final String binary = "binary.txt"; 58 | private static String fullPath = ""; 59 | @EndpointInject("mock:result") 60 | protected MockEndpoint resultEndpoint; 61 | @Produce("direct:start") 62 | protected ProducerTemplate template; 63 | @Autowired 64 | private CamelContext camelContext; 65 | 66 | @Autowired 67 | private FcrepoFixityConfig config; 68 | 69 | @BeforeClass 70 | public static void beforeClass() throws Exception { 71 | final String webPort = System.getProperty("fcrepo.dynamic.test.port", "8080"); 72 | final String jmsPort = System.getProperty("fcrepo.dynamic.jms.port", "61616"); 73 | 74 | final FcrepoClient client = client().throwExceptionOnFailure() 75 | .credentials(FEDORA_USERNAME, FEDORA_PASSWORD).build(); 76 | final FcrepoResponse res = client.post(URI.create("http://localhost:" + webPort + "/fcrepo/rest")) 77 | .body(loadResourceAsStream(binary), "text/plain").perform(); 78 | fullPath = res.getLocation().toString(); 79 | 80 | System.setProperty("fixity.failure", "mock:failure"); 81 | System.setProperty("fixity.success", "mock:success"); 82 | System.setProperty("fixity.input.stream", "direct:start"); 83 | 84 | System.setProperty("fcrepo.baseUrl", "http://localhost:" + webPort + "/fcrepo/rest"); 85 | System.setProperty("jms.brokerUrl", "tcp://localhost:" + jmsPort); 86 | System.setProperty("fixity.enabled", "true"); 87 | 88 | } 89 | 90 | @Test 91 | public void testFixityOnBinary() throws Exception { 92 | final String webPort = System.getProperty("fcrepo.dynamic.test.port", "8080"); 93 | final String path = fullPath.replaceFirst("http://localhost:[0-9]+/fcrepo/rest", ""); 94 | final String fcrepoEndpoint = "mock:fcrepo:http://localhost:" + webPort + "/fcrepo/rest"; 95 | final Namespaces ns = new Namespaces("rdf", RDF.uri); 96 | ns.add("fedora", REPOSITORY); 97 | ns.add("premis", "http://www.loc.gov/premis/rdf/v1#"); 98 | 99 | final var digest = DigestUtils.sha512Hex(loadResourceAsStream(binary)); 100 | 101 | LOGGER.info("digest={}", digest); 102 | final var context = camelContext.adapt(ModelCamelContext.class); 103 | AdviceWith.adviceWith(context, "FcrepoFixity", a -> { 104 | a.mockEndpoints("*"); 105 | }); 106 | 107 | final var fcrepoEndpointObj = MockEndpoint.resolve(camelContext, fcrepoEndpoint); 108 | fcrepoEndpointObj.expectedMessageCount(2); 109 | final var successEndpoint = MockEndpoint.resolve(camelContext, "mock:success"); 110 | successEndpoint.expectedMessageCount(1); 111 | template.sendBodyAndHeader("direct:start", "", FCREPO_URI, 112 | config.getFcrepoBaseUrl() + path); 113 | 114 | assertIsSatisfied(fcrepoEndpointObj, successEndpoint); 115 | 116 | final String body = successEndpoint.assertExchangeReceived(0).getIn().getBody(String.class); 117 | 118 | LOGGER.info("body={}", body); 119 | assertTrue(body.contains( 120 | "74")); 121 | assertTrue(body.contains( 122 | "")); 123 | } 124 | 125 | @Configuration 126 | @ComponentScan("org.fcrepo.camel") 127 | static class ContextConfig extends CamelConfiguration { 128 | 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /fcrepo-http-forwarding/src/test/java/org/fcrepo/camel/httpforwarding/RouteValidationTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The contents of this file are subject to the license and copyright 3 | * detailed in the LICENSE and NOTICE files at the root of the source 4 | * tree. 5 | */ 6 | package org.fcrepo.camel.httpforwarding; 7 | 8 | import org.apache.camel.CamelContext; 9 | import org.apache.camel.Produce; 10 | import org.apache.camel.ProducerTemplate; 11 | import org.apache.camel.builder.AdviceWith; 12 | import org.apache.camel.builder.RouteBuilder; 13 | import org.apache.camel.component.mock.MockEndpoint; 14 | import org.apache.camel.model.ModelCamelContext; 15 | import org.apache.camel.spring.javaconfig.CamelConfiguration; 16 | import org.junit.BeforeClass; 17 | import org.junit.Test; 18 | import org.junit.runner.RunWith; 19 | import org.springframework.beans.factory.annotation.Autowired; 20 | import org.springframework.context.annotation.Bean; 21 | import org.springframework.context.annotation.ComponentScan; 22 | import org.springframework.context.annotation.Configuration; 23 | import org.springframework.test.annotation.DirtiesContext; 24 | import org.springframework.test.context.ContextConfiguration; 25 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 26 | import org.springframework.test.context.support.AnnotationConfigContextLoader; 27 | 28 | import java.util.HashMap; 29 | import java.util.List; 30 | import java.util.Map; 31 | 32 | import static java.util.Arrays.asList; 33 | import static java.util.Collections.emptyList; 34 | import static org.fcrepo.camel.FcrepoHeaders.FCREPO_AGENT; 35 | import static org.fcrepo.camel.FcrepoHeaders.FCREPO_DATE_TIME; 36 | import static org.fcrepo.camel.FcrepoHeaders.FCREPO_RESOURCE_TYPE; 37 | import static org.fcrepo.camel.FcrepoHeaders.FCREPO_URI; 38 | 39 | /** 40 | * Test the route validation logic. 41 | * 42 | * @author Aaron Coburn 43 | * @author Demian Katz 44 | * @since 2015-04-10 45 | */ 46 | @RunWith(SpringJUnit4ClassRunner.class) 47 | @ContextConfiguration(classes = {RouteTest.ContextConfig.class}, loader = AnnotationConfigContextLoader.class) 48 | public class RouteValidationTest { 49 | private final String EVENT_NS = "https://www.w3.org/ns/activitystreams#"; 50 | private final String INDEXABLE = "http://fedora.info/definitions/v4/indexing#Indexable"; 51 | private static final String baseURL = "http://localhost/rest"; 52 | private static final String httpURL = "http://localhost/http_endpoint"; 53 | private static final String fileID = "/file1"; 54 | private static final String eventDate = "2015-04-06T22:45:20Z"; 55 | private static final String userID = "bypassAdmin"; 56 | private static final String userAgent = "curl/7.37.1"; 57 | private static final String auditContainer = "/audit"; 58 | private static final String inputStream = "seda:foo"; 59 | private static final String reindexStream = "seda:bar"; 60 | 61 | @Autowired 62 | private CamelContext camelContext; 63 | 64 | @Produce("direct:start") 65 | protected ProducerTemplate template; 66 | 67 | @BeforeClass 68 | public static void beforeClass() { 69 | System.setProperty("http.enabled", "true"); 70 | System.setProperty("http.filter.containers", baseURL + auditContainer); 71 | System.setProperty("http.input.stream", inputStream); 72 | System.setProperty("http.reindex.stream", reindexStream); 73 | System.setProperty("error.maxRedeliveries", "10"); 74 | System.setProperty("fcrepo.baseUrl", baseURL); 75 | System.setProperty("http.baseUrl", ""); 76 | System.setProperty("http.reindex.stream", "seda:reindex"); 77 | } 78 | 79 | @DirtiesContext 80 | @Test 81 | public void testEmptyBaseUrlBehavior() throws Exception { 82 | // If no base URL is provided, we cannot send messages... 83 | System.setProperty("http.baseUrl", ""); 84 | final List eventTypes = asList(EVENT_NS + "Delete"); 85 | 86 | final var context = camelContext.adapt(ModelCamelContext.class); 87 | AdviceWith.adviceWith(context, "FcrepoHttpSend", a -> { 88 | a.mockEndpointsAndSkip(httpURL); 89 | a.mockEndpointsAndSkip("direct:http.baseurl.missing"); 90 | }); 91 | 92 | final var sendEndpoint = MockEndpoint.resolve(camelContext, "mock:http:localhost/http_endpoint"); 93 | sendEndpoint.expectedMessageCount(0); 94 | final var errorEndpoint = MockEndpoint.resolve(camelContext, "mock:direct:http.baseurl.missing"); 95 | errorEndpoint.expectedMessageCount(1); 96 | template.sendBodyAndHeaders(inputStream, "{}", 97 | createEvent(baseURL + fileID, eventTypes)); 98 | 99 | MockEndpoint.assertIsSatisfied(sendEndpoint, errorEndpoint); 100 | } 101 | 102 | private static Map createEvent(final String identifier, final List eventTypes) { 103 | return createEvent(identifier, eventTypes, emptyList()); 104 | } 105 | 106 | private static Map createEvent(final String identifier, final List eventTypes, 107 | final List resourceTypes) { 108 | final Map headers = new HashMap<>(); 109 | headers.put(FCREPO_URI, identifier); 110 | headers.put(FCREPO_DATE_TIME, eventDate); 111 | headers.put(FCREPO_AGENT, asList(userID, userAgent)); 112 | // The HttpRouter expects to find org.fcrepo.jms.eventtype and move it into 113 | // FCREPO_EVENT_TYPE (or set a default) 114 | if (eventTypes.size() > 0) { 115 | headers.put("org.fcrepo.jms.eventtype", eventTypes.get(0)); 116 | } 117 | headers.put(FCREPO_RESOURCE_TYPE, resourceTypes); 118 | return headers; 119 | } 120 | 121 | @Configuration 122 | @ComponentScan(resourcePattern = "**/Fcrepo*.class") 123 | static class ContextConfig extends CamelConfiguration { 124 | 125 | @Bean 126 | public RouteBuilder route() { 127 | return new HttpRouter(); 128 | } 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /fcrepo-http-forwarding/src/test/java/org/fcrepo/camel/httpforwarding/integration/RouteDeleteIT.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The contents of this file are subject to the license and copyright 3 | * detailed in the LICENSE and NOTICE files at the root of the source 4 | * tree. 5 | */ 6 | package org.fcrepo.camel.httpforwarding.integration; 7 | 8 | import com.github.tomakehurst.wiremock.WireMockServer; 9 | import com.github.tomakehurst.wiremock.client.WireMock; 10 | import com.github.tomakehurst.wiremock.core.WireMockConfiguration; 11 | import org.apache.camel.CamelContext; 12 | import org.apache.camel.EndpointInject; 13 | import org.apache.camel.Produce; 14 | import org.apache.camel.ProducerTemplate; 15 | import org.apache.camel.builder.AdviceWith; 16 | import org.apache.camel.component.mock.MockEndpoint; 17 | import org.apache.camel.model.ModelCamelContext; 18 | import org.junit.After; 19 | import org.junit.Before; 20 | import org.junit.BeforeClass; 21 | import org.junit.Test; 22 | import org.junit.runner.RunWith; 23 | import org.slf4j.Logger; 24 | import org.springframework.beans.factory.annotation.Autowired; 25 | import org.springframework.test.annotation.DirtiesContext; 26 | import org.springframework.test.context.ContextConfiguration; 27 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 28 | import org.springframework.test.context.support.AnnotationConfigContextLoader; 29 | 30 | import static com.github.tomakehurst.wiremock.client.WireMock.equalTo; 31 | import static com.github.tomakehurst.wiremock.client.WireMock.ok; 32 | import static com.github.tomakehurst.wiremock.client.WireMock.post; 33 | import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor; 34 | import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; 35 | import static java.lang.Integer.parseInt; 36 | import static org.slf4j.LoggerFactory.getLogger; 37 | 38 | /** 39 | * Test the route workflow. 40 | * 41 | * @author Aaron Coburn 42 | * @author Demian Katz 43 | */ 44 | @RunWith(SpringJUnit4ClassRunner.class) 45 | @ContextConfiguration(classes = {RouteUpdateIT.ContextConfig.class}, loader = AnnotationConfigContextLoader.class) 46 | public class RouteDeleteIT { 47 | 48 | final private Logger logger = getLogger(RouteDeleteIT.class); 49 | 50 | private static final String AS_NS = "https://www.w3.org/ns/activitystreams#"; 51 | 52 | private static final String MOCK_ENDPOINT = "/endpoint"; 53 | 54 | private static final String MOCKSERVER_PORT = System.getProperty( 55 | "mockserver.dynamic.test.port", "8080"); 56 | 57 | private static final String FCREPO_PORT = System.getProperty( 58 | "fcrepo.dynamic.test.port", "8080"); 59 | 60 | private static final String BASIC_AUTH_USERNAME = "fooUser"; 61 | 62 | private static final String BASIC_AUTH_PASSWORD = "barPass"; 63 | 64 | private String fullPath = "http://localhost:" + FCREPO_PORT + "/fcrepo/rest/" + "fake-identifier"; 65 | 66 | @EndpointInject("mock:result") 67 | protected MockEndpoint resultEndpoint; 68 | 69 | @Produce("direct:start") 70 | protected ProducerTemplate template; 71 | 72 | @Autowired 73 | private CamelContext camelContext; 74 | 75 | private WireMockServer mockServer; 76 | 77 | @BeforeClass 78 | public static void beforeClass() { 79 | final String jmsPort = System.getProperty("fcrepo.dynamic.jms.port", "61616"); 80 | System.setProperty("http.enabled", "true"); 81 | System.setProperty("http.baseUrl", "http://localhost:" + MOCKSERVER_PORT + MOCK_ENDPOINT); 82 | System.setProperty("http.authUsername", BASIC_AUTH_USERNAME); 83 | System.setProperty("http.authPassword", BASIC_AUTH_PASSWORD); 84 | System.setProperty("fcrepo.baseUrl", "http://localhost:" + FCREPO_PORT + "/fcrepo/rest"); 85 | System.setProperty("jms.brokerUrl", "tcp://localhost:" + jmsPort); 86 | System.setProperty("http.input.stream", "direct:start"); 87 | System.setProperty("error.maxRedeliveries", "1"); 88 | } 89 | 90 | @After 91 | public void tearDownMockServer() throws Exception { 92 | logger.info("Stopping HTTP Server"); 93 | mockServer.stop(); 94 | } 95 | 96 | @Before 97 | public void setUpMockServer() throws Exception { 98 | mockServer = new WireMockServer(WireMockConfiguration.options().port(parseInt(MOCKSERVER_PORT))); 99 | mockServer.start(); 100 | } 101 | 102 | @DirtiesContext 103 | @Test 104 | public void testDeletedResourceWithEventBody() throws Exception { 105 | final var mockServerEndpoint = "mock:http:localhost:" + MOCKSERVER_PORT + MOCK_ENDPOINT; 106 | final var idMatcher = WireMock.matchingJsonPath("$.id", equalTo(fullPath)); 107 | final var typeMatcher = WireMock.matchingJsonPath("$.type", equalTo(AS_NS + "Delete")); 108 | 109 | // have the http server return a 200; also test that basic auth works (for variety) 110 | mockServer.stubFor(post(urlEqualTo(MOCK_ENDPOINT)) 111 | .withBasicAuth(BASIC_AUTH_USERNAME, BASIC_AUTH_PASSWORD) 112 | .willReturn(ok())); 113 | 114 | final var context = camelContext.adapt(ModelCamelContext.class); 115 | 116 | AdviceWith.adviceWith(context, "FcrepoHttpRouter", a -> a.mockEndpoints("*")); 117 | AdviceWith.adviceWith(context, "FcrepoHttpAddType", a -> a.mockEndpoints("*")); 118 | AdviceWith.adviceWith(context, "FcrepoHttpSend", a -> a.mockEndpoints("*")); 119 | 120 | final var mockServerMockEndpoint = MockEndpoint.resolve(camelContext, mockServerEndpoint); 121 | mockServerMockEndpoint.expectedMessageCount(1); 122 | final var updateEndpoint = MockEndpoint.resolve(camelContext, "mock://direct:send.to.http"); 123 | updateEndpoint.expectedMessageCount(1); 124 | 125 | logger.info("fullPath={}", fullPath); 126 | template.sendBodyAndHeader( 127 | "direct:start", TestUtils.getEvent(fullPath, AS_NS + "Delete"), "org.fcrepo.jms.eventtype", AS_NS + "Delete" 128 | ); 129 | 130 | mockServer.verify(1, postRequestedFor(urlEqualTo(MOCK_ENDPOINT)) 131 | .withRequestBody(idMatcher.and(typeMatcher))); 132 | MockEndpoint.assertIsSatisfied(mockServerMockEndpoint, updateEndpoint); 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /fcrepo-reindexing/src/test/java/org/fcrepo/camel/reindexing/integration/RouteIT.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The contents of this file are subject to the license and copyright 3 | * detailed in the LICENSE and NOTICE files at the root of the source 4 | * tree. 5 | */ 6 | package org.fcrepo.camel.reindexing.integration; 7 | 8 | import org.apache.camel.EndpointInject; 9 | import org.apache.camel.Exchange; 10 | import org.apache.camel.Processor; 11 | import org.apache.camel.Produce; 12 | import org.apache.camel.ProducerTemplate; 13 | import org.apache.camel.builder.RouteBuilder; 14 | import org.apache.camel.component.activemq.ActiveMQComponent; 15 | import org.apache.camel.component.mock.MockEndpoint; 16 | import org.apache.camel.spring.javaconfig.CamelConfiguration; 17 | import org.apache.http.HttpResponse; 18 | import org.apache.http.auth.AuthScope; 19 | import org.apache.http.auth.UsernamePasswordCredentials; 20 | import org.apache.http.client.methods.HttpPost; 21 | import org.apache.http.impl.client.BasicCredentialsProvider; 22 | import org.apache.http.impl.client.CloseableHttpClient; 23 | import org.apache.http.impl.client.HttpClients; 24 | import org.apache.http.util.EntityUtils; 25 | import org.fcrepo.camel.reindexing.ReindexingRouter; 26 | import org.junit.Before; 27 | import org.junit.BeforeClass; 28 | import org.junit.Test; 29 | import org.junit.runner.RunWith; 30 | import org.slf4j.Logger; 31 | import org.springframework.beans.factory.annotation.Autowired; 32 | import org.springframework.context.annotation.Bean; 33 | import org.springframework.context.annotation.ComponentScan; 34 | import org.springframework.context.annotation.Configuration; 35 | import org.springframework.test.annotation.DirtiesContext; 36 | import org.springframework.test.context.ContextConfiguration; 37 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 38 | import org.springframework.test.context.support.AnnotationConfigContextLoader; 39 | 40 | import java.io.IOException; 41 | 42 | import static org.apache.camel.Exchange.HTTP_URI; 43 | import static org.fcrepo.camel.FcrepoHeaders.FCREPO_URI; 44 | import static org.fcrepo.camel.reindexing.ReindexingHeaders.REINDEXING_PREFIX; 45 | import static org.fcrepo.camel.reindexing.ReindexingHeaders.REINDEXING_RECIPIENTS; 46 | import static org.slf4j.LoggerFactory.getLogger; 47 | 48 | /** 49 | * Test the route workflow. 50 | * 51 | * @author Aaron Coburn 52 | * @since 2015-04-10 53 | */ 54 | 55 | @RunWith(SpringJUnit4ClassRunner.class) 56 | @ContextConfiguration(classes = {RouteIT.ContextConfig.class}, loader = AnnotationConfigContextLoader.class) 57 | public class RouteIT { 58 | 59 | private static final Logger LOGGER = getLogger(RouteIT.class); 60 | 61 | private static final String FEDORA_AUTH_USERNAME = "fedoraAdmin"; 62 | private static final String FEDORA_AUTH_PASSWORD = "fedoraAdmin"; 63 | 64 | @EndpointInject("mock:result") 65 | protected MockEndpoint resultEndpoint; 66 | 67 | @Produce("direct:reindex") 68 | protected ProducerTemplate template; 69 | 70 | @Autowired 71 | private ActiveMQComponent activeMQComponent; 72 | 73 | private final String fullPath = ""; 74 | 75 | private static final BasicCredentialsProvider provider = new BasicCredentialsProvider(); 76 | 77 | public RouteIT() { 78 | provider.setCredentials(AuthScope.ANY, 79 | new UsernamePasswordCredentials(FEDORA_AUTH_USERNAME, FEDORA_AUTH_PASSWORD)); 80 | } 81 | 82 | @BeforeClass 83 | public static void beforeClass() { 84 | 85 | final String jmsPort = System.getProperty("fcrepo.dynamic.jms.port", "61616"); 86 | final String webPort = System.getProperty("fcrepo.dynamic.test.port", "8080"); 87 | 88 | System.setProperty("fcrepo.baseUrl", "http://localhost:" + webPort + "/fcrepo/rest"); 89 | System.setProperty("fcrepo.authUsername", FEDORA_AUTH_USERNAME); 90 | System.setProperty("fcrepo.authPassword", FEDORA_AUTH_PASSWORD); 91 | System.setProperty("jms.brokerUrl", "tcp://localhost:" + jmsPort); 92 | } 93 | 94 | @Before 95 | public void setup() { 96 | final String webPort = System.getProperty("fcrepo.dynamic.test.port", "8080"); 97 | final String basePath = "http://localhost:" + webPort + "/fcrepo/rest"; 98 | final String subPath = post(basePath); 99 | 100 | for (int i = 0; i < 10; ++i) { 101 | post(basePath); 102 | post(subPath); 103 | } 104 | } 105 | 106 | @DirtiesContext 107 | @Test 108 | public void testReindexingRouter() throws Exception { 109 | final String webPort = System.getProperty("fcrepo.dynamic.test.port", "8080"); 110 | 111 | resultEndpoint.expectedMinimumMessageCount(21); 112 | 113 | template.send("direct:reindex", new Processor() { 114 | @Override 115 | public void process(final Exchange exchange) throws Exception { 116 | exchange.getIn().setHeader(REINDEXING_RECIPIENTS, "mock:result"); 117 | exchange.getIn().setHeader(FCREPO_URI, "http://localhost:" + webPort + "/fcrepo/rest/"); 118 | exchange.getIn().setHeader(HTTP_URI, "http://localhost:" + webPort + "/reindexing/"); 119 | exchange.getIn().setHeader(REINDEXING_PREFIX, "/reindexing"); 120 | } 121 | }); 122 | 123 | MockEndpoint.assertIsSatisfied(resultEndpoint); 124 | } 125 | 126 | private String post(final String url) { 127 | final CloseableHttpClient httpclient = HttpClients.custom().setDefaultCredentialsProvider(provider).build(); 128 | 129 | try { 130 | final HttpPost httppost = new HttpPost(url); 131 | 132 | final HttpResponse response = httpclient.execute(httppost); 133 | return EntityUtils.toString(response.getEntity(), "UTF-8"); 134 | } catch (final IOException ex) { 135 | LOGGER.debug("Unable to extract HttpEntity response into an InputStream: ", ex); 136 | return ""; 137 | } 138 | } 139 | 140 | @Configuration 141 | @ComponentScan(basePackages = {"org.fcrepo.camel"}) 142 | static class ContextConfig extends CamelConfiguration { 143 | 144 | @Bean 145 | public RouteBuilder route() { 146 | return new ReindexingRouter(); 147 | } 148 | } 149 | } 150 | -------------------------------------------------------------------------------- /fcrepo-indexing-triplestore/src/main/java/org/fcrepo/camel/indexing/triplestore/TriplestoreRouter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The contents of this file are subject to the license and copyright 3 | * detailed in the LICENSE and NOTICE files at the root of the source 4 | * tree. 5 | */ 6 | package org.fcrepo.camel.indexing.triplestore; 7 | 8 | import org.apache.camel.LoggingLevel; 9 | import org.apache.camel.builder.RouteBuilder; 10 | import org.apache.camel.language.xpath.XPathBuilder; 11 | import org.apache.camel.support.builder.Namespaces; 12 | import org.fcrepo.camel.common.processor.AddBasicAuthProcessor; 13 | import org.fcrepo.camel.processor.EventProcessor; 14 | import org.fcrepo.camel.processor.SparqlDeleteProcessor; 15 | import org.fcrepo.camel.processor.SparqlUpdateProcessor; 16 | import org.slf4j.Logger; 17 | import org.springframework.beans.factory.annotation.Autowired; 18 | 19 | import static java.util.stream.Collectors.toList; 20 | import static org.apache.camel.builder.PredicateBuilder.in; 21 | import static org.apache.camel.builder.PredicateBuilder.not; 22 | import static org.apache.camel.builder.PredicateBuilder.or; 23 | import static org.fcrepo.camel.FcrepoHeaders.FCREPO_EVENT_TYPE; 24 | import static org.fcrepo.camel.FcrepoHeaders.FCREPO_NAMED_GRAPH; 25 | import static org.fcrepo.camel.FcrepoHeaders.FCREPO_URI; 26 | import static org.fcrepo.camel.processor.ProcessorUtils.tokenizePropertyPlaceholder; 27 | import static org.slf4j.LoggerFactory.getLogger; 28 | 29 | /** 30 | * A content router for handling Fedora events. 31 | * 32 | * @author Aaron Coburn 33 | */ 34 | public class TriplestoreRouter extends RouteBuilder { 35 | 36 | private static final Logger LOGGER = getLogger(TriplestoreRouter.class); 37 | 38 | private static final String RESOURCE_DELETION = "http://fedora.info/definitions/v4/event#ResourceDeletion"; 39 | private static final String DELETE = "https://www.w3.org/ns/activitystreams#Delete"; 40 | 41 | @Autowired 42 | private FcrepoTripleStoreIndexingConfig config; 43 | 44 | /** 45 | * Configure the message route workflow. 46 | */ 47 | public void configure() throws Exception { 48 | 49 | final Namespaces ns = new Namespaces("rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#"); 50 | ns.add("indexing", "http://fedora.info/definitions/v4/indexing#"); 51 | 52 | final XPathBuilder indexable = new XPathBuilder( 53 | String.format("/rdf:RDF/rdf:Description/rdf:type[@rdf:resource='%s']", 54 | "http://fedora.info/definitions/v4/indexing#Indexable")); 55 | indexable.namespaces(ns); 56 | 57 | /** 58 | * A generic error handler (specific to this RouteBuilder) 59 | */ 60 | onException(Exception.class) 61 | .maximumRedeliveries(config.getMaxRedeliveries()) 62 | .log("Index Routing Error: ${routeId}"); 63 | 64 | /** 65 | * route a message to the proper queue, based on whether 66 | * it is a DELETE or UPDATE operation. 67 | */ 68 | from(config.getInputStream()) 69 | .routeId("FcrepoTriplestoreRouter") 70 | .process(new EventProcessor()) 71 | .choice() 72 | .when(or(header(FCREPO_EVENT_TYPE).contains(RESOURCE_DELETION), 73 | header(FCREPO_EVENT_TYPE).contains(DELETE))) 74 | .log(LoggingLevel.INFO, "deleting " + header(FCREPO_URI) + " from triplestore.") 75 | .to("direct:delete.triplestore") 76 | .otherwise() 77 | .to("direct:index.triplestore"); 78 | 79 | /** 80 | * Handle re-index events 81 | */ 82 | from(config.getReindexStream()) 83 | .routeId("FcrepoTriplestoreReindex") 84 | .to("direct:index.triplestore"); 85 | 86 | /** 87 | * Based on an item's metadata, determine if it is indexable. 88 | */ 89 | from("direct:index.triplestore") 90 | .routeId("FcrepoTriplestoreIndexer") 91 | .filter(not(in(tokenizePropertyPlaceholder(getContext(), config.getFilterContainers(), ",").stream() 92 | .map(uri -> or( 93 | header(FCREPO_URI).startsWith(constant(uri + "/")), 94 | header(FCREPO_URI).isEqualTo(constant(uri)))) 95 | .collect(toList())))) 96 | .removeHeaders("CamelHttp*") 97 | .choice() 98 | .when(simple(config.isIndexingPredicate() + " != 'true'")) 99 | .to("direct:update.triplestore") 100 | .otherwise() 101 | .to("fcrepo:" + config.getFcrepoBaseUrl() + 102 | "?preferInclude=PreferMinimalContainer&accept=application/rdf+xml") 103 | .choice() 104 | .when(indexable) 105 | .to("direct:update.triplestore") 106 | .otherwise() 107 | .to("direct:delete.triplestore"); 108 | 109 | /** 110 | * Remove an item from the triplestore index. 111 | */ 112 | from("direct:delete.triplestore") 113 | .routeId("FcrepoTriplestoreDeleter") 114 | .process(new SparqlDeleteProcessor()) 115 | .log(LoggingLevel.INFO, LOGGER, 116 | "Deleting Triplestore Object ${headers[CamelFcrepoUri]}") 117 | .process(new AddBasicAuthProcessor(this.config.getTriplestoreAuthUsername(), 118 | this.config.getTriplestoreAuthPassword())) 119 | .to(config.getTriplestoreBaseUrl() + "?useSystemProperties=true"); 120 | 121 | /** 122 | * Perform the sparql update. 123 | */ 124 | from("direct:update.triplestore") 125 | .routeId("FcrepoTriplestoreUpdater") 126 | .setHeader(FCREPO_NAMED_GRAPH) 127 | .simple(config.getNamedGraph()) 128 | .to("fcrepo:" + config.getFcrepoBaseUrl() + "?accept=application/n-triples" + 129 | "&preferOmit=" + config.getPreferOmit() + "&preferInclude=" + config.getPreferInclude()) 130 | .process(new SparqlUpdateProcessor()) 131 | .log(LoggingLevel.INFO, LOGGER, 132 | "Indexing Triplestore Object ${headers[CamelFcrepoUri]}") 133 | .process(new AddBasicAuthProcessor(this.config.getTriplestoreAuthUsername(), 134 | this.config.getTriplestoreAuthPassword())) 135 | .to(config.getTriplestoreBaseUrl() + "?useSystemProperties=true"); 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /fcrepo-http-forwarding/src/test/java/org/fcrepo/camel/httpforwarding/integration/RouteUpdateIT.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The contents of this file are subject to the license and copyright 3 | * detailed in the LICENSE and NOTICE files at the root of the source 4 | * tree. 5 | */ 6 | package org.fcrepo.camel.httpforwarding.integration; 7 | 8 | import com.github.tomakehurst.wiremock.WireMockServer; 9 | import com.github.tomakehurst.wiremock.client.WireMock; 10 | import com.github.tomakehurst.wiremock.core.WireMockConfiguration; 11 | import org.apache.camel.CamelContext; 12 | import org.apache.camel.EndpointInject; 13 | import org.apache.camel.Produce; 14 | import org.apache.camel.ProducerTemplate; 15 | import org.apache.camel.builder.AdviceWith; 16 | import org.apache.camel.component.activemq.ActiveMQComponent; 17 | import org.apache.camel.component.mock.MockEndpoint; 18 | import org.apache.camel.model.ModelCamelContext; 19 | import org.apache.camel.spring.javaconfig.CamelConfiguration; 20 | import org.junit.After; 21 | import org.junit.Before; 22 | import org.junit.BeforeClass; 23 | import org.junit.Test; 24 | import org.junit.runner.RunWith; 25 | import org.slf4j.Logger; 26 | import org.springframework.beans.factory.annotation.Autowired; 27 | import org.springframework.context.annotation.Bean; 28 | import org.springframework.context.annotation.ComponentScan; 29 | import org.springframework.context.annotation.Configuration; 30 | import org.springframework.test.annotation.DirtiesContext; 31 | import org.springframework.test.context.ContextConfiguration; 32 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 33 | import org.springframework.test.context.support.AnnotationConfigContextLoader; 34 | 35 | import static com.github.tomakehurst.wiremock.client.WireMock.equalTo; 36 | import static com.github.tomakehurst.wiremock.client.WireMock.ok; 37 | import static com.github.tomakehurst.wiremock.client.WireMock.post; 38 | import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor; 39 | import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; 40 | import static java.lang.Integer.parseInt; 41 | import static org.fcrepo.camel.httpforwarding.integration.TestUtils.getEvent; 42 | import static org.slf4j.LoggerFactory.getLogger; 43 | 44 | /** 45 | * Test the route workflow. 46 | * 47 | * @author Aaron Coburn 48 | * @since 2015-04-10 49 | */ 50 | @RunWith(SpringJUnit4ClassRunner.class) 51 | @ContextConfiguration(classes = {RouteUpdateIT.ContextConfig.class}, loader = AnnotationConfigContextLoader.class) 52 | public class RouteUpdateIT { 53 | 54 | final private Logger logger = getLogger(RouteUpdateIT.class); 55 | 56 | private static final String AS_NS = "https://www.w3.org/ns/activitystreams#"; 57 | 58 | private static final String MOCK_ENDPOINT = "/endpoint"; 59 | 60 | private static final String MOCKSERVER_PORT = System.getProperty( 61 | "mockserver.dynamic.test.port", "8080"); 62 | 63 | private static final String FCREPO_PORT = System.getProperty( 64 | "fcrepo.dynamic.test.port", "8080"); 65 | 66 | private static final String JMS_PORT = System.getProperty( 67 | "fcrepo.dynamic.jms.port", "61616"); 68 | 69 | private String fullPath = "http://localhost:" + FCREPO_PORT + "/fcrepo/rest/" + "fake-identifier"; 70 | 71 | 72 | @EndpointInject("mock:result") 73 | protected MockEndpoint resultEndpoint; 74 | 75 | @Produce("direct:start") 76 | protected ProducerTemplate template; 77 | 78 | @Autowired 79 | private CamelContext camelContext; 80 | 81 | private WireMockServer mockServer; 82 | 83 | @BeforeClass 84 | public static void beforeClass() { 85 | System.setProperty("http.enabled", "true"); 86 | System.setProperty("http.baseUrl", "http://localhost:" + MOCKSERVER_PORT + MOCK_ENDPOINT); 87 | System.setProperty("jms.brokerUrl", "tcp://localhost:" + JMS_PORT); 88 | System.setProperty("http.input.stream", "direct:start"); 89 | System.setProperty("http.reindex.stream", "direct:reindex"); 90 | System.setProperty("fcrepo.baseUrl", "http://localhost:" + FCREPO_PORT + "/fcrepo/rest"); 91 | System.setProperty("error.maxRedeliveries", "1"); 92 | } 93 | 94 | @After 95 | public void tearDownMockServer() { 96 | logger.info("Stopping HTTP Server"); 97 | mockServer.stop(); 98 | } 99 | 100 | @Before 101 | public void setUpMockServer() throws Exception { 102 | mockServer = new WireMockServer(WireMockConfiguration.options().port(parseInt(MOCKSERVER_PORT))); 103 | mockServer.start(); 104 | } 105 | 106 | @DirtiesContext 107 | @Test 108 | public void testAddedEventRouter() throws Exception { 109 | final var mockServerEndpoint = "mock:http:localhost:" + MOCKSERVER_PORT + MOCK_ENDPOINT; 110 | final var idMatcher = WireMock.matchingJsonPath("$.id", equalTo(fullPath)); 111 | final var typeMatcher = WireMock.matchingJsonPath("$.type", equalTo(AS_NS + "Update")); 112 | 113 | // have the http server return a 200 114 | mockServer.stubFor(post(urlEqualTo(MOCK_ENDPOINT)).willReturn(ok())); 115 | 116 | final var context = camelContext.adapt(ModelCamelContext.class); 117 | 118 | AdviceWith.adviceWith(context, "FcrepoHttpRouter", a -> a.mockEndpoints("*")); 119 | AdviceWith.adviceWith(context, "FcrepoHttpAddType", a -> a.mockEndpoints("*")); 120 | AdviceWith.adviceWith(context, "FcrepoHttpSend", a -> a.mockEndpoints("*")); 121 | 122 | final var mockServerMockEndpoint = MockEndpoint.resolve(camelContext, mockServerEndpoint); 123 | mockServerMockEndpoint.expectedMessageCount(1); 124 | final var updateEndpoint = MockEndpoint.resolve(camelContext, "mock://direct:send.to.http"); 125 | updateEndpoint.expectedMessageCount(1); 126 | 127 | logger.info("fullPath={}", fullPath); 128 | template.sendBodyAndHeader( 129 | "direct:start", getEvent(fullPath, AS_NS + "Update"), "org.fcrepo.jms.eventtype", AS_NS + "Update" 130 | ); 131 | 132 | mockServer.verify(1, postRequestedFor(urlEqualTo(MOCK_ENDPOINT)) 133 | .withRequestBody(idMatcher.and(typeMatcher))); 134 | MockEndpoint.assertIsSatisfied(mockServerMockEndpoint, updateEndpoint); 135 | } 136 | 137 | @Configuration 138 | @ComponentScan(basePackages = "org.fcrepo.camel") 139 | static class ContextConfig extends CamelConfiguration { 140 | @Bean 141 | public ActiveMQComponent broker() { 142 | final var component = new ActiveMQComponent(); 143 | component.setBrokerURL("tcp://localhost:" + JMS_PORT); 144 | return component; 145 | } 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /fcrepo-http-forwarding/src/test/java/org/fcrepo/camel/httpforwarding/RouteTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The contents of this file are subject to the license and copyright 3 | * detailed in the LICENSE and NOTICE files at the root of the source 4 | * tree. 5 | */ 6 | package org.fcrepo.camel.httpforwarding; 7 | 8 | import org.apache.camel.CamelContext; 9 | import org.apache.camel.Produce; 10 | import org.apache.camel.ProducerTemplate; 11 | import org.apache.camel.builder.AdviceWith; 12 | import org.apache.camel.builder.RouteBuilder; 13 | import org.apache.camel.component.mock.MockEndpoint; 14 | import org.apache.camel.model.ModelCamelContext; 15 | import org.apache.camel.spring.javaconfig.CamelConfiguration; 16 | import org.junit.BeforeClass; 17 | import org.junit.Test; 18 | import org.junit.runner.RunWith; 19 | import org.springframework.beans.factory.annotation.Autowired; 20 | import org.springframework.context.annotation.Bean; 21 | import org.springframework.context.annotation.ComponentScan; 22 | import org.springframework.context.annotation.Configuration; 23 | import org.springframework.test.annotation.DirtiesContext; 24 | import org.springframework.test.context.ContextConfiguration; 25 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 26 | import org.springframework.test.context.support.AnnotationConfigContextLoader; 27 | 28 | import java.util.HashMap; 29 | import java.util.List; 30 | import java.util.Map; 31 | 32 | import static java.util.Arrays.asList; 33 | import static java.util.Collections.emptyList; 34 | import static org.fcrepo.camel.FcrepoHeaders.FCREPO_AGENT; 35 | import static org.fcrepo.camel.FcrepoHeaders.FCREPO_DATE_TIME; 36 | import static org.fcrepo.camel.FcrepoHeaders.FCREPO_EVENT_TYPE; 37 | import static org.fcrepo.camel.FcrepoHeaders.FCREPO_RESOURCE_TYPE; 38 | import static org.fcrepo.camel.FcrepoHeaders.FCREPO_URI; 39 | 40 | /** 41 | * Test the route workflow. 42 | * 43 | * @author Aaron Coburn 44 | * @author Demian Katz 45 | * @since 2015-04-10 46 | */ 47 | @RunWith(SpringJUnit4ClassRunner.class) 48 | @ContextConfiguration(classes = {RouteTest.ContextConfig.class}, loader = AnnotationConfigContextLoader.class) 49 | public class RouteTest { 50 | private final String EVENT_NS = "https://www.w3.org/ns/activitystreams#"; 51 | private static final String baseURL = "http://localhost/rest"; 52 | private static final String httpURL = "http://localhost/http_endpoint"; 53 | private static final String fileID = "/file1"; 54 | private static final String eventDate = "2015-04-06T22:45:20Z"; 55 | private static final String userID = "bypassAdmin"; 56 | private static final String userAgent = "curl/7.37.1"; 57 | private static final String auditContainer = "/audit"; 58 | private static final String inputStream = "seda:foo"; 59 | private static final String reindexStream = "seda:bar"; 60 | 61 | @Autowired 62 | private CamelContext camelContext; 63 | 64 | @Produce("direct:start") 65 | protected ProducerTemplate template; 66 | 67 | @BeforeClass 68 | public static void beforeClass() { 69 | System.setProperty("http.enabled", "true"); 70 | System.setProperty("http.filter.containers", baseURL + auditContainer); 71 | System.setProperty("http.input.stream", inputStream); 72 | System.setProperty("http.reindex.stream", reindexStream); 73 | System.setProperty("error.maxRedeliveries", "10"); 74 | System.setProperty("fcrepo.baseUrl", baseURL); 75 | System.setProperty("http.baseUrl", httpURL); 76 | System.setProperty("http.reindex.stream", "seda:reindex"); 77 | } 78 | 79 | @DirtiesContext 80 | @Test 81 | public void testEventTypeForwarding() throws Exception { 82 | // Let's be sure "Delete" gets passed along as expected 83 | final List eventTypes = asList(EVENT_NS + "Delete"); 84 | 85 | final var context = camelContext.adapt(ModelCamelContext.class); 86 | AdviceWith.adviceWith(context, "FcrepoHttpSend", a -> { 87 | a.mockEndpointsAndSkip(httpURL); 88 | }); 89 | 90 | final var sendEndpoint = MockEndpoint.resolve(camelContext, "mock:http:localhost/http_endpoint"); 91 | sendEndpoint.expectedMessageCount(1); 92 | sendEndpoint.expectedHeaderReceived(FCREPO_EVENT_TYPE, "https://www.w3.org/ns/activitystreams#Delete"); 93 | template.sendBodyAndHeaders(inputStream, "{}", 94 | createEvent(baseURL + fileID, eventTypes)); 95 | 96 | MockEndpoint.assertIsSatisfied(sendEndpoint); 97 | } 98 | 99 | @DirtiesContext 100 | @Test 101 | public void testEventTypeInjection() throws Exception { 102 | // Let's make sure "Update" is the default when no event type is provided 103 | final List eventTypes = emptyList(); 104 | 105 | final var context = camelContext.adapt(ModelCamelContext.class); 106 | AdviceWith.adviceWith(context, "FcrepoHttpSend", a -> { 107 | a.mockEndpointsAndSkip(httpURL); 108 | }); 109 | 110 | final var sendEndpoint = MockEndpoint.resolve(camelContext, "mock:http:localhost/http_endpoint"); 111 | sendEndpoint.expectedMessageCount(1); 112 | // We expect "Update" as default if nothing is provided 113 | sendEndpoint.expectedHeaderReceived(FCREPO_EVENT_TYPE, "https://www.w3.org/ns/activitystreams#Update"); 114 | template.sendBodyAndHeaders(inputStream, "{}", 115 | createEvent(baseURL + fileID, eventTypes)); 116 | 117 | MockEndpoint.assertIsSatisfied(sendEndpoint); 118 | } 119 | 120 | private static Map createEvent(final String identifier, final List eventTypes) { 121 | return createEvent(identifier, eventTypes, emptyList()); 122 | } 123 | 124 | private static Map createEvent(final String identifier, final List eventTypes, 125 | final List resourceTypes) { 126 | final Map headers = new HashMap<>(); 127 | headers.put(FCREPO_URI, identifier); 128 | headers.put(FCREPO_DATE_TIME, eventDate); 129 | headers.put(FCREPO_AGENT, asList(userID, userAgent)); 130 | // The HttpRouter expects to find org.fcrepo.jms.eventtype and move it into 131 | // FCREPO_EVENT_TYPE (or set a default) 132 | if (eventTypes.size() > 0) { 133 | headers.put("org.fcrepo.jms.eventtype", eventTypes.get(0)); 134 | } 135 | headers.put(FCREPO_RESOURCE_TYPE, resourceTypes); 136 | return headers; 137 | } 138 | 139 | @Configuration 140 | @ComponentScan(resourcePattern = "**/Fcrepo*.class") 141 | static class ContextConfig extends CamelConfiguration { 142 | 143 | @Bean 144 | public RouteBuilder route() { 145 | return new HttpRouter(); 146 | } 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /fcrepo-reindexing/src/test/java/org/fcrepo/camel/reindexing/RestProcessorTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The contents of this file are subject to the license and copyright 3 | * detailed in the LICENSE and NOTICE files at the root of the source 4 | * tree. 5 | */ 6 | package org.fcrepo.camel.reindexing; 7 | 8 | import static org.apache.camel.Exchange.CONTENT_TYPE; 9 | import static org.apache.camel.Exchange.HTTP_PATH; 10 | import static org.fcrepo.camel.reindexing.ReindexingHeaders.REINDEXING_RECIPIENTS; 11 | 12 | import java.io.IOException; 13 | import java.util.HashMap; 14 | import java.util.Map; 15 | 16 | import org.apache.camel.EndpointInject; 17 | import org.apache.camel.Produce; 18 | import org.apache.camel.ProducerTemplate; 19 | import org.apache.camel.builder.RouteBuilder; 20 | import org.apache.camel.component.mock.MockEndpoint; 21 | import org.apache.camel.test.junit4.CamelTestSupport; 22 | 23 | import org.junit.Test; 24 | 25 | /** 26 | * Test the route workflow. 27 | * 28 | * @author Aaron Coburn 29 | * @since 2015-04-10 30 | */ 31 | public class RestProcessorTest extends CamelTestSupport { 32 | 33 | @EndpointInject(uri = "mock:result") 34 | protected MockEndpoint resultEndpoint; 35 | 36 | @Produce(uri = "direct:start") 37 | protected ProducerTemplate template; 38 | 39 | @Test 40 | public void testRestProcessor() throws Exception { 41 | 42 | resultEndpoint.expectedMessageCount(3); 43 | resultEndpoint.message(0).header(REINDEXING_RECIPIENTS).isEqualTo(""); 44 | resultEndpoint.message(1).header(REINDEXING_RECIPIENTS).contains("broker:queue:bar"); 45 | resultEndpoint.message(1).header(REINDEXING_RECIPIENTS).contains("broker:queue:foo"); 46 | resultEndpoint.message(2).header(REINDEXING_RECIPIENTS).isEqualTo(""); 47 | 48 | final Map headers = new HashMap<>(); 49 | headers.put(HTTP_PATH, "/"); 50 | template.sendBodyAndHeaders("", headers); 51 | 52 | headers.clear(); 53 | headers.put(HTTP_PATH, "/foo/bar"); 54 | headers.put(REINDEXING_RECIPIENTS, 55 | "broker:queue:foo, broker:queue:bar,\t\nbroker:queue:foo "); 56 | template.sendBodyAndHeaders("", headers); 57 | 58 | headers.clear(); 59 | headers.put(HTTP_PATH, "/foo/bar"); 60 | headers.put(REINDEXING_RECIPIENTS, null); 61 | template.sendBodyAndHeaders("", headers); 62 | 63 | assertMockEndpointsSatisfied(); 64 | } 65 | 66 | @Test 67 | public void testRestProcessorWithBody1() throws Exception { 68 | final String body = "[\"broker:queue:foo\",\"broker:queue:bar\"]"; 69 | 70 | resultEndpoint.expectedMessageCount(1); 71 | resultEndpoint.message(0).header(REINDEXING_RECIPIENTS).contains("broker:queue:bar"); 72 | resultEndpoint.message(0).header(REINDEXING_RECIPIENTS).contains("broker:queue:foo"); 73 | 74 | final Map headers = new HashMap<>(); 75 | headers.put(CONTENT_TYPE, "application/json"); 76 | headers.put(HTTP_PATH, "/foo/bar"); 77 | template.sendBodyAndHeaders(body, headers); 78 | 79 | assertMockEndpointsSatisfied(); 80 | } 81 | 82 | @Test 83 | public void testRestProcessorWithBody2() throws Exception { 84 | final String body = "[\"broker:queue:foo\",\"broker:queue:bar\"]"; 85 | 86 | resultEndpoint.expectedMessageCount(1); 87 | resultEndpoint.message(0).header(REINDEXING_RECIPIENTS).contains("broker:queue:bar"); 88 | resultEndpoint.message(0).header(REINDEXING_RECIPIENTS).contains("broker:queue:foo"); 89 | resultEndpoint.message(0).header(REINDEXING_RECIPIENTS).contains("broker:queue:baz"); 90 | 91 | final Map headers = new HashMap<>(); 92 | headers.put(HTTP_PATH, "/foo/bar"); 93 | headers.put(CONTENT_TYPE, "application/json"); 94 | headers.put(REINDEXING_RECIPIENTS, "broker:queue:baz"); 95 | template.sendBodyAndHeaders(body, headers); 96 | 97 | assertMockEndpointsSatisfied(); 98 | } 99 | 100 | @Test 101 | public void testRestProcessorWithNullBody() throws Exception { 102 | 103 | resultEndpoint.expectedMessageCount(1); 104 | resultEndpoint.message(0).header(REINDEXING_RECIPIENTS).isEqualTo("broker:queue:baz"); 105 | 106 | final Map headers = new HashMap<>(); 107 | headers.put(CONTENT_TYPE, "application/json"); 108 | headers.put(HTTP_PATH, "/foo/bar"); 109 | headers.put(REINDEXING_RECIPIENTS, "broker:queue:baz"); 110 | template.sendBodyAndHeaders(null, headers); 111 | 112 | assertMockEndpointsSatisfied(); 113 | } 114 | 115 | @Test 116 | public void testRestProcessorWithNoContentType() throws Exception { 117 | 118 | final String body = "[\"broker:queue:foo\",\"broker:queue:bar\"]"; 119 | 120 | resultEndpoint.expectedMessageCount(1); 121 | resultEndpoint.message(0).header(REINDEXING_RECIPIENTS).isEqualTo("broker:queue:baz"); 122 | 123 | final Map headers = new HashMap<>(); 124 | headers.put(HTTP_PATH, "/foo/bar"); 125 | headers.put(REINDEXING_RECIPIENTS, "broker:queue:baz"); 126 | template.sendBodyAndHeaders(body, headers); 127 | 128 | assertMockEndpointsSatisfied(); 129 | } 130 | 131 | @Test 132 | public void testRestProcessorWithBadContentType() throws Exception { 133 | 134 | final String body = "[\"broker:queue:foo\",\"broker:queue:bar\"]"; 135 | 136 | resultEndpoint.expectedMessageCount(1); 137 | resultEndpoint.message(0).header(REINDEXING_RECIPIENTS).isEqualTo("broker:queue:baz"); 138 | 139 | final Map headers = new HashMap<>(); 140 | headers.put(CONTENT_TYPE, "application/foo"); 141 | headers.put(HTTP_PATH, "/foo/bar"); 142 | headers.put(REINDEXING_RECIPIENTS, "broker:queue:baz"); 143 | template.sendBodyAndHeaders(body, headers); 144 | 145 | assertMockEndpointsSatisfied(); 146 | } 147 | 148 | 149 | @Test 150 | public void testRestProcessorWithEmptyBody() throws Exception { 151 | 152 | resultEndpoint.expectedMessageCount(1); 153 | resultEndpoint.message(0).header(REINDEXING_RECIPIENTS).isEqualTo("broker:queue:baz"); 154 | 155 | final Map headers = new HashMap<>(); 156 | headers.put(CONTENT_TYPE, "application/json"); 157 | headers.put(HTTP_PATH, "/foo/bar"); 158 | headers.put(REINDEXING_RECIPIENTS, "broker:queue:baz"); 159 | template.sendBodyAndHeaders(" ", headers); 160 | 161 | assertMockEndpointsSatisfied(); 162 | } 163 | 164 | 165 | @Override 166 | protected RouteBuilder createRouteBuilder() { 167 | return new RouteBuilder() { 168 | @Override 169 | public void configure() throws IOException { 170 | from("direct:start") 171 | .process(new RestProcessor()) 172 | .to("mock:result"); 173 | } 174 | }; 175 | } 176 | } 177 | -------------------------------------------------------------------------------- /fcrepo-indexing-triplestore/src/test/java/org/fcrepo/camel/indexing/triplestore/integration/RouteDeleteIT.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The contents of this file are subject to the license and copyright 3 | * detailed in the LICENSE and NOTICE files at the root of the source 4 | * tree. 5 | */ 6 | package org.fcrepo.camel.indexing.triplestore.integration; 7 | 8 | import org.apache.camel.CamelContext; 9 | import org.apache.camel.Produce; 10 | import org.apache.camel.ProducerTemplate; 11 | import org.apache.camel.builder.AdviceWith; 12 | import org.apache.camel.component.mock.MockEndpoint; 13 | import org.apache.camel.model.ModelCamelContext; 14 | import org.apache.jena.fuseki.main.FusekiServer; 15 | import org.apache.jena.query.Dataset; 16 | import org.apache.jena.query.DatasetFactory; 17 | import org.fcrepo.client.FcrepoClient; 18 | import org.fcrepo.client.FcrepoResponse; 19 | import org.junit.After; 20 | import org.junit.Before; 21 | import org.junit.BeforeClass; 22 | import org.junit.Test; 23 | import org.junit.runner.RunWith; 24 | import org.slf4j.Logger; 25 | import org.springframework.beans.factory.annotation.Autowired; 26 | import org.springframework.test.annotation.DirtiesContext; 27 | import org.springframework.test.context.ContextConfiguration; 28 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 29 | import org.springframework.test.context.support.AnnotationConfigContextLoader; 30 | 31 | import java.net.URI; 32 | import java.util.Properties; 33 | 34 | import static com.jayway.awaitility.Awaitility.await; 35 | import static java.lang.Integer.parseInt; 36 | import static org.apache.camel.util.ObjectHelper.loadResourceAsStream; 37 | import static org.fcrepo.camel.indexing.triplestore.integration.TestUtils.ASSERT_PERIOD_MS; 38 | import static org.fcrepo.camel.indexing.triplestore.integration.TestUtils.createFcrepoClient; 39 | import static org.fcrepo.camel.indexing.triplestore.integration.TestUtils.getEvent; 40 | import static org.hamcrest.Matchers.equalTo; 41 | import static org.hamcrest.Matchers.greaterThanOrEqualTo; 42 | import static org.slf4j.LoggerFactory.getLogger; 43 | 44 | /** 45 | * Test the route workflow. 46 | * 47 | * @author Aaron Coburn 48 | * @since 2015-04-10 49 | */ 50 | @RunWith(SpringJUnit4ClassRunner.class) 51 | @ContextConfiguration(classes = {RouteUpdateIT.ContextConfig.class}, loader = AnnotationConfigContextLoader.class) 52 | public class RouteDeleteIT { 53 | 54 | final private Logger logger = getLogger(RouteDeleteIT.class); 55 | 56 | private static FusekiServer server = null; 57 | 58 | private static final String AS_NS = "https://www.w3.org/ns/activitystreams#"; 59 | 60 | private String fullPath = ""; 61 | 62 | private static final String FUSEKI_PORT = System.getProperty( 63 | "fuseki.dynamic.test.port", "8080" 64 | ); 65 | 66 | private static final String FCREPO_PORT = System.getProperty( 67 | "fcrepo.dynamic.test.port", "8080" 68 | ); 69 | 70 | @Produce("direct:start") 71 | protected ProducerTemplate template; 72 | 73 | @Autowired 74 | private CamelContext camelContext; 75 | 76 | @BeforeClass 77 | public static void beforeClass() { 78 | final String jmsPort = System.getProperty("fcrepo.dynamic.jms.port", "61616"); 79 | final Properties props = new Properties(); 80 | System.setProperty("triplestore.indexing.enabled", "true"); 81 | System.setProperty("triplestore.indexing.predicate", "true"); 82 | System.setProperty("triplestore.baseUrl", "http://localhost:" + FUSEKI_PORT + "/fuseki/test/update"); 83 | System.setProperty("fcrepo.baseUrl", "http://localhost:" + FCREPO_PORT + "/fcrepo/rest"); 84 | System.setProperty("jms.brokerUrl", "tcp://localhost:" + jmsPort); 85 | System.setProperty("triplestore.input.stream", "direct:start"); 86 | } 87 | 88 | @After 89 | public void tearDownFuseki() throws Exception { 90 | logger.info("Stopping EmbeddedFusekiServer"); 91 | server.stop(); 92 | } 93 | 94 | @Before 95 | public void setUpFuseki() throws Exception { 96 | final FcrepoClient client = createFcrepoClient(); 97 | final FcrepoResponse res = client.post(URI.create("http://localhost:" + FCREPO_PORT + "/fcrepo/rest")) 98 | .body(loadResourceAsStream("container.ttl"), "text/turtle").perform(); 99 | fullPath = res.getLocation().toString(); 100 | 101 | logger.info("Starting EmbeddedFusekiServer on port {}", FUSEKI_PORT); 102 | final Dataset ds = DatasetFactory.createTxnMem(); //new DatasetImpl(createDefaultModel()); 103 | server = FusekiServer.create() 104 | .verbose(true) 105 | .port(parseInt(FUSEKI_PORT)) 106 | .contextPath("/fuseki") 107 | .add("/test", ds, true) 108 | .build(); 109 | server.start(); 110 | } 111 | 112 | @DirtiesContext 113 | @Test 114 | public void testDeletedResourceWithEventBody() throws Exception { 115 | final String path = fullPath.replaceFirst("http://localhost:[0-9]+/fcrepo/rest", ""); 116 | final String fusekiEndpoint = "mock:http:localhost:" + FUSEKI_PORT + "/fuseki/test/update"; 117 | final String fcrepoEndpoint = "mock:fcrepo:http://localhost:" + FCREPO_PORT + "/fcrepo/rest"; 118 | final String fusekiBase = "http://localhost:" + FUSEKI_PORT + "/fuseki/test"; 119 | 120 | final var context = camelContext.adapt(ModelCamelContext.class); 121 | 122 | AdviceWith.adviceWith(context, "FcrepoTriplestoreRouter", a -> { 123 | a.mockEndpoints("*"); 124 | }); 125 | 126 | AdviceWith.adviceWith(context, "FcrepoTriplestoreUpdater", a -> { 127 | a.mockEndpoints("*"); 128 | }); 129 | 130 | AdviceWith.adviceWith(context, "FcrepoTriplestoreDeleter", a -> { 131 | a.mockEndpoints("*"); 132 | }); 133 | 134 | TestUtils.populateFuseki(fusekiBase, fullPath); 135 | 136 | await().until(TestUtils.triplestoreCount(fusekiBase, fullPath), greaterThanOrEqualTo(1)); 137 | 138 | final var fusekiMockEndpoint = MockEndpoint.resolve(camelContext, fusekiEndpoint); 139 | fusekiMockEndpoint.expectedMessageCount(1); 140 | 141 | final var deleteEndpoint = MockEndpoint.resolve(camelContext, "mock://direct:delete.triplestore"); 142 | deleteEndpoint.expectedMessageCount(1); 143 | final var updateEndpoint = MockEndpoint.resolve(camelContext, "mock://direct:update.triplestore"); 144 | updateEndpoint.expectedMessageCount(0); 145 | updateEndpoint.setAssertPeriod(ASSERT_PERIOD_MS); 146 | final var fcrepoMockEndpoint = MockEndpoint.resolve(camelContext, fcrepoEndpoint); 147 | fcrepoMockEndpoint.expectedMessageCount(0); 148 | fcrepoMockEndpoint.setAssertPeriod(ASSERT_PERIOD_MS); 149 | template.sendBody("direct:start", getEvent(fullPath, AS_NS + "Delete")); 150 | 151 | await().until(TestUtils.triplestoreCount(fusekiBase, fullPath), equalTo(0)); 152 | 153 | MockEndpoint.assertIsSatisfied(fusekiMockEndpoint, fcrepoMockEndpoint, deleteEndpoint, updateEndpoint); 154 | } 155 | } 156 | --------------------------------------------------------------------------------