001/*
002 * Licensed to DuraSpace under one or more contributor license agreements.
003 * See the NOTICE file distributed with this work for additional information
004 * regarding copyright ownership.
005 *
006 * DuraSpace licenses this file to you under the Apache License,
007 * Version 2.0 (the "License"); you may not use this file except in
008 * compliance with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.fcrepo.event.serialization;
019
020import static org.apache.jena.datatypes.xsd.XSDDatatype.XSDdateTime;
021import static org.apache.jena.rdf.model.ResourceFactory.createProperty;
022import static org.apache.jena.rdf.model.ResourceFactory.createResource;
023import static org.apache.jena.rdf.model.ResourceFactory.createTypedLiteral;
024import static org.apache.jena.vocabulary.DCTerms.identifier;
025import static org.apache.jena.vocabulary.DCTerms.isPartOf;
026import static org.apache.jena.vocabulary.RDF.type;
027import static java.time.Instant.ofEpochMilli;
028import static org.fcrepo.kernel.api.RdfLexicon.EVENT_NAMESPACE;
029import static org.fcrepo.kernel.api.RdfLexicon.PROV_NAMESPACE;
030import static org.fcrepo.kernel.api.RdfLexicon.REPOSITORY_NAMESPACE;
031import static org.fcrepo.kernel.api.observer.OptionalValues.BASE_URL;
032import static org.fcrepo.kernel.api.observer.OptionalValues.USER_AGENT;
033import static org.fcrepo.event.serialization.EventSerializer.toModel;
034import static org.junit.Assert.assertEquals;
035import static org.junit.Assert.assertTrue;
036import static org.mockito.Mockito.when;
037
038import java.time.Instant;
039import java.util.HashMap;
040import java.util.HashSet;
041import java.util.Map;
042import java.util.Set;
043import java.util.concurrent.atomic.AtomicInteger;
044
045import org.apache.jena.rdf.model.Model;
046import org.apache.jena.rdf.model.Resource;
047import org.apache.jena.rdf.model.SimpleSelector;
048import org.fcrepo.kernel.api.observer.EventType;
049import org.fcrepo.kernel.api.observer.FedoraEvent;
050import org.junit.Before;
051import org.junit.Test;
052import org.junit.runner.RunWith;
053import org.mockito.Mock;
054import org.mockito.runners.MockitoJUnitRunner;
055
056/**
057 * <p>FedoraEventTest class.</p>
058 *
059 * @author acoburn
060 */
061@RunWith(MockitoJUnitRunner.class)
062public class FedoraEventTest {
063
064    private static String FOAF_NAMESPACE = "http://xmlns.com/foaf/0.1/";
065
066    @Mock
067    private FedoraEvent mockEvent;
068
069    private String baseUrl = "http://localhost:8080/fcrepo/rest";
070
071    private String path = "/path/to/resource";
072
073    private Instant timestamp = ofEpochMilli(1465919304000L);
074
075    @Before
076    public void setUp() {
077        final Set<EventType> typeSet = new HashSet<>();
078        typeSet.add(EventType.RESOURCE_MODIFICATION);
079        final Set<String> resourceTypeSet = new HashSet<>();
080        resourceTypeSet.add(REPOSITORY_NAMESPACE + "Resource");
081        resourceTypeSet.add(REPOSITORY_NAMESPACE + "Container");
082        resourceTypeSet.add("http://example.com/SampleType");
083        final Map<String, String> auxInfo = new HashMap<>();
084        auxInfo.put(BASE_URL, baseUrl);
085        auxInfo.put(USER_AGENT, "fcrepo-client/1.0");
086        when(mockEvent.getTypes()).thenReturn(typeSet);
087        when(mockEvent.getResourceTypes()).thenReturn(resourceTypeSet);
088        when(mockEvent.getPath()).thenReturn(path);
089        when(mockEvent.getUserID()).thenReturn("fedo raadmin");
090        when(mockEvent.getDate()).thenReturn(timestamp);
091        when(mockEvent.getEventID()).thenReturn("urn:uuid:some-event");
092        when(mockEvent.getInfo()).thenReturn(auxInfo);
093    }
094
095    @Test
096    public void testModel() {
097        final Model model = toModel(mockEvent);
098        final Resource subject = createResource(baseUrl + path);
099        final Resource blankNode = null;
100
101        assertTrue(model.contains(subject, type, createResource(REPOSITORY_NAMESPACE + "Resource")));
102        assertTrue(model.contains(subject, type, createResource(REPOSITORY_NAMESPACE + "Container")));
103        assertTrue(model.contains(subject, type, createResource("http://example.com/SampleType")));
104        assertTrue(model.contains(subject, isPartOf, createResource(baseUrl)));
105        assertTrue(model.contains(subject, createProperty(PROV_NAMESPACE + "wasGeneratedBy")));
106        assertTrue(model.contains(subject, createProperty(PROV_NAMESPACE + "wasAttributedTo")));
107
108        final AtomicInteger activities = new AtomicInteger();
109        model.listStatements(new SimpleSelector(subject, createProperty(PROV_NAMESPACE + "wasGeneratedBy"), blankNode))
110            .forEachRemaining(statement -> {
111                final Resource r = statement.getResource();
112                assertTrue(r.hasProperty(type, createResource(EVENT_NAMESPACE + "ResourceModification")));
113                assertTrue(r.hasProperty(type, createResource(PROV_NAMESPACE + "Activity")));
114                assertTrue(r.hasProperty(identifier, createResource("urn:uuid:some-event")));
115                assertTrue(r.hasProperty(createProperty(PROV_NAMESPACE + "atTime"),
116                        createTypedLiteral(timestamp.toString(), XSDdateTime)));
117                activities.incrementAndGet();
118            });
119        assertEquals(activities.get(), 1);
120
121        final AtomicInteger agents = new AtomicInteger();
122        model.listStatements(new SimpleSelector(subject, createProperty(PROV_NAMESPACE + "wasAttributedTo"), blankNode))
123            .forEachRemaining(statement -> {
124                final Resource r = statement.getResource();
125                if (r.hasProperty(type, createResource(PROV_NAMESPACE + "Person"))) {
126                    assertTrue(r.hasProperty(type, createResource(PROV_NAMESPACE + "Person")));
127                    assertTrue(r.hasProperty(createProperty(FOAF_NAMESPACE + "name"), "fedo raadmin"));
128                } else {
129                    assertTrue(r.hasProperty(type, createResource(PROV_NAMESPACE + "SoftwareAgent")));
130                    assertTrue(r.hasProperty(createProperty(FOAF_NAMESPACE + "name"), "fcrepo-client/1.0"));
131                }
132                agents.incrementAndGet();
133            });
134        assertEquals(agents.get(), 2);
135    }
136
137    @Test
138    public void testTurtle() {
139        final EventSerializer serializer = new TurtleSerializer();
140        final String ttl = serializer.serialize(mockEvent);
141        assertTrue(ttl.contains("<http://localhost:8080/fcrepo/rest/path/to/resource>"));
142    }
143}