diff options
author | Brett Porter <brett@apache.org> | 2014-07-31 15:10:37 +1000 |
---|---|---|
committer | Brett Porter <brett@apache.org> | 2014-07-31 15:10:37 +1000 |
commit | fafb8d284f3b80847c0373d1f7485565ef306b19 (patch) | |
tree | 5f61678291912cc7fe875fd9a8a5de9f7f3eae66 /archiva-modules/metadata | |
parent | be20d16cfdc0525e9b5cc58a5953b78c57fc17e1 (diff) | |
download | archiva-fafb8d284f3b80847c0373d1f7485565ef306b19.tar.gz archiva-fafb8d284f3b80847c0373d1f7485565ef306b19.zip |
split out audit facet and listener to match others
by placing these in the metadata model / API they can be used more broadly,
while the storage-dependant implementation can be in a plugin. This means the
plugins can be removed from the admin implementation, which can then be used
(as required) in the CLI
Diffstat (limited to 'archiva-modules/metadata')
2 files changed, 398 insertions, 0 deletions
diff --git a/archiva-modules/metadata/metadata-model/src/main/java/org/apache/archiva/metadata/model/facets/AuditEvent.java b/archiva-modules/metadata/metadata-model/src/main/java/org/apache/archiva/metadata/model/facets/AuditEvent.java new file mode 100644 index 000000000..ba47519e7 --- /dev/null +++ b/archiva-modules/metadata/metadata-model/src/main/java/org/apache/archiva/metadata/model/facets/AuditEvent.java @@ -0,0 +1,361 @@ +package org.apache.archiva.metadata.model.facets; + +/* + * 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 java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.TimeZone; + +/** + * AuditEvent + * + * + */ +public class AuditEvent + implements MetadataFacet +{ + public static final String TIMESTAMP_FORMAT = "yyyy/MM/dd/HHmmss.SSS"; + + public static final String CREATE_DIR = "Created Directory"; + + public static final String CREATE_FILE = "Created File"; + + public static final String REMOVE_DIR = "Removed Directory"; + + public static final String REMOVE_FILE = "Removed File"; + + public static final String MODIFY_FILE = "Modified File"; + + public static final String MOVE_FILE = "Moved File"; + + public static final String MOVE_DIRECTORY = "Moved Directory"; + + public static final String COPY_DIRECTORY = "Copied Directory"; + + public static final String COPY_FILE = "Copied File"; + + public static final String UPLOAD_FILE = "Uploaded File"; + + public static final String ADD_LEGACY_PATH = "Added Legacy Artifact Path"; + + public static final String REMOVE_LEGACY_PATH = "Removed Legacy Artifact Path"; + + public static final String PURGE_ARTIFACT = "Purged Artifact"; + + public static final String PURGE_FILE = "Purged Support File"; + + public static final String REMOVE_SCANNED = "Removed in Filesystem"; + + public static final String MERGING_REPOSITORIES = "Merged Artifact"; + + // configuration events + + public static final String ADD_MANAGED_REPO = "Added Managed Repository"; + + public static final String MODIFY_MANAGED_REPO = "Updated Managed Repository"; + + public static final String DELETE_MANAGED_REPO = "Deleted Managed Repository"; + + public static final String ADD_REMOTE_REPO = "Added Remote Repository"; + + public static final String MODIFY_REMOTE_REPO = "Updated Remote Repository"; + + public static final String DELETE_REMOTE_REPO = "Deleted Remote Repository"; + + public static final String ADD_REPO_GROUP = "Added Repository Group"; + + public static final String DELETE_REPO_GROUP = "Deleted Repository Group"; + + public static final String MODIFY_REPO_GROUP = "Modify Repository Group"; + + public static final String ADD_REPO_TO_GROUP = "Added Repository to Group"; + + public static final String DELETE_REPO_FROM_GROUP = "Deleted Repository from Group"; + + public static final String ENABLE_REPO_CONSUMER = "Enabled Content Consumer"; + + public static final String DISABLE_REPO_CONSUMER = "Disabled Content Consumer"; + + public static final String ADD_PATTERN = "Added File Type Pattern"; + + public static final String REMOVE_PATTERN = "Removed File Type Pattern"; + + public static final String MERGE_REPO_REMOTE = "Merged Staging Repository Triggered Remotely"; + + public static final String ADD_PROXY_CONNECTOR = "Added Proxy Connector"; + + public static final String DELETE_PROXY_CONNECTOR = "Deleted Proxy Connector"; + + public static final String MODIFY_PROXY_CONNECTOR = "Updated Proxy Connector"; + + public static final String ADD_NETWORK_PROXY = "Added Network Proxy"; + + public static final String DELETE_NETWORK_PROXY = "Deleted Network Proxy"; + + public static final String MODIFY_NETWORK_PROXY = "Updated Network Proxy"; + + private String repositoryId; + + private String userId; + + private String remoteIP; + + // TODO: change to artifact reference? does it ever refer to just a path? + + private String resource; + + private String action; + + private Date timestamp; + + public static final String FACET_ID = "org.apache.archiva.audit"; + + private static final TimeZone UTC_TIME_ZONE = TimeZone.getTimeZone( "UTC" ); + + private static final int TS_LENGTH = TIMESTAMP_FORMAT.length(); + + public AuditEvent() + { + /* do nothing */ + } + + public AuditEvent( String name, String repositoryId ) + { + String ts = name.substring( 0, TS_LENGTH ); + try + { + timestamp = createNameFormat().parse( ts ); + } + catch ( ParseException e ) + { + throw new IllegalArgumentException( "Improperly formatted timestamp for audit log event: " + ts, e); + } + + if ( name.length() > TS_LENGTH ) + { + if ( name.charAt( TS_LENGTH ) != '/' ) + { + throw new IllegalArgumentException( + "Improperly formatted name for audit log event, no / separator between timestamp and resource: " + + name ); + } + } + + this.repositoryId = repositoryId; + } + + public AuditEvent( String repoId, String user, String resource, String action ) + { + this.repositoryId = repoId; + this.userId = user; + this.resource = resource; + this.action = action; + this.timestamp = Calendar.getInstance().getTime(); + } + + public String getRepositoryId() + { + return repositoryId; + } + + public void setRepositoryId( String repositoryId ) + { + this.repositoryId = repositoryId; + } + + public String getUserId() + { + return userId; + } + + public void setUserId( String userId ) + { + this.userId = userId; + } + + public String getResource() + { + return resource; + } + + public void setResource( String resource ) + { + this.resource = resource; + } + + public String getAction() + { + return action; + } + + public void setAction( String action ) + { + this.action = action; + } + + public String getRemoteIP() + { + return remoteIP; + } + + public void setRemoteIP( String remoteIP ) + { + this.remoteIP = remoteIP; + } + + public Date getTimestamp() + { + return timestamp; + } + + public void setTimestamp( Date timestamp ) + { + this.timestamp = timestamp; + } + + @Override + public String getFacetId() + { + return FACET_ID; + } + + @Override + public String getName() + { + // use the hashCode here to make it unique if multiple events occur at a certain timestamp. None of the other + // fields is unique on its own + return createNameFormat().format( timestamp ) + "/" + Integer.toHexString( hashCode() ); + // TODO: a simple incremental counter might be better since it will retain ordering, but then we need to do a + // bit of locking... + } + + private static SimpleDateFormat createNameFormat() + { + SimpleDateFormat fmt = new SimpleDateFormat( TIMESTAMP_FORMAT ); + fmt.setTimeZone( UTC_TIME_ZONE ); + return fmt; + } + + @Override + public Map<String, String> toProperties() + { + Map<String, String> properties = new HashMap<>(); + properties.put( "action", this.action ); + if ( this.userId != null ) + { + properties.put( "user", this.userId ); + } + if ( this.remoteIP != null ) + { + properties.put( "remoteIP", this.remoteIP ); + } + if ( this.resource != null ) + { + properties.put( "resource", this.resource ); + } + return properties; + } + + @Override + public void fromProperties( Map<String, String> properties ) + { + this.action = properties.get( "action" ); + this.remoteIP = properties.get( "remoteIP" ); + this.userId = properties.get( "user" ); + this.resource = properties.get( "resource" ); + } + + @Override + public boolean equals( Object o ) + { + if ( this == o ) + { + return true; + } + if ( o == null || getClass() != o.getClass() ) + { + return false; + } + + AuditEvent that = (AuditEvent) o; + + if ( !action.equals( that.action ) ) + { + return false; + } + if ( remoteIP != null ? !remoteIP.equals( that.remoteIP ) : that.remoteIP != null ) + { + return false; + } + if ( repositoryId != null ? !repositoryId.equals( that.repositoryId ) : that.repositoryId != null ) + { + return false; + } + if ( resource != null ? !resource.equals( that.resource ) : that.resource != null ) + { + return false; + } + if ( !timestamp.equals( that.timestamp ) ) + { + return false; + } + if ( userId != null ? !userId.equals( that.userId ) : that.userId != null ) + { + return false; + } + + return true; + } + + @Override + public int hashCode() + { + int result = repositoryId != null ? repositoryId.hashCode() : 0; + result = 31 * result + ( userId != null ? userId.hashCode() : 0 ); + result = 31 * result + ( remoteIP != null ? remoteIP.hashCode() : 0 ); + result = 31 * result + ( resource != null ? resource.hashCode() : 0 ); + result = 31 * result + action.hashCode(); + result = 31 * result + timestamp.hashCode(); + return result; + } + + @Override + public String toString() + { + final StringBuilder sb = new StringBuilder(); + sb.append( "AuditEvent" ); + sb.append( "{repositoryId='" ).append( repositoryId ).append( '\'' ); + sb.append( ", userId='" ).append( userId ).append( '\'' ); + sb.append( ", remoteIP='" ).append( remoteIP ).append( '\'' ); + sb.append( ", resource='" ).append( resource ).append( '\'' ); + sb.append( ", action='" ).append( action ).append( '\'' ); + sb.append( ", timestamp=" ).append( timestamp ); + sb.append( '}' ); + return sb.toString(); + } + + +} diff --git a/archiva-modules/metadata/metadata-repository-api/src/main/java/org/apache/archiva/repository/events/AuditListener.java b/archiva-modules/metadata/metadata-repository-api/src/main/java/org/apache/archiva/repository/events/AuditListener.java new file mode 100644 index 000000000..ade9f7959 --- /dev/null +++ b/archiva-modules/metadata/metadata-repository-api/src/main/java/org/apache/archiva/repository/events/AuditListener.java @@ -0,0 +1,37 @@ +package org.apache.archiva.repository.events; + +/* + * 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.facets.AuditEvent; + +/** + * AuditListener + * + * + */ +public interface AuditListener +{ + /** + * Notification that an audit event occured. + * + * @param event the event details. + */ + void auditEvent( AuditEvent event ); +} |