Skip to content

Commit

Permalink
Configure AWSPinpointAnalyticsPlugin with AmplifyOutputs
Browse files Browse the repository at this point in the history
  • Loading branch information
mattcreaser committed Apr 11, 2024
1 parent 5d83536 commit 8cfdc0a
Show file tree
Hide file tree
Showing 7 changed files with 229 additions and 35 deletions.
25 changes: 25 additions & 0 deletions aws-analytics-pinpoint/api/aws-analytics-pinpoint.api
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
public final class com/amplifyframework/analytics/pinpoint/AWSPinpointAnalyticsPlugin : com/amplifyframework/analytics/AnalyticsPlugin {
public fun <init> ()V
public fun <init> (Lcom/amplifyframework/analytics/pinpoint/AWSPinpointAnalyticsPluginOptions;)V
public synthetic fun <init> (Lcom/amplifyframework/analytics/pinpoint/AWSPinpointAnalyticsPluginOptions;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun configure (Lorg/json/JSONObject;Landroid/content/Context;)V
public fun disable ()V
public fun enable ()V
Expand All @@ -15,6 +17,29 @@ public final class com/amplifyframework/analytics/pinpoint/AWSPinpointAnalyticsP
public fun unregisterGlobalProperties ([Ljava/lang/String;)V
}

public final class com/amplifyframework/analytics/pinpoint/AWSPinpointAnalyticsPluginOptions {
public static final field Companion Lcom/amplifyframework/analytics/pinpoint/AWSPinpointAnalyticsPluginOptions$Companion;
public static final fun builder ()Lcom/amplifyframework/analytics/pinpoint/AWSPinpointAnalyticsPluginOptions$Builder;
public final fun component1 ()J
public final fun copy (J)Lcom/amplifyframework/analytics/pinpoint/AWSPinpointAnalyticsPluginOptions;
public static synthetic fun copy$default (Lcom/amplifyframework/analytics/pinpoint/AWSPinpointAnalyticsPluginOptions;JILjava/lang/Object;)Lcom/amplifyframework/analytics/pinpoint/AWSPinpointAnalyticsPluginOptions;
public fun equals (Ljava/lang/Object;)Z
public final fun getAutoFlushEventsInterval ()J
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}

public final class com/amplifyframework/analytics/pinpoint/AWSPinpointAnalyticsPluginOptions$Builder {
public final fun autoFlushEventsInterval (J)Lcom/amplifyframework/analytics/pinpoint/AWSPinpointAnalyticsPluginOptions$Builder;
public final fun getAutoFlushEventsInterval ()J
public final synthetic fun setAutoFlushEventsInterval (J)V
}

public final class com/amplifyframework/analytics/pinpoint/AWSPinpointAnalyticsPluginOptions$Companion {
public final fun builder ()Lcom/amplifyframework/analytics/pinpoint/AWSPinpointAnalyticsPluginOptions$Builder;
public final synthetic fun invoke (Lkotlin/jvm/functions/Function1;)Lcom/amplifyframework/analytics/pinpoint/AWSPinpointAnalyticsPluginOptions;
}

public final class com/amplifyframework/analytics/pinpoint/AnalyticsChannelEventName : java/lang/Enum {
public static final field FLUSH_EVENTS Lcom/amplifyframework/analytics/pinpoint/AnalyticsChannelEventName;
public static fun getEntries ()Lkotlin/enums/EnumEntries;
Expand Down
2 changes: 2 additions & 0 deletions aws-analytics-pinpoint/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ dependencies {
testImplementation(libs.test.androidx.junit)
testImplementation(libs.test.androidx.core)
testImplementation(libs.test.kotlin.coroutines)
testImplementation(libs.test.kotest.assertions)
testImplementation(project(":testutils"))
testImplementation(project(":aws-analytics-pinpoint"))

androidTestImplementation(project(":testutils"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,17 @@ import com.amplifyframework.analytics.AnalyticsEventBehavior
import com.amplifyframework.analytics.AnalyticsPlugin
import com.amplifyframework.analytics.AnalyticsProperties
import com.amplifyframework.analytics.UserProfile
import com.amplifyframework.annotations.InternalAmplifyApi
import com.amplifyframework.auth.CognitoCredentialsProvider
import com.amplifyframework.core.configuration.AmplifyOutputsData
import org.json.JSONObject

/**
* The plugin implementation for Amazon Pinpoint in Analytics category.
*/
class AWSPinpointAnalyticsPlugin : AnalyticsPlugin<PinpointClient>() {
class AWSPinpointAnalyticsPlugin @JvmOverloads constructor(
private val options: AWSPinpointAnalyticsPluginOptions? = null
) : AnalyticsPlugin<PinpointClient>() {

private val pluginKey = "awsPinpointAnalyticsPlugin"
private val analyticsConfigKey = "pinpointAnalytics"
Expand Down Expand Up @@ -79,28 +83,37 @@ class AWSPinpointAnalyticsPlugin : AnalyticsPlugin<PinpointClient>() {
configBuilder.withRegion(
pinpointAnalyticsConfigJson.getString(PinpointConfigurationKey.REGION.configurationKey)
)
if (pinpointAnalyticsConfigJson.has(PinpointConfigurationKey.AUTO_FLUSH_INTERVAL.configurationKey)) {

// Use the programmatic options if they were supplied, otherwise read additional options from the
// amplifyconfiguration file
if (options != null) {
configBuilder.withAutoFlushEventsInterval(options.autoFlushEventsInterval)
} else if (pinpointAnalyticsConfigJson.has(PinpointConfigurationKey.AUTO_FLUSH_INTERVAL.configurationKey)) {
configBuilder.withAutoFlushEventsInterval(
pinpointAnalyticsConfigJson.getLong(PinpointConfigurationKey.AUTO_FLUSH_INTERVAL.configurationKey)
)
}
if (pinpointAnalyticsConfigJson.has(PinpointConfigurationKey.TRACK_APP_LIFECYCLE_EVENTS.configurationKey)) {
configBuilder.withTrackAppLifecycleEvents(
pinpointAnalyticsConfigJson.getBoolean(
PinpointConfigurationKey.TRACK_APP_LIFECYCLE_EVENTS.configurationKey
)
)
}
val awsAnalyticsConfig = configBuilder.build()
configure(awsAnalyticsConfig, context)
}

@InternalAmplifyApi
override fun configure(configuration: AmplifyOutputsData, context: Context) {
val options = this.options ?: AWSPinpointAnalyticsPluginOptions.defaults()
val analyticsConfig = AWSPinpointAnalyticsPluginConfiguration.from(configuration, options)
configure(analyticsConfig, context)
}

private fun configure(configuration: AWSPinpointAnalyticsPluginConfiguration, context: Context) {
pinpointManager = PinpointManager(
context,
awsAnalyticsConfig,
configuration,
CognitoCredentialsProvider()
)

awsPinpointAnalyticsPluginBehavior = AWSPinpointAnalyticsPluginBehavior(
pinpointManager.analyticsClient,
pinpointManager.targetingClient,
pinpointManager.targetingClient
)
}

Expand Down Expand Up @@ -132,10 +145,5 @@ private enum class PinpointConfigurationKey(
/**
* Time interval after which the events are automatically submitted to pinpoint.
*/
AUTO_FLUSH_INTERVAL("autoFlushEventsInterval"),

/**
* Whether to track app lifecycle events automatically.
*/
TRACK_APP_LIFECYCLE_EVENTS("trackAppLifecycleEvents");
AUTO_FLUSH_INTERVAL("autoFlushEventsInterval")
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,27 @@

package com.amplifyframework.analytics.pinpoint;

import androidx.annotation.NonNull;

import com.amplifyframework.AmplifyException;
import com.amplifyframework.analytics.AnalyticsException;
import com.amplifyframework.core.configuration.AmplifyOutputsData;

/**
* Configuration options for Amplify Analytics Pinpoint plugin.
*/
final class AWSPinpointAnalyticsPluginConfiguration {

private static final long DEFAULT_AUTO_FLUSH_INTERVAL = 30000L;
static final long DEFAULT_AUTO_FLUSH_INTERVAL = 30000L;

// Pinpoint plugin configuration options
private final String appId;
private final boolean trackAppLifecycleEvents;
private final String region;
private final long autoFlushEventsInterval;

private AWSPinpointAnalyticsPluginConfiguration(Builder builder) {
this.appId = builder.appId;
this.region = builder.region;
this.trackAppLifecycleEvents = builder.trackAppLifecycleEvents;
this.autoFlushEventsInterval = builder.autoFlushEventsInterval;
}

Expand Down Expand Up @@ -62,29 +66,41 @@ long getAutoFlushEventsInterval() {
return autoFlushEventsInterval;
}

/**
* Is auto session tracking enabled.
* @return Is auto session tracking enabled.
*/
boolean isTrackAppLifecycleEvents() {
return trackAppLifecycleEvents;
}

/**
* Return a builder that can be used to construct a new instance of
* {@link AWSPinpointAnalyticsPluginConfiguration}.
* @return An {@link PinpointProperties.Builder} instance
* @return An {@link AWSPinpointAnalyticsPluginConfiguration.Builder} instance
*/
static Builder builder() {
return new Builder();
}

static AWSPinpointAnalyticsPluginConfiguration from(
@NonNull AmplifyOutputsData outputs,
@NonNull AWSPinpointAnalyticsPluginOptions options
) throws AmplifyException {
AmplifyOutputsData.Analytics analytics = outputs.getAnalytics();
if (analytics == null) {
throw new AnalyticsException(
"Missing Analytics configuration",
"Ensure that analytics is enabled and exists in your configuration file"
);
}

// Note: autoFlushEventsInterval is not supported in Gen2 config.
// Customers should use the programmatic plugin options API instead.
return builder()
.withAppId(analytics.getAppId())
.withRegion(analytics.getAwsRegion())
.withAutoFlushEventsInterval(options.getAutoFlushEventsInterval())
.build();
}

/**
* Used for fluent construction of an immutable {@link AWSPinpointAnalyticsPluginConfiguration} object.
*/
static final class Builder {
private String appId;
private boolean trackAppLifecycleEvents = false;
private String region;
private long autoFlushEventsInterval = DEFAULT_AUTO_FLUSH_INTERVAL;

Expand All @@ -103,11 +119,6 @@ Builder withAutoFlushEventsInterval(final long autoFlushEventsInterval) {
return this;
}

Builder withTrackAppLifecycleEvents(final boolean trackAppLifecycleEvents) {
this.trackAppLifecycleEvents = trackAppLifecycleEvents;
return this;
}

AWSPinpointAnalyticsPluginConfiguration build() {
return new AWSPinpointAnalyticsPluginConfiguration(this);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

package com.amplifyframework.analytics.pinpoint

import com.amplifyframework.analytics.pinpoint.AWSPinpointAnalyticsPluginConfiguration.DEFAULT_AUTO_FLUSH_INTERVAL

/**
* Options that can be specified to fine-tune the behavior of the Pinpoint Analytics Plugin.
*/
data class AWSPinpointAnalyticsPluginOptions internal constructor(
/**
* The interval between sends of queued analytics events, in milliseconds
*/
val autoFlushEventsInterval: Long
) {
companion object {
/**
* Create a new [Builder] instance
*/
@JvmStatic
fun builder() = Builder()

/**
* Create an [AWSPinpointAnalyticsPluginOptions] instance
*/
@JvmSynthetic
operator fun invoke(func: Builder.() -> Unit) = Builder().apply(func).build()

internal fun defaults() = builder().build()
}

/**
* Builder API for constructing [AWSPinpointAnalyticsPluginOptions] instances
*/
class Builder internal constructor() {
/**
* Set the interval between sends of queed analytics events, in milliseconds
*/
var autoFlushEventsInterval: Long = DEFAULT_AUTO_FLUSH_INTERVAL
@JvmSynthetic set

/**
* Set the interval between sends of queed analytics events, in milliseconds
*/
fun autoFlushEventsInterval(value: Long) = apply { autoFlushEventsInterval = value }

internal fun build() = AWSPinpointAnalyticsPluginOptions(
autoFlushEventsInterval = autoFlushEventsInterval
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

package com.amplifyframework.analytics.pinpoint

import com.amplifyframework.testutils.configuration.amplifyOutputsData
import io.kotest.matchers.shouldBe
import org.junit.Test

class AWSPinpointAnalyticsPluginConfigurationTest {

@Test
fun `reads values from AmplifyOutputsData and Options`() {
val outputs = amplifyOutputsData {
analytics {
awsRegion = "test-region"
appId = "test-app"
}
}
val options = AWSPinpointAnalyticsPluginOptions {
autoFlushEventsInterval = 42
}

val configuration = AWSPinpointAnalyticsPluginConfiguration.from(outputs, options)

configuration.appId shouldBe "test-app"
configuration.region shouldBe "test-region"
configuration.autoFlushEventsInterval shouldBe 42
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

package com.amplifyframework.testutils.configuration

import com.amplifyframework.core.configuration.AmplifyOutputsData
import kotlinx.serialization.json.JsonObject

fun amplifyOutputsData(func: AmplifyOutputsDataBuilder.() -> Unit): AmplifyOutputsData =
AmplifyOutputsDataBuilder().apply(func)

class AmplifyOutputsDataBuilder : AmplifyOutputsData {
override var version = "1"
override var analytics: AmplifyOutputsData.Analytics? = null
override var auth: AmplifyOutputsData.Auth? = null
override val data: AmplifyOutputsData.Data? = null
override val geo: AmplifyOutputsData.Geo? = null
override val notifications: AmplifyOutputsData.Notifications? = null
override val storage: AmplifyOutputsData.Storage? = null
override val custom: JsonObject? = null

fun analytics(func: AnalyticsBuilder.() -> Unit) {
analytics = AnalyticsBuilder().apply(func)
}
}

class AnalyticsBuilder : AmplifyOutputsData.Analytics {
override var awsRegion: String = "us-east-1"
override var appId: String = "analytics-app-id"
}

0 comments on commit 8cfdc0a

Please sign in to comment.