diff --git a/iterableapi/build.gradle b/iterableapi/build.gradle index b57f4ccb3..0fc6685bb 100644 --- a/iterableapi/build.gradle +++ b/iterableapi/build.gradle @@ -55,6 +55,7 @@ dependencies { testImplementation 'org.khronos:opengl-api:gl1.1-android-2.1_r1' testImplementation 'com.squareup.okhttp3:mockwebserver:4.2.2' testImplementation 'org.skyscreamer:jsonassert:1.5.0' + testImplementation project(path: ':iterableapi') androidTestImplementation 'androidx.test:runner:1.3.0' androidTestImplementation 'androidx.test:rules:1.3.0' androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' @@ -96,6 +97,8 @@ task javadoc(type: Javadoc) { source = android.sourceSets.main.java.srcDirs excludes = ['**/*.kt'] classpath += project.files(android.getBootClasspath().join(File.pathSeparator)) + + exclude '**/*.kt' } tasks.withType(Test) { diff --git a/iterableapi/src/main/java/com/iterable/iterableapi/IterableConfig.java b/iterableapi/src/main/java/com/iterable/iterableapi/IterableConfig.java index 5d6b85773..9c90a2c96 100644 --- a/iterableapi/src/main/java/com/iterable/iterableapi/IterableConfig.java +++ b/iterableapi/src/main/java/com/iterable/iterableapi/IterableConfig.java @@ -71,6 +71,11 @@ public class IterableConfig { */ final String[] allowedProtocols; + /** + * Data region determining which data center and endpoints are used by the SDK. + */ + final IterableDataRegion dataRegion; + /** * This controls whether the in-app content should be saved to disk, or only kept in memory. * By default, the SDK will save in-apps to disk. @@ -91,6 +96,7 @@ private IterableConfig(Builder builder) { authHandler = builder.authHandler; expiringAuthTokenRefreshPeriod = builder.expiringAuthTokenRefreshPeriod; allowedProtocols = builder.allowedProtocols; + dataRegion = builder.dataRegion; useInMemoryStorageForInApps = builder.useInMemoryStorageForInApps; encryptionEnforced = builder.encryptionEnforced; } @@ -107,6 +113,7 @@ public static class Builder { private IterableAuthHandler authHandler; private long expiringAuthTokenRefreshPeriod = 60000L; private String[] allowedProtocols = new String[0]; + private IterableDataRegion dataRegion = IterableDataRegion.US; private boolean useInMemoryStorageForInApps = false; private boolean encryptionEnforced = false; @@ -235,6 +242,16 @@ public Builder setEncryptionEnforced(boolean encryptionEnforced) { return this; } + /** + * Set the data region used by the SDK + * @param dataRegion enum value that determines which endpoint to use, defaults to IterableDataRegion.US + */ + @NonNull + public Builder setDataRegion(@NonNull IterableDataRegion dataRegion) { + this.dataRegion = dataRegion; + return this; + } + /** * Set whether the SDK should store in-apps only in memory, or in file storage * @param useInMemoryStorageForInApps `true` will have in-apps be only in memory @@ -251,5 +268,4 @@ public IterableConfig build() { return new IterableConfig(this); } } - -} +} \ No newline at end of file diff --git a/iterableapi/src/main/java/com/iterable/iterableapi/IterableConstants.java b/iterableapi/src/main/java/com/iterable/iterableapi/IterableConstants.java index fabd9a3f4..985d60480 100644 --- a/iterableapi/src/main/java/com/iterable/iterableapi/IterableConstants.java +++ b/iterableapi/src/main/java/com/iterable/iterableapi/IterableConstants.java @@ -252,4 +252,4 @@ public final class IterableConstants { public static final String NO_MESSAGES_TITLE = "noMessagesTitle"; public static final String NO_MESSAGES_BODY = "noMessagesBody"; -} +} \ No newline at end of file diff --git a/iterableapi/src/main/java/com/iterable/iterableapi/IterableDataRegion.java b/iterableapi/src/main/java/com/iterable/iterableapi/IterableDataRegion.java new file mode 100644 index 000000000..aec57c0f2 --- /dev/null +++ b/iterableapi/src/main/java/com/iterable/iterableapi/IterableDataRegion.java @@ -0,0 +1,16 @@ +package com.iterable.iterableapi; + +public enum IterableDataRegion { + US("https://api.iterable.com/api/"), + EU("https://api.eu.iterable.com/api/"); + + private final String endpoint; + + IterableDataRegion(String endpoint) { + this.endpoint = endpoint; + } + + public String getEndpoint() { + return this.endpoint; + } +} diff --git a/iterableapi/src/main/java/com/iterable/iterableapi/IterableRequestTask.java b/iterableapi/src/main/java/com/iterable/iterableapi/IterableRequestTask.java index b0fd7ffe6..d5fe00046 100644 --- a/iterableapi/src/main/java/com/iterable/iterableapi/IterableRequestTask.java +++ b/iterableapi/src/main/java/com/iterable/iterableapi/IterableRequestTask.java @@ -27,7 +27,6 @@ */ class IterableRequestTask extends AsyncTask { static final String TAG = "IterableRequest"; - static final String ITERABLE_BASE_URL = "https://api.iterable.com/api/"; static String overrideUrl; @@ -65,8 +64,8 @@ static IterableApiResponse executeApiRequest(IterableApiRequest iterableApiReque HttpURLConnection urlConnection = null; IterableLogger.v(TAG, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); - String baseUrl = (iterableApiRequest.baseUrl != null && !iterableApiRequest.baseUrl.isEmpty()) ? iterableApiRequest.baseUrl : - ITERABLE_BASE_URL; + String baseUrl = getBaseUrl(); + try { if (overrideUrl != null && !overrideUrl.isEmpty()) { baseUrl = overrideUrl; @@ -225,6 +224,18 @@ static IterableApiResponse executeApiRequest(IterableApiRequest iterableApiReque return apiResponse; } + private static String getBaseUrl() { + IterableConfig config = IterableApi.getInstance().config; + IterableDataRegion dataRegion = config.dataRegion; + String baseUrl = dataRegion.getEndpoint(); + + if (overrideUrl != null && !overrideUrl.isEmpty()) { + baseUrl = overrideUrl; + } + + return baseUrl; + } + private static boolean matchesErrorCode(JSONObject jsonResponse, String errorCode) { try { return jsonResponse != null && jsonResponse.has("code") && jsonResponse.getString("code").equals(errorCode); diff --git a/iterableapi/src/test/java/com/iterable/iterableapi/IterableConfigTest.kt b/iterableapi/src/test/java/com/iterable/iterableapi/IterableConfigTest.kt new file mode 100644 index 000000000..1d5124815 --- /dev/null +++ b/iterableapi/src/test/java/com/iterable/iterableapi/IterableConfigTest.kt @@ -0,0 +1,23 @@ +package com.iterable.iterableapi + +import org.hamcrest.Matchers.`is` +import org.junit.Assert.* +import org.junit.Test + +class IterableConfigTest { + + @Test + fun defaultDataRegion() { + val configBuilder: IterableConfig.Builder = IterableConfig.Builder() + val config: IterableConfig = configBuilder.build() + assertThat(config.dataRegion, `is`(IterableDataRegion.US)) + } + + @Test + fun setDataRegionToEU() { + val configBuilder: IterableConfig.Builder = IterableConfig.Builder() + .setDataRegion(IterableDataRegion.EU) + val config: IterableConfig = configBuilder.build() + assertThat(config.dataRegion, `is`(IterableDataRegion.EU)) + } +} \ No newline at end of file