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 */
018
019package org.fcrepo.kernel.impl.observer;
020
021import org.fcrepo.config.ServerManagedPropsMode;
022import org.fcrepo.kernel.api.Transaction;
023import org.fcrepo.kernel.api.identifiers.FedoraId;
024import org.fcrepo.kernel.api.observer.Event;
025import org.fcrepo.kernel.api.observer.EventType;
026import org.fcrepo.kernel.impl.operations.DeleteResourceOperationFactoryImpl;
027import org.fcrepo.kernel.impl.operations.NonRdfSourceOperationFactoryImpl;
028import org.fcrepo.kernel.impl.operations.RdfSourceOperationFactoryImpl;
029import org.fcrepo.kernel.impl.operations.VersionResourceOperationFactoryImpl;
030
031import org.junit.Before;
032import org.junit.Test;
033import org.junit.runner.RunWith;
034import org.mockito.Mock;
035import org.mockito.junit.MockitoJUnitRunner;
036
037import java.io.ByteArrayInputStream;
038import java.util.Set;
039
040import static org.fcrepo.kernel.api.RdfLexicon.RDF_SOURCE;
041import static org.hamcrest.MatcherAssert.assertThat;
042import static org.hamcrest.Matchers.contains;
043import static org.hamcrest.Matchers.containsInAnyOrder;
044import static org.junit.Assert.assertEquals;
045import static org.junit.Assert.assertNotNull;
046import static org.mockito.Mockito.when;
047
048/**
049 * @author pwinckles
050 */
051@RunWith(MockitoJUnitRunner.Silent.class)
052public class ResourceOperationEventBuilderTest {
053
054    private static final FedoraId FEDORA_ID = FedoraId.create("/test");
055    private static final String USER = "user1";
056    private static final String BASE_URL = "http://locahost/rest";
057
058    @Mock
059    private Transaction transaction;
060
061    @Before
062    public void setup() {
063        when(transaction.getId()).thenReturn("tx-123");
064    }
065
066    @Test
067    public void buildCreateEventFromCreateRdfOperation() {
068        final var operation = new RdfSourceOperationFactoryImpl()
069                .createBuilder(transaction, FEDORA_ID, RDF_SOURCE.toString(), ServerManagedPropsMode.RELAXED)
070                .userPrincipal(USER)
071                .build();
072
073        final var event = ResourceOperationEventBuilder.fromResourceOperation(FEDORA_ID, operation, null)
074                .withBaseUrl(BASE_URL)
075                .build();
076
077        assertDefaultEvent(event, EventType.RESOURCE_CREATION);
078    }
079
080    @Test
081    public void buildCreateEventFromCreateNonRdfOperation() {
082        final var fedoraId = FedoraId.create("/test/ab/c");
083        final var user = "user2";
084        final var operation = new NonRdfSourceOperationFactoryImpl()
085                .createInternalBinaryBuilder(transaction, fedoraId, new ByteArrayInputStream(new byte[]{}))
086                .userPrincipal(user)
087                .build();
088
089        final var event = ResourceOperationEventBuilder.fromResourceOperation(fedoraId, operation, null)
090                .withBaseUrl(BASE_URL)
091                .build();
092
093        assertEquals(fedoraId, event.getFedoraId());
094        assertEquals(fedoraId.getFullIdPath(), event.getPath());
095        assertEquals(user, event.getUserID());
096        assertThat(event.getTypes(), contains(EventType.RESOURCE_CREATION));
097        assertNotNull(event.getEventID());
098        assertNotNull(event.getDate());
099    }
100
101    @Test
102    public void buildCreateEventFromVersionOperation() {
103        final var operation = new VersionResourceOperationFactoryImpl().createBuilder(transaction, FEDORA_ID)
104                .userPrincipal(USER)
105                .build();
106
107        final var event = ResourceOperationEventBuilder.fromResourceOperation(FEDORA_ID, operation, null)
108                .withBaseUrl(BASE_URL)
109                .build();
110
111        assertDefaultEvent(event, EventType.RESOURCE_MODIFICATION);
112    }
113
114    @Test
115    public void buildDeleteEventFromDeleteOperation() {
116        final var operation = new DeleteResourceOperationFactoryImpl().deleteBuilder(transaction, FEDORA_ID)
117                .userPrincipal(USER)
118                .build();
119
120        final var event = ResourceOperationEventBuilder.fromResourceOperation(FEDORA_ID, operation, null)
121                .withBaseUrl(BASE_URL)
122                .build();
123
124        assertDefaultEvent(event, EventType.RESOURCE_DELETION);
125    }
126
127    @Test
128    public void buildUpdateEventFromUpdateRdfOperation() {
129        final var operation = new RdfSourceOperationFactoryImpl()
130                .updateBuilder(transaction, FEDORA_ID, ServerManagedPropsMode.RELAXED)
131                .userPrincipal(USER)
132                .build();
133
134        final var event = ResourceOperationEventBuilder.fromResourceOperation(FEDORA_ID, operation, null)
135                .withBaseUrl(BASE_URL)
136                .build();
137
138        assertDefaultEvent(event, EventType.RESOURCE_MODIFICATION);
139    }
140
141    @Test
142    public void buildUpdateEventFromUpdateNonRdfOperation() {
143        final var operation = new NonRdfSourceOperationFactoryImpl()
144                .updateInternalBinaryBuilder(transaction, FEDORA_ID, new ByteArrayInputStream(new byte[]{}))
145                .userPrincipal(USER)
146                .build();
147
148        final var event = ResourceOperationEventBuilder.fromResourceOperation(FEDORA_ID, operation, null)
149                .withBaseUrl(BASE_URL)
150                .build();
151
152        assertDefaultEvent(event, EventType.RESOURCE_MODIFICATION);
153    }
154
155    @Test
156    public void mergeValidObjects() {
157        final var createOperation = new RdfSourceOperationFactoryImpl()
158                .createBuilder(transaction, FEDORA_ID, RDF_SOURCE.toString(), ServerManagedPropsMode.RELAXED)
159                .userPrincipal(USER)
160                .build();
161
162        final var createEventBuilder = ResourceOperationEventBuilder
163                .fromResourceOperation(FEDORA_ID, createOperation, null)
164                .withBaseUrl(BASE_URL);
165
166        final var updateOperation = new NonRdfSourceOperationFactoryImpl()
167                .updateInternalBinaryBuilder(transaction, FEDORA_ID, new ByteArrayInputStream(new byte[]{}))
168                .userPrincipal(USER)
169                .build();
170
171        final var updateEventBuilder = ResourceOperationEventBuilder
172                .fromResourceOperation(FEDORA_ID, updateOperation, null)
173                .withBaseUrl(BASE_URL);
174        final var updateEvent = updateEventBuilder.build();
175
176        final var merged = createEventBuilder.merge(updateEventBuilder).build();
177
178        assertEquals(FEDORA_ID, merged.getFedoraId());
179        assertEquals(FEDORA_ID.getFullIdPath(), merged.getPath());
180        assertEquals(USER, merged.getUserID());
181        assertThat(merged.getTypes(), containsInAnyOrder(EventType.RESOURCE_CREATION, EventType.RESOURCE_MODIFICATION));
182        assertEquals(updateEvent.getDate(), merged.getDate());
183    }
184
185    @Test
186    public void populateOtherEventFields() {
187        final var operation = new NonRdfSourceOperationFactoryImpl()
188                .updateInternalBinaryBuilder(transaction, FEDORA_ID, new ByteArrayInputStream(new byte[]{}))
189                .userPrincipal(USER)
190                .build();
191
192        final var baseUrl = "http://localhost/rest";
193        final var userAgent = "user-agent";
194        final var resourceTypes = Set.of("resource-type");
195
196        final var event = ResourceOperationEventBuilder.fromResourceOperation(FEDORA_ID, operation, null)
197                .withBaseUrl(baseUrl)
198                .withUserAgent(userAgent)
199                .withResourceTypes(resourceTypes)
200                .build();
201
202        assertEquals(baseUrl, event.getBaseUrl());
203        assertEquals(userAgent, event.getUserAgent());
204        assertEquals(resourceTypes, event.getResourceTypes());
205    }
206
207    private void assertDefaultEvent(final Event event, final EventType type) {
208        assertEquals(FEDORA_ID, event.getFedoraId());
209        assertEquals(FEDORA_ID.getFullIdPath(), event.getPath());
210        assertEquals(USER, event.getUserID());
211        assertThat(event.getTypes(), contains(type));
212        assertNotNull(event.getEventID());
213        assertNotNull(event.getDate());
214    }
215
216}