diff --git a/pom.xml b/pom.xml
index ee79d13..e3d290b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -42,12 +42,22 @@
http://github.com/optimove/Optimove-SDK-Engagement-java/tree/master
+
+
+
+ com.google.cloud
+ libraries-bom
+ 26.52.0
+ pom
+ import
+
+
+
com.google.cloud
google-cloud-storage
- 2.34.0
com.fasterxml.jackson.dataformat
@@ -62,7 +72,7 @@
org.apache.avro
avro
- 1.11.3
+ 1.11.4
org.apache.commons
diff --git a/readme.md b/readme.md
index d35f276..db66f5a 100644
--- a/readme.md
+++ b/readme.md
@@ -41,15 +41,15 @@ public class Main {
public static void main(String[] args) {
Logger logger = LoggerFactory.getLogger(Main.class);
- Engagement engagement = new Engagement(null, 1, "bucket-name", "customers-folder/customers", "metadata-path/metadata_287934", logger);
+ Engagement engagement = new Engagement("{\r\n \"EventTypeID\": 14,\r\n \"TimeStamp\": \"2025-01-08 08:58\",\r\n \"CampaignID\": 1111,\r\n \"EngagementID\": 1111,\r\n \"TenantID\": 1111,\r\n \"BucketName\": \"bucketName\",\r\n \"CustomersFolderPath\": \"path\",\r\n \"MetadataFilePath\": \"pathCustomers\",\r\n \"DecryptionKey\": \"some-secret-key\",\r\n \"ChannelID\": 1111\r\n}", logger);
Metadata metadata = engagement.getMetadata();
- System.out.println(metadata.getNumberOfFiles());
+ System.out.println(metadata.getNumberOfBatches());
- for (int fileNumber = 1; fileNumber <= metadata.getNumberOfFiles(); fileNumber++) {
- System.out.println("file number: " + fileNumber);
+ for (int batchNumber = 1; batchNumber <= metadata.getNumberOfBatches(); batchNumber++) {
+ System.out.println("batch number: " + batchNumber);
- try (DataFileStream dataFileReader = engagement.getCustomerBatchById(fileNumber)) {
+ try (DataFileStream dataFileReader = engagement.getCustomerBatchById(batchNumber)) {
GenericRecord record = null;
while (dataFileReader.hasNext()) {
record = dataFileReader.next(record);
@@ -86,27 +86,27 @@ logger.error("Failed to retrieve metadata: " + e.getMessage(), e);
}
```
### Customer Data Retrieval
-When retrieving customer data for an engagement, the SDK may encounter errors such as a missing or malformed customer data file, or an invalid file ID.
+When retrieving customer data for an engagement, the SDK may encounter errors such as a missing or malformed customer data file, or an invalid batch ID.
In the case of a missing or malformed customer data file, the getCustomerBatchById() method will throw a RuntimeException with a message indicating the cause of the error. For example:
```java
-try (DataFileStream dataFileReader = engagement.getCustomerBatchById(fileNumber)) {
+try (DataFileStream dataFileReader = engagement.getCustomerBatchById(batchNumber)) {
// use dataFileReader
} catch (RuntimeException e) {
logger.error("Failed to get customer batch by id: " + e.getMessage(), e);
// handle error
}
```
-If an invalid file ID is provided, the getCustomerBatchById() method will throw an IllegalArgumentException with a message indicating the cause of the error. For example:
+If an invalid batch ID is provided, the getCustomerBatchById() method will throw an IllegalArgumentException with a message indicating the cause of the error. For example:
```java
try (DataFileStream dataFileReader = engagement.getCustomerBatchById(-1)) {
// use dataFileReader
} catch (IllegalArgumentException e) {
-logger.error("Invalid file id: " + e.getMessage(), e);
+logger.error("Invalid batch id: " + e.getMessage(), e);
// handle error
}
```
diff --git a/src/main/java/optimove/sdk/engagement/Engagement.java b/src/main/java/optimove/sdk/engagement/Engagement.java
index 4f89d8b..872adff 100644
--- a/src/main/java/optimove/sdk/engagement/Engagement.java
+++ b/src/main/java/optimove/sdk/engagement/Engagement.java
@@ -1,5 +1,6 @@
package optimove.sdk.engagement;
+import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.cloud.storage.Blob;
import com.google.cloud.ReadChannel;
@@ -25,9 +26,56 @@ public Engagement(String decryptionKey, int tenantID, String bucketName, String
this.logger = logger;
}
+ // Constructor that accepts JSON string and logger
+ public Engagement(String jsonConfig, Logger logger) {
+ if (jsonConfig == null || logger == null) {
+ throw new IllegalArgumentException("Neither jsonConfig nor logger can be null");
+ }
+
+ try {
+ ObjectMapper mapper = new ObjectMapper();
+ EngagementConfig config = mapper.readValue(jsonConfig, EngagementConfig.class);
+ this.settings = createSettingsFromConfig(config);
+ this.logger = logger;
+ } catch (IOException e) {
+ throw new RuntimeException("Failed to parse engagement configuration: " + e.getMessage(), e);
+ }
+ }
+
+ // Constructor that accepts any object and logger
+ public Engagement(Object configObject, Logger logger) {
+ if (configObject == null || logger == null) {
+ throw new IllegalArgumentException("Neither configObject nor logger can be null");
+ }
+
+ try {
+ ObjectMapper mapper = new ObjectMapper();
+ // First convert the object to a JSON string
+ String jsonString = mapper.writeValueAsString(configObject);
+ // Then convert it to our EngagementConfig class
+ EngagementConfig config = mapper.readValue(jsonString, EngagementConfig.class);
+
+ this.settings = createSettingsFromConfig(config);
+ this.logger = logger;
+ } catch (IOException e) {
+ throw new RuntimeException("Failed to convert object to engagement configuration: " + e.getMessage(), e);
+ }
+ }
+
+ // Helper method to create settings from config
+ private EngagementSettings createSettingsFromConfig(EngagementConfig config) {
+ return new EngagementSettings(
+ config.getDecryptionKey(),
+ config.getTenantID(),
+ config.getBucketName(),
+ config.getCustomersFolderPath(),
+ config.getMetadataFilePath()
+ );
+ }
+
public Metadata getMetadata() {
try {
- Blob fileBlob = StorageSingleton.getBlob(this.settings.getBucketName(), this.settings.getMetadataFilePath());
+ Blob fileBlob = StorageSingleton.getBlob(this.settings.getBucketName(), this.settings.getMetadataFilePath(), this.settings.getDecryptionKey());
String metadataString = StorageSingleton.blobToString(fileBlob, this.settings.getDecryptionKey());
return MetadataService.jsonStringToMetadata(metadataString);
diff --git a/src/main/java/optimove/sdk/engagement/EngagementConfig.java b/src/main/java/optimove/sdk/engagement/EngagementConfig.java
new file mode 100644
index 0000000..a316cf3
--- /dev/null
+++ b/src/main/java/optimove/sdk/engagement/EngagementConfig.java
@@ -0,0 +1,49 @@
+package optimove.sdk.engagement;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+class EngagementConfig {
+ @JsonProperty("DecryptionKey")
+ private String decryptionKey;
+
+ @JsonProperty("TenantID")
+ private int tenantID;
+
+ @JsonProperty("BucketName")
+ private String bucketName;
+
+ @JsonProperty("CustomersFolderPath")
+ private String customersFolderPath;
+
+ @JsonProperty("MetadataFilePath")
+ private String metadataFilePath;
+
+ @JsonProperty("EventTypeID")
+ private int eventTypeId;
+
+ @JsonProperty("TimeStamp")
+ private String timestamp;
+
+ @JsonProperty("CampaignID")
+ private int campaignId;
+
+ @JsonProperty("EngagementID")
+ private int engagementId;
+
+ @JsonProperty("ChannelID")
+ private int channelId;
+
+ // Getters
+ public String getDecryptionKey() { return decryptionKey; }
+ public int getTenantID() { return tenantID; }
+ public String getBucketName() { return bucketName; }
+ public String getCustomersFolderPath() { return customersFolderPath; }
+ public String getMetadataFilePath() { return metadataFilePath; }
+ public int getEventTypeId() { return eventTypeId; }
+ public String getTimestamp() { return timestamp; }
+ public int getCampaignId() { return campaignId; }
+ public int getEngagementId() { return engagementId; }
+ public int getChannelId() { return channelId; }
+}
diff --git a/src/main/java/optimove/sdk/engagement/Metadata.java b/src/main/java/optimove/sdk/engagement/Metadata.java
index 1095f75..360dd3e 100644
--- a/src/main/java/optimove/sdk/engagement/Metadata.java
+++ b/src/main/java/optimove/sdk/engagement/Metadata.java
@@ -92,6 +92,10 @@ public long getNumberOfFiles() {
return NumberOfFiles;
}
+ public long getNumberOfBatches() {
+ return NumberOfFiles;
+ }
+
public long getPlanDetailChannelID() {
return PlanDetailChannelID;
}
diff --git a/src/main/java/optimove/sdk/engagement/StorageSingleton.java b/src/main/java/optimove/sdk/engagement/StorageSingleton.java
index b2295b0..bfae4a6 100644
--- a/src/main/java/optimove/sdk/engagement/StorageSingleton.java
+++ b/src/main/java/optimove/sdk/engagement/StorageSingleton.java
@@ -12,22 +12,22 @@
public class StorageSingleton {
private static Storage instance = null;
- private static final String projectId = "optimoveSDK";
private StorageSingleton() { }
public static Storage getInstance() {
if(instance == null) {
instance = StorageOptions.newBuilder()
- .setProjectId(projectId)
.build()
.getService();
}
return instance;
}
-
public static Blob getBlob(String bucketName, String srcFileName) {
- return getInstance().get(bucketName, srcFileName);
+ return getInstance().get(BlobId.of(bucketName, srcFileName));
+ }
+ public static Blob getBlob(String bucketName, String srcFileName, String decryptionKey) {
+ return getInstance().get(BlobId.of(bucketName, srcFileName), Storage.BlobGetOption.decryptionKey(decryptionKey));
}
public static ReadChannel getReadChanel(String bucketName, String srcFileName) {
return getInstance().reader(BlobId.of(bucketName, srcFileName));
diff --git a/src/main/java/org/example/Main.java b/src/main/java/org/example/Main.java
index 9827a32..7d9b953 100644
--- a/src/main/java/org/example/Main.java
+++ b/src/main/java/org/example/Main.java
@@ -3,10 +3,13 @@
import org.apache.avro.file.DataFileStream;
import org.apache.avro.generic.GenericRecord;
import java.io.IOException;
+import java.time.Duration;
+import java.time.Instant;
import optimove.sdk.engagement.Engagement;
import optimove.sdk.engagement.Metadata;
+import org.apache.commons.lang3.time.StopWatch;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -14,15 +17,17 @@ public class Main {
public static void main(String[] args) {
Logger logger = LoggerFactory.getLogger(Main.class);
- Engagement engagement = new Engagement(null, 1, "bucket-name", "customers-folder/customers", "metadata-path/metadata_287934", logger);
+ Engagement engagement = new Engagement("{\r\n \"EventTypeID\": 14,\r\n \"TimeStamp\": \"2025-01-08 08:58\",\r\n \"CampaignID\": 1111,\r\n \"EngagementID\": 1111,\r\n \"TenantID\": 1111,\r\n \"BucketName\": \"bucketName\",\r\n \"CustomersFolderPath\": \"path\",\r\n \"MetadataFilePath\": \"pathCustomers\",\r\n \"DecryptionKey\": \"some-secret-key\",\r\n \"ChannelID\": 1111\r\n}", logger);
Metadata metadata = engagement.getMetadata();
- System.out.println(metadata.getNumberOfFiles());
+ System.out.println(metadata.getNumberOfBatches());
- for (int fileNumber = 1; fileNumber <= metadata.getNumberOfFiles(); fileNumber++) {
- System.out.println("file number: " + fileNumber);
+ for (int batchNumber = 1; batchNumber <= metadata.getNumberOfBatches(); batchNumber++) {
+ System.out.println("batch number: " + batchNumber);
- try (DataFileStream dataFileReader = engagement.getCustomerBatchById(fileNumber)) {
+ DataFileStream dataFileReader = null;
+ try {
+ dataFileReader = engagement.getCustomerBatchById(batchNumber);
GenericRecord record = null;
while (dataFileReader.hasNext()) {
record = dataFileReader.next(record);
diff --git a/src/test/java/EngagementTest.java b/src/test/java/EngagementTest.java
index d7f1fe5..e62d69f 100644
--- a/src/test/java/EngagementTest.java
+++ b/src/test/java/EngagementTest.java
@@ -57,7 +57,7 @@ public void test_retrieving_metadata_from_valid_bucket_and_file_path() {
try (MockedStatic classMock = mockStatic(StorageSingleton.class)) {
- classMock.when(() -> StorageSingleton.getBlob(anyString(), anyString())).thenReturn(fileBlob);
+ classMock.when(() -> StorageSingleton.getBlob(anyString(), anyString(), anyString())).thenReturn(fileBlob);
classMock.when(() -> StorageSingleton.blobToString(eq(fileBlob), any(String.class))).thenReturn(metadataString);
classMock.when(() -> StorageSingleton.getReadChanel(anyString(), anyString(), anyString())).thenReturn(readChannel);
@@ -68,7 +68,7 @@ public void test_retrieving_metadata_from_valid_bucket_and_file_path() {
// Verify the expected behavior
assertNotNull(metadata);
- assumeTrue(metadata.getNumberOfFiles() == 3);
+ assumeTrue(metadata.getNumberOfBatches() == 3);
assumeTrue(metadata.getNumberOfCustomers() == 300);
assumeTrue(metadata.getCampaignPlanID() == 10);
assumeTrue(metadata.getCampaignID() == 1);