com.dnastack.audit.client.EventsClient Maven / Gradle / Ivy
The newest version!
package com.dnastack.audit.client;
import com.dnastack.audit.ObjectMapperFactory;
import com.dnastack.audit.exception.HttpRequestFailedException;
import com.dnastack.audit.model.AuditEventBody;
import com.dnastack.audit.model.AuditEventBodyBatch;
import com.dnastack.audit.model.AuditEventLoggerConfig;
import com.dnastack.audit.util.AuditTracer;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import interceptor.AuthorizationInterceptor;
import interceptor.TokenDelegate;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import okhttp3.logging.HttpLoggingInterceptor;
import okio.BufferedSink;
import java.io.IOException;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.util.Objects;
import static java.lang.String.format;
@Slf4j
public class EventsClient {
private final AuditEventLoggerConfig.Publisher publisherConfig;
private final ObjectMapper objectMapper;
private final AuditTracer auditTracer;
private final OkHttpClient eventsHttpClient;
public EventsClient(
AuditEventLoggerConfig.Publisher publisherConfig,
TokenDelegate tokenDelegate,
AuditTracer auditTracer
) {
Objects.requireNonNull(publisherConfig, "publisherConfig must not be null");
Objects.requireNonNull(tokenDelegate, "accessTokenSupplier must not be null");
Objects.requireNonNull(auditTracer, "auditTracer must not be null");
this.publisherConfig = publisherConfig;
this.objectMapper = ObjectMapperFactory.create();
this.auditTracer = auditTracer;
eventsHttpClient = new OkHttpClient.Builder()
.addInterceptor(
new HttpLoggingInterceptor(log::info)
.setLevel(HttpLoggingInterceptor.Level.BASIC)
)
.addInterceptor(new AuthorizationInterceptor(tokenDelegate))
.addInterceptor(new RetryInterceptor(publisherConfig.getGiveUpAfter(), publisherConfig.getDelayBetweenTriesInMillis()))
.build();
}
public void publishBatch(AuditEventBodyBatch auditEventBodyBatch) {
try {
RequestBody requestBody = new RequestBody() {
@Override public MediaType contentType() {
return MediaType.get("application/json");
}
@Override public void writeTo(BufferedSink sink) throws IOException {
OutputStream os = sink.outputStream();
objectMapper.writeValue(os, auditEventBodyBatch);
}
};
final Request request = new Request.Builder()
.url(publisherConfig.getEventsBatchUri())
.header("Content-Type", "application/json")
.header("X-B3-TraceId", auditTracer.currentTraceId())
.header("X-B3-SpanId", auditTracer.currentSpanId())
.method("POST", requestBody)
.build();
log.info("Preparing batch request [{}] [{}] - number of events in batch: [{}], content length: [{}] Bytes",
request.method(),
request.url(),
auditEventBodyBatch.getEvents().size(),
request.body() != null ? request.body().contentLength() : "unknown");
send(request);
} catch (JsonProcessingException | MalformedURLException ex) {
throw new HttpRequestFailedException(format("Failed to process %s", auditEventBodyBatch), ex);
} catch (IOException e) {
log.error(e.getMessage());
}
}
public void publish(AuditEventBody auditEvent) {
try {
RequestBody requestBody = new RequestBody() {
@Override public MediaType contentType() {
return MediaType.get("application/json");
}
@Override public void writeTo(BufferedSink sink) throws IOException {
OutputStream os = sink.outputStream();
objectMapper.writeValue(os, auditEvent);
}
};
final Request request = new Request.Builder()
.url(publisherConfig.getEventsUri())
.header("Content-Type", "application/json")
.header("X-B3-TraceId", auditTracer.currentTraceId())
.header("X-B3-SpanId", auditTracer.currentSpanId())
.method("POST", requestBody)
.build();
log.info("Preparing single request [{}] [{}] - content length: [{}] Bytes",
request.method(),
request.url(),
request.body() != null ? request.body().contentLength() : "unknown");
send(request);
} catch (JsonProcessingException | MalformedURLException ex) {
throw new HttpRequestFailedException(format("Failed to process %s", auditEvent), ex);
} catch (IOException e) {
log.error(e.getMessage());
}
}
private void send(final Request request) {
try (Response response = eventsHttpClient.newCall(request).execute()) {
if (response.code() == 200 && response.body() != null) {
AuditEventBodyBatch auditEventBodyBatch = objectMapper.readValue(response.body().charStream(), AuditEventBodyBatch.class);
if(auditEventBodyBatch.getEvents() != null) {
auditEventBodyBatch.getEvents().forEach((auditEventBody) -> log.error("Failed to store Audit Event {} ", auditEventBody));
}
} else if (!response.isSuccessful()) {
log.warn("Failed request [{}] [{}] after [{}] retries with status [{}]",
request.method(),
request.url(),
publisherConfig.getGiveUpAfter(),
response.code()
);
auditTracer.setCurrentSpanError(new HttpRequestFailedException(format("Failed request [%s] [%s] after [%s] retries with status [%s]",
request.method(),
request.url(),
publisherConfig.getGiveUpAfter(),
response.code()
)));
}
} catch (IOException e) {
log.error(e.getMessage());
auditTracer.setCurrentSpanError(e);
} catch (RuntimeException re) {
auditTracer.setCurrentSpanError(re);
throw re;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy