diff --git a/pom.xml b/pom.xml
index 4a4d474..86cd6a8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -128,10 +128,9 @@
3.2.0
-
- 1.33.0
-
-
+
+ 2.85.0
+
diff --git a/src/main/java/io/apitally/common/ApitallyClient.java b/src/main/java/io/apitally/common/ApitallyClient.java
index 16b735e..7d1acdd 100644
--- a/src/main/java/io/apitally/common/ApitallyClient.java
+++ b/src/main/java/io/apitally/common/ApitallyClient.java
@@ -44,18 +44,16 @@ public enum HubRequestStatus {
private static final int INITIAL_PERIOD_SECONDS = 3600;
private static final int MAX_QUEUE_TIME_SECONDS = 3600;
private static final int REQUEST_TIMEOUT_SECONDS = 10;
- private static final String HUB_BASE_URL =
- Optional.ofNullable(System.getenv("APITALLY_HUB_BASE_URL"))
- .filter(s -> !s.trim().isEmpty())
- .orElse("https://hub.apitally.io");
+ private static final String HUB_BASE_URL = Optional.ofNullable(System.getenv("APITALLY_HUB_BASE_URL"))
+ .filter(s -> !s.trim().isEmpty())
+ .orElse("https://hub.apitally.io");
private static final Logger logger = LoggerFactory.getLogger(ApitallyClient.class);
- private static final RetryTemplate retryTemplate =
- RetryTemplate.builder()
- .maxAttempts(3)
- .exponentialBackoff(Duration.ofSeconds(1), 2, Duration.ofSeconds(4), true)
- .retryOn(RetryableHubRequestException.class)
- .build();
+ private static final RetryTemplate retryTemplate = RetryTemplate.builder()
+ .maxAttempts(3)
+ .exponentialBackoff(Duration.ofSeconds(1), 2, Duration.ofSeconds(4), true)
+ .retryOn(RetryableHubRequestException.class)
+ .build();
private final String clientId;
private final String env;
@@ -87,9 +85,7 @@ public ApitallyClient(String clientId, String env, RequestLoggingConfig requestL
this.requestCounter = new RequestCounter();
this.requestLogger = new RequestLogger(requestLoggingConfig);
this.spanCollector =
- new SpanCollector(
- requestLoggingConfig.isEnabled()
- && requestLoggingConfig.isTracingEnabled());
+ new SpanCollector(requestLoggingConfig.isEnabled() && requestLoggingConfig.isTracingEnabled());
this.validationErrorCounter = new ValidationErrorCounter();
this.serverErrorCounter = new ServerErrorCounter();
this.consumerRegistry = new ConsumerRegistry();
@@ -128,36 +124,32 @@ private void sendStartupData() {
if (startupData == null) {
return;
}
- HttpRequest request =
- HttpRequest.newBuilder()
- .uri(getHubUrl("startup"))
- .header("Content-Type", "application/json")
- .POST(HttpRequest.BodyPublishers.ofString(startupData.toJSON()))
- .build();
- sendHubRequest(request)
- .thenAccept(
- status -> {
- if (status == HubRequestStatus.OK) {
- startupDataSent = true;
- startupData = null;
- } else if (status == HubRequestStatus.VALIDATION_ERROR) {
- startupDataSent = false;
- startupData = null;
- } else {
- startupDataSent = false;
- }
- });
+ HttpRequest request = HttpRequest.newBuilder()
+ .uri(getHubUrl("startup"))
+ .header("Content-Type", "application/json")
+ .POST(HttpRequest.BodyPublishers.ofString(startupData.toJSON()))
+ .build();
+ sendHubRequest(request).thenAccept(status -> {
+ if (status == HubRequestStatus.OK) {
+ startupDataSent = true;
+ startupData = null;
+ } else if (status == HubRequestStatus.VALIDATION_ERROR) {
+ startupDataSent = false;
+ startupData = null;
+ } else {
+ startupDataSent = false;
+ }
+ });
}
private void sendSyncData() {
- SyncData data =
- new SyncData(
- instanceLock.getInstanceUuid(),
- requestCounter.getAndResetRequests(),
- validationErrorCounter.getAndResetValidationErrors(),
- serverErrorCounter.getAndResetServerErrors(),
- consumerRegistry.getAndResetConsumers(),
- resourceMonitor.getCpuMemoryUsage());
+ SyncData data = new SyncData(
+ instanceLock.getInstanceUuid(),
+ requestCounter.getAndResetRequests(),
+ validationErrorCounter.getAndResetValidationErrors(),
+ serverErrorCounter.getAndResetServerErrors(),
+ consumerRegistry.getAndResetConsumers(),
+ resourceMonitor.getCpuMemoryUsage());
syncDataQueue.offer(data);
int i = 0;
@@ -170,12 +162,11 @@ private void sendSyncData() {
// Add random delay between retries
Thread.sleep(100 + random.nextInt(400));
}
- HttpRequest request =
- HttpRequest.newBuilder()
- .uri(getHubUrl("sync"))
- .header("Content-Type", "application/json")
- .POST(HttpRequest.BodyPublishers.ofString(payload.toJSON()))
- .build();
+ HttpRequest request = HttpRequest.newBuilder()
+ .uri(getHubUrl("sync"))
+ .header("Content-Type", "application/json")
+ .POST(HttpRequest.BodyPublishers.ofString(payload.toJSON()))
+ .build();
HubRequestStatus status = sendHubRequest(request).join();
if (status == HubRequestStatus.RETRYABLE_ERROR) {
syncDataQueue.offer(payload);
@@ -204,12 +195,11 @@ private void sendLogData() {
}
}
try (InputStream inputStream = logFile.getInputStream()) {
- HttpRequest request =
- HttpRequest.newBuilder()
- .uri(getHubUrl("log", "uuid=" + logFile.getUuid().toString()))
- .header("Content-Type", "application/octet-stream")
- .POST(HttpRequest.BodyPublishers.ofInputStream(() -> inputStream))
- .build();
+ HttpRequest request = HttpRequest.newBuilder()
+ .uri(getHubUrl("log", "uuid=" + logFile.getUuid().toString()))
+ .header("Content-Type", "application/octet-stream")
+ .POST(HttpRequest.BodyPublishers.ofInputStream(() -> inputStream))
+ .build();
HubRequestStatus status = sendHubRequest(request).join();
if (status == HubRequestStatus.PAYMENT_REQUIRED) {
requestLogger.clear();
@@ -231,63 +221,47 @@ private void sendLogData() {
}
public CompletableFuture sendHubRequest(HttpRequest request) {
- return CompletableFuture.supplyAsync(
- () -> {
+ return CompletableFuture.supplyAsync(() -> {
+ try {
+ return retryTemplate.execute(context -> {
try {
- return retryTemplate.execute(
- context -> {
- try {
- logger.debug(
- "Sending request to Apitally hub: {}",
- request.uri());
- HttpResponse response =
- httpClient.send(
- request,
- HttpResponse.BodyHandlers.ofString());
- if (response.statusCode() >= 200
- && response.statusCode() < 300) {
- return HubRequestStatus.OK;
- } else if (response.statusCode() == 402) {
- return HubRequestStatus.PAYMENT_REQUIRED;
- } else if (response.statusCode() == 404) {
- enabled = false;
- stopSync();
- requestLogger.close();
- logger.error(
- "Invalid Apitally client ID: {}", clientId);
- return HubRequestStatus.INVALID_CLIENT_ID;
- } else if (response.statusCode() == 422) {
- logger.error(
- "Received validation error from Apitally hub: {}",
- response.body());
- return HubRequestStatus.VALIDATION_ERROR;
- } else {
- throw new RetryableHubRequestException(
- "Hub request failed with status code "
- + response.statusCode());
- }
- } catch (Exception e) {
- throw new RetryableHubRequestException(
- "Hub request failed with exception: "
- + e.getMessage());
- }
- });
+ logger.debug("Sending request to Apitally hub: {}", request.uri());
+ HttpResponse response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
+ if (response.statusCode() >= 200 && response.statusCode() < 300) {
+ return HubRequestStatus.OK;
+ } else if (response.statusCode() == 402) {
+ return HubRequestStatus.PAYMENT_REQUIRED;
+ } else if (response.statusCode() == 404) {
+ enabled = false;
+ stopSync();
+ requestLogger.close();
+ logger.error("Invalid Apitally client ID: {}", clientId);
+ return HubRequestStatus.INVALID_CLIENT_ID;
+ } else if (response.statusCode() == 422) {
+ logger.error("Received validation error from Apitally hub: {}", response.body());
+ return HubRequestStatus.VALIDATION_ERROR;
+ } else {
+ throw new RetryableHubRequestException(
+ "Hub request failed with status code " + response.statusCode());
+ }
} catch (Exception e) {
- logger.error("Error sending request to Apitally hub", e);
- return HubRequestStatus.RETRYABLE_ERROR;
+ throw new RetryableHubRequestException("Hub request failed with exception: " + e.getMessage());
}
});
+ } catch (Exception e) {
+ logger.error("Error sending request to Apitally hub", e);
+ return HubRequestStatus.RETRYABLE_ERROR;
+ }
+ });
}
public void startSync() {
if (scheduler == null) {
- scheduler =
- Executors.newSingleThreadScheduledExecutor(
- r -> {
- Thread thread = new Thread(r, "apitally-sync");
- thread.setDaemon(true);
- return thread;
- });
+ scheduler = Executors.newSingleThreadScheduledExecutor(r -> {
+ Thread thread = new Thread(r, "apitally-sync");
+ thread.setDaemon(true);
+ return thread;
+ });
}
if (syncTask != null) {
@@ -295,20 +269,14 @@ public void startSync() {
}
// Start with shorter initial sync interval
- syncTask =
- scheduler.scheduleAtFixedRate(
- this::sync, 0, INITIAL_SYNC_INTERVAL_SECONDS, TimeUnit.SECONDS);
+ syncTask = scheduler.scheduleAtFixedRate(this::sync, 0, INITIAL_SYNC_INTERVAL_SECONDS, TimeUnit.SECONDS);
// Schedule a one-time task to switch to regular sync interval
scheduler.schedule(
() -> {
syncTask.cancel(false);
- syncTask =
- scheduler.scheduleAtFixedRate(
- this::sync,
- SYNC_INTERVAL_SECONDS,
- SYNC_INTERVAL_SECONDS,
- TimeUnit.SECONDS);
+ syncTask = scheduler.scheduleAtFixedRate(
+ this::sync, SYNC_INTERVAL_SECONDS, SYNC_INTERVAL_SECONDS, TimeUnit.SECONDS);
},
INITIAL_PERIOD_SECONDS,
TimeUnit.SECONDS);
diff --git a/src/main/java/io/apitally/common/ConsumerRegistry.java b/src/main/java/io/apitally/common/ConsumerRegistry.java
index 1c66360..1eb90da 100644
--- a/src/main/java/io/apitally/common/ConsumerRegistry.java
+++ b/src/main/java/io/apitally/common/ConsumerRegistry.java
@@ -56,9 +56,7 @@ public void addOrUpdateConsumer(Consumer consumer) {
}
if (hasChanges) {
- consumers.put(
- consumer.getIdentifier(),
- new Consumer(consumer.getIdentifier(), newName, newGroup));
+ consumers.put(consumer.getIdentifier(), new Consumer(consumer.getIdentifier(), newName, newGroup));
updated.add(consumer.getIdentifier());
}
}
diff --git a/src/main/java/io/apitally/common/InstanceLock.java b/src/main/java/io/apitally/common/InstanceLock.java
index 144459f..05f2a89 100644
--- a/src/main/java/io/apitally/common/InstanceLock.java
+++ b/src/main/java/io/apitally/common/InstanceLock.java
@@ -55,12 +55,8 @@ static InstanceLock create(String clientId, String env, Path lockDir) {
Path lockPath = lockDir.resolve("instance_" + appEnvHash + "_" + slot + ".lock");
FileChannel channel = null;
try {
- channel =
- FileChannel.open(
- lockPath,
- StandardOpenOption.CREATE,
- StandardOpenOption.READ,
- StandardOpenOption.WRITE);
+ channel = FileChannel.open(
+ lockPath, StandardOpenOption.CREATE, StandardOpenOption.READ, StandardOpenOption.WRITE);
FileLock lock = channel.tryLock();
if (lock == null) {
@@ -69,9 +65,9 @@ static InstanceLock create(String clientId, String env, Path lockDir) {
}
FileTime lastModified = Files.getLastModifiedTime(lockPath);
- boolean tooOld =
- Duration.between(lastModified.toInstant(), Instant.now()).getSeconds()
- > MAX_LOCK_AGE_SECONDS;
+ boolean tooOld = Duration.between(lastModified.toInstant(), Instant.now())
+ .getSeconds()
+ > MAX_LOCK_AGE_SECONDS;
String existingUuid = readChannel(channel);
UUID uuid = parseUuid(existingUuid);
@@ -120,8 +116,7 @@ private static UUID parseUuid(String s) {
}
}
- private static String getAppEnvHash(String clientId, String env)
- throws NoSuchAlgorithmException {
+ private static String getAppEnvHash(String clientId, String env) throws NoSuchAlgorithmException {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] hash = digest.digest((clientId + ":" + env).getBytes(StandardCharsets.UTF_8));
return HexFormat.of().formatHex(hash, 0, 4);
diff --git a/src/main/java/io/apitally/common/RequestCounter.java b/src/main/java/io/apitally/common/RequestCounter.java
index 3656c6b..81fad58 100644
--- a/src/main/java/io/apitally/common/RequestCounter.java
+++ b/src/main/java/io/apitally/common/RequestCounter.java
@@ -31,8 +31,7 @@ public void addRequest(
long responseTime,
long requestSize,
long responseSize) {
- String key =
- String.join("|", consumer, method.toUpperCase(), path, String.valueOf(statusCode));
+ String key = String.join("|", consumer, method.toUpperCase(), path, String.valueOf(statusCode));
// Increment request count
requestCounts.merge(key, 1, Integer::sum);
@@ -73,25 +72,21 @@ public List getAndResetRequests() {
String path = parts[2];
int statusCode = Integer.parseInt(parts[3]);
- Map responseTimeMap =
- responseTimes.getOrDefault(key, new ConcurrentHashMap<>());
- Map requestSizeMap =
- requestSizes.getOrDefault(key, new ConcurrentHashMap<>());
- Map responseSizeMap =
- responseSizes.getOrDefault(key, new ConcurrentHashMap<>());
+ Map responseTimeMap = responseTimes.getOrDefault(key, new ConcurrentHashMap<>());
+ Map requestSizeMap = requestSizes.getOrDefault(key, new ConcurrentHashMap<>());
+ Map responseSizeMap = responseSizes.getOrDefault(key, new ConcurrentHashMap<>());
- Requests item =
- new Requests(
- consumer,
- method,
- path,
- statusCode,
- entry.getValue(),
- requestSizeSums.getOrDefault(key, 0L),
- responseSizeSums.getOrDefault(key, 0L),
- responseTimeMap,
- requestSizeMap,
- responseSizeMap);
+ Requests item = new Requests(
+ consumer,
+ method,
+ path,
+ statusCode,
+ entry.getValue(),
+ requestSizeSums.getOrDefault(key, 0L),
+ responseSizeSums.getOrDefault(key, 0L),
+ responseTimeMap,
+ requestSizeMap,
+ responseSizeMap);
data.add(item);
}
diff --git a/src/main/java/io/apitally/common/RequestLogger.java b/src/main/java/io/apitally/common/RequestLogger.java
index 1d92819..c415ec3 100644
--- a/src/main/java/io/apitally/common/RequestLogger.java
+++ b/src/main/java/io/apitally/common/RequestLogger.java
@@ -36,44 +36,35 @@ public class RequestLogger {
private static final int MAX_FILE_SIZE = 1_000_000; // 1 MB (compressed)
private static final int MAX_FILES = 50;
private static final int MAX_PENDING_WRITES = 100;
- private static final byte[] BODY_TOO_LARGE =
- "".getBytes(StandardCharsets.UTF_8);
+ private static final byte[] BODY_TOO_LARGE = "".getBytes(StandardCharsets.UTF_8);
private static final byte[] BODY_MASKED = "".getBytes(StandardCharsets.UTF_8);
private static final String MASKED = "******";
- public static final List ALLOWED_CONTENT_TYPES =
- Arrays.asList("application/json", "text/plain");
- private static final Pattern JSON_CONTENT_TYPE_PATTERN =
- Pattern.compile("\\bjson\\b", Pattern.CASE_INSENSITIVE);
- private static final List EXCLUDE_PATH_PATTERNS =
- Arrays.asList(
- "/_?healthz?$",
- "/_?health[_-]?checks?$",
- "/_?heart[_-]?beats?$",
- "/ping$",
- "/ready$",
- "/live$",
- "/favicon(?:-[\\w-]+)?\\.(ico|png|svg)$",
- "/apple-touch-icon(?:-[\\w-]+)?\\.png$",
- "/robots\\.txt$",
- "/sitemap\\.xml$",
- "/manifest\\.json$",
- "/site\\.webmanifest$",
- "/service-worker\\.js$",
- "/sw\\.js$",
- "/\\.well-known/");
+ public static final List ALLOWED_CONTENT_TYPES = Arrays.asList("application/json", "text/plain");
+ private static final Pattern JSON_CONTENT_TYPE_PATTERN = Pattern.compile("\\bjson\\b", Pattern.CASE_INSENSITIVE);
+ private static final List EXCLUDE_PATH_PATTERNS = Arrays.asList(
+ "/_?healthz?$",
+ "/_?health[_-]?checks?$",
+ "/_?heart[_-]?beats?$",
+ "/ping$",
+ "/ready$",
+ "/live$",
+ "/favicon(?:-[\\w-]+)?\\.(ico|png|svg)$",
+ "/apple-touch-icon(?:-[\\w-]+)?\\.png$",
+ "/robots\\.txt$",
+ "/sitemap\\.xml$",
+ "/manifest\\.json$",
+ "/site\\.webmanifest$",
+ "/service-worker\\.js$",
+ "/sw\\.js$",
+ "/\\.well-known/");
private static final List EXCLUDE_USER_AGENT_PATTERNS =
- Arrays.asList(
- "health[-_ ]?check",
- "microsoft-azure-application-lb",
- "googlehc",
- "kube-probe");
+ Arrays.asList("health[-_ ]?check", "microsoft-azure-application-lb", "googlehc", "kube-probe");
private static final List MASK_QUERY_PARAM_PATTERNS =
Arrays.asList("auth", "api-?key", "secret", "token", "password", "pwd");
private static final List MASK_HEADER_PATTERNS =
Arrays.asList("auth", "api-?key", "secret", "token", "cookie");
private static final List MASK_BODY_FIELD_PATTERNS =
- Arrays.asList(
- "password", "pwd", "token", "secret", "auth", "card[-_ ]?number", "ccv", "ssn");
+ Arrays.asList("password", "pwd", "token", "secret", "auth", "card[-_ ]?number", "ccv", "ssn");
private static final int MAINTAIN_INTERVAL_SECONDS = 1;
private final RequestLoggingConfig config;
@@ -101,13 +92,11 @@ public RequestLogger(RequestLoggingConfig config) {
this.files = new ConcurrentLinkedDeque<>();
this.enabled = config.isEnabled();
- this.compiledPathExcludePatterns =
- compilePatterns(EXCLUDE_PATH_PATTERNS, config.getPathExcludePatterns());
+ this.compiledPathExcludePatterns = compilePatterns(EXCLUDE_PATH_PATTERNS, config.getPathExcludePatterns());
this.compiledUserAgentExcludePatterns = compilePatterns(EXCLUDE_USER_AGENT_PATTERNS, null);
this.compiledQueryParamMaskPatterns =
compilePatterns(MASK_QUERY_PARAM_PATTERNS, config.getQueryParamMaskPatterns());
- this.compiledHeaderMaskPatterns =
- compilePatterns(MASK_HEADER_PATTERNS, config.getHeaderMaskPatterns());
+ this.compiledHeaderMaskPatterns = compilePatterns(MASK_HEADER_PATTERNS, config.getHeaderMaskPatterns());
this.compiledBodyFieldMaskPatterns =
compilePatterns(MASK_BODY_FIELD_PATTERNS, config.getBodyFieldMaskPatterns());
@@ -116,8 +105,7 @@ public RequestLogger(RequestLoggingConfig config) {
}
}
- private static List compilePatterns(
- List defaultPatterns, List additionalPatterns) {
+ private static List compilePatterns(List defaultPatterns, List additionalPatterns) {
List patterns = new ArrayList<>(defaultPatterns);
if (additionalPatterns != null) {
patterns.addAll(additionalPatterns);
@@ -163,16 +151,14 @@ public void logRequest(
if (shouldExcludePath(path) || shouldExcludeUserAgent(userAgent)) {
return;
}
- if (config.getCallbacks() != null
- && config.getCallbacks().shouldExclude(request, response)) {
+ if (config.getCallbacks() != null && config.getCallbacks().shouldExclude(request, response)) {
return;
}
if (!config.isRequestBodyIncluded() || !hasSupportedContentType(request.getHeaders())) {
request.setBody(null);
}
- if (!config.isResponseBodyIncluded()
- || !hasSupportedContentType(response.getHeaders())) {
+ if (!config.isResponseBodyIncluded() || !hasSupportedContentType(response.getHeaders())) {
response.setBody(null);
}
@@ -190,8 +176,7 @@ public void logRequest(
traceId = null;
}
- RequestLogItem item =
- new RequestLogItem(request, response, exceptionDto, logs, spans, traceId);
+ RequestLogItem item = new RequestLogItem(request, response, exceptionDto, logs, spans, traceId);
pendingWrites.add(item);
if (pendingWrites.size() > MAX_PENDING_WRITES) {
@@ -264,13 +249,12 @@ && hasJsonContentType(response.getHeaders())) {
} else if (query != null) {
query = maskQueryParams(query);
}
- request.setUrl(
- new java.net.URL(
- url.getProtocol(),
- url.getHost(),
- url.getPort(),
- url.getPath() + (query != null ? "?" + query : ""))
- .toString());
+ request.setUrl(new java.net.URL(
+ url.getProtocol(),
+ url.getHost(),
+ url.getPort(),
+ url.getPath() + (query != null ? "?" + query : ""))
+ .toString());
} catch (MalformedURLException e) {
// Keep original URL if malformed
}
@@ -292,10 +276,8 @@ public void writeToFile() throws IOException {
ObjectNode itemNode = objectMapper.createObjectNode();
itemNode.put("uuid", item.getUuid());
- itemNode.set(
- "request", skipEmptyValues(objectMapper.valueToTree(item.getRequest())));
- itemNode.set(
- "response", skipEmptyValues(objectMapper.valueToTree(item.getResponse())));
+ itemNode.set("request", skipEmptyValues(objectMapper.valueToTree(item.getRequest())));
+ itemNode.set("response", skipEmptyValues(objectMapper.valueToTree(item.getResponse())));
if (item.getException() != null) {
itemNode.set("exception", objectMapper.valueToTree(item.getException()));
}
@@ -375,17 +357,13 @@ public void close() {
private void startMaintenance() {
if (scheduler == null) {
- scheduler =
- Executors.newSingleThreadScheduledExecutor(
- r -> {
- Thread thread = new Thread(r, "apitally-request-logger");
- thread.setDaemon(true);
- return thread;
- });
+ scheduler = Executors.newSingleThreadScheduledExecutor(r -> {
+ Thread thread = new Thread(r, "apitally-request-logger");
+ thread.setDaemon(true);
+ return thread;
+ });
}
- maintainTask =
- scheduler.scheduleAtFixedRate(
- this::maintain, 0, MAINTAIN_INTERVAL_SECONDS, TimeUnit.SECONDS);
+ maintainTask = scheduler.scheduleAtFixedRate(this::maintain, 0, MAINTAIN_INTERVAL_SECONDS, TimeUnit.SECONDS);
}
private void stopMaintenance() {
@@ -410,7 +388,8 @@ private boolean shouldExcludePath(String path) {
if (path == null || path.isEmpty()) {
return false;
}
- return compiledPathExcludePatterns.stream().anyMatch(p -> p.matcher(path).find());
+ return compiledPathExcludePatterns.stream()
+ .anyMatch(p -> p.matcher(path).find());
}
private boolean shouldExcludeUserAgent(String userAgent) {
@@ -421,7 +400,8 @@ private boolean shouldExcludeUserAgent(String userAgent) {
}
private boolean shouldMaskQueryParam(String name) {
- return compiledQueryParamMaskPatterns.stream().anyMatch(p -> p.matcher(name).find());
+ return compiledQueryParamMaskPatterns.stream()
+ .anyMatch(p -> p.matcher(name).find());
}
private boolean shouldMaskHeader(String name) {
@@ -429,7 +409,8 @@ private boolean shouldMaskHeader(String name) {
}
private boolean shouldMaskBodyField(String name) {
- return compiledBodyFieldMaskPatterns.stream().anyMatch(p -> p.matcher(name).find());
+ return compiledBodyFieldMaskPatterns.stream()
+ .anyMatch(p -> p.matcher(name).find());
}
private String maskQueryParams(String query) {
@@ -453,13 +434,8 @@ private String maskQueryParams(String query) {
private List maskHeaders(Header[] headers) {
return Arrays.stream(headers)
- .map(
- header ->
- new Header(
- header.getName(),
- shouldMaskHeader(header.getName())
- ? MASKED
- : header.getValue()))
+ .map(header ->
+ new Header(header.getName(), shouldMaskHeader(header.getName()) ? MASKED : header.getValue()))
.collect(Collectors.toList());
}
@@ -477,17 +453,13 @@ private byte[] maskJsonBody(byte[] body) {
private void maskJsonNode(JsonNode node) {
if (node.isObject()) {
ObjectNode objectNode = (ObjectNode) node;
- objectNode
- .fields()
- .forEachRemaining(
- entry -> {
- if (entry.getValue().isTextual()
- && shouldMaskBodyField(entry.getKey())) {
- objectNode.put(entry.getKey(), MASKED);
- } else {
- maskJsonNode(entry.getValue());
- }
- });
+ objectNode.fields().forEachRemaining(entry -> {
+ if (entry.getValue().isTextual() && shouldMaskBodyField(entry.getKey())) {
+ objectNode.put(entry.getKey(), MASKED);
+ } else {
+ maskJsonNode(entry.getValue());
+ }
+ });
} else if (node.isArray()) {
node.forEach(this::maskJsonNode);
}
@@ -495,13 +467,13 @@ && shouldMaskBodyField(entry.getKey())) {
private boolean hasSupportedContentType(Header[] headers) {
String contentType = findHeader(headers, "content-type");
- return contentType != null
- && ALLOWED_CONTENT_TYPES.stream().anyMatch(contentType::startsWith);
+ return contentType != null && ALLOWED_CONTENT_TYPES.stream().anyMatch(contentType::startsWith);
}
private boolean hasJsonContentType(Header[] headers) {
String contentType = findHeader(headers, "content-type");
- return contentType != null && JSON_CONTENT_TYPE_PATTERN.matcher(contentType).find();
+ return contentType != null
+ && JSON_CONTENT_TYPE_PATTERN.matcher(contentType).find();
}
private String findHeader(Header[] headers, String name) {
@@ -514,21 +486,18 @@ private String findHeader(Header[] headers, String name) {
private ObjectNode skipEmptyValues(ObjectNode node) {
ObjectNode result = objectMapper.createObjectNode();
- node.fields()
- .forEachRemaining(
- entry -> {
- if (entry.getValue().isNull()) {
- return;
- }
- if (entry.getValue().isArray() && entry.getValue().size() == 0) {
- return;
- }
- if (entry.getValue().isTextual()
- && entry.getValue().asText().isEmpty()) {
- return;
- }
- result.set(entry.getKey(), entry.getValue());
- });
+ node.fields().forEachRemaining(entry -> {
+ if (entry.getValue().isNull()) {
+ return;
+ }
+ if (entry.getValue().isArray() && entry.getValue().size() == 0) {
+ return;
+ }
+ if (entry.getValue().isTextual() && entry.getValue().asText().isEmpty()) {
+ return;
+ }
+ result.set(entry.getKey(), entry.getValue());
+ });
return result;
}
}
diff --git a/src/main/java/io/apitally/common/ResourceMonitor.java b/src/main/java/io/apitally/common/ResourceMonitor.java
index 0cec7a0..7f812c6 100644
--- a/src/main/java/io/apitally/common/ResourceMonitor.java
+++ b/src/main/java/io/apitally/common/ResourceMonitor.java
@@ -21,8 +21,7 @@ public ResourceUsage getCpuMemoryUsage() {
return null;
}
- double cpuPercent =
- 100.0 * currentProcess.getProcessCpuLoadBetweenTicks(previousSnapshot);
+ double cpuPercent = 100.0 * currentProcess.getProcessCpuLoadBetweenTicks(previousSnapshot);
long memoryRss = currentProcess.getResidentSetSize();
previousSnapshot = currentProcess;
diff --git a/src/main/java/io/apitally/common/ServerErrorCounter.java b/src/main/java/io/apitally/common/ServerErrorCounter.java
index 04fcd6a..2006087 100644
--- a/src/main/java/io/apitally/common/ServerErrorCounter.java
+++ b/src/main/java/io/apitally/common/ServerErrorCounter.java
@@ -20,14 +20,13 @@ public ServerErrorCounter() {
}
public void addServerError(String consumer, String method, String path, Exception exception) {
- ServerError error =
- new ServerError(
- consumer,
- method,
- path,
- exception.getClass().getSimpleName(),
- exception.getMessage(),
- exception.getStackTrace());
+ ServerError error = new ServerError(
+ consumer,
+ method,
+ path,
+ exception.getClass().getSimpleName(),
+ exception.getMessage(),
+ exception.getStackTrace());
String key = getKey(error);
errorDetails.putIfAbsent(key, error);
errorCounts.merge(key, 1, Integer::sum);
@@ -35,36 +34,33 @@ public void addServerError(String consumer, String method, String path, Exceptio
public List getAndResetServerErrors() {
List data = new ArrayList<>();
- errorCounts.forEach(
- (key, count) -> {
- ServerError error = errorDetails.get(key);
- if (error != null) {
- data.add(
- new ServerErrors(
- error.getConsumer(),
- error.getMethod(),
- error.getPath(),
- error.getType(),
- error.getMessage(),
- error.getStackTrace(),
- count));
- }
- });
+ errorCounts.forEach((key, count) -> {
+ ServerError error = errorDetails.get(key);
+ if (error != null) {
+ data.add(new ServerErrors(
+ error.getConsumer(),
+ error.getMethod(),
+ error.getPath(),
+ error.getType(),
+ error.getMessage(),
+ error.getStackTrace(),
+ count));
+ }
+ });
errorCounts.clear();
errorDetails.clear();
return data;
}
private String getKey(ServerError error) {
- String hashInput =
- String.join(
- "|",
- error.getConsumer() != null ? error.getConsumer() : "",
- error.getMethod(),
- error.getPath(),
- error.getType(),
- error.getMessage(),
- error.getStackTraceString());
+ String hashInput = String.join(
+ "|",
+ error.getConsumer() != null ? error.getConsumer() : "",
+ error.getMethod(),
+ error.getPath(),
+ error.getType(),
+ error.getMessage(),
+ error.getStackTraceString());
try {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] digest = md.digest(hashInput.getBytes());
diff --git a/src/main/java/io/apitally/common/SpanCollector.java b/src/main/java/io/apitally/common/SpanCollector.java
index 01a562f..af0dd21 100644
--- a/src/main/java/io/apitally/common/SpanCollector.java
+++ b/src/main/java/io/apitally/common/SpanCollector.java
@@ -23,8 +23,7 @@ public class SpanCollector implements SpanProcessor {
private final boolean enabled;
private volatile Tracer tracer;
private final Map> includedSpanIds = new ConcurrentHashMap<>();
- private final Map> collectedSpans =
- new ConcurrentHashMap<>();
+ private final Map> collectedSpans = new ConcurrentHashMap<>();
public SpanCollector(boolean enabled) {
this.enabled = enabled;
@@ -121,10 +120,9 @@ private SpanData serializeSpan(ReadableSpan span) {
SpanContext parentSpanContext = spanData.getParentSpanContext();
String parentSpanId = parentSpanContext.isValid() ? parentSpanContext.getSpanId() : null;
- String status =
- spanData.getStatus().getStatusCode() != StatusCode.UNSET
- ? spanData.getStatus().getStatusCode().name()
- : null;
+ String status = spanData.getStatus().getStatusCode() != StatusCode.UNSET
+ ? spanData.getStatus().getStatusCode().name()
+ : null;
Map attributes = null;
if (!spanData.getAttributes().isEmpty()) {
diff --git a/src/main/java/io/apitally/common/TempGzipFile.java b/src/main/java/io/apitally/common/TempGzipFile.java
index 3385604..38fbf34 100644
--- a/src/main/java/io/apitally/common/TempGzipFile.java
+++ b/src/main/java/io/apitally/common/TempGzipFile.java
@@ -75,8 +75,7 @@ public InputStream getInputStream() throws IOException {
public List readDecompressedLines() throws IOException {
try (InputStream inputStream = getInputStream();
GZIPInputStream gzipInputStream = new GZIPInputStream(inputStream);
- BufferedReader reader =
- new BufferedReader(new InputStreamReader(gzipInputStream))) {
+ BufferedReader reader = new BufferedReader(new InputStreamReader(gzipInputStream))) {
return reader.lines().collect(Collectors.toList());
}
}
diff --git a/src/main/java/io/apitally/common/ValidationErrorCounter.java b/src/main/java/io/apitally/common/ValidationErrorCounter.java
index a29f16c..fab0632 100644
--- a/src/main/java/io/apitally/common/ValidationErrorCounter.java
+++ b/src/main/java/io/apitally/common/ValidationErrorCounter.java
@@ -19,10 +19,8 @@ public ValidationErrorCounter() {
this.errorDetails = new ConcurrentHashMap<>();
}
- public void addValidationError(
- String consumer, String method, String path, String loc, String msg, String type) {
- ValidationError validationError =
- new ValidationError(consumer, method, path, loc, msg, type);
+ public void addValidationError(String consumer, String method, String path, String loc, String msg, String type) {
+ ValidationError validationError = new ValidationError(consumer, method, path, loc, msg, type);
String key = getKey(validationError);
errorDetails.putIfAbsent(key, validationError);
errorCounts.merge(key, 1, Integer::sum);
@@ -30,36 +28,33 @@ public void addValidationError(
public List getAndResetValidationErrors() {
List data = new ArrayList<>();
- errorCounts.forEach(
- (key, count) -> {
- ValidationError error = errorDetails.get(key);
- if (error != null) {
- data.add(
- new ValidationErrors(
- error.getConsumer(),
- error.getMethod(),
- error.getPath(),
- error.getLoc(),
- error.getMsg(),
- error.getType(),
- count));
- }
- });
+ errorCounts.forEach((key, count) -> {
+ ValidationError error = errorDetails.get(key);
+ if (error != null) {
+ data.add(new ValidationErrors(
+ error.getConsumer(),
+ error.getMethod(),
+ error.getPath(),
+ error.getLoc(),
+ error.getMsg(),
+ error.getType(),
+ count));
+ }
+ });
errorCounts.clear();
errorDetails.clear();
return data;
}
private String getKey(ValidationError error) {
- String hashInput =
- String.join(
- "|",
- error.getConsumer() != null ? error.getConsumer() : "",
- error.getMethod().toUpperCase(),
- error.getPath(),
- String.join(".", error.getLoc()),
- error.getMsg().trim(),
- error.getType());
+ String hashInput = String.join(
+ "|",
+ error.getConsumer() != null ? error.getConsumer() : "",
+ error.getMethod().toUpperCase(),
+ error.getPath(),
+ String.join(".", error.getLoc()),
+ error.getMsg().trim(),
+ error.getType());
try {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] digest = md.digest(hashInput.getBytes());
diff --git a/src/main/java/io/apitally/common/dto/ServerError.java b/src/main/java/io/apitally/common/dto/ServerError.java
index 86d8201..5cd1964 100644
--- a/src/main/java/io/apitally/common/dto/ServerError.java
+++ b/src/main/java/io/apitally/common/dto/ServerError.java
@@ -18,12 +18,7 @@ public class ServerError {
private final String stackTraceString;
public ServerError(
- String consumer,
- String method,
- String path,
- String type,
- String message,
- StackTraceElement[] stackTrace) {
+ String consumer, String method, String path, String type, String message, StackTraceElement[] stackTrace) {
this.consumer = consumer;
this.method = method;
this.path = path;
diff --git a/src/main/java/io/apitally/common/dto/StartupData.java b/src/main/java/io/apitally/common/dto/StartupData.java
index a094130..6710dcd 100644
--- a/src/main/java/io/apitally/common/dto/StartupData.java
+++ b/src/main/java/io/apitally/common/dto/StartupData.java
@@ -12,8 +12,7 @@ public class StartupData extends BaseDto {
private final Map versions;
private final String client;
- public StartupData(
- UUID instanceUuid, List paths, Map versions, String client) {
+ public StartupData(UUID instanceUuid, List paths, Map versions, String client) {
this.instanceUuid = instanceUuid;
this.messageUuid = UUID.randomUUID();
this.paths = paths;
diff --git a/src/main/java/io/apitally/common/dto/ValidationError.java b/src/main/java/io/apitally/common/dto/ValidationError.java
index 0de8de0..c95ad69 100644
--- a/src/main/java/io/apitally/common/dto/ValidationError.java
+++ b/src/main/java/io/apitally/common/dto/ValidationError.java
@@ -11,8 +11,7 @@ public class ValidationError extends BaseDto {
private final String msg;
private final String type;
- public ValidationError(
- String consumer, String method, String path, String loc, String msg, String type) {
+ public ValidationError(String consumer, String method, String path, String loc, String msg, String type) {
this.consumer = consumer;
this.method = method;
this.path = path;
diff --git a/src/main/java/io/apitally/common/dto/ValidationErrors.java b/src/main/java/io/apitally/common/dto/ValidationErrors.java
index 48052b7..666efca 100644
--- a/src/main/java/io/apitally/common/dto/ValidationErrors.java
+++ b/src/main/java/io/apitally/common/dto/ValidationErrors.java
@@ -6,13 +6,7 @@ public class ValidationErrors extends ValidationError {
private final int errorCount;
public ValidationErrors(
- String consumer,
- String method,
- String path,
- String loc,
- String msg,
- String type,
- int errorCount) {
+ String consumer, String method, String path, String loc, String msg, String type, int errorCount) {
super(consumer, method, path, loc, msg, type);
this.errorCount = errorCount;
}
diff --git a/src/main/java/io/apitally/spring/ApitallyAutoConfiguration.java b/src/main/java/io/apitally/spring/ApitallyAutoConfiguration.java
index 93c84a7..b9eff9a 100644
--- a/src/main/java/io/apitally/spring/ApitallyAutoConfiguration.java
+++ b/src/main/java/io/apitally/spring/ApitallyAutoConfiguration.java
@@ -17,13 +17,9 @@
public class ApitallyAutoConfiguration {
@Bean
public ApitallyClient apitallyClient(
- ApitallyProperties properties,
- RequestMappingHandlerMapping requestMappingHandlerMapping) {
+ ApitallyProperties properties, RequestMappingHandlerMapping requestMappingHandlerMapping) {
ApitallyClient client =
- new ApitallyClient(
- properties.getClientId(),
- properties.getEnv(),
- properties.getRequestLogging());
+ new ApitallyClient(properties.getClientId(), properties.getEnv(), properties.getRequestLogging());
List paths = ApitallyUtils.getPaths(requestMappingHandlerMapping);
Map versions = ApitallyUtils.getVersions();
client.setStartupData(paths, versions, "java:spring");
@@ -42,10 +38,8 @@ public ApitallyClient apitallyClient(
}
@Bean
- public FilterRegistrationBean apitallyFilterRegistration(
- ApitallyClient apitallyClient) {
- final FilterRegistrationBean registrationBean =
- new FilterRegistrationBean<>();
+ public FilterRegistrationBean apitallyFilterRegistration(ApitallyClient apitallyClient) {
+ final FilterRegistrationBean registrationBean = new FilterRegistrationBean<>();
registrationBean.setFilter(new ApitallyFilter(apitallyClient));
registrationBean.setOrder(Ordered.LOWEST_PRECEDENCE - 10);
return registrationBean;
diff --git a/src/main/java/io/apitally/spring/ApitallyFilter.java b/src/main/java/io/apitally/spring/ApitallyFilter.java
index dd04a42..5c1b860 100644
--- a/src/main/java/io/apitally/spring/ApitallyFilter.java
+++ b/src/main/java/io/apitally/spring/ApitallyFilter.java
@@ -59,16 +59,12 @@ protected void doFilterInternal(
final boolean requestLoggingEnabled = requestLoggingConfig.isEnabled();
String requestContentType = request.getContentType();
- final boolean shouldCacheRequest =
- requestLoggingEnabled
- && requestLoggingConfig.isRequestBodyIncluded()
- && requestContentType != null
- && RequestLogger.ALLOWED_CONTENT_TYPES.stream()
- .anyMatch(
- allowedContentType ->
- requestContentType.startsWith(allowedContentType));
- final boolean shouldCacheResponse =
- requestLoggingEnabled && requestLoggingConfig.isResponseBodyIncluded();
+ final boolean shouldCacheRequest = requestLoggingEnabled
+ && requestLoggingConfig.isRequestBodyIncluded()
+ && requestContentType != null
+ && RequestLogger.ALLOWED_CONTENT_TYPES.stream()
+ .anyMatch(allowedContentType -> requestContentType.startsWith(allowedContentType));
+ final boolean shouldCacheResponse = requestLoggingEnabled && requestLoggingConfig.isResponseBodyIncluded();
ContentCachingRequestWrapper cachingRequest =
shouldCacheRequest ? new ContentCachingRequestWrapper(request) : null;
ContentCachingResponseWrapper cachingResponse =
@@ -76,10 +72,8 @@ protected void doFilterInternal(
CountingResponseWrapper countingResponse =
cachingResponse == null ? new CountingResponseWrapper(response) : null;
- final boolean shouldCaptureLogs =
- requestLoggingEnabled && requestLoggingConfig.isLogCaptureEnabled();
- final boolean shouldCaptureSpans =
- requestLoggingEnabled && requestLoggingConfig.isTracingEnabled();
+ final boolean shouldCaptureLogs = requestLoggingEnabled && requestLoggingConfig.isLogCaptureEnabled();
+ final boolean shouldCaptureSpans = requestLoggingEnabled && requestLoggingConfig.isTracingEnabled();
Exception exception = null;
final long startTime = System.currentTimeMillis();
@@ -88,8 +82,7 @@ protected void doFilterInternal(
LogAppender.startCapture();
}
- final SpanCollector.SpanHandle spanHandle =
- shouldCaptureSpans ? client.spanCollector.startCollection() : null;
+ final SpanCollector.SpanHandle spanHandle = shouldCaptureSpans ? client.spanCollector.startCollection() : null;
try {
filterChain.doFilter(
@@ -101,17 +94,13 @@ protected void doFilterInternal(
} finally {
try {
final long responseTimeInMillis = System.currentTimeMillis() - startTime;
- final String path =
- (String)
- request.getAttribute(
- HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE);
+ final String path = (String) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE);
// End span collection and get spans
List spans = null;
String traceId = null;
if (spanHandle != null) {
- Object handler =
- request.getAttribute(HandlerMapping.BEST_MATCHING_HANDLER_ATTRIBUTE);
+ Object handler = request.getAttribute(HandlerMapping.BEST_MATCHING_HANDLER_ATTRIBUTE);
if (handler instanceof HandlerMethod handlerMethod) {
String controllerName = handlerMethod.getBeanType().getSimpleName();
String methodName = handlerMethod.getMethod().getName();
@@ -122,52 +111,39 @@ protected void doFilterInternal(
}
// End log capture and get logs
- final List capturedLogs =
- shouldCaptureLogs ? LogAppender.endCapture() : null;
+ final List capturedLogs = shouldCaptureLogs ? LogAppender.endCapture() : null;
// Get request and response body
final byte[] requestBody =
- cachingRequest != null
- ? cachingRequest.getContentAsByteArray()
- : new byte[0];
+ cachingRequest != null ? cachingRequest.getContentAsByteArray() : new byte[0];
final byte[] responseBody =
- cachingResponse != null
- ? cachingResponse.getContentAsByteArray()
- : new byte[0];
+ cachingResponse != null ? cachingResponse.getContentAsByteArray() : new byte[0];
if (cachingResponse != null) {
cachingResponse.copyBodyToResponse();
}
// Register consumer and get consumer identifier
- final Consumer consumer =
- ConsumerRegistry.consumerFromObject(
- request.getAttribute("apitallyConsumer"));
+ final Consumer consumer = ConsumerRegistry.consumerFromObject(request.getAttribute("apitallyConsumer"));
client.consumerRegistry.addOrUpdateConsumer(consumer);
final String consumerIdentifier = consumer != null ? consumer.getIdentifier() : "";
// Get captured exception
Object capturedException = request.getAttribute("apitallyCapturedException");
- if (exception == null
- && capturedException != null
- && capturedException instanceof Exception) {
+ if (exception == null && capturedException != null && capturedException instanceof Exception) {
exception = (Exception) capturedException;
}
// Add request to counter
final long requestContentLength = request.getContentLengthLong();
- final long requestSize =
- requestContentLength >= 0
- ? requestContentLength
- : cachingRequest != null ? requestBody.length : -1;
+ final long requestSize = requestContentLength >= 0
+ ? requestContentLength
+ : cachingRequest != null ? requestBody.length : -1;
final long responseContentLength = getResponseContentLength(response);
- final long responseSize =
- responseContentLength >= 0
- ? responseContentLength
- : cachingResponse != null
- ? responseBody.length
- : countingResponse != null
- ? countingResponse.getByteCount()
- : -1;
+ final long responseSize = responseContentLength >= 0
+ ? responseContentLength
+ : cachingResponse != null
+ ? responseBody.length
+ : countingResponse != null ? countingResponse.getByteCount() : -1;
client.requestCounter.addRequest(
consumerIdentifier,
request.getMethod(),
@@ -179,21 +155,13 @@ protected void doFilterInternal(
// Log request
if (client.requestLogger.isEnabled()) {
- final Header[] requestHeaders =
- Collections.list(request.getHeaderNames()).stream()
- .flatMap(
- name ->
- Collections.list(request.getHeaders(name))
- .stream()
- .map(value -> new Header(name, value)))
- .toArray(Header[]::new);
- final Header[] responseHeaders =
- response.getHeaderNames().stream()
- .flatMap(
- name ->
- response.getHeaders(name).stream()
- .map(value -> new Header(name, value)))
- .toArray(Header[]::new);
+ final Header[] requestHeaders = Collections.list(request.getHeaderNames()).stream()
+ .flatMap(name -> Collections.list(request.getHeaders(name)).stream()
+ .map(value -> new Header(name, value)))
+ .toArray(Header[]::new);
+ final Header[] responseHeaders = response.getHeaderNames().stream()
+ .flatMap(name -> response.getHeaders(name).stream().map(value -> new Header(name, value)))
+ .toArray(Header[]::new);
client.requestLogger.logRequest(
new Request(
@@ -248,8 +216,7 @@ protected void doFilterInternal(
// Add server error to counter
if (response.getStatus() == 500 && exception != null) {
- client.serverErrorCounter.addServerError(
- consumerIdentifier, request.getMethod(), path, exception);
+ client.serverErrorCounter.addServerError(consumerIdentifier, request.getMethod(), path, exception);
}
} catch (Exception e) {
logger.error("Error in Apitally filter", e);
diff --git a/src/main/java/io/apitally/spring/ApitallyProperties.java b/src/main/java/io/apitally/spring/ApitallyProperties.java
index 6b813ad..1b04c33 100644
--- a/src/main/java/io/apitally/spring/ApitallyProperties.java
+++ b/src/main/java/io/apitally/spring/ApitallyProperties.java
@@ -20,8 +20,7 @@ public class ApitallyProperties {
@Pattern(
regexp = "^[\\w-]{1,32}$",
- message =
- "Env must be 1-32 characters long and contain only word characters and hyphens")
+ message = "Env must be 1-32 characters long and contain only word characters and hyphens")
private String env = "default";
private RequestLoggingConfig requestLogging = new RequestLoggingConfig();
@@ -63,9 +62,8 @@ public void setCallbacksClass(String callbacksClass) {
try {
Class> clazz = Class.forName(callbacksClass);
if (RequestLoggingCallbacks.class.isAssignableFrom(clazz)) {
- setCallbacks(
- (RequestLoggingCallbacks)
- clazz.getDeclaredConstructor().newInstance());
+ setCallbacks((RequestLoggingCallbacks)
+ clazz.getDeclaredConstructor().newInstance());
}
} catch (ReflectiveOperationException e) {
logger.error("Failed to initialize request logging callbacks", e);
diff --git a/src/main/java/io/apitally/spring/ApitallySpanCollector.java b/src/main/java/io/apitally/spring/ApitallySpanCollector.java
index 00bda4c..7cf948e 100644
--- a/src/main/java/io/apitally/spring/ApitallySpanCollector.java
+++ b/src/main/java/io/apitally/spring/ApitallySpanCollector.java
@@ -32,8 +32,10 @@ public void setDelegate(SpanCollector spanCollector) {
private void initializeTracer(SpanCollector spanCollector) {
try {
- SdkTracerProvider provider = SdkTracerProvider.builder().addSpanProcessor(this).build();
- OpenTelemetrySdk sdk = OpenTelemetrySdk.builder().setTracerProvider(provider).build();
+ SdkTracerProvider provider =
+ SdkTracerProvider.builder().addSpanProcessor(this).build();
+ OpenTelemetrySdk sdk =
+ OpenTelemetrySdk.builder().setTracerProvider(provider).build();
Tracer tracer;
try {
GlobalOpenTelemetry.set(sdk);
diff --git a/src/main/java/io/apitally/spring/ApitallyUtils.java b/src/main/java/io/apitally/spring/ApitallyUtils.java
index 01616c2..51ad91c 100644
--- a/src/main/java/io/apitally/spring/ApitallyUtils.java
+++ b/src/main/java/io/apitally/spring/ApitallyUtils.java
@@ -15,42 +15,24 @@
public final class ApitallyUtils {
public static List getPaths(RequestMappingHandlerMapping requestMappingHandlerMapping) {
return requestMappingHandlerMapping.getHandlerMethods().entrySet().stream()
- .flatMap(
- entry -> {
- RequestMappingInfo mappingInfo = entry.getKey();
- return mappingInfo.getMethodsCondition().getMethods().stream()
- .filter(
- method ->
- method != RequestMethod.OPTIONS
- && method != RequestMethod.HEAD)
- .flatMap(
- method -> {
- PathPatternsRequestCondition pathPatterns =
- mappingInfo.getPathPatternsCondition();
- if (pathPatterns != null
- && pathPatterns.getPatterns() != null) {
- return pathPatterns.getPatterns().stream()
- .map(
- pattern ->
- new Path(
- method.name(),
- pattern
- .getPatternString()));
- }
- PatternsRequestCondition patterns =
- mappingInfo.getPatternsCondition();
- if (patterns != null
- && patterns.getPatterns() != null) {
- return patterns.getPatterns().stream()
- .map(
- pattern ->
- new Path(
- method.name(),
- pattern));
- }
- return List.of().stream();
- });
- })
+ .flatMap(entry -> {
+ RequestMappingInfo mappingInfo = entry.getKey();
+ return mappingInfo.getMethodsCondition().getMethods().stream()
+ .filter(method -> method != RequestMethod.OPTIONS && method != RequestMethod.HEAD)
+ .flatMap(method -> {
+ PathPatternsRequestCondition pathPatterns = mappingInfo.getPathPatternsCondition();
+ if (pathPatterns != null && pathPatterns.getPatterns() != null) {
+ return pathPatterns.getPatterns().stream()
+ .map(pattern -> new Path(method.name(), pattern.getPatternString()));
+ }
+ PatternsRequestCondition patterns = mappingInfo.getPatternsCondition();
+ if (patterns != null && patterns.getPatterns() != null) {
+ return patterns.getPatterns().stream()
+ .map(pattern -> new Path(method.name(), pattern));
+ }
+ return List.of().stream();
+ });
+ })
.collect(Collectors.toList());
}
diff --git a/src/test/java/io/apitally/common/ApitallyClientTest.java b/src/test/java/io/apitally/common/ApitallyClientTest.java
index 6973cfe..e6b93b6 100644
--- a/src/test/java/io/apitally/common/ApitallyClientTest.java
+++ b/src/test/java/io/apitally/common/ApitallyClientTest.java
@@ -31,9 +31,7 @@ class ApitallyClientTest {
void setUp() {
RequestLoggingConfig requestLoggingConfig = new RequestLoggingConfig();
requestLoggingConfig.setEnabled(true);
- client =
- new ApitallyClient(
- "00000000-0000-0000-0000-000000000000", "test", requestLoggingConfig);
+ client = new ApitallyClient("00000000-0000-0000-0000-000000000000", "test", requestLoggingConfig);
clientSpy = spy(client);
when(clientSpy.sendHubRequest(any(HttpRequest.class)))
.thenReturn(CompletableFuture.completedFuture(ApitallyClient.HubRequestStatus.OK));
@@ -46,27 +44,22 @@ void tearDown() {
@Test
void testSync() {
- Header[] requestHeaders =
- new Header[] {
- new Header("Content-Type", "application/json"),
- new Header("User-Agent", "test-client"),
- };
- Header[] responseHeaders =
- new Header[] {
- new Header("Content-Type", "application/json"),
- };
- Request request =
- new Request(
- System.currentTimeMillis() / 1000.0,
- "tester",
- "GET",
- "/items",
- "http://test/items",
- requestHeaders,
- 0L,
- new byte[0]);
- Response response =
- new Response(200, 0.123, responseHeaders, 13L, "{\"items\": []}".getBytes());
+ Header[] requestHeaders = new Header[] {
+ new Header("Content-Type", "application/json"), new Header("User-Agent", "test-client"),
+ };
+ Header[] responseHeaders = new Header[] {
+ new Header("Content-Type", "application/json"),
+ };
+ Request request = new Request(
+ System.currentTimeMillis() / 1000.0,
+ "tester",
+ "GET",
+ "/items",
+ "http://test/items",
+ requestHeaders,
+ 0L,
+ new byte[0]);
+ Response response = new Response(200, 0.123, responseHeaders, 13L, "{\"items\": []}".getBytes());
client.requestLogger.logRequest(request, response, null, null, null, null);
client.requestLogger.maintain();
@@ -79,8 +72,7 @@ void testSync() {
ArgumentCaptor requestCaptor = ArgumentCaptor.forClass(HttpRequest.class);
verify(clientSpy, timeout(5000).times(3)).sendHubRequest(requestCaptor.capture());
List capturedRequests = requestCaptor.getAllValues();
- assertTrue(
- capturedRequests.stream().anyMatch(r -> r.uri().toString().contains("/startup")));
+ assertTrue(capturedRequests.stream().anyMatch(r -> r.uri().toString().contains("/startup")));
assertTrue(capturedRequests.stream().anyMatch(r -> r.uri().toString().contains("/sync")));
assertTrue(capturedRequests.stream().anyMatch(r -> r.uri().toString().contains("/log")));
diff --git a/src/test/java/io/apitally/common/InstanceLockTest.java b/src/test/java/io/apitally/common/InstanceLockTest.java
index 6e0ded3..b8eebd8 100644
--- a/src/test/java/io/apitally/common/InstanceLockTest.java
+++ b/src/test/java/io/apitally/common/InstanceLockTest.java
@@ -32,14 +32,12 @@ void setUp() throws IOException {
void tearDown() throws IOException {
if (tempDir != null && Files.exists(tempDir)) {
try (var paths = Files.walk(tempDir)) {
- paths.sorted(Comparator.reverseOrder())
- .forEach(
- path -> {
- try {
- Files.deleteIfExists(path);
- } catch (IOException ignored) {
- }
- });
+ paths.sorted(Comparator.reverseOrder()).forEach(path -> {
+ try {
+ Files.deleteIfExists(path);
+ } catch (IOException ignored) {
+ }
+ });
}
}
}
diff --git a/src/test/java/io/apitally/common/RequestLoggerTest.java b/src/test/java/io/apitally/common/RequestLoggerTest.java
index adbf2ff..8eee9b0 100644
--- a/src/test/java/io/apitally/common/RequestLoggerTest.java
+++ b/src/test/java/io/apitally/common/RequestLoggerTest.java
@@ -46,55 +46,29 @@ void tearDown() {
@Test
void testEndToEnd() {
- Header[] requestHeaders =
- new Header[] {
- new Header("User-Agent", "Test"),
- };
- Header[] responseHeaders =
- new Header[] {
- new Header("Content-Type", "application/json"),
- };
- Request request =
- new Request(
- System.currentTimeMillis() / 1000.0,
- "tester",
- "GET",
- "/items",
- "http://test/items",
- requestHeaders,
- 0L,
- new byte[0]);
- Response response =
- new Response(200, 0.123, responseHeaders, 13L, "{\"items\": []}".getBytes());
+ Header[] requestHeaders = new Header[] {
+ new Header("User-Agent", "Test"),
+ };
+ Header[] responseHeaders = new Header[] {
+ new Header("Content-Type", "application/json"),
+ };
+ Request request = new Request(
+ System.currentTimeMillis() / 1000.0,
+ "tester",
+ "GET",
+ "/items",
+ "http://test/items",
+ requestHeaders,
+ 0L,
+ new byte[0]);
+ Response response = new Response(200, 0.123, responseHeaders, 13L, "{\"items\": []}".getBytes());
Exception exception = new Exception("test");
List logs = new ArrayList<>();
- logs.add(
- new LogRecord(
- System.currentTimeMillis() / 1000.0,
- "test.Logger",
- "INFO",
- "Test log message"));
+ logs.add(new LogRecord(System.currentTimeMillis() / 1000.0, "test.Logger", "INFO", "Test log message"));
List spans = new ArrayList<>();
- spans.add(
- new SpanData(
- "a1b2c3d4e5f6a7b8",
- null,
- "root",
- "INTERNAL",
- 1000000L,
- 2000000L,
- null,
- null));
- spans.add(
- new SpanData(
- "b2c3d4e5f6a7b8c9",
- "a1b2c3d4e5f6a7b8",
- "child",
- "INTERNAL",
- 1100000L,
- 1900000L,
- "OK",
- null));
+ spans.add(new SpanData("a1b2c3d4e5f6a7b8", null, "root", "INTERNAL", 1000000L, 2000000L, null, null));
+ spans.add(new SpanData(
+ "b2c3d4e5f6a7b8c9", "a1b2c3d4e5f6a7b8", "child", "INTERNAL", 1100000L, 1900000L, "OK", null));
String traceId = "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6";
requestLogger.logRequest(request, response, exception, logs, spans, traceId);
@@ -110,8 +84,8 @@ void testEndToEnd() {
assertEquals(0.123, jsonNode.get("response").get("responseTime").asDouble(), 0.001);
assertEquals(
"{\"items\":[]}",
- new String(
- Base64.getDecoder().decode(jsonNode.get("response").get("body").asText())));
+ new String(Base64.getDecoder()
+ .decode(jsonNode.get("response").get("body").asText())));
JsonNode requestHeadersNode = jsonNode.get("request").get("headers");
assertTrue(requestHeadersNode.isArray());
@@ -138,7 +112,8 @@ void testEndToEnd() {
assertEquals("INFO", logsNode.get(0).get("level").asText());
assertEquals("Test log message", logsNode.get(0).get("message").asText());
- assertEquals("a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6", jsonNode.get("trace_id").asText());
+ assertEquals(
+ "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6", jsonNode.get("trace_id").asText());
JsonNode spansNode = jsonNode.get("spans");
assertTrue(spansNode.isArray());
assertEquals(2, spansNode.size());
@@ -162,26 +137,22 @@ void testExcludeBasedOnOptions() {
requestLoggingConfig.setResponseBodyIncluded(false);
requestLogger = new RequestLogger(requestLoggingConfig);
- Header[] requestHeaders =
- new Header[] {
- new Header("Content-Type", "application/json"),
- };
- Header[] responseHeaders =
- new Header[] {
- new Header("Content-Type", "application/json"),
- };
- Request request =
- new Request(
- System.currentTimeMillis() / 1000.0,
- "tester",
- "POST",
- "/items",
- "http://test/items?token=my-secret-token",
- requestHeaders,
- 16L,
- "{\"key\": \"value\"}".getBytes());
- Response response =
- new Response(200, 0.123, responseHeaders, 16L, "{\"key\": \"value\"}".getBytes());
+ Header[] requestHeaders = new Header[] {
+ new Header("Content-Type", "application/json"),
+ };
+ Header[] responseHeaders = new Header[] {
+ new Header("Content-Type", "application/json"),
+ };
+ Request request = new Request(
+ System.currentTimeMillis() / 1000.0,
+ "tester",
+ "POST",
+ "/items",
+ "http://test/items?token=my-secret-token",
+ requestHeaders,
+ 16L,
+ "{\"key\": \"value\"}".getBytes());
+ Response response = new Response(200, 0.123, responseHeaders, 16L, "{\"key\": \"value\"}".getBytes());
requestLogger.logRequest(request, response, null, null, null, null);
@@ -197,28 +168,24 @@ void testExcludeBasedOnOptions() {
@Test
void testExcludeBasedOnCallback() {
requestLoggingConfig.setEnabled(true);
- requestLoggingConfig.setCallbacks(
- new RequestLoggingCallbacks() {
- @Override
- public boolean shouldExclude(Request request, Response response) {
- return request.getConsumer() != null
- && request.getConsumer().contains("tester");
- }
- });
+ requestLoggingConfig.setCallbacks(new RequestLoggingCallbacks() {
+ @Override
+ public boolean shouldExclude(Request request, Response response) {
+ return request.getConsumer() != null && request.getConsumer().contains("tester");
+ }
+ });
requestLogger = new RequestLogger(requestLoggingConfig);
- Request request =
- new Request(
- System.currentTimeMillis() / 1000.0,
- "tester",
- "GET",
- "/items",
- "http://test/items",
- new Header[0],
- 0L,
- new byte[0]);
- Response response =
- new Response(200, 0.123, new Header[0], 13L, "{\"items\": []}".getBytes());
+ Request request = new Request(
+ System.currentTimeMillis() / 1000.0,
+ "tester",
+ "GET",
+ "/items",
+ "http://test/items",
+ new Header[0],
+ 0L,
+ new byte[0]);
+ Response response = new Response(200, 0.123, new Header[0], 13L, "{\"items\": []}".getBytes());
requestLogger.logRequest(request, response, null, null, null, null);
@@ -228,18 +195,16 @@ public boolean shouldExclude(Request request, Response response) {
@Test
void testExcludeBasedOnPath() {
- Request request =
- new Request(
- System.currentTimeMillis() / 1000.0,
- null,
- "GET",
- "/healthz",
- "http://test/healthz",
- new Header[0],
- 0L,
- new byte[0]);
- Response response =
- new Response(200, 0.123, new Header[0], 17L, "{\"healthy\": true}".getBytes());
+ Request request = new Request(
+ System.currentTimeMillis() / 1000.0,
+ null,
+ "GET",
+ "/healthz",
+ "http://test/healthz",
+ new Header[0],
+ 0L,
+ new byte[0]);
+ Response response = new Response(200, 0.123, new Header[0], 17L, "{\"healthy\": true}".getBytes());
requestLogger.logRequest(request, response, null, null, null, null);
@@ -249,20 +214,11 @@ void testExcludeBasedOnPath() {
@Test
void testExcludeBasedOnUserAgent() {
- Header[] requestHeaders =
- new Header[] {
- new Header("User-Agent", "ELB-HealthChecker/2.0"),
- };
- Request request =
- new Request(
- System.currentTimeMillis() / 1000.0,
- null,
- "GET",
- "/",
- "http://test/",
- requestHeaders,
- 0L,
- new byte[0]);
+ Header[] requestHeaders = new Header[] {
+ new Header("User-Agent", "ELB-HealthChecker/2.0"),
+ };
+ Request request = new Request(
+ System.currentTimeMillis() / 1000.0, null, "GET", "/", "http://test/", requestHeaders, 0L, new byte[0]);
Response response = new Response(200, 0, new Header[0], 0L, new byte[0]);
requestLogger.logRequest(request, response, null, null, null, null);
@@ -278,22 +234,20 @@ void testMaskHeaders() {
requestLoggingConfig.setHeaderMaskPatterns(List.of("(?i)test"));
requestLogger = new RequestLogger(requestLoggingConfig);
- Header[] requestHeaders =
- new Header[] {
- new Header("Accept", "text/plain"),
- new Header("Authorization", "Bearer 123456"),
- new Header("X-Test", "123456"),
- };
- Request request =
- new Request(
- System.currentTimeMillis() / 1000.0,
- null,
- "GET",
- "/test",
- "http://localhost:8000/test?foo=bar",
- requestHeaders,
- 0L,
- new byte[0]);
+ Header[] requestHeaders = new Header[] {
+ new Header("Accept", "text/plain"),
+ new Header("Authorization", "Bearer 123456"),
+ new Header("X-Test", "123456"),
+ };
+ Request request = new Request(
+ System.currentTimeMillis() / 1000.0,
+ null,
+ "GET",
+ "/test",
+ "http://localhost:8000/test?foo=bar",
+ requestHeaders,
+ 0L,
+ new byte[0]);
Response response = new Response(200, 0, new Header[0], 0L, new byte[0]);
requestLogger.logRequest(request, response, null, null, null, null);
@@ -320,16 +274,15 @@ void testMaskQueryParams() {
requestLoggingConfig.setQueryParamMaskPatterns(List.of("(?i)test"));
requestLogger = new RequestLogger(requestLoggingConfig);
- Request request =
- new Request(
- System.currentTimeMillis() / 1000.0,
- null,
- "GET",
- "/test",
- "http://localhost/test?secret=123456&test=123456&other=abcdef",
- new Header[0],
- 0L,
- new byte[0]);
+ Request request = new Request(
+ System.currentTimeMillis() / 1000.0,
+ null,
+ "GET",
+ "/test",
+ "http://localhost/test?secret=123456&test=123456&other=abcdef",
+ new Header[0],
+ 0L,
+ new byte[0]);
Response response = new Response(200, 0, new Header[0], 0L, new byte[0]);
requestLogger.logRequest(request, response, null, null, null, null);
@@ -347,60 +300,50 @@ void testMaskBodyUsingCallback() {
requestLoggingConfig.setEnabled(true);
requestLoggingConfig.setRequestBodyIncluded(true);
requestLoggingConfig.setResponseBodyIncluded(true);
- requestLoggingConfig.setCallbacks(
- new RequestLoggingCallbacks() {
- @Override
- public byte[] maskRequestBody(Request request) {
- if ("/test".equals(request.getPath())) {
- return null;
- }
- return request.getBody();
- }
-
- @Override
- public byte[] maskResponseBody(Request request, Response response) {
- if ("/test".equals(request.getPath())) {
- return null;
- }
- return response.getBody();
- }
- });
+ requestLoggingConfig.setCallbacks(new RequestLoggingCallbacks() {
+ @Override
+ public byte[] maskRequestBody(Request request) {
+ if ("/test".equals(request.getPath())) {
+ return null;
+ }
+ return request.getBody();
+ }
+
+ @Override
+ public byte[] maskResponseBody(Request request, Response response) {
+ if ("/test".equals(request.getPath())) {
+ return null;
+ }
+ return response.getBody();
+ }
+ });
requestLogger = new RequestLogger(requestLoggingConfig);
- Header[] requestHeaders =
- new Header[] {
- new Header("Content-Type", "application/json"),
- };
- Request request =
- new Request(
- System.currentTimeMillis() / 1000.0,
- null,
- "GET",
- "/test",
- "http://test/test",
- requestHeaders,
- 4L,
- "test".getBytes());
- Response response =
- new Response(
- 200,
- 0,
- new Header[] {new Header("Content-Type", "application/json")},
- 4L,
- "test".getBytes());
+ Header[] requestHeaders = new Header[] {
+ new Header("Content-Type", "application/json"),
+ };
+ Request request = new Request(
+ System.currentTimeMillis() / 1000.0,
+ null,
+ "GET",
+ "/test",
+ "http://test/test",
+ requestHeaders,
+ 4L,
+ "test".getBytes());
+ Response response = new Response(
+ 200, 0, new Header[] {new Header("Content-Type", "application/json")}, 4L, "test".getBytes());
requestLogger.logRequest(request, response, null, null, null, null);
JsonNode[] items = getLoggedItems(requestLogger);
assertEquals(1, items.length);
- String requestBody =
- new String(
- Base64.getDecoder().decode(items[0].get("request").get("body").asText()));
+ String requestBody = new String(
+ Base64.getDecoder().decode(items[0].get("request").get("body").asText()));
assertEquals("", requestBody);
- String responseBody =
- new String(
- Base64.getDecoder().decode(items[0].get("response").get("body").asText()));
+ String responseBody = new String(
+ Base64.getDecoder().decode(items[0].get("response").get("body").asText()));
assertEquals("", responseBody);
}
@@ -417,27 +360,24 @@ void testMaskBodyFields() {
String responseBodyJson =
"{\"status\":\"success\",\"secret\":\"response_secret\",\"data\":{\"pwd\":\"response_pwd\"}}";
- Header[] requestHeaders =
- new Header[] {
- new Header("Content-Type", "application/json"),
- };
- Request request =
- new Request(
- System.currentTimeMillis() / 1000.0,
- null,
- "POST",
- "/test",
- "http://localhost:8000/test?foo=bar",
- requestHeaders,
- (long) requestBodyJson.getBytes().length,
- requestBodyJson.getBytes());
- Response response =
- new Response(
- 200,
- 0.1,
- new Header[] {new Header("Content-Type", "application/json")},
- (long) responseBodyJson.getBytes().length,
- responseBodyJson.getBytes());
+ Header[] requestHeaders = new Header[] {
+ new Header("Content-Type", "application/json"),
+ };
+ Request request = new Request(
+ System.currentTimeMillis() / 1000.0,
+ null,
+ "POST",
+ "/test",
+ "http://localhost:8000/test?foo=bar",
+ requestHeaders,
+ (long) requestBodyJson.getBytes().length,
+ requestBodyJson.getBytes());
+ Response response = new Response(
+ 200,
+ 0.1,
+ new Header[] {new Header("Content-Type", "application/json")},
+ (long) responseBodyJson.getBytes().length,
+ responseBodyJson.getBytes());
requestLogger.logRequest(request, response, null, null, null, null);
diff --git a/src/test/java/io/apitally/common/SpanCollectorTest.java b/src/test/java/io/apitally/common/SpanCollectorTest.java
index 95a08d4..c49ab2a 100644
--- a/src/test/java/io/apitally/common/SpanCollectorTest.java
+++ b/src/test/java/io/apitally/common/SpanCollectorTest.java
@@ -92,16 +92,17 @@ void testCollectorWithChildSpans() {
assertTrue(spanNames.contains("child1"));
assertTrue(spanNames.contains("child2"));
- SpanData rootSpan =
- spans.stream()
- .filter(s -> s.getName().equals("TestController.getTest"))
- .findFirst()
- .orElse(null);
+ SpanData rootSpan = spans.stream()
+ .filter(s -> s.getName().equals("TestController.getTest"))
+ .findFirst()
+ .orElse(null);
assertNotNull(rootSpan);
assertNull(rootSpan.getParentSpanId());
- SpanData childSpan =
- spans.stream().filter(s -> s.getName().equals("child1")).findFirst().orElse(null);
+ SpanData childSpan = spans.stream()
+ .filter(s -> s.getName().equals("child1"))
+ .findFirst()
+ .orElse(null);
assertNotNull(childSpan);
assertEquals(rootSpan.getSpanId(), childSpan.getParentSpanId());
}
@@ -144,8 +145,10 @@ void testSpanDataSerialization() {
List spans = handle.end();
assertNotNull(spans);
- SpanData testSpan =
- spans.stream().filter(s -> s.getName().equals("testSpan")).findFirst().orElse(null);
+ SpanData testSpan = spans.stream()
+ .filter(s -> s.getName().equals("testSpan"))
+ .findFirst()
+ .orElse(null);
assertNotNull(testSpan);
assertEquals(16, testSpan.getSpanId().length());
assertEquals("INTERNAL", testSpan.getKind());
diff --git a/src/test/java/io/apitally/spring/ApitallyFilterTest.java b/src/test/java/io/apitally/spring/ApitallyFilterTest.java
index c596f14..fd40f0e 100644
--- a/src/test/java/io/apitally/spring/ApitallyFilterTest.java
+++ b/src/test/java/io/apitally/spring/ApitallyFilterTest.java
@@ -39,9 +39,7 @@
import org.springframework.test.context.ContextConfiguration;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
-@SpringBootTest(
- classes = TestApplication.class,
- webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
+@SpringBootTest(classes = TestApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ContextConfiguration(classes = {ApitallyFilterTest.TestConfig.class})
class ApitallyFilterTest {
@@ -54,19 +52,14 @@ static class TestConfig {
public ApitallyClient apitallyClient(ApitallyProperties properties) {
LogAppender.register();
ApitallyClient client =
- new ApitallyClient(
- properties.getClientId(),
- properties.getEnv(),
- properties.getRequestLogging());
+ new ApitallyClient(properties.getClientId(), properties.getEnv(), properties.getRequestLogging());
ApitallySpanCollector.getInstance().setDelegate(client.spanCollector);
return client;
}
@Bean
- public FilterRegistrationBean filterRegistration(
- ApitallyClient apitallyClient) {
- final FilterRegistrationBean registrationBean =
- new FilterRegistrationBean<>();
+ public FilterRegistrationBean filterRegistration(ApitallyClient apitallyClient) {
+ final FilterRegistrationBean registrationBean = new FilterRegistrationBean<>();
registrationBean.setFilter(new ApitallyFilter(apitallyClient));
registrationBean.setOrder(Ordered.LOWEST_PRECEDENCE - 10);
return registrationBean;
@@ -78,11 +71,14 @@ public ApitallyExceptionResolver apitallyExceptionResolver() {
}
}
- @Autowired private TestRestTemplate restTemplate;
+ @Autowired
+ private TestRestTemplate restTemplate;
- @Autowired private ApitallyClient apitallyClient;
+ @Autowired
+ private ApitallyClient apitallyClient;
- @Autowired private RequestMappingHandlerMapping requestMappingHandlerMapping;
+ @Autowired
+ private RequestMappingHandlerMapping requestMappingHandlerMapping;
@BeforeEach
void setUp() {
@@ -117,40 +113,28 @@ void testRequestCounter() {
List requests = apitallyClient.requestCounter.getAndResetRequests();
assertEquals(4, requests.size(), "4 requests counted");
- assertTrue(
- requests.stream()
- .anyMatch(
- r ->
- r.getMethod().equals("GET")
- && r.getPath().equals("/items")
- && r.getStatusCode() == 200
- && r.getRequestCount() == 1
- && r.getResponseSizeSum() > 0));
- assertTrue(
- requests.stream()
- .anyMatch(
- r ->
- r.getMethod().equals("GET")
- && r.getPath().equals("/items/{id}")
- && r.getStatusCode() == 200
- && r.getRequestCount() == 2));
- assertTrue(
- requests.stream()
- .anyMatch(
- r ->
- r.getMethod().equals("GET")
- && r.getPath().equals("/items/{id}")
- && r.getStatusCode() == 400
- && r.getRequestCount() == 1));
- assertTrue(
- requests.stream()
- .anyMatch(
- r ->
- r.getMethod().equals("GET")
- && r.getPath().equals("/throw")
- && r.getStatusCode() == 500
- && r.getRequestCount() == 1
- && r.getResponseSizeSum() == 0));
+ assertTrue(requests.stream()
+ .anyMatch(r -> r.getMethod().equals("GET")
+ && r.getPath().equals("/items")
+ && r.getStatusCode() == 200
+ && r.getRequestCount() == 1
+ && r.getResponseSizeSum() > 0));
+ assertTrue(requests.stream()
+ .anyMatch(r -> r.getMethod().equals("GET")
+ && r.getPath().equals("/items/{id}")
+ && r.getStatusCode() == 200
+ && r.getRequestCount() == 2));
+ assertTrue(requests.stream()
+ .anyMatch(r -> r.getMethod().equals("GET")
+ && r.getPath().equals("/items/{id}")
+ && r.getStatusCode() == 400
+ && r.getRequestCount() == 1));
+ assertTrue(requests.stream()
+ .anyMatch(r -> r.getMethod().equals("GET")
+ && r.getPath().equals("/throw")
+ && r.getStatusCode() == 500
+ && r.getRequestCount() == 1
+ && r.getResponseSizeSum() == 0));
requests = apitallyClient.requestCounter.getAndResetRequests();
assertEquals(0, requests.size(), "No requests counted after reset");
@@ -174,36 +158,26 @@ void testValidationErrorCounter() {
delay(100);
- List validationErrors =
- apitallyClient.validationErrorCounter.getAndResetValidationErrors();
+ List validationErrors = apitallyClient.validationErrorCounter.getAndResetValidationErrors();
assertEquals(3, validationErrors.size());
- assertTrue(
- validationErrors.stream()
- .anyMatch(
- e ->
- e.getMethod().equals("POST")
- && e.getPath().equals("/items")
- && e.getLoc().equals("testItem.name")
- && e.getType().equals("Size")
- && e.getErrorCount() == 1));
- assertTrue(
- validationErrors.stream()
- .anyMatch(
- e ->
- e.getMethod().equals("GET")
- && e.getPath().equals("/items")
- && e.getLoc().equals("getItems.name")
- && e.getType().equals("Size")
- && e.getErrorCount() == 1));
- assertTrue(
- validationErrors.stream()
- .anyMatch(
- e ->
- e.getMethod().equals("GET")
- && e.getPath().equals("/items/{id}")
- && e.getLoc().equals("getItem.id")
- && e.getType().equals("Min")
- && e.getErrorCount() == 1));
+ assertTrue(validationErrors.stream()
+ .anyMatch(e -> e.getMethod().equals("POST")
+ && e.getPath().equals("/items")
+ && e.getLoc().equals("testItem.name")
+ && e.getType().equals("Size")
+ && e.getErrorCount() == 1));
+ assertTrue(validationErrors.stream()
+ .anyMatch(e -> e.getMethod().equals("GET")
+ && e.getPath().equals("/items")
+ && e.getLoc().equals("getItems.name")
+ && e.getType().equals("Size")
+ && e.getErrorCount() == 1));
+ assertTrue(validationErrors.stream()
+ .anyMatch(e -> e.getMethod().equals("GET")
+ && e.getPath().equals("/items/{id}")
+ && e.getLoc().equals("getItem.id")
+ && e.getType().equals("Min")
+ && e.getErrorCount() == 1));
validationErrors = apitallyClient.validationErrorCounter.getAndResetValidationErrors();
assertEquals(0, validationErrors.size());
@@ -216,17 +190,13 @@ void testServerErrorCounter() {
delay(100);
- List serverErrors =
- apitallyClient.serverErrorCounter.getAndResetServerErrors();
+ List serverErrors = apitallyClient.serverErrorCounter.getAndResetServerErrors();
assertEquals(1, serverErrors.size());
- assertTrue(
- serverErrors.stream()
- .anyMatch(
- e ->
- e.getType().equals("TestException")
- && e.getMessage().equals("test")
- && e.getStackTraceString().length() > 100
- && e.getErrorCount() == 1));
+ assertTrue(serverErrors.stream()
+ .anyMatch(e -> e.getType().equals("TestException")
+ && e.getMessage().equals("test")
+ && e.getStackTraceString().length() > 100
+ && e.getErrorCount() == 1));
serverErrors = apitallyClient.serverErrorCounter.getAndResetServerErrors();
assertEquals(0, serverErrors.size());
@@ -254,32 +224,16 @@ void testConsumerRegistry() {
void testGetPaths() {
List paths = ApitallyUtils.getPaths(requestMappingHandlerMapping);
assertEquals(6, paths.size());
- assertTrue(
- paths.stream()
- .anyMatch(
- p -> p.getMethod().equals("GET") && p.getPath().equals("/items")));
- assertTrue(
- paths.stream()
- .anyMatch(
- p ->
- p.getMethod().equals("GET")
- && p.getPath().equals("/items/{id}")));
- assertTrue(
- paths.stream()
- .anyMatch(
- p -> p.getMethod().equals("POST") && p.getPath().equals("/items")));
- assertTrue(
- paths.stream()
- .anyMatch(
- p ->
- p.getMethod().equals("PUT")
- && p.getPath().equals("/items/{id}")));
- assertTrue(
- paths.stream()
- .anyMatch(
- p ->
- p.getMethod().equals("DELETE")
- && p.getPath().equals("/items/{id}")));
+ assertTrue(paths.stream()
+ .anyMatch(p -> p.getMethod().equals("GET") && p.getPath().equals("/items")));
+ assertTrue(paths.stream()
+ .anyMatch(p -> p.getMethod().equals("GET") && p.getPath().equals("/items/{id}")));
+ assertTrue(paths.stream()
+ .anyMatch(p -> p.getMethod().equals("POST") && p.getPath().equals("/items")));
+ assertTrue(paths.stream()
+ .anyMatch(p -> p.getMethod().equals("PUT") && p.getPath().equals("/items/{id}")));
+ assertTrue(paths.stream()
+ .anyMatch(p -> p.getMethod().equals("DELETE") && p.getPath().equals("/items/{id}")));
}
@Test
@@ -317,9 +271,8 @@ void testRequestLogger() {
assertEquals("GET", firstItem.get("request").get("method").asText());
assertTrue(firstItem.get("request").get("url").asText().contains("/items"));
assertEquals(200, firstItem.get("response").get("statusCode").asInt());
- String responseBody =
- new String(
- Base64.getDecoder().decode(firstItem.get("response").get("body").asText()));
+ String responseBody = new String(
+ Base64.getDecoder().decode(firstItem.get("response").get("body").asText()));
assertTrue(responseBody.contains("alice"));
// Verify application logs were captured
@@ -332,17 +285,15 @@ void testRequestLogger() {
assertTrue(firstItem.has("spans"));
assertTrue(firstItem.get("spans").isArray());
assertTrue(firstItem.get("spans").size() >= 2); // root span + child span
- assertTrue(
- StreamSupport.stream(firstItem.get("spans").spliterator(), false)
- .anyMatch(span -> span.get("name").asText().equals("fetchItems")));
+ assertTrue(StreamSupport.stream(firstItem.get("spans").spliterator(), false)
+ .anyMatch(span -> span.get("name").asText().equals("fetchItems")));
// Verify POST request logging with request body
JsonNode secondItem = items[1];
assertEquals("POST", secondItem.get("request").get("method").asText());
assertTrue(secondItem.get("request").get("url").asText().contains("/items"));
- String requestBody =
- new String(
- Base64.getDecoder().decode(secondItem.get("request").get("body").asText()));
+ String requestBody = new String(
+ Base64.getDecoder().decode(secondItem.get("request").get("body").asText()));
assertTrue(requestBody.contains("bob"));
}
diff --git a/src/test/java/io/apitally/spring/app/TestController.java b/src/test/java/io/apitally/spring/app/TestController.java
index 017e0b1..9f936ba 100644
--- a/src/test/java/io/apitally/spring/app/TestController.java
+++ b/src/test/java/io/apitally/spring/app/TestController.java
@@ -35,8 +35,7 @@ public class TestController {
@GetMapping("/items")
public List getItems(
- HttpServletRequest request,
- @RequestParam(required = false) @Size(min = 2, max = 10) String name) {
+ HttpServletRequest request, @RequestParam(required = false) @Size(min = 2, max = 10) String name) {
logger.info("Getting items with filter: {}", name != null ? name : "none");
ApitallyConsumer consumer = new ApitallyConsumer("tester", "Tester", "Test Group");
@@ -66,8 +65,7 @@ public TestItem getItem(@PathVariable @Min(1) Integer id) {
@PutMapping("/items/{id}")
@ResponseStatus(HttpStatus.NO_CONTENT)
- public void updateItem(
- @Valid @RequestBody TestItem newItem, @PathVariable @Min(1) Integer id) {}
+ public void updateItem(@Valid @RequestBody TestItem newItem, @PathVariable @Min(1) Integer id) {}
@DeleteMapping(value = "/items/{id}")
@ResponseStatus(HttpStatus.NO_CONTENT)
@@ -80,10 +78,8 @@ public String getError() {
@ExceptionHandler({ConstraintViolationException.class})
@ResponseStatus(HttpStatus.BAD_REQUEST)
- private ResponseEntity