This project has retired. For details please refer to its Attic page.
Source code
001package org.apache.archiva.audit;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 *   http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import org.apache.archiva.metadata.model.facets.AuditEvent;
023import org.apache.archiva.metadata.repository.MetadataRepository;
024import org.apache.archiva.metadata.repository.MetadataRepositoryException;
025import org.slf4j.Logger;
026import org.slf4j.LoggerFactory;
027import org.springframework.stereotype.Service;
028
029import java.text.ParseException;
030import java.text.SimpleDateFormat;
031import java.util.ArrayList;
032import java.util.Collection;
033import java.util.Collections;
034import java.util.Comparator;
035import java.util.Date;
036import java.util.List;
037import java.util.TimeZone;
038
039/**
040 *
041 */
042@Service("auditManager#default")
043public class DefaultAuditManager
044    implements AuditManager
045{
046    private static final int NUM_RECENT_EVENTS = 10;
047
048    private static final Logger log = LoggerFactory.getLogger( DefaultAuditManager.class );
049
050    private static final TimeZone UTC_TIME_ZONE = TimeZone.getTimeZone( "UTC" );
051
052    @Override
053    public List<AuditEvent> getMostRecentAuditEvents( MetadataRepository metadataRepository,
054                                                      List<String> repositoryIds )
055        throws MetadataRepositoryException
056    {
057        // TODO: consider a more efficient implementation that directly gets the last ten from the content repository
058        List<AuditRecord> records = new ArrayList<>();
059        for ( String repositoryId : repositoryIds )
060        {
061            List<String> names = metadataRepository.getMetadataFacets( repositoryId, AuditEvent.FACET_ID );
062            for ( String name : names )
063            {
064                records.add( new AuditRecord( repositoryId, name ) );
065            }
066        }
067        Collections.sort( records );
068        records = records.subList( 0, records.size() < NUM_RECENT_EVENTS ? records.size() : NUM_RECENT_EVENTS );
069
070        List<AuditEvent> events = new ArrayList<>( records.size() );
071        for ( AuditRecord record : records )
072        {
073            AuditEvent auditEvent = (AuditEvent) metadataRepository.getMetadataFacet( record.repositoryId,
074                                                                                      AuditEvent.FACET_ID,
075                                                                                      record.name );
076            events.add( auditEvent );
077        }
078        return events;
079    }
080
081    @Override
082    public void addAuditEvent( MetadataRepository repository, AuditEvent event )
083        throws MetadataRepositoryException
084    {
085        // ignore those with no repository - they will still be logged to the textual audit log
086        if ( event.getRepositoryId() != null )
087        {
088            repository.addMetadataFacet( event.getRepositoryId(), event );
089        }
090    }
091
092    @Override
093    public void deleteAuditEvents( MetadataRepository metadataRepository, String repositoryId )
094        throws MetadataRepositoryException
095    {
096        metadataRepository.removeMetadataFacets( repositoryId, AuditEvent.FACET_ID );
097    }
098
099    @Override
100    public List<AuditEvent> getAuditEventsInRange( MetadataRepository metadataRepository,
101                                                   Collection<String> repositoryIds, Date startTime, Date endTime )
102        throws MetadataRepositoryException
103    {
104        return getAuditEventsInRange( metadataRepository, repositoryIds, null, startTime, endTime );
105    }
106
107    @Override
108    public List<AuditEvent> getAuditEventsInRange( MetadataRepository metadataRepository,
109                                                   Collection<String> repositoryIds, String resource, Date startTime,
110                                                   Date endTime )
111        throws MetadataRepositoryException
112    {
113        List<AuditEvent> results = new ArrayList<>();
114        for ( String repositoryId : repositoryIds )
115        {
116            List<String> list = metadataRepository.getMetadataFacets( repositoryId, AuditEvent.FACET_ID );
117            for ( String name : list )
118            {
119                try
120                {
121                    Date date = createNameFormat().parse( name );
122                    if ( ( startTime == null || !date.before( startTime ) ) && ( endTime == null || !date.after(
123                        endTime ) ) )
124                    {
125                        AuditEvent event = (AuditEvent) metadataRepository.getMetadataFacet( repositoryId,
126                                                                                             AuditEvent.FACET_ID,
127                                                                                             name );
128
129                        if ( resource == null || event.getResource().startsWith( resource ) )
130                        {
131                            results.add( event );
132                        }
133                    }
134                }
135                catch ( ParseException e )
136                {
137                    log.error( "Invalid audit event found in the metadata repository: " + e.getMessage() );
138                    // continue and ignore this one
139                }
140            }
141        }
142        Collections.sort( results, new Comparator<AuditEvent>()
143        {
144            @Override
145            public int compare( AuditEvent o1, AuditEvent o2 )
146            {
147                return o2.getTimestamp().compareTo( o1.getTimestamp() );
148            }
149        } );
150        return results;
151    }
152
153    private static SimpleDateFormat createNameFormat()
154    {
155        SimpleDateFormat fmt = new SimpleDateFormat( AuditEvent.TIMESTAMP_FORMAT );
156        fmt.setTimeZone( UTC_TIME_ZONE );
157        return fmt;
158    }
159
160    private static final class AuditRecord
161        implements Comparable<AuditRecord>
162    {
163        private String repositoryId;
164
165        private String name;
166
167        public AuditRecord( String repositoryId, String name )
168        {
169            this.repositoryId = repositoryId;
170            this.name = name;
171        }
172
173        @Override
174        public int compareTo( AuditRecord other )
175        {
176            // reverse ordering
177            return other.name.compareTo( name );
178        }
179    }
180}