mirror of https://github.com/apache/lucene.git
SOLR-13969: Clean up and document AuditEvent API (#1041)
This commit is contained in:
parent
cc4f3802ef
commit
9f78482295
|
@ -152,6 +152,8 @@ Improvements
|
||||||
* SOLR-13961: When using partial/atomic updates to remove child documents, we now support setting to null or
|
* SOLR-13961: When using partial/atomic updates to remove child documents, we now support setting to null or
|
||||||
an empty list as equivalent to the "remove" command. (Thomas Wöckinger)
|
an empty list as equivalent to the "remove" command. (Thomas Wöckinger)
|
||||||
|
|
||||||
|
* SOLR-13969: Clean up and document AuditEvent API (janhoy)
|
||||||
|
|
||||||
Optimizations
|
Optimizations
|
||||||
---------------------
|
---------------------
|
||||||
(No changes)
|
(No changes)
|
||||||
|
|
|
@ -29,6 +29,7 @@ import java.util.Map;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
import org.apache.solr.common.SolrException;
|
import org.apache.solr.common.SolrException;
|
||||||
import org.apache.solr.common.cloud.ZkStateReader;
|
import org.apache.solr.common.cloud.ZkStateReader;
|
||||||
import org.apache.solr.servlet.ServletUtils;
|
import org.apache.solr.servlet.ServletUtils;
|
||||||
|
@ -48,7 +49,7 @@ import static org.apache.solr.security.AuditEvent.EventType.ERROR;
|
||||||
*/
|
*/
|
||||||
public class AuditEvent {
|
public class AuditEvent {
|
||||||
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
|
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
|
||||||
private StringBuffer requestUrl;
|
private String baseUrl;
|
||||||
private String nodeName;
|
private String nodeName;
|
||||||
private String message;
|
private String message;
|
||||||
private Level level;
|
private Level level;
|
||||||
|
@ -69,7 +70,7 @@ public class AuditEvent {
|
||||||
private EventType eventType;
|
private EventType eventType;
|
||||||
private AuthorizationResponse autResponse;
|
private AuthorizationResponse autResponse;
|
||||||
private RequestType requestType;
|
private RequestType requestType;
|
||||||
private double QTime = -1;
|
private double qTime = -1;
|
||||||
private int status = -1;
|
private int status = -1;
|
||||||
private Throwable exception;
|
private Throwable exception;
|
||||||
|
|
||||||
|
@ -134,7 +135,7 @@ public class AuditEvent {
|
||||||
this.httpMethod = httpRequest.getMethod();
|
this.httpMethod = httpRequest.getMethod();
|
||||||
this.httpQueryString = httpRequest.getQueryString();
|
this.httpQueryString = httpRequest.getQueryString();
|
||||||
this.headers = getHeadersFromRequest(httpRequest);
|
this.headers = getHeadersFromRequest(httpRequest);
|
||||||
this.requestUrl = httpRequest.getRequestURL();
|
this.baseUrl = httpRequest.getRequestURL().toString();
|
||||||
this.nodeName = MDC.get(ZkStateReader.NODE_NAME_PROP);
|
this.nodeName = MDC.get(ZkStateReader.NODE_NAME_PROP);
|
||||||
SolrRequestParsers.parseQueryString(httpQueryString).forEach(sp -> {
|
SolrRequestParsers.parseQueryString(httpQueryString).forEach(sp -> {
|
||||||
this.solrParams.put(sp.getKey(), Arrays.asList(sp.getValue()));
|
this.solrParams.put(sp.getKey(), Arrays.asList(sp.getValue()));
|
||||||
|
@ -223,74 +224,134 @@ public class AuditEvent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The human readable message about this event
|
||||||
|
*/
|
||||||
public String getMessage() {
|
public String getMessage() {
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Level of this event. Can be INFO, WARN or ERROR
|
||||||
|
* @return {@link Level} enum
|
||||||
|
*/
|
||||||
public Level getLevel() {
|
public Level getLevel() {
|
||||||
return level;
|
return level;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Date that the event happened
|
||||||
|
*/
|
||||||
public Date getDate() {
|
public Date getDate() {
|
||||||
return date;
|
return date;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Username of logged in user, or null if no authenticated user
|
||||||
|
*/
|
||||||
public String getUsername() {
|
public String getUsername() {
|
||||||
return username;
|
return username;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Session identifier
|
||||||
|
*/
|
||||||
public String getSession() {
|
public String getSession() {
|
||||||
return session;
|
return session;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IP address of the client doing the request
|
||||||
|
*/
|
||||||
public String getClientIp() {
|
public String getClientIp() {
|
||||||
return clientIp;
|
return clientIp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A general purpose context map with potential extra information about the event
|
||||||
|
*/
|
||||||
public Map<String, Object> getContext() {
|
public Map<String, Object> getContext() {
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of collection names involved in request
|
||||||
|
*/
|
||||||
public List<String> getCollections() {
|
public List<String> getCollections() {
|
||||||
return collections;
|
return collections;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Identifies the resource being operated on. This is not the same as URL path.
|
||||||
|
* For queries the resource is relative to collection name, e.g. /select or /update.
|
||||||
|
* For other events the resource may be /api/node/health or /admin/collection
|
||||||
|
*/
|
||||||
public String getResource() {
|
public String getResource() {
|
||||||
return resource;
|
return resource;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The HTTP method. E.g. GET, POST, PUT
|
||||||
|
*/
|
||||||
public String getHttpMethod() {
|
public String getHttpMethod() {
|
||||||
return httpMethod;
|
return httpMethod;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Query part of URL or null if query part
|
||||||
|
*/
|
||||||
public String getHttpQueryString() {
|
public String getHttpQueryString() {
|
||||||
return httpQueryString;
|
return httpQueryString;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EventType tells the outcome of the event such as REJECTED, UNAUTHORIZED or ERROR
|
||||||
|
* @return {@link EventType} enum
|
||||||
|
*/
|
||||||
public EventType getEventType() {
|
public EventType getEventType() {
|
||||||
return eventType;
|
return eventType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Host name of the Solr node logging the event
|
||||||
|
*/
|
||||||
public String getSolrHost() {
|
public String getSolrHost() {
|
||||||
return solrHost;
|
return solrHost;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IP address of the Solr node logging the event
|
||||||
|
*/
|
||||||
public String getSolrIp() {
|
public String getSolrIp() {
|
||||||
return solrIp;
|
return solrIp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Port number of the Solr node logging the event
|
||||||
|
*/
|
||||||
public int getSolrPort() {
|
public int getSolrPort() {
|
||||||
return solrPort;
|
return solrPort;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map of all HTTP request headers belonging to the request
|
||||||
|
*/
|
||||||
public Map<String, String> getHeaders() {
|
public Map<String, String> getHeaders() {
|
||||||
return headers;
|
return headers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map of all Solr request parameters attached to the request. Pulled from url
|
||||||
|
*/
|
||||||
public Map<String, List<String>> getSolrParams() {
|
public Map<String, List<String>> getSolrParams() {
|
||||||
return solrParams;
|
return solrParams;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets first value of a certain Solr request parameter
|
||||||
|
* @param key name of request parameter to retrieve
|
||||||
|
* @return String value of the first value, regardless of number of valies
|
||||||
|
*/
|
||||||
public String getSolrParamAsString(String key) {
|
public String getSolrParamAsString(String key) {
|
||||||
List<String> v = getSolrParams().get(key);
|
List<String> v = getSolrParams().get(key);
|
||||||
if (v != null && v.size() > 0) {
|
if (v != null && v.size() > 0) {
|
||||||
|
@ -299,38 +360,80 @@ public class AuditEvent {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The authorization response object from authorization plugin, or null authz has not happened
|
||||||
|
*/
|
||||||
public AuthorizationResponse getAutResponse() {
|
public AuthorizationResponse getAutResponse() {
|
||||||
return autResponse;
|
return autResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Node name of Solr node, on the internal format host:port_context, e.g. 10.0.0.1:8983_solr
|
||||||
|
*/
|
||||||
public String getNodeName() {
|
public String getNodeName() {
|
||||||
return nodeName;
|
return nodeName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines the type of request. Can be ADMIN, SEARCH, UPDATE, STREAMING, UNKNOWN
|
||||||
|
* @return {@link RequestType} enum
|
||||||
|
*/
|
||||||
public RequestType getRequestType() {
|
public RequestType getRequestType() {
|
||||||
return requestType;
|
return requestType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HTTP status code of event, i.e. 200 = OK, 401 = unauthorized
|
||||||
|
*/
|
||||||
public int getStatus() {
|
public int getStatus() {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request time in milliseconds for completed requests
|
||||||
|
*/
|
||||||
public double getQTime() {
|
public double getQTime() {
|
||||||
return QTime;
|
return qTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In case of ERROR event, find the exception causing the error
|
||||||
|
*/
|
||||||
public Throwable getException() {
|
public Throwable getException() {
|
||||||
return exception;
|
return exception;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get baseUrl as StringBuffer for back compat with previous version
|
||||||
|
* @deprecated Please use {@link #getBaseUrl()} instead
|
||||||
|
* @return StringBuffer of the base url without query part
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
@JsonIgnore
|
||||||
public StringBuffer getRequestUrl() {
|
public StringBuffer getRequestUrl() {
|
||||||
return requestUrl;
|
return new StringBuffer(baseUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Full URL of the original request. This is {@link #baseUrl} + "?" + {@link #httpQueryString}.
|
||||||
|
* Returns null if not set
|
||||||
|
*/
|
||||||
|
public String getUrl() {
|
||||||
|
if (baseUrl == null) return null;
|
||||||
|
return baseUrl + (httpQueryString != null ? "?" + httpQueryString : "");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* First part of URL of the request, but not including request parameters, or null if not set
|
||||||
|
*/
|
||||||
|
public String getBaseUrl() {
|
||||||
|
return baseUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setters, builder style
|
// Setters, builder style
|
||||||
|
|
||||||
public AuditEvent setRequestUrl(StringBuffer requestUrl) {
|
public AuditEvent setBaseUrl(String baseUrl) {
|
||||||
this.requestUrl = requestUrl;
|
this.baseUrl = baseUrl;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -429,8 +532,8 @@ public class AuditEvent {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AuditEvent setQTime(double QTime) {
|
public AuditEvent setQTime(double qTime) {
|
||||||
this.QTime = QTime;
|
this.qTime = qTime;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,13 @@ public class AuditLoggerPluginTest extends SolrTestCaseJ4 {
|
||||||
.setMessage("Anonymous")
|
.setMessage("Anonymous")
|
||||||
.setResource("/collection1")
|
.setResource("/collection1")
|
||||||
.setDate(SAMPLE_DATE);
|
.setDate(SAMPLE_DATE);
|
||||||
|
protected static final AuditEvent EVENT_WITH_URL = new AuditEvent(AuditEvent.EventType.ANONYMOUS)
|
||||||
|
.setHttpMethod("GET")
|
||||||
|
.setMessage("Anonymous")
|
||||||
|
.setResource("/collection1")
|
||||||
|
.setBaseUrl("http://myserver/mypath")
|
||||||
|
.setHttpQueryString("a=b&c=d")
|
||||||
|
.setDate(SAMPLE_DATE);
|
||||||
protected static final AuditEvent EVENT_ANONYMOUS_REJECTED = new AuditEvent(AuditEvent.EventType.ANONYMOUS_REJECTED)
|
protected static final AuditEvent EVENT_ANONYMOUS_REJECTED = new AuditEvent(AuditEvent.EventType.ANONYMOUS_REJECTED)
|
||||||
.setHttpMethod("GET")
|
.setHttpMethod("GET")
|
||||||
.setMessage("Anonymous rejected")
|
.setMessage("Anonymous rejected")
|
||||||
|
@ -196,4 +203,16 @@ public class AuditLoggerPluginTest extends SolrTestCaseJ4 {
|
||||||
plugin.formatter.formatEvent(EVENT_AUTHENTICATED));
|
plugin.formatter.formatEvent(EVENT_AUTHENTICATED));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getBaseUrl() {
|
||||||
|
assertEquals("http://myserver/mypath", EVENT_WITH_URL.getBaseUrl());
|
||||||
|
// Deprecated
|
||||||
|
assertEquals("http://myserver/mypath", EVENT_WITH_URL.getRequestUrl().toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getUrl() {
|
||||||
|
assertEquals("http://myserver/mypath?a=b&c=d",
|
||||||
|
EVENT_WITH_URL.getUrl());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue