Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Update event machinery to collapse events about content nodes
- Filter out 'fcr:content' so add/remove content only produces a single event
- Add IT demonstrating only a single event is emitted when content node is added

Resolves: https://jira.duraspace.org/browse/FCREPO-1440
  • Loading branch information
escowles authored and Andrew Woods committed Apr 8, 2015
1 parent 9a70b54 commit 3de050c
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 2 deletions.
Expand Up @@ -59,7 +59,8 @@ public class AllNodeEventsOneEvent implements InternalExternalEventMapper {
@Override
public String apply(final Event ev) {
try {
final String id = ev.getIdentifier();
// build id from nodepath+user to collapse multiple nodes from adding/removing content nodes
final String id = FedoraEvent.getPath(ev).replaceAll("/fcr:content","") + "-" + ev.getUserID();
LOGGER.debug("Sorting an event by identifier: {}", id);
return id;
} catch (final RepositoryException e) {
Expand Down
Expand Up @@ -15,13 +15,17 @@
*/
package org.fcrepo.integration.kernel.impl.observer;

import static org.fcrepo.kernel.FedoraJcrTypes.FEDORA_BINARY;
import static org.fcrepo.kernel.FedoraJcrTypes.FEDORA_CONTAINER;
import static org.fcrepo.kernel.RdfLexicon.REPOSITORY_NAMESPACE;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.modeshape.jcr.api.JcrConstants.JCR_DATA;

import java.io.ByteArrayInputStream;
import javax.inject.Inject;
import javax.jcr.Node;
import javax.jcr.Repository;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
Expand All @@ -31,6 +35,8 @@
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.modeshape.jcr.api.Binary;
import org.modeshape.jcr.api.ValueFactory;
import org.springframework.test.context.ContextConfiguration;

import com.google.common.eventbus.EventBus;
Expand Down Expand Up @@ -77,6 +83,28 @@ public void TestEventBusPublishing() throws RepositoryException {

}

@Test
public void contentEventCollapsing() throws RepositoryException {

final Session se = repository.login();
final Binary bin = ((ValueFactory)se.getValueFactory()).createBinary(
new ByteArrayInputStream("test content".getBytes()), null );
final Node node = se.getRootNode().addNode("/object1");
node.addMixin(FEDORA_BINARY);
node.setProperty(JCR_DATA, bin);
se.save();
se.logout();

try {
Thread.sleep(500);
} catch (final InterruptedException e) {
e.printStackTrace();
}

assertEquals("Node and content events not collapsed!", (Integer) 1, eventBusMessageCount);

}

@Subscribe
public void countMessages(final FedoraEvent e) {
eventBusMessageCount++;
Expand Down
Expand Up @@ -17,6 +17,8 @@

import static com.google.common.collect.Iterators.getLast;
import static com.google.common.collect.Iterators.size;
import static javax.jcr.observation.Event.NODE_ADDED;
import static javax.jcr.observation.Event.PROPERTY_ADDED;
import static javax.jcr.observation.Event.PROPERTY_CHANGED;
import static org.jgroups.util.UUID.randomUUID;
import static org.junit.Assert.assertEquals;
Expand Down Expand Up @@ -51,12 +53,20 @@ public class AllNodeEventsOneEventTest {

private static final String TEST_IDENTIFIER2 = TEST_IDENTIFIER1;

private static final String TEST_PATH2 = TEST_PATH1 + "/property";
private static final String TEST_PATH2 = TEST_PATH1 + "/dc:title";

private static final String TEST_IDENTIFIER3 = randomUUID().toString();

private static final String TEST_PATH3 = "/test/node2";

private static final String TEST_IDENTIFIER4 = randomUUID().toString();

private static final String TEST_PATH4 = "/test/node3";

private static final String TEST_IDENTIFIER5 = randomUUID().toString();

private static final String TEST_PATH5 = "/test/node3/fcr:content";

private final AllNodeEventsOneEvent testMapping = new AllNodeEventsOneEvent();

@Mock
Expand All @@ -68,21 +78,41 @@ public class AllNodeEventsOneEventTest {
@Mock
private Event mockEvent3;

@Mock
private Event mockEvent4;

@Mock
private Event mockEvent5;

@Mock
private Iterator<Event> mockIterator;

@Mock
private Iterator<Event> mockIterator2;

@Before
public void setUp() throws RepositoryException {
initMocks(this);
when(mockEvent1.getIdentifier()).thenReturn(TEST_IDENTIFIER1);
when(mockEvent1.getPath()).thenReturn(TEST_PATH1);
when(mockEvent1.getType()).thenReturn(NODE_ADDED);
when(mockEvent2.getIdentifier()).thenReturn(TEST_IDENTIFIER2);
when(mockEvent2.getPath()).thenReturn(TEST_PATH2);
when(mockEvent2.getType()).thenReturn(PROPERTY_ADDED);
when(mockEvent3.getIdentifier()).thenReturn(TEST_IDENTIFIER3);
when(mockEvent3.getPath()).thenReturn(TEST_PATH3);
when(mockEvent3.getType()).thenReturn(PROPERTY_CHANGED);
when(mockIterator.next()).thenReturn(mockEvent1, mockEvent2, mockEvent3);
when(mockIterator.hasNext()).thenReturn(true, true, true, false);

when(mockEvent4.getIdentifier()).thenReturn(TEST_IDENTIFIER4);
when(mockEvent4.getPath()).thenReturn(TEST_PATH4);
when(mockEvent4.getType()).thenReturn(NODE_ADDED);
when(mockEvent5.getIdentifier()).thenReturn(TEST_IDENTIFIER5);
when(mockEvent5.getPath()).thenReturn(TEST_PATH5);
when(mockEvent5.getType()).thenReturn(NODE_ADDED);
when(mockIterator2.next()).thenReturn(mockEvent4, mockEvent5);
when(mockIterator2.hasNext()).thenReturn(true, true, false);
}

@Test
Expand All @@ -91,6 +121,11 @@ public void testCardinality() {
size(testMapping.apply(mockIterator)));
}

@Test
public void testCollapseContentEvents() {
assertEquals("Didn't collapse content node and fcr:content events!", 1, size(testMapping.apply(mockIterator2)));
}

@Test(expected = UnsupportedOperationException.class)
public void testBadOPeration() {
testMapping.apply(mockIterator).remove();
Expand Down
Expand Up @@ -111,6 +111,15 @@ public FedoraEvent addProperty( final String property ) {
* @throws RepositoryException if the repository exception occurred
*/
public String getPath() throws RepositoryException {
return getPath(e);
}

/**
* Get the path of the node related to this event (removing property names
* from the end of property nodes).
* @param e JCR Event
**/
public static String getPath(final Event e) throws RepositoryException {
if (e.getType() == PROPERTY_ADDED ||
e.getType() == PROPERTY_CHANGED ||
e.getType() == PROPERTY_REMOVED) {
Expand Down

0 comments on commit 3de050c

Please sign in to comment.