Skip to content

Commit

Permalink
Add RequestInfo to AuditEntry
Browse files Browse the repository at this point in the history
  • Loading branch information
kfaraz committed Dec 8, 2023
1 parent 956e6a5 commit 6144091
Show file tree
Hide file tree
Showing 15 changed files with 289 additions and 48 deletions.
22 changes: 21 additions & 1 deletion processing/src/main/java/org/apache/druid/audit/AuditEntry.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.apache.druid.java.util.common.DateTimes;
import org.joda.time.DateTime;

import javax.annotation.Nullable;
import java.util.Objects;

/**
Expand All @@ -37,6 +38,7 @@ public class AuditEntry
private final String key;
private final String type;
private final AuditInfo auditInfo;
private final RequestInfo request;
private final Payload payload;
private final DateTime auditTime;

Expand All @@ -45,6 +47,7 @@ public AuditEntry(
@JsonProperty("key") String key,
@JsonProperty("type") String type,
@JsonProperty("auditInfo") AuditInfo authorInfo,
@JsonProperty("request") @Nullable RequestInfo requestInfo,
@JsonProperty("payload") Payload payload,
@JsonProperty("auditTime") DateTime auditTime
)
Expand All @@ -55,6 +58,7 @@ public AuditEntry(
this.key = key;
this.type = type;
this.auditInfo = authorInfo;
this.request = requestInfo;
this.auditTime = auditTime == null ? DateTimes.nowUtc() : auditTime;
this.payload = payload == null ? Payload.fromString("") : payload;
}
Expand All @@ -77,6 +81,15 @@ public AuditInfo getAuditInfo()
return auditInfo;
}

/**
* Details of the REST API request associated with this audit, if any.
*/
@JsonProperty
public RequestInfo getRequest()
{
return request;
}

/**
* Non-null payload of the audit event.
*/
Expand Down Expand Up @@ -129,6 +142,7 @@ public static class Builder
private String key;
private String type;
private AuditInfo auditInfo;
private RequestInfo requestInfo;
private Object payload;
private String serializedPayload;

Expand Down Expand Up @@ -157,6 +171,12 @@ public Builder auditInfo(AuditInfo auditInfo)
return this;
}

public Builder request(RequestInfo requestInfo)
{
this.requestInfo = requestInfo;
return this;
}

