001/*
002 * The contents of this file are subject to the license and copyright
003 * detailed in the LICENSE and NOTICE files at the root of the source
004 * tree.
005 */
006package org.fcrepo.camel.audit.triplestore;
007
008import static java.util.Arrays.asList;
009import static org.fcrepo.camel.FcrepoHeaders.FCREPO_AGENT;
010import static org.fcrepo.camel.FcrepoHeaders.FCREPO_DATE_TIME;
011import static org.fcrepo.camel.FcrepoHeaders.FCREPO_EVENT_TYPE;
012import static org.fcrepo.camel.FcrepoHeaders.FCREPO_EVENT_ID;
013import static org.fcrepo.camel.FcrepoHeaders.FCREPO_RESOURCE_TYPE;
014import static org.fcrepo.camel.FcrepoHeaders.FCREPO_URI;
015import static org.fcrepo.camel.audit.triplestore.AuditSparqlProcessor.AUDIT;
016import static org.fcrepo.camel.audit.triplestore.AuditSparqlProcessor.EVENT_TYPE;
017import static org.fcrepo.camel.audit.triplestore.AuditSparqlProcessor.PREMIS;
018import static org.fcrepo.camel.audit.triplestore.AuditSparqlProcessor.XSD;
019
020import java.io.IOException;
021import java.util.HashMap;
022import java.util.List;
023import java.util.Map;
024
025import org.apache.camel.EndpointInject;
026import org.apache.camel.Exchange;
027import org.apache.camel.Produce;
028import org.apache.camel.ProducerTemplate;
029import org.apache.camel.builder.RouteBuilder;
030import org.apache.camel.component.mock.MockEndpoint;
031import org.apache.camel.test.junit4.CamelTestSupport;
032
033import org.junit.Test;
034
035/**
036 * Test the route workflow.
037 *
038 * @author escowles
039 * @author Aaron Coburn
040 * @since 2015-04-10
041 */
042public class ProcessorTest extends CamelTestSupport {
043
044    @EndpointInject("mock:result")
045    protected MockEndpoint resultEndpoint;
046
047    @Produce("direct:start")
048    protected ProducerTemplate template;
049
050    private static final String baseURL = "http://localhost/rest";
051    private static final String eventBaseURI = "http://example.com/event";
052    private static final String nodeID = "/foo";
053    private static final String fileID = "/file1";
054    private static final String eventDate = "2015-04-06T22:45:20Z";
055    private static final String userID = "bypassAdmin";
056    private static final String userAgent = "curl/7.37.1";
057    private static final String eventID = "ab/cd/ef/gh/abcdefgh12345678";
058    private static final String eventURI = eventBaseURI + "/" + eventID;
059    private static final String EVENT_NS = "http://fedora.info/definitions/v4/event#";
060    private static final String AS_NS = "https://www.w3.org/ns/activitystreams#";
061    private static final String REPOSITORY = "http://fedora.info/definitions/v4/repository#";
062
063    @Test
064    public void testNodeAdded() throws Exception {
065
066        resultEndpoint.expectedMessageCount(1);
067        resultEndpoint.expectedHeaderReceived(Exchange.CONTENT_TYPE, "application/x-www-form-urlencoded");
068        resultEndpoint.expectedHeaderReceived(Exchange.HTTP_METHOD, "POST");
069
070        template.sendBodyAndHeaders("",
071                createEvent(nodeID, asList(EVENT_NS + "ResourceCreation"), asList(REPOSITORY + "Resource"), eventID));
072
073        assertMockEndpointsSatisfied();
074        final String body = (String)resultEndpoint.assertExchangeReceived(0).getIn().getBody();
075        assertTrue("Event type not found!",
076            body.contains("<" + eventURI + "> <" + PREMIS + "hasEventType> <" + EVENT_TYPE + "cre>"));
077        assertTrue("Object link not found!",
078            body.contains("<" + eventURI + "> <" + PREMIS + "hasEventRelatedObject> <" + baseURL + nodeID + ">"));
079        assertTrue("Event date not found!",
080            body.contains("<" + eventURI + "> <" + PREMIS + "hasEventDateTime> \"" + eventDate + "\"^^<"
081                    + XSD + "dateTime>"));
082        assertTrue("Event user not found!",
083            body.contains("<" + eventURI + "> <" + PREMIS + "hasEventRelatedAgent> \"" + userID + "\" ."));
084        assertTrue("Event agent not found!",
085            body.contains("<" + eventURI + "> <" + PREMIS + "hasEventRelatedAgent> \"" + userAgent + "\" ."));
086    }
087
088    @Test
089    public void testNodeRemoved() throws Exception {
090
091        resultEndpoint.expectedMessageCount(1);
092        resultEndpoint.expectedHeaderReceived(Exchange.CONTENT_TYPE, "application/x-www-form-urlencoded");
093        resultEndpoint.expectedHeaderReceived(Exchange.HTTP_METHOD, "POST");
094
095        template.sendBodyAndHeaders("",
096                createEvent(nodeID, asList(EVENT_NS + "ResourceDeletion"), asList(REPOSITORY + "Resource"), eventID));
097
098        assertMockEndpointsSatisfied();
099        final String body = (String)resultEndpoint.assertExchangeReceived(0).getIn().getBody();
100        assertTrue("Event type not found!",
101            body.contains("<" + eventURI + "> <" + PREMIS + "hasEventType> <" + EVENT_TYPE + "del>"));
102        assertTrue("Object link not found!",
103            body.contains("<" + eventURI + "> <" + PREMIS + "hasEventRelatedObject> <" + baseURL + nodeID + ">"));
104    }
105
106    @Test
107    public void testPropertiesChanged() throws Exception {
108
109        resultEndpoint.expectedMessageCount(1);
110        resultEndpoint.expectedHeaderReceived(Exchange.CONTENT_TYPE, "application/x-www-form-urlencoded");
111        resultEndpoint.expectedHeaderReceived(Exchange.HTTP_METHOD, "POST");
112
113        template.sendBodyAndHeaders("",
114                createEvent(nodeID, asList(AS_NS + "Update"), asList(REPOSITORY + "Resource"), eventID));
115
116        assertMockEndpointsSatisfied();
117        final String body = (String)resultEndpoint.assertExchangeReceived(0).getIn().getBody();
118        assertTrue("Event type not found!",
119            body.contains("<" + eventURI + "> <" + PREMIS + "hasEventType> <" + AUDIT + "metadataModification>"));
120        assertTrue("Object link not found!",
121            body.contains("<" + eventURI + "> <" + PREMIS + "hasEventRelatedObject> <" + baseURL + nodeID + ">"));
122    }
123
124    @Test
125    public void testFileAdded() throws Exception {
126
127        resultEndpoint.expectedMessageCount(1);
128        resultEndpoint.expectedHeaderReceived(Exchange.CONTENT_TYPE, "application/x-www-form-urlencoded");
129        resultEndpoint.expectedHeaderReceived(Exchange.HTTP_METHOD, "POST");
130
131        template.sendBodyAndHeaders("",
132                createEvent(fileID, asList(AS_NS + "Create"), asList(REPOSITORY + "Binary"), eventID));
133
134        assertMockEndpointsSatisfied();
135        final String body = (String)resultEndpoint.assertExchangeReceived(0).getIn().getBody();
136        assertTrue("Event type not found!",
137            body.contains("<" + eventURI + "> <" + PREMIS + "hasEventType> <" + EVENT_TYPE + "ing>"));
138        assertTrue("Object link not found!",
139            body.contains("<" + eventURI + "> <" + PREMIS + "hasEventRelatedObject> <" + baseURL + fileID + ">"));
140    }
141
142    @Test
143    public void testFileChanged() throws Exception {
144
145        resultEndpoint.expectedMessageCount(1);
146        resultEndpoint.expectedHeaderReceived(Exchange.CONTENT_TYPE, "application/x-www-form-urlencoded");
147        resultEndpoint.expectedHeaderReceived(Exchange.HTTP_METHOD, "POST");
148
149        template.sendBodyAndHeaders("",
150                createEvent(fileID, asList(AS_NS + "Update"), asList(REPOSITORY + "Binary"), eventID));
151
152        assertMockEndpointsSatisfied();
153        final String body = (String)resultEndpoint.assertExchangeReceived(0).getIn().getBody();
154        assertTrue("Event type not found!",
155            body.contains("<" + eventURI + "> <" + PREMIS + "hasEventType> <" + AUDIT + "contentModification>"));
156        assertTrue("Object link not found!",
157            body.contains("<" + eventURI + "> <" + PREMIS + "hasEventRelatedObject> <" + baseURL + fileID + ">"));
158    }
159
160    @Test
161    public void testFileRemoved() throws Exception {
162
163        resultEndpoint.expectedMessageCount(1);
164        resultEndpoint.expectedHeaderReceived(Exchange.CONTENT_TYPE, "application/x-www-form-urlencoded");
165        resultEndpoint.expectedHeaderReceived(Exchange.HTTP_METHOD, "POST");
166
167        template.sendBodyAndHeaders("",
168                createEvent(fileID, asList(AS_NS + "Delete"), asList(REPOSITORY + "Binary"), eventID));
169
170        assertMockEndpointsSatisfied();
171        final String body = (String)resultEndpoint.assertExchangeReceived(0).getIn().getBody();
172        assertTrue("Event type not found!",
173            body.contains("<" + eventURI + "> <" + PREMIS + "hasEventType> <" + AUDIT + "contentRemoval>"));
174        assertTrue("Object link not found!",
175            body.contains("<" + eventURI + "> <" + PREMIS + "hasEventRelatedObject> <" + baseURL + fileID + ">"));
176    }
177
178    private static Map<String,Object> createEvent(final String identifier, final List<String> eventTypes,
179            final List<String> resourceTypes, final String eventID) {
180
181        final Map<String, Object> headers = new HashMap<>();
182        headers.put(FCREPO_URI, baseURL + identifier);
183        headers.put(FCREPO_DATE_TIME, eventDate);
184        headers.put(FCREPO_AGENT, asList(userID, userAgent));
185        headers.put(FCREPO_RESOURCE_TYPE, resourceTypes);
186        headers.put(FCREPO_EVENT_TYPE, eventTypes);
187        headers.put(FCREPO_EVENT_ID, eventID);
188        return headers;
189    }
190
191    @Override
192    protected RouteBuilder createRouteBuilder() {
193        return new RouteBuilder() {
194            @Override
195            public void configure() throws IOException {
196                from("direct:start")
197                    .setHeader(AuditHeaders.EVENT_BASE_URI, constant(eventBaseURI))
198                    .process(new AuditSparqlProcessor())
199                    .to("mock:result");
200            }
201        };
202    }
203}