diff --git a/packages/java/examples/OwlTestApp/src/main/java/com/readme/example/CustomUserDataCollectorConfig.java b/packages/java/examples/OwlTestApp/src/main/java/com/readme/example/CustomUserDataCollectorConfig.java
index aee161660..f971870b9 100644
--- a/packages/java/examples/OwlTestApp/src/main/java/com/readme/example/CustomUserDataCollectorConfig.java
+++ b/packages/java/examples/OwlTestApp/src/main/java/com/readme/example/CustomUserDataCollectorConfig.java
@@ -1,6 +1,5 @@
package com.readme.example;
-import com.readme.dataextraction.UserDataCollector;
import org.springframework.context.annotation.Configuration;
/**
diff --git a/packages/java/readme-metrics-spring-boot-starter/pom.xml b/packages/java/readme-metrics-spring-boot-starter/pom.xml
index 377871aff..ba743b364 100644
--- a/packages/java/readme-metrics-spring-boot-starter/pom.xml
+++ b/packages/java/readme-metrics-spring-boot-starter/pom.xml
@@ -32,7 +32,7 @@
com.readme
- readme-metrics
+ metrics-core
${readme-metrics.version}
diff --git a/packages/java/readme-metrics-spring-boot-starter/src/main/java/com/readme/starter/config/DataCollectionAutoConfiguration.java b/packages/java/readme-metrics-spring-boot-starter/src/main/java/com/readme/starter/config/DataCollectionAutoConfiguration.java
index 9c26311a3..f09f97ab6 100644
--- a/packages/java/readme-metrics-spring-boot-starter/src/main/java/com/readme/starter/config/DataCollectionAutoConfiguration.java
+++ b/packages/java/readme-metrics-spring-boot-starter/src/main/java/com/readme/starter/config/DataCollectionAutoConfiguration.java
@@ -1,15 +1,18 @@
package com.readme.starter.config;
-import com.readme.dataextraction.RequestDataCollector;
-import com.readme.dataextraction.UserDataCollector;
-import com.readme.dataextraction.UserDataExtractor;
+import com.readme.config.CoreConfig;
+
+import com.readme.dataextraction.payload.RequestDataCollector;
+import com.readme.dataextraction.user.UserDataCollector;
+import com.readme.dataextraction.user.UserDataExtractor;
+import com.readme.datatransfer.DataSender;
+import com.readme.datatransfer.HttpDataSender;
import com.readme.starter.datacollection.DataCollectionFilter;
import com.readme.starter.datacollection.ServletDataPayloadAdapter;
import com.readme.starter.datacollection.userinfo.ServletUserDataCollector;
import lombok.AllArgsConstructor;
-import lombok.extern.log4j.Log4j;
import lombok.extern.slf4j.Slf4j;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import okhttp3.OkHttpClient;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
@@ -34,6 +37,8 @@
@Slf4j
public class DataCollectionAutoConfiguration {
+ private ReadmeConfigurationProperties readmeProperties;
+
@Bean
public FilterRegistrationBean metricsFilter(
RequestDataCollector requestDataCollector,
@@ -52,4 +57,15 @@ public UserDataCollector userDataCollector(UserDataPr
log.info("readme-metrics: Creating of default user data collector");
return new ServletUserDataCollector(userDataProperties, extractionService);
}
+
+ @Bean
+ public DataSender dataSender() {
+ String readmeApiKey = readmeProperties.getReadmeApiKey();
+ CoreConfig coreConfig = CoreConfig.builder()
+ .readmeAPIKey(readmeApiKey)
+ .build();
+ OkHttpClient okHttpClient = new OkHttpClient();
+
+ return new HttpDataSender(okHttpClient, coreConfig);
+ }
}
diff --git a/packages/java/readme-metrics-spring-boot-starter/src/main/java/com/readme/starter/datacollection/DataCollectionFilter.java b/packages/java/readme-metrics-spring-boot-starter/src/main/java/com/readme/starter/datacollection/DataCollectionFilter.java
index 85a8f5afd..0adfcb69e 100644
--- a/packages/java/readme-metrics-spring-boot-starter/src/main/java/com/readme/starter/datacollection/DataCollectionFilter.java
+++ b/packages/java/readme-metrics-spring-boot-starter/src/main/java/com/readme/starter/datacollection/DataCollectionFilter.java
@@ -1,20 +1,18 @@
package com.readme.starter.datacollection;
-import com.readme.dataextraction.RequestDataCollector;
-import com.readme.dataextraction.UserDataCollector;
-import com.readme.domain.UserData;
+
+import com.readme.dataextraction.payload.RequestDataCollector;
+import com.readme.dataextraction.user.UserData;
+import com.readme.dataextraction.user.UserDataCollector;
import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
-import org.springframework.util.StreamUtils;
import org.springframework.web.util.ContentCachingRequestWrapper;
import org.springframework.web.util.ContentCachingResponseWrapper;
-
import java.io.IOException;
-import static org.springframework.http.HttpMethod.GET;
import static org.springframework.http.HttpMethod.OPTIONS;
@@ -43,7 +41,7 @@ public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain
} else {
//TODO: Handle case if SDK user configured getting request user data from body, but GET req doesn't have it
//TODO: Validate user data. Collect request data only if user data is valid ?
-
+ //TODO: Does it make sense to collect everything except body before chain execution?....
chain.doFilter(request, response);
ServletDataPayloadAdapter payload =
new ServletDataPayloadAdapter(request, response);
diff --git a/packages/java/readme-metrics-spring-boot-starter/src/main/java/com/readme/starter/datacollection/ServletRequestDataCollector.java b/packages/java/readme-metrics-spring-boot-starter/src/main/java/com/readme/starter/datacollection/ServletRequestDataCollector.java
index 07f9def30..6a351f797 100644
--- a/packages/java/readme-metrics-spring-boot-starter/src/main/java/com/readme/starter/datacollection/ServletRequestDataCollector.java
+++ b/packages/java/readme-metrics-spring-boot-starter/src/main/java/com/readme/starter/datacollection/ServletRequestDataCollector.java
@@ -1,24 +1,39 @@
package com.readme.starter.datacollection;
-import com.readme.dataextraction.RequestDataCollector;
-import com.readme.domain.UserData;
-import com.readme.starter.config.ReadmeConfigurationProperties;
+
+import com.readme.dataextraction.payload.ApiKeyMasker;
+import com.readme.dataextraction.payload.PayloadData;
+import com.readme.dataextraction.payload.RequestDataCollector;
+import com.readme.dataextraction.user.UserData;
+import com.readme.datatransfer.DataSender;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
+import java.util.UUID;
+
+import static com.readme.dataextraction.payload.ApiKeyMasker.*;
+
@Slf4j
@AllArgsConstructor
@Component
public class ServletRequestDataCollector implements RequestDataCollector {
- private ReadmeConfigurationProperties readmeProperties;
+ private DataSender dataSender;
@Override
public void collect(ServletDataPayloadAdapter dataPayload, UserData userData) {
- String readmeAPIKey = readmeProperties.getReadmeApiKey();
+ String maskedApiKey = mask(userData.getApiKey());
+ PayloadData payloadData = PayloadData.builder()
+ .apiKey(maskedApiKey)
+ .email(userData.getEmail())
+ .label(userData.getLabel())
+ .logId(UUID.randomUUID())
+ .requestBody(dataPayload.getRequestBody())
+ .build();
- log.info(">>>>>>>> Sending data to the server with key {}", readmeAPIKey);
+ dataSender.send(payloadData);
+ log.info(">>>>>>>> Sending data to the server...");
log.info(">>>>>>>> and user data: {}", userData);
}
}
diff --git a/packages/java/readme-metrics-spring-boot-starter/src/main/java/com/readme/starter/datacollection/userinfo/ServletUserDataCollector.java b/packages/java/readme-metrics-spring-boot-starter/src/main/java/com/readme/starter/datacollection/userinfo/ServletUserDataCollector.java
index 3f1ef68f5..64bde0c7d 100644
--- a/packages/java/readme-metrics-spring-boot-starter/src/main/java/com/readme/starter/datacollection/userinfo/ServletUserDataCollector.java
+++ b/packages/java/readme-metrics-spring-boot-starter/src/main/java/com/readme/starter/datacollection/userinfo/ServletUserDataCollector.java
@@ -1,16 +1,14 @@
package com.readme.starter.datacollection.userinfo;
import com.readme.config.FieldMapping;
-import com.readme.dataextraction.UserDataCollector;
-import com.readme.dataextraction.UserDataExtractor;
-import com.readme.dataextraction.UserDataSource;
-import com.readme.domain.UserData;
+import com.readme.dataextraction.user.UserData;
+import com.readme.dataextraction.user.UserDataCollector;
+import com.readme.dataextraction.user.UserDataExtractor;
+import com.readme.dataextraction.user.UserDataSource;
import com.readme.starter.config.UserDataProperties;
import com.readme.starter.datacollection.ServletDataPayloadAdapter;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
-import org.springframework.stereotype.Component;
/**
* Responsible for selecting the appropriate {@link UserDataExtractor}
diff --git a/packages/java/readme-metrics-spring-boot-starter/src/main/java/com/readme/starter/datacollection/userinfo/ServletUserDataExtractor.java b/packages/java/readme-metrics-spring-boot-starter/src/main/java/com/readme/starter/datacollection/userinfo/ServletUserDataExtractor.java
index cffa75e1c..82824c2c6 100644
--- a/packages/java/readme-metrics-spring-boot-starter/src/main/java/com/readme/starter/datacollection/userinfo/ServletUserDataExtractor.java
+++ b/packages/java/readme-metrics-spring-boot-starter/src/main/java/com/readme/starter/datacollection/userinfo/ServletUserDataExtractor.java
@@ -3,7 +3,7 @@
import com.auth0.jwt.interfaces.DecodedJWT;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
-import com.readme.dataextraction.UserDataExtractor;
+import com.readme.dataextraction.user.UserDataExtractor;
import com.readme.starter.datacollection.ServletDataPayloadAdapter;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
diff --git a/packages/java/readme-metrics-spring-boot-starter/src/test/java/com/readme/starter/datacollection/DataCollectionFilterTest.java b/packages/java/readme-metrics-spring-boot-starter/src/test/java/com/readme/starter/datacollection/DataCollectionFilterTest.java
index 5a2bc8cee..2855533f5 100644
--- a/packages/java/readme-metrics-spring-boot-starter/src/test/java/com/readme/starter/datacollection/DataCollectionFilterTest.java
+++ b/packages/java/readme-metrics-spring-boot-starter/src/test/java/com/readme/starter/datacollection/DataCollectionFilterTest.java
@@ -1,8 +1,8 @@
package com.readme.starter.datacollection;
-import com.readme.dataextraction.RequestDataCollector;
-import com.readme.dataextraction.UserDataCollector;
-import com.readme.domain.UserData;
+import com.readme.dataextraction.payload.RequestDataCollector;
+import com.readme.dataextraction.user.UserData;
+import com.readme.dataextraction.user.UserDataCollector;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
diff --git a/packages/java/readme-metrics-spring-boot-starter/src/test/java/com/readme/starter/datacollection/userinfo/ServletUserDataCollectorTest.java b/packages/java/readme-metrics-spring-boot-starter/src/test/java/com/readme/starter/datacollection/userinfo/ServletUserDataCollectorTest.java
index 0aa639b1b..0813e95a3 100644
--- a/packages/java/readme-metrics-spring-boot-starter/src/test/java/com/readme/starter/datacollection/userinfo/ServletUserDataCollectorTest.java
+++ b/packages/java/readme-metrics-spring-boot-starter/src/test/java/com/readme/starter/datacollection/userinfo/ServletUserDataCollectorTest.java
@@ -1,9 +1,9 @@
package com.readme.starter.datacollection.userinfo;
import com.readme.config.FieldMapping;
-import com.readme.dataextraction.UserDataExtractor;
-import com.readme.dataextraction.UserDataSource;
-import com.readme.domain.UserData;
+import com.readme.dataextraction.user.UserData;
+import com.readme.dataextraction.user.UserDataExtractor;
+import com.readme.dataextraction.user.UserDataSource;
import com.readme.starter.config.UserDataProperties;
import com.readme.starter.datacollection.ServletDataPayloadAdapter;
import org.junit.jupiter.api.BeforeEach;
diff --git a/packages/java/readme-metrics/src/main/java/com/readme/dataextraction/payload/ApiKeyMasker.java b/packages/java/readme-metrics/src/main/java/com/readme/dataextraction/payload/ApiKeyMasker.java
new file mode 100644
index 000000000..da444ae22
--- /dev/null
+++ b/packages/java/readme-metrics/src/main/java/com/readme/dataextraction/payload/ApiKeyMasker.java
@@ -0,0 +1,26 @@
+package com.readme.dataextraction.payload;
+
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Base64;
+
+public class ApiKeyMasker {
+
+ public static String mask(String apiKey) {
+ try {
+ String base64Hash = Base64.getEncoder()
+ .encodeToString(MessageDigest
+ .getInstance("SHA-512")
+ .digest(apiKey.getBytes(StandardCharsets.UTF_8)));
+
+ String last4Digits = apiKey.substring(apiKey.length() - 4);
+ return "sha512-" + base64Hash + "?" + last4Digits;
+ } catch (NoSuchAlgorithmException e) {
+ throw new RuntimeException("SHA-512 algorithm not available", e);
+ } catch (StringIndexOutOfBoundsException e) {
+ throw new IllegalArgumentException("API key must be at least 4 characters long", e);
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/packages/java/readme-metrics/src/main/java/com/readme/datatransfer/HttpDataSender.java b/packages/java/readme-metrics/src/main/java/com/readme/datatransfer/HttpDataSender.java
index c34a5f5d4..9afbf5045 100644
--- a/packages/java/readme-metrics/src/main/java/com/readme/datatransfer/HttpDataSender.java
+++ b/packages/java/readme-metrics/src/main/java/com/readme/datatransfer/HttpDataSender.java
@@ -31,7 +31,7 @@ public HttpDataSender(OkHttpClient client, CoreConfig coreConfig) {
@Override
public int send(PayloadData payloadData) {
- if (payloadData != null && payloadData.getBody() != null && !payloadData.getBody().isEmpty()) {
+ if (payloadData != null) {
String encodedReadmeApiKey = getEncodedReadmeApiKey();
Request request = createRequest(payloadData, encodedReadmeApiKey);
@@ -45,7 +45,7 @@ public int send(PayloadData payloadData) {
}
private static Request createRequest(PayloadData payloadData, String encodedReadmeApiKey) {
- RequestBody body = RequestBody.create(payloadData.getBody(), MediaType.get(APPLICATION_JSON_TYPE));
+ RequestBody body = RequestBody.create(payloadData.getRequestBody(), MediaType.get(APPLICATION_JSON_TYPE));
return new Request.Builder()
.url(README_METRICS_URL)
.header("Accept", APPLICATION_JSON_TYPE)
diff --git a/packages/java/readme-metrics/src/test/java/com/readme/datatransfer/HttpDataSenderTest.java b/packages/java/readme-metrics/src/test/java/com/readme/datatransfer/HttpDataSenderTest.java
index 2e40d87eb..ae43a9814 100644
--- a/packages/java/readme-metrics/src/test/java/com/readme/datatransfer/HttpDataSenderTest.java
+++ b/packages/java/readme-metrics/src/test/java/com/readme/datatransfer/HttpDataSenderTest.java
@@ -29,20 +29,6 @@ public void testSendOnSuccess() throws IOException {
assertEquals(200, httpDataSender.send(payloadData));
}
- @Test
- public void testSendOnBodyDoesntExist() throws IOException {
- OkHttpClient client = mock(OkHttpClient.class);
- Call call = mock(Call.class);
- Response response = mockResponse();
- PayloadData payloadData = PayloadData.builder().build();
-
- when(client.newCall(any(Request.class))).thenReturn(call);
- when(call.execute()).thenReturn(response);
- HttpDataSender httpDataSender = new HttpDataSender(client, mockCoreConfig());
-
- assertThrows(EmptyRequestBodyException.class, () -> httpDataSender.send(payloadData));
- }
-
@NotNull
private static Response mockResponse() {
return new Response.Builder()
@@ -58,7 +44,7 @@ private static Response mockResponse() {
private static PayloadData mockRequestMetadata() {
return PayloadData.builder()
- .body("body")
+ .requestBody("body")
.build();
}