From 517d9225fab63b685d4e8a7e114cf76ed3a92a7a Mon Sep 17 00:00:00 2001 From: Arif Burak Demiray Date: Fri, 5 Jan 2024 12:40:19 +0300 Subject: [PATCH 1/4] feat: id generator --- .../java/ly/count/sdk/java/internal/IdGenerator.java | 7 +++++++ .../java/ly/count/sdk/java/internal/InternalConfig.java | 2 ++ .../main/java/ly/count/sdk/java/internal/SDKCore.java | 9 +++++++++ 3 files changed, 18 insertions(+) create mode 100644 sdk-java/src/main/java/ly/count/sdk/java/internal/IdGenerator.java diff --git a/sdk-java/src/main/java/ly/count/sdk/java/internal/IdGenerator.java b/sdk-java/src/main/java/ly/count/sdk/java/internal/IdGenerator.java new file mode 100644 index 00000000..05b9fa0e --- /dev/null +++ b/sdk-java/src/main/java/ly/count/sdk/java/internal/IdGenerator.java @@ -0,0 +1,7 @@ +package ly.count.sdk.java.internal; + +import javax.annotation.Nonnull; + +public interface IdGenerator { + @Nonnull String generateId(); +} diff --git a/sdk-java/src/main/java/ly/count/sdk/java/internal/InternalConfig.java b/sdk-java/src/main/java/ly/count/sdk/java/internal/InternalConfig.java index 976f7b7c..2add2b0e 100644 --- a/sdk-java/src/main/java/ly/count/sdk/java/internal/InternalConfig.java +++ b/sdk-java/src/main/java/ly/count/sdk/java/internal/InternalConfig.java @@ -29,6 +29,8 @@ public class InternalConfig extends Config { ImmediateRequestGenerator immediateRequestGenerator = null; public SDKCore sdk; public StorageProvider storageProvider; + protected IdGenerator viewIdGenerator; + protected IdGenerator eventIdGenerator; /** * Shouldn't be used! diff --git a/sdk-java/src/main/java/ly/count/sdk/java/internal/SDKCore.java b/sdk-java/src/main/java/ly/count/sdk/java/internal/SDKCore.java index 31b0fc68..ba5a361c 100644 --- a/sdk-java/src/main/java/ly/count/sdk/java/internal/SDKCore.java +++ b/sdk-java/src/main/java/ly/count/sdk/java/internal/SDKCore.java @@ -482,6 +482,15 @@ public void init(final InternalConfig givenConfig) { setDeviceIdFromStorageIfExist(config); requestQueueMemory = new ArrayDeque<>(config.getRequestQueueMaxSize()); + + if (config.viewIdGenerator == null) { + config.viewIdGenerator = Utils::safeRandomVal; + } + + if (config.eventIdGenerator == null) { + config.eventIdGenerator = Utils::safeRandomVal; + } + // ModuleSessions is always enabled, even without consent int consents = config.getFeatures1() | CoreFeature.Sessions.getIndex(); // build modules From 1a759c5a870cbcab6203fcb4e5a27f3279a89dc6 Mon Sep 17 00:00:00 2001 From: Arif Burak Demiray Date: Fri, 5 Jan 2024 12:49:39 +0300 Subject: [PATCH 2/4] feat: validate test case --- .../count/sdk/java/internal/UtilsTests.java | 28 +++++++++++++++---- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/sdk-java/src/test/java/ly/count/sdk/java/internal/UtilsTests.java b/sdk-java/src/test/java/ly/count/sdk/java/internal/UtilsTests.java index 66459073..8db11eb8 100644 --- a/sdk-java/src/test/java/ly/count/sdk/java/internal/UtilsTests.java +++ b/sdk-java/src/test/java/ly/count/sdk/java/internal/UtilsTests.java @@ -564,16 +564,34 @@ public void readStream() { /** * "safeRandomVal" - * An random value is generated and validated by the base64 regex, and consist of 2 parts - * Should return the string value generated by the algorithm and matches with the regex + * ### 001_validatingIDGenerator + *

+ * testing the ID generator function that is used for events and views + *

+ * Generate 2 values + *

+ * they should be different. + * They should be 21 chars long. + * They should contain on base64 characters. first 8 one is base64 string and last 13 one is timestamp * * @throws NumberFormatException for parsing part 2 */ @Test - public void safeRandomVal() throws NumberFormatException { - String val = Utils.safeRandomVal(); + public void safeRandomVal_001_validatingIDGenerator() throws NumberFormatException { + String val1 = Utils.safeRandomVal(); + String val2 = Utils.safeRandomVal(); + + Assert.assertNotEquals(val2, val1); + + validateSafeRandomVal(val1); + validateSafeRandomVal(val2); + } + + private void validateSafeRandomVal(String val) { + Assert.assertEquals(21, val.length()); + Pattern base64Pattern = Pattern.compile("^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{4})$"); - + String timestampStr = val.substring(val.length() - 13); String base64Str = val.substring(0, val.length() - 13); From 475d34f23be0cba2c1b7fba0431f7f71cb1b1ac7 Mon Sep 17 00:00:00 2001 From: Arif Burak Demiray Date: Fri, 5 Jan 2024 13:13:10 +0300 Subject: [PATCH 3/4] feat: better validation --- .../ly/count/sdk/java/internal/TimeUtils.java | 2 +- .../ly/count/sdk/java/internal/TestUtils.java | 30 +++++++++++++++++++ .../count/sdk/java/internal/UtilsTests.java | 22 ++------------ 3 files changed, 33 insertions(+), 21 deletions(-) diff --git a/sdk-java/src/main/java/ly/count/sdk/java/internal/TimeUtils.java b/sdk-java/src/main/java/ly/count/sdk/java/internal/TimeUtils.java index 4f0614d0..842fd7ae 100644 --- a/sdk-java/src/main/java/ly/count/sdk/java/internal/TimeUtils.java +++ b/sdk-java/src/main/java/ly/count/sdk/java/internal/TimeUtils.java @@ -33,7 +33,7 @@ public static Instant getCurrentInstant() { return getCurrentInstant(timestampMs()); } - private static Instant getCurrentInstant(long timestamp) { + protected static Instant getCurrentInstant(long timestamp) { Calendar calendar = Calendar.getInstance(); calendar.setTimeInMillis(timestamp); return new Instant(timestamp, diff --git a/sdk-java/src/test/java/ly/count/sdk/java/internal/TestUtils.java b/sdk-java/src/test/java/ly/count/sdk/java/internal/TestUtils.java index 12cc69f7..fb37fbe8 100644 --- a/sdk-java/src/test/java/ly/count/sdk/java/internal/TestUtils.java +++ b/sdk-java/src/test/java/ly/count/sdk/java/internal/TestUtils.java @@ -13,6 +13,8 @@ import java.util.Map; import java.util.Scanner; import java.util.concurrent.ConcurrentHashMap; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import java.util.stream.Stream; import ly.count.sdk.java.Config; import ly.count.sdk.java.Countly; @@ -586,4 +588,32 @@ protected static Map map(Map gonnaAddMap, Object } return map; } + + /** + * Validates a random generated safe value, + * Value length should be 21 + * Value should contain a timestamp at the end + * Value should be base64 encoded and first 8 should be it + * + * @param val + */ + static void validateSafeRandomVal(String val) { + Assert.assertEquals(21, val.length()); + + Pattern base64Pattern = Pattern.compile("^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{4})$"); + + String timestampStr = val.substring(val.length() - 13); + String base64Str = val.substring(0, val.length() - 13); + + Matcher matcher = base64Pattern.matcher(base64Str); + if (matcher.matches()) { + TimeUtils.Instant instant = TimeUtils.getCurrentInstant(Long.parseLong(timestampStr)); + Assert.assertTrue(instant.dow >= 0 && instant.dow < 7); + Assert.assertTrue(instant.hour >= 0 && instant.hour < 24); + Assert.assertTrue(instant.timestamp > 0); + Assert.assertTrue(instant.tz >= -720 && instant.tz <= 840); + } else { + Assert.fail("No match for " + val); + } + } } diff --git a/sdk-java/src/test/java/ly/count/sdk/java/internal/UtilsTests.java b/sdk-java/src/test/java/ly/count/sdk/java/internal/UtilsTests.java index 8db11eb8..b3685899 100644 --- a/sdk-java/src/test/java/ly/count/sdk/java/internal/UtilsTests.java +++ b/sdk-java/src/test/java/ly/count/sdk/java/internal/UtilsTests.java @@ -13,8 +13,6 @@ import java.util.EnumSet; import java.util.HashMap; import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import ly.count.sdk.java.Config; import org.junit.Assert; import org.junit.Before; @@ -583,23 +581,7 @@ public void safeRandomVal_001_validatingIDGenerator() throws NumberFormatExcepti Assert.assertNotEquals(val2, val1); - validateSafeRandomVal(val1); - validateSafeRandomVal(val2); - } - - private void validateSafeRandomVal(String val) { - Assert.assertEquals(21, val.length()); - - Pattern base64Pattern = Pattern.compile("^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{4})$"); - - String timestampStr = val.substring(val.length() - 13); - String base64Str = val.substring(0, val.length() - 13); - - Matcher matcher = base64Pattern.matcher(base64Str); - if (matcher.matches()) { - Assert.assertTrue(Long.parseLong(timestampStr) > 0); - } else { - Assert.fail("No match for " + val); - } + TestUtils.validateSafeRandomVal(val1); + TestUtils.validateSafeRandomVal(val2); } } From d38ef196742d4b64859fcca69939fa91cf300967 Mon Sep 17 00:00:00 2001 From: Arif Burak Demiray Date: Mon, 8 Jan 2024 15:21:08 +0300 Subject: [PATCH 4/4] feat: scenario utils test --- .../sdk/java/internal/ScenarioUtilsTests.java | 35 +++++++++++++++++++ .../count/sdk/java/internal/UtilsTests.java | 25 ------------- 2 files changed, 35 insertions(+), 25 deletions(-) create mode 100644 sdk-java/src/test/java/ly/count/sdk/java/internal/ScenarioUtilsTests.java diff --git a/sdk-java/src/test/java/ly/count/sdk/java/internal/ScenarioUtilsTests.java b/sdk-java/src/test/java/ly/count/sdk/java/internal/ScenarioUtilsTests.java new file mode 100644 index 00000000..f857f4a9 --- /dev/null +++ b/sdk-java/src/test/java/ly/count/sdk/java/internal/ScenarioUtilsTests.java @@ -0,0 +1,35 @@ +package ly.count.sdk.java.internal; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public class ScenarioUtilsTests { + + /** + * "safeRandomVal" + * ### 001_validatingIDGenerator + *

+ * testing the ID generator function that is used for events and views + *

+ * Generate 2 values + *

+ * they should be different. + * They should be 21 chars long. + * They should contain on base64 characters. first 8 one is base64 string and last 13 one is timestamp + * + * @throws NumberFormatException for parsing part 2 + */ + @Test + public void _001_validatingIDGenerator() throws NumberFormatException { + String val1 = Utils.safeRandomVal(); + String val2 = Utils.safeRandomVal(); + + Assert.assertNotEquals(val2, val1); + + TestUtils.validateSafeRandomVal(val1); + TestUtils.validateSafeRandomVal(val2); + } +} diff --git a/sdk-java/src/test/java/ly/count/sdk/java/internal/UtilsTests.java b/sdk-java/src/test/java/ly/count/sdk/java/internal/UtilsTests.java index b3685899..a3c83858 100644 --- a/sdk-java/src/test/java/ly/count/sdk/java/internal/UtilsTests.java +++ b/sdk-java/src/test/java/ly/count/sdk/java/internal/UtilsTests.java @@ -559,29 +559,4 @@ public void readStream() { Assert.assertNull(Utils.readStream(null, logger)); Assert.assertEquals(value, new String(Utils.readStream(new ByteArrayInputStream(value.getBytes()), logger))); } - - /** - * "safeRandomVal" - * ### 001_validatingIDGenerator - *

- * testing the ID generator function that is used for events and views - *

- * Generate 2 values - *

- * they should be different. - * They should be 21 chars long. - * They should contain on base64 characters. first 8 one is base64 string and last 13 one is timestamp - * - * @throws NumberFormatException for parsing part 2 - */ - @Test - public void safeRandomVal_001_validatingIDGenerator() throws NumberFormatException { - String val1 = Utils.safeRandomVal(); - String val2 = Utils.safeRandomVal(); - - Assert.assertNotEquals(val2, val1); - - TestUtils.validateSafeRandomVal(val1); - TestUtils.validateSafeRandomVal(val2); - } }