public Builder serializedPayload(String serializedPayload)
{
this.serializedPayload = serializedPayload;
Expand All @@ -177,7 +197,7 @@ public Builder auditTime(DateTime auditTime)

public AuditEntry build()
{
return new AuditEntry(key, type, auditInfo, new Payload(serializedPayload, payload), auditTime);
return new AuditEntry(key, type, auditInfo, requestInfo, new Payload(serializedPayload, payload), auditTime);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@

import java.util.Objects;

/**
* Contains information about the author who performed an audited operation.
*/
public class AuditInfo
{
private final String author;
Expand Down
107 changes: 107 additions & 0 deletions processing/src/main/java/org/apache/druid/audit/RequestInfo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/*
* 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.
*/

package org.apache.druid.audit;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;

import java.util.Objects;

/**
* Contains information about a REST API request that was audited.
*/
public class RequestInfo
{
private final String service;
private final String method;
private final String path;
private final String queryParams;

@JsonCreator
public RequestInfo(
@JsonProperty("service") String service,
@JsonProperty("method") String method,
@JsonProperty("path") String path,
@JsonProperty("queryParams") String queryParams
)
{
this.service = service;
this.method = method;
this.path = path;
this.queryParams = queryParams;
}

@JsonProperty
public String getService()
{
return service;
}

@JsonProperty
public String getMethod()
{
return method;
}

@JsonProperty
public String getPath()
{
return path;
}

@JsonProperty
public String getQueryParams()
{
return queryParams;
}

@Override
public boolean equals(Object o)
{
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
RequestInfo that = (RequestInfo) o;
return Objects.equals(this.service, that.service)
&& Objects.equals(this.method, that.method)
&& Objects.equals(this.path, that.path)
&& Objects.equals(this.queryParams, that.queryParams);
}

@Override
public int hashCode()
{
return Objects.hash(service, method, path, queryParams);
}

@Override
public String toString()
{
return "RequestInfo{" +
"service='" + service + '\'' +
", method='" + method + '\'' +
", path='" + path + '\'' +
", queryParams='" + queryParams + '\'' +
'}';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ public void testAuditEntrySerde() throws IOException
"testComment",
"127.0.0.1"
),
new RequestInfo("overlord", "GET", "/segments", "?abc=1"),
AuditEntry.Payload.fromString("testPayload"),
DateTimes.of("2013-01-01T00:00:00Z")
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
import com.google.inject.Module;
import com.google.inject.multibindings.MapBinder;
import org.apache.druid.audit.AuditManager;
import org.apache.druid.audit.AuditManagerConfig;
import org.apache.druid.indexer.MetadataStorageUpdaterJobHandler;
import org.apache.druid.indexer.SQLMetadataStorageUpdaterJobHandler;
import org.apache.druid.indexing.overlord.IndexerMetadataStorageCoordinator;
Expand All @@ -47,11 +46,10 @@
import org.apache.druid.metadata.SegmentsMetadataManagerProvider;
import org.apache.druid.metadata.SqlSegmentsMetadataManager;
import org.apache.druid.metadata.SqlSegmentsMetadataManagerProvider;
import org.apache.druid.server.audit.AuditManagerConfig;
import org.apache.druid.server.audit.AuditSerdeHelper;
import org.apache.druid.server.audit.LoggingAuditManager;
import org.apache.druid.server.audit.LoggingAuditManagerConfig;
import org.apache.druid.server.audit.SQLAuditManager;
import org.apache.druid.server.audit.SQLAuditManagerConfig;

public class SQLMetadataStorageDruidModule implements Module
{
Expand Down Expand Up @@ -87,7 +85,7 @@ public void createBindingChoices(Binder binder, String defaultValue)
PolyBind.createChoiceWithDefault(binder, prop, Key.get(MetadataStorageUpdaterJobHandler.class), defaultValue);
PolyBind.createChoiceWithDefault(binder, prop, Key.get(MetadataSupervisorManager.class), defaultValue);

configureAuditDestination(binder);
configureAuditManager(binder);
}

@Override
Expand Down Expand Up @@ -139,8 +137,10 @@ public void configure(Binder binder)
.in(LazySingleton.class);
}

private void configureAuditDestination(Binder binder)
private void configureAuditManager(Binder binder)
{
JsonConfigProvider.bind(binder, "druid.audit.manager", AuditManagerConfig.class);

PolyBind.createChoice(
binder,
"druid.audit.manager.type",
Expand All @@ -158,23 +158,6 @@ private void configureAuditDestination(Binder binder)
.to(SQLAuditManager.class)
.in(LazySingleton.class);

PolyBind.createChoice(
binder,
"druid.audit.manager.type",
Key.get(AuditManagerConfig.class),
Key.get(SQLAuditManagerConfig.class)
);
final MapBinder<String, AuditManagerConfig> auditManagerConfigBinder
= PolyBind.optionBinder(binder, Key.get(AuditManagerConfig.class));
auditManagerConfigBinder
.addBinding("log")
.to(LoggingAuditManagerConfig.class)
.in(LazySingleton.class);
auditManagerConfigBinder
.addBinding("sql")
.to(SQLAuditManagerConfig.class)
.in(LazySingleton.class);

binder.bind(AuditSerdeHelper.class);
binder.bind(AuditSerdeHelper.class).in(LazySingleton.class);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public enum Level
}

private static final String MSG_FORMAT
= "[%s] User[%s], identity[%s], ip[%s] performed action[%s] on key[%s] with comment[%s]. Payload[%s].";
= "User[%s], identity[%s], IP[%s] performed action[%s] on key[%s] with comment[%s]. Payload[%s].";

private final Level level;
private final Logger logger = new Logger(AuditLogger.class);
Expand All @@ -43,7 +43,6 @@ public AuditLogger(Level level)
public void log(AuditEntry entry)
{
Object[] args = {
entry.getAuditTime(),
entry.getAuditInfo().getAuthor(),
entry.getAuditInfo().getIdentity(),
entry.getAuditInfo().getIp(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,17 @@
* under the License.
*/

package org.apache.druid.audit;
package org.apache.druid.server.audit;

import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonSubTypes.Type;
import com.fasterxml.jackson.annotation.JsonTypeInfo;

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type", defaultImpl = SQLAuditManagerConfig.class)
@JsonSubTypes(value = {
@Type(name = "log", value = LoggingAuditManagerConfig.class),
@Type(name = "sql", value = SQLAuditManagerConfig.class)
})
public interface AuditManagerConfig
{
boolean isSkipNullField();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.inject.Inject;
import org.apache.druid.audit.AuditEntry;
import org.apache.druid.audit.AuditManagerConfig;
import org.apache.druid.guice.annotations.Json;
import org.apache.druid.guice.annotations.JsonNonNull;
import org.apache.druid.java.util.common.StringUtils;
Expand Down Expand Up @@ -87,6 +86,7 @@ public AuditEntry processAuditEntry(AuditEntry entry)
entry.getKey(),
entry.getType(),
entry.getAuditInfo(),
entry.getRequest(),
processedPayload,
entry.getAuditTime()
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import com.google.inject.Inject;
import org.apache.druid.audit.AuditEntry;
import org.apache.druid.audit.AuditManager;
import org.apache.druid.error.DruidException;
import org.joda.time.Interval;

import java.util.Collections;
Expand All @@ -38,12 +39,17 @@ public class LoggingAuditManager implements AuditManager

@Inject
public LoggingAuditManager(
LoggingAuditManagerConfig config,
AuditManagerConfig config,
AuditSerdeHelper serdeHelper
)
{
this.serdeHelper = serdeHelper;
this.auditLogger = new AuditLogger(config.getLogLevel());
if (!(config instanceof LoggingAuditManagerConfig)) {
throw DruidException.defensive("Config[%s] is not an instance of LoggingAuditManagerConfig", config);
}

LoggingAuditManagerConfig logAuditConfig = (LoggingAuditManagerConfig) config;
this.auditLogger = new AuditLogger(logAuditConfig.getLogLevel());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
package org.apache.druid.server.audit;

import com.fasterxml.jackson.annotation.JsonProperty;
import org.apache.druid.audit.AuditManagerConfig;
import org.apache.druid.java.util.common.HumanReadableBytes;
import org.apache.druid.java.util.common.HumanReadableBytesRange;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import com.google.inject.Inject;
import org.apache.druid.audit.AuditEntry;
import org.apache.druid.audit.AuditManager;
import org.apache.druid.error.DruidException;
import org.apache.druid.guice.ManageLifecycle;
import org.apache.druid.guice.annotations.Json;
import org.apache.druid.java.util.common.DateTimes;
Expand Down Expand Up @@ -65,7 +66,7 @@ public class SQLAuditManager implements AuditManager

@Inject
public SQLAuditManager(
SQLAuditManagerConfig config,
AuditManagerConfig config,
AuditSerdeHelper serdeHelper,
SQLMetadataConnector connector,
Supplier<MetadataStorageTablesConfig> dbTables,
Expand All @@ -79,8 +80,12 @@ public SQLAuditManager(
this.emitter = emitter;
this.jsonMapper = jsonMapper;
this.serdeHelper = serdeHelper;
this.config = config;
this.resultMapper = new AuditEntryMapper();

if (!(config instanceof SQLAuditManagerConfig)) {
throw DruidException.defensive("Config[%s] is not an instance of SQLAuditManagerConfig", config);
}
this.config = (SQLAuditManagerConfig) config;
}

@LifecycleStart
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
package org.apache.druid.server.audit;

import com.fasterxml.jackson.annotation.JsonProperty;
import org.apache.druid.audit.AuditManagerConfig;
import org.apache.druid.java.util.common.HumanReadableBytes;
import org.apache.druid.java.util.common.HumanReadableBytesRange;

Expand Down
Loading

0 comments on commit 6144091

Please sign in to comment.