001/* 002 * Copyright 2012-2018 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.boot.actuate.audit; 018 019import java.io.Serializable; 020import java.time.Instant; 021import java.util.Collections; 022import java.util.HashMap; 023import java.util.Map; 024 025import com.fasterxml.jackson.annotation.JsonInclude; 026import com.fasterxml.jackson.annotation.JsonInclude.Include; 027 028import org.springframework.context.ApplicationEventPublisher; 029import org.springframework.context.ApplicationEventPublisherAware; 030import org.springframework.util.Assert; 031 032/** 033 * A value object representing an audit event: at a particular time, a particular user or 034 * agent carried out an action of a particular type. This object records the details of 035 * such an event. 036 * <p> 037 * Users can inject a {@link AuditEventRepository} to publish their own events or 038 * alternatively use Spring's {@link ApplicationEventPublisher} (usually obtained by 039 * implementing {@link ApplicationEventPublisherAware}) to publish AuditApplicationEvents 040 * (wrappers for AuditEvent). 041 * 042 * @author Dave Syer 043 * @see AuditEventRepository 044 */ 045@JsonInclude(Include.NON_EMPTY) 046public class AuditEvent implements Serializable { 047 048 private final Instant timestamp; 049 050 private final String principal; 051 052 private final String type; 053 054 private final Map<String, Object> data; 055 056 /** 057 * Create a new audit event for the current time. 058 * @param principal the user principal responsible 059 * @param type the event type 060 * @param data the event data 061 */ 062 public AuditEvent(String principal, String type, Map<String, Object> data) { 063 this(Instant.now(), principal, type, data); 064 } 065 066 /** 067 * Create a new audit event for the current time from data provided as name-value 068 * pairs. 069 * @param principal the user principal responsible 070 * @param type the event type 071 * @param data the event data in the form 'key=value' or simply 'key' 072 */ 073 public AuditEvent(String principal, String type, String... data) { 074 this(Instant.now(), principal, type, convert(data)); 075 } 076 077 /** 078 * Create a new audit event. 079 * @param timestamp the date/time of the event 080 * @param principal the user principal responsible 081 * @param type the event type 082 * @param data the event data 083 */ 084 public AuditEvent(Instant timestamp, String principal, String type, 085 Map<String, Object> data) { 086 Assert.notNull(timestamp, "Timestamp must not be null"); 087 Assert.notNull(type, "Type must not be null"); 088 this.timestamp = timestamp; 089 this.principal = (principal != null) ? principal : ""; 090 this.type = type; 091 this.data = Collections.unmodifiableMap(data); 092 } 093 094 private static Map<String, Object> convert(String[] data) { 095 Map<String, Object> result = new HashMap<>(); 096 for (String entry : data) { 097 int index = entry.indexOf('='); 098 if (index != -1) { 099 result.put(entry.substring(0, index), entry.substring(index + 1)); 100 } 101 else { 102 result.put(entry, null); 103 } 104 } 105 return result; 106 } 107 108 /** 109 * Returns the date/time that the event was logged. 110 * @return the timestamp 111 */ 112 public Instant getTimestamp() { 113 return this.timestamp; 114 } 115 116 /** 117 * Returns the user principal responsible for the event or an empty String if the 118 * principal is not available. 119 * @return the principal 120 */ 121 public String getPrincipal() { 122 return this.principal; 123 } 124 125 /** 126 * Returns the type of event. 127 * @return the event type 128 */ 129 public String getType() { 130 return this.type; 131 } 132 133 /** 134 * Returns the event data. 135 * @return the event data 136 */ 137 public Map<String, Object> getData() { 138 return this.data; 139 } 140 141 @Override 142 public String toString() { 143 return "AuditEvent [timestamp=" + this.timestamp + ", principal=" + this.principal 144 + ", type=" + this.type + ", data=" + this.data + "]"; 145 } 146 147}