Skip to content

Commit

Permalink
Merge pull request #30 from futures/43942653
Browse files Browse the repository at this point in the history
43942653: Build an audit (logging) service
  • Loading branch information
cbeer committed Feb 7, 2013
2 parents 456a6ff + 7706408 commit 245b8d7
Show file tree
Hide file tree
Showing 5 changed files with 166 additions and 1 deletion.
8 changes: 7 additions & 1 deletion pom.xml
Expand Up @@ -20,7 +20,6 @@
<enunciate.version>1.26.2</enunciate.version>
</properties>


<dependencyManagement>
<dependencies>
<!-- Import the ModeShape BOM for embedded usage. This adds to the "dependenciesManagement"
Expand Down Expand Up @@ -160,6 +159,13 @@
<artifactId>rome</artifactId>
<version>1.0</version>
</dependency>

<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>1.9.5</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand Down
17 changes: 17 additions & 0 deletions src/main/java/org/fcrepo/modeshape/modules/audit/Auditor.java
@@ -0,0 +1,17 @@
package org.fcrepo.modeshape.modules.audit;

import javax.jcr.RepositoryException;
import javax.jcr.observation.Event;

import com.google.common.eventbus.Subscribe;

/**
* An interface for recording auditable Fedora events.
*
* @author Edwin Shin
*/
public interface Auditor {

@Subscribe
public void recordEvent(Event e) throws RepositoryException;
}
@@ -0,0 +1,69 @@
package org.fcrepo.modeshape.modules.audit;

import javax.jcr.RepositoryException;
import javax.jcr.observation.Event;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.eventbus.Subscribe;

/**
* A proof-of-concept Auditor implementation that uses Logback.
*
* @author Edwin Shin
*/
public class LogbackAuditor implements Auditor {

Logger logger = LoggerFactory.getLogger(LogbackAuditor.class);

/**
*
*/
@Override
@Subscribe
public void recordEvent(Event e) throws RepositoryException {
logger.info(e.getUserID() + " " + getEventName(e.getType()) + " " +
e.getPath());
}

/**
* Static utility method to retrieve a String representation of the type
* defined by a {@link javax.jcr.observation.Event JCR event}.
*
* @param jcrEvent
* @return Event name of the given JCR event type.
* @throws IllegalArgumentException if the given int does not represent a
* valid type constants as defined by {@link Event}.<br>
*/
private static String getEventName(int jcrEvent) {
String eventName;
switch (jcrEvent) {
case Event.NODE_ADDED:
eventName = "node added";
break;
case Event.NODE_REMOVED:
eventName = "node removed";
break;
case Event.PROPERTY_ADDED:
eventName = "property added";
break;
case Event.PROPERTY_CHANGED:
eventName = "property changed";
break;
case Event.PROPERTY_REMOVED:
eventName = "property removed";
break;
case Event.NODE_MOVED:
eventName = "node moved";
break;
case Event.PERSIST:
eventName = "persist";
break;
default: // no default
throw new IllegalArgumentException("Invalid JCR event type: " +
jcrEvent);
}
return eventName;
}
}
@@ -0,0 +1,68 @@
package org.fcrepo.modeshape.modules.audit;

import static org.mockito.Matchers.argThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import javax.jcr.observation.Event;

import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentMatcher;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.slf4j.LoggerFactory;

import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.classic.spi.LoggingEvent;
import ch.qos.logback.core.Appender;

import com.google.common.eventbus.EventBus;


public class LogbackAuditorTest {

private int jcrEventType = 1;

private String jcrEventUserID = "jdoe";

private String jcrEventPath = "/foo/bar";

@Mock
private Appender<ILoggingEvent> mockAppender;

@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}

@Test
public void testEventAuditing() throws Exception {
Logger root = (Logger) LoggerFactory.getLogger(LogbackAuditor.class);

when(mockAppender.getName()).thenReturn("MockAppender");

Event mockEvent = mock(Event.class);
when(mockEvent.getType()).thenReturn(jcrEventType);
when(mockEvent.getUserID()).thenReturn(jcrEventUserID);
when(mockEvent.getPath()).thenReturn(jcrEventPath);

root.addAppender(mockAppender);

EventBus eventBus = new EventBus("Test EventBus");
Auditor auditor = new LogbackAuditor();
eventBus.register(auditor);
eventBus.post(mockEvent);

verify(mockAppender).doAppend(
(ILoggingEvent) argThat(new ArgumentMatcher<Object>() {
@Override
public boolean matches(final Object argument) {
return ((LoggingEvent) argument).getFormattedMessage()
.contains("jdoe node added /foo/bar");
}
}));
}
}
5 changes: 5 additions & 0 deletions src/test/resources/logback.xml
Expand Up @@ -6,6 +6,11 @@
<pattern>%p %d{HH:mm:ss.SSS} \(%c{0}\) %m%n</pattern>
</encoder>
</appender>

<logger name="org.fcrepo.modeshape.modules.audit" additivity="false" level="DEBUG">
<appender-ref ref="STDOUT"/>
</logger>

<logger name="org.fcrepo" additivity="false" level="DEBUG">
<appender-ref ref="STDOUT"/>
</logger>
Expand Down

0 comments on commit 245b8d7

Please sign in to comment.