aboutsummaryrefslogtreecommitdiffstats
path: root/archiva-modules/plugins/audit
diff options
context:
space:
mode:
authorBrett Porter <brett@apache.org>2010-01-19 06:15:09 +0000
committerBrett Porter <brett@apache.org>2010-01-19 06:15:09 +0000
commit606c82cbcad53a9f2c0dd1212ce302e3c8626910 (patch)
tree721b99dd1c650636b7c9909eb843b909c0311ba1 /archiva-modules/plugins/audit
parent685419f0824f9f788513d3f3c3b89eac58118fe6 (diff)
parent96c99628aab4b63d71e660b661120596868a7f25 (diff)
downloadarchiva-606c82cbcad53a9f2c0dd1212ce302e3c8626910.tar.gz
archiva-606c82cbcad53a9f2c0dd1212ce302e3c8626910.zip
merged recent changes from trunk, and reimplemented incoming audit log functionality as a plugin using the metadata repository
git-svn-id: https://svn.apache.org/repos/asf/archiva/branches/MRM-1025@900664 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'archiva-modules/plugins/audit')
-rw-r--r--archiva-modules/plugins/audit/pom.xml45
-rw-r--r--archiva-modules/plugins/audit/src/main/java/org/apache/archiva/audit/AuditEventFactory.java41
-rw-r--r--archiva-modules/plugins/audit/src/main/java/org/apache/archiva/audit/AuditManager.java36
-rw-r--r--archiva-modules/plugins/audit/src/main/java/org/apache/archiva/audit/DefaultAuditManager.java154
-rw-r--r--archiva-modules/plugins/audit/src/main/java/org/apache/archiva/audit/MetadataAuditListener.java44
-rw-r--r--archiva-modules/plugins/audit/src/test/java/org/apache/archiva/audit/AuditManagerTest.java507
6 files changed, 827 insertions, 0 deletions
diff --git a/archiva-modules/plugins/audit/pom.xml b/archiva-modules/plugins/audit/pom.xml
new file mode 100644
index 000000000..276905786
--- /dev/null
+++ b/archiva-modules/plugins/audit/pom.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+-->
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>plugins</artifactId>
+ <groupId>org.apache.archiva</groupId>
+ <version>1.4-SNAPSHOT</version>
+ </parent>
+ <artifactId>audit</artifactId>
+ <name>Audit Logging</name>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.archiva</groupId>
+ <artifactId>archiva-repository-layer</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.archiva</groupId>
+ <artifactId>metadata-repository-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-simple</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/archiva-modules/plugins/audit/src/main/java/org/apache/archiva/audit/AuditEventFactory.java b/archiva-modules/plugins/audit/src/main/java/org/apache/archiva/audit/AuditEventFactory.java
new file mode 100644
index 000000000..9573d5509
--- /dev/null
+++ b/archiva-modules/plugins/audit/src/main/java/org/apache/archiva/audit/AuditEventFactory.java
@@ -0,0 +1,41 @@
+package org.apache.archiva.audit;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.archiva.metadata.model.MetadataFacet;
+import org.apache.archiva.metadata.model.MetadataFacetFactory;
+import org.apache.maven.archiva.repository.audit.AuditEvent;
+
+/**
+ * @plexus.component role="org.apache.archiva.metadata.model.MetadataFacetFactory" role-hint="org.apache.archiva.audit"
+ */
+public class AuditEventFactory
+ implements MetadataFacetFactory
+{
+ public MetadataFacet createMetadataFacet()
+ {
+ throw new UnsupportedOperationException( "Must construct an audit event with a name" );
+ }
+
+ public MetadataFacet createMetadataFacet( String repositoryId, String name )
+ {
+ return new AuditEvent( name, repositoryId );
+ }
+} \ No newline at end of file
diff --git a/archiva-modules/plugins/audit/src/main/java/org/apache/archiva/audit/AuditManager.java b/archiva-modules/plugins/audit/src/main/java/org/apache/archiva/audit/AuditManager.java
new file mode 100644
index 000000000..addb9c0e3
--- /dev/null
+++ b/archiva-modules/plugins/audit/src/main/java/org/apache/archiva/audit/AuditManager.java
@@ -0,0 +1,36 @@
+package org.apache.archiva.audit;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Date;
+import java.util.List;
+
+import org.apache.maven.archiva.repository.audit.AuditEvent;
+
+public interface AuditManager
+{
+ List<AuditEvent> getMostRecentAuditEvents();
+
+ void addAuditEvent( AuditEvent event );
+
+ void deleteAuditEvents( String repositoryId );
+
+ List<AuditEvent> getAuditEventsInRange( String repositoryId, Date startTime, Date endTime );
+} \ No newline at end of file
diff --git a/archiva-modules/plugins/audit/src/main/java/org/apache/archiva/audit/DefaultAuditManager.java b/archiva-modules/plugins/audit/src/main/java/org/apache/archiva/audit/DefaultAuditManager.java
new file mode 100644
index 000000000..e8161f982
--- /dev/null
+++ b/archiva-modules/plugins/audit/src/main/java/org/apache/archiva/audit/DefaultAuditManager.java
@@ -0,0 +1,154 @@
+package org.apache.archiva.audit;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.List;
+
+import org.apache.archiva.metadata.repository.MetadataRepository;
+import org.apache.maven.archiva.repository.audit.AuditEvent;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @plexus.component role="org.apache.archiva.audit.AuditManager"
+ */
+public class DefaultAuditManager
+ implements AuditManager
+{
+ /**
+ * @plexus.requirement
+ */
+ private MetadataRepository metadataRepository;
+
+ private static final int NUM_RECENT_REVENTS = 10;
+
+ private static final Logger log = LoggerFactory.getLogger( DefaultAuditManager.class );
+
+ public List<AuditEvent> getMostRecentAuditEvents()
+ {
+ // TODO: consider a more efficient implementation that directly gets the last ten from the content repository
+ List<AuditRecord> records = new ArrayList<AuditRecord>();
+ for ( String repositoryId : metadataRepository.getRepositories() )
+ {
+ List<String> timestamps = metadataRepository.getMetadataFacets( repositoryId, AuditEvent.FACET_ID );
+ for ( String timestamp : timestamps )
+ {
+ records.add( new AuditRecord( repositoryId, timestamp ) );
+ }
+ }
+ Collections.sort( records );
+ records = records.subList( 0, records.size() < NUM_RECENT_REVENTS ? records.size() : NUM_RECENT_REVENTS );
+
+ List<AuditEvent> events = new ArrayList<AuditEvent>( records.size() );
+ for ( AuditRecord record : records )
+ {
+ AuditEvent auditEvent =
+ (AuditEvent) metadataRepository.getMetadataFacet( record.repositoryId, AuditEvent.FACET_ID,
+ record.name );
+ events.add( auditEvent );
+ }
+ return events;
+ }
+
+ public void addAuditEvent( AuditEvent event )
+ {
+ // ignore those with no repository - they will still be logged to the textual audit log
+ if ( event.getRepositoryId() != null )
+ {
+ metadataRepository.addMetadataFacet( event.getRepositoryId(), event );
+ }
+ }
+
+ public void deleteAuditEvents( String repositoryId )
+ {
+ metadataRepository.removeMetadataFacets( repositoryId, AuditEvent.FACET_ID );
+ }
+
+ public List<AuditEvent> getAuditEventsInRange( String repoId, Date startTime, Date endTime )
+ {
+ Collection<String> repositoryIds =
+ repoId != null ? Collections.singletonList( repoId ) : metadataRepository.getRepositories();
+
+ List<AuditEvent> results = new ArrayList<AuditEvent>();
+ for ( String repositoryId : repositoryIds )
+ {
+ List<String> list = metadataRepository.getMetadataFacets( repositoryId, AuditEvent.FACET_ID );
+ for ( String name : list )
+ {
+ try
+ {
+ Date date = new SimpleDateFormat( AuditEvent.TIMESTAMP_FORMAT ).parse( name );
+ if ( ( startTime == null || !date.before( startTime ) ) &&
+ ( endTime == null || !date.after( endTime ) ) )
+ {
+ AuditEvent event =
+ (AuditEvent) metadataRepository.getMetadataFacet( repositoryId, AuditEvent.FACET_ID, name );
+ results.add( event );
+ }
+ }
+ catch ( ParseException e )
+ {
+ log.error( "Invalid audit event found in the metadata repository: " + e.getMessage() );
+ // continue and ignore this one
+ }
+ }
+ }
+ Collections.sort( results, new Comparator<AuditEvent>()
+ {
+ public int compare( AuditEvent o1, AuditEvent o2 )
+ {
+ return o2.getTimestamp().compareTo( o1.getTimestamp() );
+ }
+ } );
+ return results;
+ }
+
+ public void setMetadataRepository( MetadataRepository metadataRepository )
+ {
+ this.metadataRepository = metadataRepository;
+ }
+
+ private static final class AuditRecord
+ implements Comparable<AuditRecord>
+ {
+ private String repositoryId;
+
+ private String name;
+
+ public AuditRecord( String repositoryId, String name )
+ {
+ this.repositoryId = repositoryId;
+ this.name = name;
+ }
+
+ public int compareTo( AuditRecord other )
+ {
+ // reverse ordering
+ return other.name.compareTo( name );
+ }
+ }
+}
diff --git a/archiva-modules/plugins/audit/src/main/java/org/apache/archiva/audit/MetadataAuditListener.java b/archiva-modules/plugins/audit/src/main/java/org/apache/archiva/audit/MetadataAuditListener.java
new file mode 100644
index 000000000..612eb51af
--- /dev/null
+++ b/archiva-modules/plugins/audit/src/main/java/org/apache/archiva/audit/MetadataAuditListener.java
@@ -0,0 +1,44 @@
+package org.apache.archiva.audit;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.archiva.repository.audit.AuditEvent;
+import org.apache.maven.archiva.repository.audit.AuditListener;
+
+/**
+ * @plexus.component role="org.apache.maven.archiva.repository.audit.AuditListener" role-hint="metadata"
+ */
+public class MetadataAuditListener
+ implements AuditListener
+{
+ /**
+ * @plexus.requirement
+ */
+ private AuditManager auditManager;
+
+ public void auditEvent( AuditEvent event )
+ {
+ // for now we only log upload events, some of the others are quite noisy
+ if ( event.getAction().equals( AuditEvent.CREATE_FILE ) || event.getAction().equals( AuditEvent.UPLOAD_FILE ) )
+ {
+ auditManager.addAuditEvent( event );
+ }
+ }
+}
diff --git a/archiva-modules/plugins/audit/src/test/java/org/apache/archiva/audit/AuditManagerTest.java b/archiva-modules/plugins/audit/src/test/java/org/apache/archiva/audit/AuditManagerTest.java
new file mode 100644
index 000000000..a384a83dc
--- /dev/null
+++ b/archiva-modules/plugins/audit/src/test/java/org/apache/archiva/audit/AuditManagerTest.java
@@ -0,0 +1,507 @@
+package org.apache.archiva.audit;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.text.DecimalFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Date;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import junit.framework.TestCase;
+import org.apache.archiva.metadata.repository.MetadataRepository;
+import org.apache.maven.archiva.configuration.ManagedRepositoryConfiguration;
+import org.apache.maven.archiva.repository.RepositoryContentFactory;
+import org.apache.maven.archiva.repository.audit.AuditEvent;
+import org.apache.maven.archiva.repository.content.ManagedDefaultRepositoryContent;
+import org.easymock.MockControl;
+import org.easymock.classextension.MockClassControl;
+
+public class AuditManagerTest
+ extends TestCase
+{
+ private DefaultAuditManager auditManager;
+
+ private MockControl metadataRepositoryControl;
+
+ private MetadataRepository metadataRepository;
+
+ private static final String AUDIT_EVENT_BASE = "2010/01/18/123456.";
+
+ private static final String TEST_REPO_ID = "test-repo";
+
+ private static final String TEST_REPO_ID_2 = "repo2";
+
+ private static final String TEST_USER = "test_user";
+
+ private static final String TEST_RESOURCE_BASE = "test/resource";
+
+ private static final String TEST_IP_ADDRESS = "127.0.0.1";
+
+ private static final SimpleDateFormat TIMESTAMP_FORMAT = new SimpleDateFormat( AuditEvent.TIMESTAMP_FORMAT );
+
+ private static final DecimalFormat MILLIS_FORMAT = new DecimalFormat( "000" );
+
+ @Override
+ protected void setUp()
+ throws Exception
+ {
+ super.setUp();
+
+ auditManager = new DefaultAuditManager();
+
+ metadataRepositoryControl = MockControl.createControl( MetadataRepository.class );
+ metadataRepository = (MetadataRepository) metadataRepositoryControl.getMock();
+ auditManager.setMetadataRepository( metadataRepository );
+
+ ManagedRepositoryConfiguration repository = new ManagedRepositoryConfiguration();
+ repository.setId( TEST_REPO_ID );
+ repository.setLocation( "" );
+ ManagedDefaultRepositoryContent content = new ManagedDefaultRepositoryContent();
+ content.setRepository( repository );
+ MockControl control = MockClassControl.createControl( RepositoryContentFactory.class );
+ RepositoryContentFactory contentFactory = (RepositoryContentFactory) control.getMock();
+ contentFactory.getManagedRepositoryContent( TEST_REPO_ID );
+ control.setDefaultReturnValue( content );
+ control.replay();
+ }
+
+ public void testGetMostRecentEvents()
+ throws ParseException
+ {
+ metadataRepositoryControl.expectAndReturn( metadataRepository.getRepositories(),
+ Collections.singletonList( TEST_REPO_ID ) );
+
+ int numEvents = 11;
+ List<String> eventNames = new ArrayList<String>( numEvents );
+ for ( int i = 0; i < numEvents; i++ )
+ {
+ eventNames.add( AUDIT_EVENT_BASE + MILLIS_FORMAT.format( i ) );
+ }
+
+ metadataRepositoryControl.expectAndReturn(
+ metadataRepository.getMetadataFacets( TEST_REPO_ID, AuditEvent.FACET_ID ), eventNames );
+
+ for ( String name : eventNames.subList( 1, eventNames.size() ) )
+ {
+ AuditEvent event = createTestEvent( name );
+
+ metadataRepositoryControl.expectAndReturn(
+ metadataRepository.getMetadataFacet( TEST_REPO_ID, AuditEvent.FACET_ID, name ), event );
+ }
+ metadataRepositoryControl.replay();
+
+ List<AuditEvent> events = auditManager.getMostRecentAuditEvents();
+ assertNotNull( events );
+ assertEquals( numEvents - 1, events.size() );
+ int expectedTimestampCounter = numEvents - 1;
+ for ( AuditEvent event : events )
+ {
+ String num = MILLIS_FORMAT.format( expectedTimestampCounter );
+ assertEvent( event, AUDIT_EVENT_BASE + num, TEST_RESOURCE_BASE + "/" + num );
+ expectedTimestampCounter--;
+ }
+
+ metadataRepositoryControl.verify();
+ }
+
+ private static AuditEvent createTestEvent( String name )
+ throws ParseException
+ {
+ return createTestEvent( TEST_REPO_ID, name );
+ }
+
+ private static AuditEvent createTestEvent( String repositoryId, String name )
+ throws ParseException
+ {
+ AuditEvent event = new AuditEvent();
+ event.setTimestamp( TIMESTAMP_FORMAT.parse( name ) );
+ event.setAction( AuditEvent.UPLOAD_FILE );
+ event.setRemoteIP( TEST_IP_ADDRESS );
+ event.setRepositoryId( repositoryId );
+ event.setUserId( TEST_USER );
+ event.setResource( TEST_RESOURCE_BASE + "/" + name.substring( AUDIT_EVENT_BASE.length() ) );
+ return event;
+ }
+
+ public void testGetMostRecentEventsLessThan10()
+ throws ParseException
+ {
+ metadataRepositoryControl.expectAndReturn( metadataRepository.getRepositories(),
+ Collections.singletonList( TEST_REPO_ID ) );
+ int numEvents = 5;
+ List<String> eventNames = new ArrayList<String>( numEvents );
+ for ( int i = 0; i < numEvents; i++ )
+ {
+ eventNames.add( AUDIT_EVENT_BASE + MILLIS_FORMAT.format( i ) );
+ }
+
+ metadataRepositoryControl.expectAndReturn(
+ metadataRepository.getMetadataFacets( TEST_REPO_ID, AuditEvent.FACET_ID ), eventNames );
+
+ for ( String name : eventNames )
+ {
+ AuditEvent event = createTestEvent( name );
+
+ metadataRepositoryControl.expectAndReturn(
+ metadataRepository.getMetadataFacet( TEST_REPO_ID, AuditEvent.FACET_ID, name ), event );
+ }
+ metadataRepositoryControl.replay();
+
+ List<AuditEvent> events = auditManager.getMostRecentAuditEvents();
+ assertNotNull( events );
+ assertEquals( numEvents, events.size() );
+ int expectedTimestampCounter = numEvents - 1;
+ for ( AuditEvent event : events )
+ {
+ String num = MILLIS_FORMAT.format( expectedTimestampCounter );
+ assertEvent( event, AUDIT_EVENT_BASE + num, TEST_RESOURCE_BASE + "/" + num );
+ expectedTimestampCounter--;
+ }
+
+ metadataRepositoryControl.verify();
+ }
+
+ public void testGetMostRecentEventsInterleavedRepositories()
+ throws ParseException
+ {
+ metadataRepositoryControl.expectAndReturn( metadataRepository.getRepositories(),
+ Arrays.asList( TEST_REPO_ID, TEST_REPO_ID_2 ) );
+ int numEvents = 11;
+ Map<String, List<String>> eventNames = new LinkedHashMap<String, List<String>>();
+ List<AuditEvent> events = new ArrayList<AuditEvent>();
+ eventNames.put( TEST_REPO_ID, new ArrayList<String>() );
+ eventNames.put( TEST_REPO_ID_2, new ArrayList<String>() );
+ for ( int i = 0; i < numEvents; i++ )
+ {
+ String name = AUDIT_EVENT_BASE + MILLIS_FORMAT.format( i );
+ String repositoryId = i % 2 == 0 ? TEST_REPO_ID : TEST_REPO_ID_2;
+ eventNames.get( repositoryId ).add( name );
+ events.add( createTestEvent( repositoryId, name ) );
+ }
+
+ metadataRepositoryControl.expectAndReturn(
+ metadataRepository.getMetadataFacets( TEST_REPO_ID, AuditEvent.FACET_ID ), eventNames.get( TEST_REPO_ID ) );
+ metadataRepositoryControl.expectAndReturn(
+ metadataRepository.getMetadataFacets( TEST_REPO_ID_2, AuditEvent.FACET_ID ),
+ eventNames.get( TEST_REPO_ID_2 ) );
+
+ for ( AuditEvent event : events.subList( 1, events.size() ) )
+ {
+ metadataRepositoryControl.expectAndReturn(
+ metadataRepository.getMetadataFacet( event.getRepositoryId(), AuditEvent.FACET_ID, event.getName() ),
+ event );
+ }
+ metadataRepositoryControl.replay();
+
+ events = auditManager.getMostRecentAuditEvents();
+ assertNotNull( events );
+ assertEquals( numEvents - 1, events.size() );
+ int expectedTimestampCounter = numEvents - 1;
+ for ( AuditEvent event : events )
+ {
+ String num = MILLIS_FORMAT.format( expectedTimestampCounter );
+ assertEvent( event, AUDIT_EVENT_BASE + num, TEST_RESOURCE_BASE + "/" + num,
+ expectedTimestampCounter % 2 == 0 ? TEST_REPO_ID : TEST_REPO_ID_2 );
+ expectedTimestampCounter--;
+ }
+
+ metadataRepositoryControl.verify();
+ }
+
+ private static void assertEvent( AuditEvent event, String name, String resource )
+ {
+ assertEvent( event, name, resource, TEST_REPO_ID );
+ }
+
+ private static void assertEvent( AuditEvent event, String name, String resource, String repositoryId )
+ {
+ assertEquals( name, TIMESTAMP_FORMAT.format( event.getTimestamp() ) );
+ assertEquals( AuditEvent.UPLOAD_FILE, event.getAction() );
+ assertEquals( TEST_IP_ADDRESS, event.getRemoteIP() );
+ assertEquals( repositoryId, event.getRepositoryId() );
+ assertEquals( TEST_USER, event.getUserId() );
+ assertEquals( resource, event.getResource() );
+ }
+
+ public void testGetMostRecentEventsWhenEmpty()
+ {
+ metadataRepositoryControl.expectAndReturn( metadataRepository.getRepositories(),
+ Collections.singletonList( TEST_REPO_ID ) );
+
+ metadataRepositoryControl.expectAndReturn(
+ metadataRepository.getMetadataFacets( TEST_REPO_ID, AuditEvent.FACET_ID ), Collections.emptyList() );
+ metadataRepositoryControl.replay();
+
+ assertTrue( auditManager.getMostRecentAuditEvents().isEmpty() );
+
+ metadataRepositoryControl.verify();
+ }
+
+ public void testAddAuditEvent()
+ throws ParseException
+ {
+ String name = TIMESTAMP_FORMAT.format( new Date() );
+ AuditEvent event = createTestEvent( name );
+
+ metadataRepository.addMetadataFacet( TEST_REPO_ID, event );
+
+ metadataRepositoryControl.replay();
+
+ auditManager.addAuditEvent( event );
+
+ metadataRepositoryControl.verify();
+ }
+
+ public void testAddAuditEventNoRepositoryId()
+ throws ParseException
+ {
+ String name = TIMESTAMP_FORMAT.format( new Date() );
+ AuditEvent event = createTestEvent( null, name );
+
+ // should just be ignored
+
+ metadataRepositoryControl.replay();
+
+ auditManager.addAuditEvent( event );
+
+ metadataRepositoryControl.verify();
+ }
+
+ public void testDeleteStats()
+ {
+ metadataRepository.removeMetadataFacets( TEST_REPO_ID, AuditEvent.FACET_ID );
+
+ metadataRepositoryControl.replay();
+
+ auditManager.deleteAuditEvents( TEST_REPO_ID );
+
+ metadataRepositoryControl.verify();
+ }
+
+ public void testGetEventsRangeInside()
+ throws ParseException
+ {
+ Date current = new Date();
+
+ String name1 = TIMESTAMP_FORMAT.format( new Date( current.getTime() - 12345 ) );
+ Date expectedTimestamp = new Date( current.getTime() - 3000 );
+ String name2 = TIMESTAMP_FORMAT.format( expectedTimestamp );
+ AuditEvent expectedEvent = createTestEvent( name2 );
+ String name3 = TIMESTAMP_FORMAT.format( new Date( current.getTime() - 1000 ) );
+
+ metadataRepositoryControl.expectAndReturn(
+ metadataRepository.getMetadataFacets( TEST_REPO_ID, AuditEvent.FACET_ID ),
+ Arrays.asList( name1, name2, name3 ) );
+
+ // only match the middle one
+ metadataRepositoryControl.expectAndReturn(
+ metadataRepository.getMetadataFacet( TEST_REPO_ID, AuditEvent.FACET_ID, name2 ), expectedEvent );
+
+ metadataRepositoryControl.replay();
+
+ List<AuditEvent> events =
+ auditManager.getAuditEventsInRange( TEST_REPO_ID, new Date( current.getTime() - 4000 ),
+ new Date( current.getTime() - 2000 ) );
+
+ assertEquals( 1, events.size() );
+ assertEvent( events.get( 0 ), name2, expectedEvent.getResource() );
+
+ metadataRepositoryControl.verify();
+ }
+
+ public void testGetEventsRangeUpperOutside()
+ throws ParseException
+ {
+ Date current = new Date();
+
+ String name1 = TIMESTAMP_FORMAT.format( new Date( current.getTime() - 12345 ) );
+ Date expectedTimestamp = new Date( current.getTime() - 3000 );
+ String name2 = TIMESTAMP_FORMAT.format( expectedTimestamp );
+ AuditEvent expectedEvent2 = createTestEvent( name2 );
+ String name3 = TIMESTAMP_FORMAT.format( new Date( current.getTime() - 1000 ) );
+ AuditEvent expectedEvent3 = createTestEvent( name3 );
+
+ metadataRepositoryControl.expectAndReturn(
+ metadataRepository.getMetadataFacets( TEST_REPO_ID, AuditEvent.FACET_ID ),
+ Arrays.asList( name1, name2, name3 ) );
+
+ metadataRepositoryControl.expectAndReturn(
+ metadataRepository.getMetadataFacet( TEST_REPO_ID, AuditEvent.FACET_ID, name2 ), expectedEvent2 );
+ metadataRepositoryControl.expectAndReturn(
+ metadataRepository.getMetadataFacet( TEST_REPO_ID, AuditEvent.FACET_ID, name3 ), expectedEvent3 );
+
+ metadataRepositoryControl.replay();
+
+ List<AuditEvent> events =
+ auditManager.getAuditEventsInRange( TEST_REPO_ID, new Date( current.getTime() - 4000 ), current );
+
+ assertEquals( 2, events.size() );
+ assertEvent( events.get( 0 ), name3, expectedEvent3.getResource() );
+ assertEvent( events.get( 1 ), name2, expectedEvent2.getResource() );
+
+ metadataRepositoryControl.verify();
+ }
+
+ public void testGetEventsRangeLowerOutside()
+ throws ParseException
+ {
+ Date current = new Date();
+
+ String name1 = TIMESTAMP_FORMAT.format( new Date( current.getTime() - 12345 ) );
+ AuditEvent expectedEvent1 = createTestEvent( name1 );
+ Date expectedTimestamp = new Date( current.getTime() - 3000 );
+ String name2 = TIMESTAMP_FORMAT.format( expectedTimestamp );
+ AuditEvent expectedEvent2 = createTestEvent( name2 );
+ String name3 = TIMESTAMP_FORMAT.format( new Date( current.getTime() - 1000 ) );
+
+ metadataRepositoryControl.expectAndReturn(
+ metadataRepository.getMetadataFacets( TEST_REPO_ID, AuditEvent.FACET_ID ),
+ Arrays.asList( name1, name2, name3 ) );
+
+ metadataRepositoryControl.expectAndReturn(
+ metadataRepository.getMetadataFacet( TEST_REPO_ID, AuditEvent.FACET_ID, name1 ), expectedEvent1 );
+ metadataRepositoryControl.expectAndReturn(
+ metadataRepository.getMetadataFacet( TEST_REPO_ID, AuditEvent.FACET_ID, name2 ), expectedEvent2 );
+
+ metadataRepositoryControl.replay();
+
+ List<AuditEvent> events =
+ auditManager.getAuditEventsInRange( TEST_REPO_ID, new Date( current.getTime() - 20000 ),
+ new Date( current.getTime() - 2000 ) );
+
+ assertEquals( 2, events.size() );
+ assertEvent( events.get( 0 ), name2, expectedEvent2.getResource() );
+ assertEvent( events.get( 1 ), name1, expectedEvent1.getResource() );
+
+ metadataRepositoryControl.verify();
+ }
+
+ public void testGetEventsRangeLowerAndUpperOutside()
+ throws ParseException
+ {
+ Date current = new Date();
+
+ String name1 = TIMESTAMP_FORMAT.format( new Date( current.getTime() - 12345 ) );
+ AuditEvent expectedEvent1 = createTestEvent( name1 );
+ Date expectedTimestamp = new Date( current.getTime() - 3000 );
+ String name2 = TIMESTAMP_FORMAT.format( expectedTimestamp );
+ AuditEvent expectedEvent2 = createTestEvent( name2 );
+ String name3 = TIMESTAMP_FORMAT.format( new Date( current.getTime() - 1000 ) );
+ AuditEvent expectedEvent3 = createTestEvent( name3 );
+
+ metadataRepositoryControl.expectAndReturn(
+ metadataRepository.getMetadataFacets( TEST_REPO_ID, AuditEvent.FACET_ID ),
+ Arrays.asList( name1, name2, name3 ) );
+
+ metadataRepositoryControl.expectAndReturn(
+ metadataRepository.getMetadataFacet( TEST_REPO_ID, AuditEvent.FACET_ID, name1 ), expectedEvent1 );
+ metadataRepositoryControl.expectAndReturn(
+ metadataRepository.getMetadataFacet( TEST_REPO_ID, AuditEvent.FACET_ID, name2 ), expectedEvent2 );
+ metadataRepositoryControl.expectAndReturn(
+ metadataRepository.getMetadataFacet( TEST_REPO_ID, AuditEvent.FACET_ID, name3 ), expectedEvent3 );
+
+ metadataRepositoryControl.replay();
+
+ List<AuditEvent> events =
+ auditManager.getAuditEventsInRange( TEST_REPO_ID, new Date( current.getTime() - 20000 ), current );
+
+ assertEquals( 3, events.size() );
+ assertEvent( events.get( 0 ), name3, expectedEvent3.getResource() );
+ assertEvent( events.get( 1 ), name2, expectedEvent2.getResource() );
+ assertEvent( events.get( 2 ), name1, expectedEvent1.getResource() );
+
+ metadataRepositoryControl.verify();
+ }
+
+ public void testGetEventsRangeMultipleRepositories()
+ throws ParseException
+ {
+ metadataRepositoryControl.expectAndReturn( metadataRepository.getRepositories(),
+ Arrays.asList( TEST_REPO_ID, TEST_REPO_ID_2 ) );
+
+ Date current = new Date();
+
+ String name1 = TIMESTAMP_FORMAT.format( new Date( current.getTime() - 12345 ) );
+ AuditEvent expectedEvent1 = createTestEvent( TEST_REPO_ID, name1 );
+ Date expectedTimestamp = new Date( current.getTime() - 3000 );
+ String name2 = TIMESTAMP_FORMAT.format( expectedTimestamp );
+ AuditEvent expectedEvent2 = createTestEvent( TEST_REPO_ID_2, name2 );
+ String name3 = TIMESTAMP_FORMAT.format( new Date( current.getTime() - 1000 ) );
+ AuditEvent expectedEvent3 = createTestEvent( TEST_REPO_ID, name3 );
+
+ metadataRepositoryControl.expectAndReturn(
+ metadataRepository.getMetadataFacets( TEST_REPO_ID, AuditEvent.FACET_ID ), Arrays.asList( name1, name3 ) );
+ metadataRepositoryControl.expectAndReturn(
+ metadataRepository.getMetadataFacets( TEST_REPO_ID_2, AuditEvent.FACET_ID ), Arrays.asList( name2 ) );
+
+ metadataRepositoryControl.expectAndReturn(
+ metadataRepository.getMetadataFacet( TEST_REPO_ID, AuditEvent.FACET_ID, name1 ), expectedEvent1 );
+ metadataRepositoryControl.expectAndReturn(
+ metadataRepository.getMetadataFacet( TEST_REPO_ID_2, AuditEvent.FACET_ID, name2 ), expectedEvent2 );
+ metadataRepositoryControl.expectAndReturn(
+ metadataRepository.getMetadataFacet( TEST_REPO_ID, AuditEvent.FACET_ID, name3 ), expectedEvent3 );
+
+ metadataRepositoryControl.replay();
+
+ List<AuditEvent> events =
+ auditManager.getAuditEventsInRange( null, new Date( current.getTime() - 20000 ), current );
+
+ assertEquals( 3, events.size() );
+ assertEvent( events.get( 0 ), name3, expectedEvent3.getResource() );
+ assertEvent( events.get( 1 ), name2, expectedEvent2.getResource(), TEST_REPO_ID_2 );
+ assertEvent( events.get( 2 ), name1, expectedEvent1.getResource() );
+
+ metadataRepositoryControl.verify();
+ }
+
+ public void testGetEventsRangeNotInside()
+ throws ParseException
+ {
+ Date current = new Date();
+
+ String name1 = TIMESTAMP_FORMAT.format( new Date( current.getTime() - 12345 ) );
+ AuditEvent expectedEvent1 = createTestEvent( name1 );
+ Date expectedTimestamp = new Date( current.getTime() - 3000 );
+ String name2 = TIMESTAMP_FORMAT.format( expectedTimestamp );
+ AuditEvent expectedEvent2 = createTestEvent( name2 );
+ String name3 = TIMESTAMP_FORMAT.format( new Date( current.getTime() - 1000 ) );
+ AuditEvent expectedEvent3 = createTestEvent( name3 );
+
+ metadataRepositoryControl.expectAndReturn(
+ metadataRepository.getMetadataFacets( TEST_REPO_ID, AuditEvent.FACET_ID ),
+ Arrays.asList( name1, name2, name3 ) );
+
+ metadataRepositoryControl.replay();
+
+ List<AuditEvent> events =
+ auditManager.getAuditEventsInRange( TEST_REPO_ID, new Date( current.getTime() - 20000 ),
+ new Date( current.getTime() - 16000 ) );
+
+ assertEquals( 0, events.size() );
+
+ metadataRepositoryControl.verify();
+ }
+} \ No newline at end of file