com.sap.cds.repackaged.audit.client.impl.AuditLogMessageImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of cds-feature-auditlog-v2 Show documentation
Show all versions of cds-feature-auditlog-v2 Show documentation
Handler to send auditlog messages to AuditLog Service V2
package com.sap.cds.repackaged.audit.client.impl;
import static com.sap.cds.repackaged.audit.client.impl.Utils.IDP_VALUE;
import static com.sap.cds.repackaged.audit.client.impl.Utils.OAUTH2_PLAN;
import static com.sap.cds.repackaged.audit.client.impl.Utils.PROVIDER_VALUE;
import static com.sap.cds.repackaged.audit.client.impl.Utils.SUBSCRIBER_VALUE;
import static com.sap.cds.repackaged.audit.client.impl.Utils.USER_VALUE;
import java.time.Instant;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.sap.cds.repackaged.audit.api.AuditLogMessage;
import com.sap.cds.repackaged.audit.api.exception.AuditLogNotAvailableException;
import com.sap.cds.repackaged.audit.api.exception.AuditLogWriteException;
import com.sap.xs.audit.message.ValidationError;
import com.sap.xs.audit.message.utils.JsonParserUtils;
public abstract class AuditLogMessageImpl implements AuditLogMessage {
protected static Logger LOGGER = LoggerFactory.getLogger(AuditLogMessageImpl.class);
private static final String ALREADY_LOGGED = "Audit message has already been logged. No changes possible.";
protected static final String ALREADY_LOGGED_WARNING = "Audit message ignored as it has already been persisted successfully.";
private static final String SUBSCRIBER_URL_TEMPLATE_PATH = "https://%s.%s";
protected boolean alreadyPrepared = false;
protected boolean alreadyLogged = false;
protected String endpoint;
protected T message;
protected Instant eventTime;
protected AuditLogMessageFactoryImpl factory;
protected Communicator communicator;
@Deprecated
public AuditLogMessageImpl(AuditLogMessageFactoryImpl factory) {
this.factory = factory;
this.communicator = factory.getCommunicator();
}
public AuditLogMessageImpl(Communicator communicator) {
this.communicator = communicator;
}
protected void ensureNotLogged() throws IllegalStateException {
if (alreadyPrepared || alreadyLogged) {
throw new IllegalStateException(ALREADY_LOGGED);
}
}
public String serializeMessage() throws AuditLogWriteException {
try {
return JsonParserUtils.serializeMessage(message);
} catch (JsonProcessingException e) {
throw new AuditLogWriteException("Cannot serialize audit message " + e);
}
}
protected String serializeMessage(Object message) throws AuditLogWriteException {
try {
return JsonParserUtils.serializeMessage(message);
} catch (JsonProcessingException e) {
throw new AuditLogWriteException("Cannot serialize audit message " + e);
}
}
@Override
public void log() throws AuditLogNotAvailableException, AuditLogWriteException {
if (alreadyLogged) {
LOGGER.warn(ALREADY_LOGGED_WARNING);
return;
}
if (message.getUser() == null || USER_VALUE.equals(message.getUser())) {
String user = Utils.getUser();
message.setUser(user != null ? user : communicator.getClientId());
}
if (eventTime == null) {
eventTime = Instant.now();
}
message.setTime(eventTime);
try {
validateUser(message.getUser());
validateIdentityProvider(message.getIdentityProvider());
validateTenant(message.getTenant());
message.validate();
} catch (ValidationError e) {
throw new AuditLogWriteException("Audit log message cannot be validated. " + e.getMessage(), message.getErrors());
}
communicator.send(serializeMessage(), endpoint, message.getSubscriberTokenIssuer());
alreadyLogged = true;
}
@Override
public void setUser(String user) {
ensureNotLogged();
message.setUser(user);
}
@Override
public void setIdentityProvider(String idp) {
ensureNotLogged();
message.setIdentityProvider(idp);
}
@Override
public void setTenant(String tenant) {
ensureNotLogged();
message.setTenant(tenant);
}
@Override
public void setTenant(String tenant, String subscriberTokenIssuer) {
ensureNotLogged();
message.setSubscriberTokenIssuer(subscriberTokenIssuer);
message.setTenant(tenant);
}
@Override
public void setTenantBySubscriberSubdomain(String subdomain) {
ensureNotLogged();
String uaaDomain = communicator.getUaaDomain();
String subscriberTokenIssuer = String.format(SUBSCRIBER_URL_TEMPLATE_PATH, subdomain, uaaDomain);
message.setSubscriberTokenIssuer(subscriberTokenIssuer);
message.setTenant(SUBSCRIBER_VALUE);
}
@Override
public void addCustomDetails(String key, Object value) {
ensureNotLogged();
message.addCustomDetails(key, value);
}
@Override
public void setEventTime(Instant time) {
this.eventTime = time;
}
/**
* @deprecated Use com.sap.cds.repackaged.audit.api.AuditLogMessage.setEventTime instead
* @param time
*/
@Deprecated
public void setTime(Instant time) {
message.setTime(time);
}
/**
* @deprecated The UUID is always automatically generated by the service and can't be changed.
* @param uuid
*/
@Deprecated
public void setUuid(String uuid) {
message.setUuid(uuid);
}
private void validateUser(String user) throws ValidationError {
String plan = communicator.getServicePlan();
if (OAUTH2_PLAN.equals(plan) && isUserValueInvalid(user)) {
throw new ValidationError("The user field of the Audit log message should not be empty for the 'oauth2' scenario!");
}
}
private void validateIdentityProvider(String identityProvider) throws ValidationError {
String plan = communicator.getServicePlan();
if (OAUTH2_PLAN.equals(plan) && isIdPValueInvalid(identityProvider)) {
throw new ValidationError("The identityProvider field of the Audit log message is invaid for the 'oauth2' scenario!");
}
}
private void validateTenant(String tenant) throws ValidationError {
String plan = communicator.getServicePlan();
if (OAUTH2_PLAN.equals(plan) && isTenantValueInvalid(tenant)) {
throw new ValidationError("The tenant field of the Audit log message is invaid for the 'oauth2' scenario!");
}
}
private boolean isTenantValueInvalid(String tenant) {
return !(PROVIDER_VALUE.equals(tenant) || SUBSCRIBER_VALUE.equals(tenant));
}
private boolean isUserValueInvalid(String user) {
if (user != null) {
return user.trim()
.isEmpty();
}
return true;
}
private boolean isIdPValueInvalid(String identityProvider) {
return !(identityProvider == null || IDP_VALUE.equals(identityProvider));
}
}