diff --git a/libraries/bot-applicationinsights/pom.xml b/libraries/bot-applicationinsights/pom.xml
index c7bfde216..1dc45c1cf 100644
--- a/libraries/bot-applicationinsights/pom.xml
+++ b/libraries/bot-applicationinsights/pom.xml
@@ -60,9 +60,22 @@
2.4.1
+
+ com.microsoft.bot
+ bot-dialogs
+
+
+ org.mockito
+ mockito-core
+ test
+
+
com.microsoft.bot
bot-builder
+ ${project.version}
+ test-jar
+ test
diff --git a/libraries/bot-applicationinsights/src/main/java/com/microsoft/bot/applicationinsights/AvailabilityTelemetry.java b/libraries/bot-applicationinsights/src/main/java/com/microsoft/bot/applicationinsights/AvailabilityTelemetry.java
new file mode 100644
index 000000000..80911aa58
--- /dev/null
+++ b/libraries/bot-applicationinsights/src/main/java/com/microsoft/bot/applicationinsights/AvailabilityTelemetry.java
@@ -0,0 +1,217 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+package com.microsoft.bot.applicationinsights;
+
+import com.microsoft.applicationinsights.internal.schemav2.AvailabilityData;
+import com.microsoft.applicationinsights.internal.util.LocalStringsUtils;
+import com.microsoft.applicationinsights.internal.util.Sanitizer;
+import com.microsoft.applicationinsights.telemetry.BaseSampleSourceTelemetry;
+import com.microsoft.applicationinsights.telemetry.Duration;
+import java.util.Date;
+import java.util.concurrent.ConcurrentMap;
+
+/**
+ * We took this class from https://github.com/microsoft/ApplicationInsights-Java/issues/1099
+ * as this is not already migrated in ApplicationInsights-Java library.
+ */
+public final class AvailabilityTelemetry extends BaseSampleSourceTelemetry {
+ private Double samplingPercentage;
+ private final AvailabilityData data;
+
+ public static final String ENVELOPE_NAME = "Availability";
+
+ public static final String BASE_TYPE = "AvailabilityData";
+
+
+ /**
+ * Initializes a new instance of the AvailabilityTelemetry class.
+ */
+ public AvailabilityTelemetry() {
+ this.data = new AvailabilityData();
+ initialize(this.data.getProperties());
+ setId(LocalStringsUtils.generateRandomIntegerId());
+
+ // Setting mandatory fields.
+ setTimestamp(new Date());
+ setSuccess(true);
+ }
+
+ /**
+ * Initializes a new instance of the AvailabilityTelemetry class with the given name,
+ * time stamp, duration, HTTP response code and success property values.
+ * @param name A user-friendly name for the request.
+ * @param duration The time of the request.
+ * @param runLocation The duration, in milliseconds, of the request processing.
+ * @param message The HTTP response code.
+ * @param success 'true' if the request was a success, 'false' otherwise.
+ * @param measurements The measurements.
+ * @param properties The corresponding properties.
+ */
+ public AvailabilityTelemetry(String name, Duration duration, String runLocation, String message,
+ boolean success, ConcurrentMap measurements,
+ ConcurrentMap properties) {
+
+ this.data = new AvailabilityData();
+
+ this.data.setProperties(properties);
+ this.data.setMeasurements(measurements);
+ this.data.setMessage(message);
+
+ initialize(this.data.getProperties());
+
+ setId(LocalStringsUtils.generateRandomIntegerId());
+
+ setTimestamp(new Date());
+
+ setName(name);
+ setRunLocation(runLocation);
+ setDuration(duration);
+ setSuccess(success);
+ }
+
+
+ /**
+ * Gets the ver value from the data object.
+ * @return The ver value.
+ */
+ @Override
+ public int getVer() {
+ return getData().getVer();
+ }
+
+ /**
+ * Gets a map of application-defined request metrics.
+ * @return The map of metrics
+ */
+ public ConcurrentMap getMetrics() {
+ return data.getMeasurements();
+ }
+
+ /**
+ * Sets the StartTime. Uses the default behavior and sets the property on the 'data' start time.
+ * @param timestamp The timestamp as Date.
+ */
+ @Override
+ public void setTimestamp(Date timestamp) {
+ if (timestamp == null) {
+ timestamp = new Date();
+ }
+
+ super.setTimestamp(timestamp);
+ }
+
+ /**
+ * Gets or human-readable name of the requested page.
+ * @return A human-readable name.
+ */
+ public String getName() {
+ return data.getName();
+ }
+
+ /**
+ * Sets or human-readable name of the requested page.
+ * @param name A human-readable name.
+ */
+ public void setName(String name) {
+ data.setName(name);
+ }
+
+ /**
+ * Gets or human-readable name of the run location.
+ * @return A human-readable name.
+ */
+ public String getRunLocation() {
+ return data.getRunLocation();
+ }
+
+ /**
+ * Sets or human-readable name of the run location.
+ * @param runLocation A human-readable name
+ */
+ public void setRunLocation(String runLocation) {
+ data.setRunLocation(runLocation);
+ }
+
+ /**
+ * Gets the unique identifier of the request.
+ * @return Unique identifier.
+ */
+ public String getId() {
+ return data.getId();
+ }
+
+ /**
+ * Sets the unique identifier of the request.
+ * @param id Unique identifier.
+ */
+ public void setId(String id) {
+ data.setId(id);
+ }
+
+ /**
+ * Gets a value indicating whether application handled the request successfully.
+ * @return Success indication.
+ */
+ public boolean isSuccess() {
+ return data.getSuccess();
+ }
+
+ /**
+ * Sets a value indicating whether application handled the request successfully.
+ * @param success Success indication.
+ */
+ public void setSuccess(boolean success) {
+ data.setSuccess(success);
+ }
+
+ /**
+ * Gets the amount of time it took the application to handle the request.
+ * @return Amount of time in milliseconds.
+ */
+ public Duration getDuration() {
+ return data.getDuration();
+ }
+
+ /**
+ * Sets the amount of time it took the application to handle the request.
+ * @param duration Amount of time in captured in a {@link com.microsoft.applicationinsights.telemetry.Duration}.
+ */
+ public void setDuration(Duration duration) {
+ data.setDuration(duration);
+ }
+
+ @Override
+ public Double getSamplingPercentage() {
+ return samplingPercentage;
+ }
+
+ @Override
+ public void setSamplingPercentage(Double samplingPercentage) {
+ this.samplingPercentage = samplingPercentage;
+ }
+
+ @Override
+ @Deprecated
+ protected void additionalSanitize() {
+ data.setName(Sanitizer.sanitizeName(data.getName()));
+ data.setId(Sanitizer.sanitizeName(data.getId()));
+ Sanitizer.sanitizeMeasurements(getMetrics());
+ }
+
+ @Override
+ protected AvailabilityData getData() {
+ return data;
+ }
+
+ @Override
+ public String getEnvelopName() {
+ return ENVELOPE_NAME;
+ }
+
+ @Override
+ public String getBaseTypeName() {
+ return BASE_TYPE;
+ }
+}
+
diff --git a/libraries/bot-applicationinsights/src/main/java/com/microsoft/bot/applicationinsights/BotTelemetryClientImpl.java b/libraries/bot-applicationinsights/src/main/java/com/microsoft/bot/applicationinsights/BotTelemetryClientImpl.java
new file mode 100644
index 000000000..5a574164b
--- /dev/null
+++ b/libraries/bot-applicationinsights/src/main/java/com/microsoft/bot/applicationinsights/BotTelemetryClientImpl.java
@@ -0,0 +1,247 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+package com.microsoft.bot.applicationinsights;
+
+import com.microsoft.applicationinsights.TelemetryClient;
+import com.microsoft.applicationinsights.telemetry.EventTelemetry;
+import com.microsoft.applicationinsights.telemetry.ExceptionTelemetry;
+import com.microsoft.applicationinsights.telemetry.PageViewTelemetry;
+import com.microsoft.applicationinsights.telemetry.RemoteDependencyTelemetry;
+import com.microsoft.applicationinsights.telemetry.SeverityLevel;
+import com.microsoft.applicationinsights.telemetry.TraceTelemetry;
+import com.microsoft.bot.builder.BotTelemetryClient;
+import com.microsoft.bot.builder.Severity;
+
+import java.time.Duration;
+import java.time.OffsetDateTime;
+import java.util.Date;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+/**
+ * A logging client for bot telemetry.
+ */
+public class BotTelemetryClientImpl implements BotTelemetryClient {
+
+ private final TelemetryClient telemetryClient;
+
+ /**
+ * Initializes a new instance of the {@link BotTelemetryClient}.
+ *
+ * @param withTelemetryClient The telemetry client to forward bot events to.
+ */
+ public BotTelemetryClientImpl(TelemetryClient withTelemetryClient) {
+ if (withTelemetryClient == null) {
+ throw new IllegalArgumentException("withTelemetry should be provided");
+ }
+ this.telemetryClient = withTelemetryClient;
+ }
+
+ /**
+ * Send information about availability of an application.
+ *
+ * @param name Availability test name.
+ * @param timeStamp The time when the availability was captured.
+ * @param duration The time taken for the availability test to run.
+ * @param runLocation Name of the location the availability test was run from.
+ * @param success True if the availability test ran successfully.
+ * @param message Error message on availability test run failure.
+ * @param properties Named string values you can use to classify and search for this availability telemetry.
+ * @param metrics Additional values associated with this availability telemetry.
+ */
+ @SuppressWarnings("checkstyle:ParameterNumber")
+ @Override
+ public void trackAvailability(String name,
+ OffsetDateTime timeStamp,
+ Duration duration,
+ String runLocation,
+ boolean success,
+ String message,
+ Map properties,
+ Map metrics) {
+ com.microsoft.applicationinsights.telemetry.Duration durationTelemetry =
+ new com.microsoft.applicationinsights.telemetry.Duration(duration.toNanos());
+ ConcurrentMap concurrentProperties = new ConcurrentHashMap<>(properties);
+ ConcurrentMap concurrentMetrics = new ConcurrentHashMap<>(metrics);
+ AvailabilityTelemetry telemetry = new AvailabilityTelemetry(
+ name,
+ durationTelemetry,
+ runLocation,
+ message,
+ success,
+ concurrentMetrics,
+ concurrentProperties);
+ if (properties != null) {
+ for (Map.Entry pair: properties.entrySet()) {
+ telemetry.getProperties().put(pair.getKey(), pair.getValue());
+ }
+ }
+
+ if (metrics != null) {
+ for (Map.Entry pair: metrics.entrySet()) {
+ telemetry.getMetrics().put(pair.getKey(), pair.getValue());
+ }
+ }
+
+ /**
+ * This should be telemetryClient.trackAvailability(telemetry).
+ * However, it is not present in TelemetryClient class
+ */
+ telemetryClient.track(telemetry);
+ }
+
+ /**
+ * Send information about an external dependency (outgoing call) in the application.
+ *
+ * @param dependencyTypeName Name of the command initiated with this dependency call. Low cardinality value.
+ * Examples are SQL, Azure table, and HTTP.
+ * @param target External dependency target.
+ * @param dependencyName Name of the command initiated with this dependency call. Low cardinality value.
+ * Examples are stored procedure name and URL path template.
+ * @param data Command initiated by this dependency call. Examples are SQL statement and HTTP
+ * URL's with all query parameters.
+ * @param startTime The time when the dependency was called.
+ * @param duration The time taken by the external dependency to handle the call.
+ * @param resultCode Result code of dependency call execution.
+ * @param success True if the dependency call was handled successfully.
+ */
+ @SuppressWarnings("checkstyle:ParameterNumber")
+ @Override
+ public void trackDependency(String dependencyTypeName,
+ String target,
+ String dependencyName,
+ String data,
+ OffsetDateTime startTime,
+ Duration duration,
+ String resultCode,
+ boolean success) {
+ com.microsoft.applicationinsights.telemetry.Duration durationTelemetry =
+ new com.microsoft.applicationinsights.telemetry.Duration(duration.toNanos());
+
+ RemoteDependencyTelemetry telemetry =
+ new RemoteDependencyTelemetry(dependencyName, data, durationTelemetry, success);
+
+ telemetry.setType(dependencyTypeName);
+ telemetry.setTarget(target);
+ telemetry.setTimestamp(new Date(startTime.toInstant().toEpochMilli()));
+ telemetry.setResultCode(resultCode);
+
+ telemetryClient.trackDependency(telemetry);
+ }
+
+ /**
+ * Logs custom events with extensible named fields.
+ *
+ * @param eventName A name for the event.
+ * @param properties Named string values you can use to search and classify events.
+ * @param metrics Measurements associated with this event.
+ */
+ @Override
+ public void trackEvent(String eventName, Map properties, Map metrics) {
+ EventTelemetry telemetry = new EventTelemetry(eventName);
+ if (properties != null) {
+ for (Map.Entry pair: properties.entrySet()) {
+ telemetry.getProperties().put(pair.getKey(), pair.getValue());
+ }
+ }
+
+ if (metrics != null) {
+ for (Map.Entry pair: metrics.entrySet()) {
+ telemetry.getMetrics().put(pair.getKey(), pair.getValue());
+ }
+ }
+
+ telemetryClient.trackEvent(telemetry);
+ }
+
+ /**
+ * Logs a system exception.
+ *
+ * @param exception The exception to log.
+ * @param properties Named string values you can use to classify and search for this exception.
+ * @param metrics Additional values associated with this exception
+ */
+ @Override
+ public void trackException(Exception exception, Map properties, Map metrics) {
+ ExceptionTelemetry telemetry = new ExceptionTelemetry(exception);
+ if (properties != null) {
+ for (Map.Entry pair: properties.entrySet()) {
+ telemetry.getProperties().put(pair.getKey(), pair.getValue());
+ }
+ }
+
+ if (metrics != null) {
+ for (Map.Entry pair: metrics.entrySet()) {
+ telemetry.getMetrics().put(pair.getKey(), pair.getValue());
+ }
+ }
+
+ telemetryClient.trackException(telemetry);
+ }
+
+ /**
+ * Send a trace message.
+ *
+ * @param message Message to display.
+ * @param severityLevel Trace severity level {@link Severity}.
+ * @param properties Named string values you can use to search and classify events.
+ */
+ @Override
+ public void trackTrace(String message, Severity severityLevel, Map properties) {
+ TraceTelemetry telemetry = new TraceTelemetry(message);
+ telemetry.setSeverityLevel(SeverityLevel.values()[severityLevel.ordinal()]);
+
+ if (properties != null) {
+ for (Map.Entry pair: properties.entrySet()) {
+ telemetry.getProperties().put(pair.getKey(), pair.getValue());
+ }
+ }
+
+ telemetryClient.trackTrace(telemetry);
+ }
+
+ /**
+ * We implemented this method calling the tracePageView method from {@link BotTelemetryClientImpl} as the
+ * IBotPageViewTelemetryClient has not been implemented.
+ * {@inheritDoc}
+ */
+ @Override
+ public void trackDialogView(String dialogName, Map properties, Map metrics) {
+ trackPageView(dialogName, properties, metrics);
+ }
+
+ /**
+ * Logs a dialog entry / as an Application Insights page view.
+ *
+ * @param dialogName The name of the dialog to log the entry / start for.
+ * @param properties Named string values you can use to search and classify events.
+ * @param metrics Measurements associated with this event.
+ */
+ public void trackPageView(String dialogName, Map properties, Map metrics) {
+ PageViewTelemetry telemetry = new PageViewTelemetry(dialogName);
+
+ if (properties != null) {
+ for (Map.Entry pair: properties.entrySet()) {
+ telemetry.getProperties().put(pair.getKey(), pair.getValue());
+ }
+ }
+
+ if (metrics != null) {
+ for (Map.Entry pair: metrics.entrySet()) {
+ telemetry.getMetrics().put(pair.getKey(), pair.getValue());
+ }
+ }
+
+ telemetryClient.trackPageView(telemetry);
+ }
+
+ /**
+ * Flushes the in-memory buffer and any metrics being pre-aggregated.
+ */
+ @Override
+ public void flush() {
+ telemetryClient.flush();
+ }
+}
diff --git a/libraries/bot-applicationinsights/src/main/java/com/microsoft/bot/applicationinsights/core/TelemetryInitializerMiddleware.java b/libraries/bot-applicationinsights/src/main/java/com/microsoft/bot/applicationinsights/core/TelemetryInitializerMiddleware.java
new file mode 100644
index 000000000..4126e9369
--- /dev/null
+++ b/libraries/bot-applicationinsights/src/main/java/com/microsoft/bot/applicationinsights/core/TelemetryInitializerMiddleware.java
@@ -0,0 +1,74 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for
+// license information.
+
+package com.microsoft.bot.applicationinsights.core;
+
+import com.microsoft.applicationinsights.core.dependencies.http.client.protocol.HttpClientContext;
+import com.microsoft.applicationinsights.core.dependencies.http.protocol.HttpContext;
+import com.microsoft.bot.builder.BotAssert;
+import com.microsoft.bot.builder.Middleware;
+import com.microsoft.bot.builder.NextDelegate;
+import com.microsoft.bot.builder.TelemetryLoggerMiddleware;
+import com.microsoft.bot.builder.TurnContext;
+import com.microsoft.bot.schema.Activity;
+
+import java.util.concurrent.CompletableFuture;
+
+/**
+ * Middleware for storing incoming activity on the HttpContext.
+ */
+public class TelemetryInitializerMiddleware implements Middleware {
+
+ private HttpContext httpContext;
+ private final String botActivityKey = "BotBuilderActivity";
+ private final TelemetryLoggerMiddleware telemetryLoggerMiddleware;
+ private final Boolean logActivityTelemetry;
+
+ /**
+ * Initializes a new instance of the {@link TelemetryInitializerMiddleware}.
+ * @param withTelemetryLoggerMiddleware The TelemetryLoggerMiddleware to use.
+ * @param withLogActivityTelemetry Boolean determining if you want to log telemetry activity
+ */
+ public TelemetryInitializerMiddleware(TelemetryLoggerMiddleware withTelemetryLoggerMiddleware,
+ Boolean withLogActivityTelemetry) {
+ telemetryLoggerMiddleware = withTelemetryLoggerMiddleware;
+ if (withLogActivityTelemetry == null) {
+ withLogActivityTelemetry = true;
+ }
+ logActivityTelemetry = withLogActivityTelemetry;
+ }
+
+ /**
+ * Stores the incoming activity as JSON in the items collection on the HttpContext.
+ * @param context The incoming TurnContext
+ * @param next Delegate to run next on
+ * @return Returns a CompletableFuture with Void value
+ */
+ public CompletableFuture onTurn(TurnContext context, NextDelegate next) {
+ BotAssert.contextNotNull(context);
+
+ if (context.getActivity() != null) {
+ Activity activity = context.getActivity();
+
+ if (this.httpContext == null) {
+ this.httpContext = HttpClientContext.create();
+ }
+
+ Object item = httpContext.getAttribute(botActivityKey);
+
+ if (item != null) {
+ httpContext.removeAttribute(botActivityKey);
+ }
+
+ httpContext.setAttribute(botActivityKey, activity);
+ }
+
+ if (logActivityTelemetry) {
+ return telemetryLoggerMiddleware.onTurn(context, next);
+ } else {
+ return next.next();
+ }
+ }
+}
+
diff --git a/libraries/bot-applicationinsights/src/main/java/com/microsoft/bot/applicationinsights/core/package-info.java b/libraries/bot-applicationinsights/src/main/java/com/microsoft/bot/applicationinsights/core/package-info.java
new file mode 100644
index 000000000..300ffc6bb
--- /dev/null
+++ b/libraries/bot-applicationinsights/src/main/java/com/microsoft/bot/applicationinsights/core/package-info.java
@@ -0,0 +1,8 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for
+// license information.
+
+/**
+ * This package contains the classes for bot-applicationinsights.
+ */
+package com.microsoft.bot.applicationinsights.core;
diff --git a/libraries/bot-applicationinsights/src/main/java/com/microsoft/bot/applicationinsights/package-info.java b/libraries/bot-applicationinsights/src/main/java/com/microsoft/bot/applicationinsights/package-info.java
new file mode 100644
index 000000000..4bf130b60
--- /dev/null
+++ b/libraries/bot-applicationinsights/src/main/java/com/microsoft/bot/applicationinsights/package-info.java
@@ -0,0 +1,8 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for
+// license information.
+
+/**
+ * This package contains the classes for bot-applicationinsights.
+ */
+package com.microsoft.bot.applicationinsights;
diff --git a/libraries/bot-applicationinsights/src/test/java/com/microsoft/bot/applicationinsights/BotTelemetryClientTests.java b/libraries/bot-applicationinsights/src/test/java/com/microsoft/bot/applicationinsights/BotTelemetryClientTests.java
new file mode 100644
index 000000000..5ae1436a7
--- /dev/null
+++ b/libraries/bot-applicationinsights/src/test/java/com/microsoft/bot/applicationinsights/BotTelemetryClientTests.java
@@ -0,0 +1,183 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+package com.microsoft.bot.applicationinsights;
+
+import com.microsoft.applicationinsights.TelemetryClient;
+import com.microsoft.applicationinsights.TelemetryConfiguration;
+import com.microsoft.applicationinsights.channel.TelemetryChannel;
+import com.microsoft.applicationinsights.telemetry.EventTelemetry;
+import com.microsoft.applicationinsights.telemetry.RemoteDependencyTelemetry;
+import com.microsoft.applicationinsights.telemetry.PageViewTelemetry;
+import com.microsoft.applicationinsights.telemetry.ExceptionTelemetry;
+import com.microsoft.applicationinsights.telemetry.TraceTelemetry;
+import com.microsoft.applicationinsights.telemetry.SeverityLevel;
+import com.microsoft.bot.builder.BotTelemetryClient;
+import com.microsoft.bot.builder.Severity;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import java.time.Duration;
+import java.time.OffsetDateTime;
+import java.util.HashMap;
+import java.util.Map;
+
+public class BotTelemetryClientTests {
+
+ private BotTelemetryClient botTelemetryClient;
+ private TelemetryChannel mockTelemetryChannel;
+
+ @Before
+ public void initialize() {
+ mockTelemetryChannel = Mockito.mock(TelemetryChannel.class);
+
+ TelemetryConfiguration telemetryConfiguration = new TelemetryConfiguration();
+ telemetryConfiguration.setInstrumentationKey("UNITTEST-INSTRUMENTATION-KEY");
+ telemetryConfiguration.setChannel(mockTelemetryChannel);
+ TelemetryClient telemetryClient = new TelemetryClient(telemetryConfiguration);
+
+ botTelemetryClient = new BotTelemetryClientImpl(telemetryClient);
+ }
+
+ @Test
+ public void nullTelemetryClientThrows() {
+ Assert.assertThrows(IllegalArgumentException.class, () -> {
+ new BotTelemetryClientImpl(null);
+ });
+ }
+
+ @Test
+ public void nonNullTelemetryClientSucceeds() {
+ TelemetryClient telemetryClient = new TelemetryClient();
+
+ BotTelemetryClient botTelemetryClient = new BotTelemetryClientImpl(telemetryClient);
+ }
+
+ @Test
+ public void overrideTest() {
+ TelemetryClient telemetryClient = new TelemetryClient();
+ MyBotTelemetryClient botTelemetryClient = new MyBotTelemetryClient(telemetryClient);
+ }
+
+ @Test
+ public void trackAvailabilityTest() {
+ Map properties = new HashMap<>();
+ Map metrics = new HashMap<>();
+ properties.put("hello", "value");
+ metrics.put("metric", 0.6);
+
+ botTelemetryClient.trackAvailability(
+ "test",
+ OffsetDateTime.now(),
+ Duration.ofNanos(1000),
+ "run location",
+ true,
+ "message",
+ properties,
+ metrics);
+
+ Mockito.verify(mockTelemetryChannel, invocations -> {
+ AvailabilityTelemetry availabilityTelemetry = invocations.getAllInvocations().get(0).getArgument(0);
+ Assert.assertEquals("test", availabilityTelemetry.getName());
+ Assert.assertEquals("message", availabilityTelemetry.getData().getMessage());
+ Assert.assertEquals("value", availabilityTelemetry.getProperties().get("hello"));
+ Assert.assertEquals(0, Double.compare(0.6, availabilityTelemetry.getMetrics().get("metric")));
+ }).send(Mockito.any(AvailabilityTelemetry.class));
+
+ }
+
+ @Test
+ public void trackEventTest() {
+ Map properties = new HashMap<>();
+ properties.put("hello", "value");
+ Map metrics = new HashMap<>();
+ metrics.put("metric", 0.6);
+
+ botTelemetryClient.trackEvent("test", properties, metrics);
+
+ Mockito.verify(mockTelemetryChannel, invocations -> {
+ EventTelemetry eventTelemetry = invocations.getAllInvocations().get(0).getArgument(0);
+
+ Assert.assertEquals("test", eventTelemetry.getName());
+ Assert.assertEquals("value", eventTelemetry.getProperties().get("hello"));
+ Assert.assertEquals(0, Double.compare(0.6, eventTelemetry.getMetrics().get("metric")));
+ }).send(Mockito.any(AvailabilityTelemetry.class));
+ }
+
+ @Test
+ public void trackDependencyTest() {
+ botTelemetryClient.trackDependency(
+ "test",
+ "target",
+ "dependencyname",
+ "data",
+ OffsetDateTime.now(),
+ Duration.ofNanos(1000),
+ "result", false);
+
+ Mockito.verify(mockTelemetryChannel, invocations -> {
+ RemoteDependencyTelemetry remoteDependencyTelemetry = invocations.getAllInvocations().get(0).getArgument(0);
+
+ Assert.assertEquals("test", remoteDependencyTelemetry.getType());
+ Assert.assertEquals("target", remoteDependencyTelemetry.getTarget());
+ Assert.assertEquals("dependencyname", remoteDependencyTelemetry.getName());
+ Assert.assertEquals("result", remoteDependencyTelemetry.getResultCode());
+ Assert.assertFalse(remoteDependencyTelemetry.getSuccess());
+ }).send(Mockito.any(AvailabilityTelemetry.class));
+ }
+
+ @Test
+ public void trackExceptionTest() {
+ Exception expectedException = new Exception("test-exception");
+ Map properties = new HashMap<>();
+ properties.put("foo", "bar");
+ Map metrics = new HashMap<>();
+ metrics.put("metric", 0.6);
+
+ botTelemetryClient.trackException(expectedException, properties, metrics);
+
+ Mockito.verify(mockTelemetryChannel, invocations -> {
+ ExceptionTelemetry exceptionTelemetry = invocations.getAllInvocations().get(0).getArgument(0);
+
+ Assert.assertEquals(expectedException, exceptionTelemetry.getException());
+ Assert.assertEquals("bar", exceptionTelemetry.getProperties().get("foo"));
+ Assert.assertEquals(0, Double.compare(0.6, exceptionTelemetry.getMetrics().get("metric")));
+ }).send(Mockito.any(ExceptionTelemetry.class));
+ }
+
+ @Test
+ public void trackTraceTest() {
+ Map properties = new HashMap<>();
+ properties.put("foo", "bar");
+
+ botTelemetryClient.trackTrace("hello", Severity.CRITICAL, properties);
+
+ Mockito.verify(mockTelemetryChannel, invocations -> {
+ TraceTelemetry traceTelemetry = invocations.getAllInvocations().get(0).getArgument(0);
+
+ Assert.assertEquals("hello", traceTelemetry.getMessage());
+ Assert.assertEquals(SeverityLevel.Critical, traceTelemetry.getSeverityLevel());
+ Assert.assertEquals("bar", traceTelemetry.getProperties().get("foo"));
+ }).send(Mockito.any(TraceTelemetry.class));
+ }
+
+ @Test
+ public void trackPageViewTest() {
+ Map properties = new HashMap<>();
+ properties.put("hello", "value");
+ Map metrics = new HashMap<>();
+ metrics.put("metric", 0.6);
+
+ botTelemetryClient.trackDialogView("test", properties, metrics);
+
+ Mockito.verify(mockTelemetryChannel, invocations -> {
+ PageViewTelemetry pageViewTelemetry = invocations.getAllInvocations().get(0).getArgument(0);
+
+ Assert.assertEquals("test", pageViewTelemetry.getName());
+ Assert.assertEquals("value", pageViewTelemetry.getProperties().get("hello"));
+ Assert.assertEquals(0, Double.compare(0.6, pageViewTelemetry.getMetrics().get("metric")));
+ }).send(Mockito.any(PageViewTelemetry.class));
+ }
+}
diff --git a/libraries/bot-applicationinsights/src/test/java/com/microsoft/bot/applicationinsights/MyBotTelemetryClient.java b/libraries/bot-applicationinsights/src/test/java/com/microsoft/bot/applicationinsights/MyBotTelemetryClient.java
new file mode 100644
index 000000000..5558ca0d0
--- /dev/null
+++ b/libraries/bot-applicationinsights/src/test/java/com/microsoft/bot/applicationinsights/MyBotTelemetryClient.java
@@ -0,0 +1,87 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+package com.microsoft.bot.applicationinsights;
+
+import com.microsoft.applicationinsights.TelemetryClient;
+import com.microsoft.bot.builder.Severity;
+
+import java.time.Duration;
+import java.time.OffsetDateTime;
+import java.util.Map;
+
+public class MyBotTelemetryClient extends BotTelemetryClientImpl {
+ public MyBotTelemetryClient(TelemetryClient telemetryClient) {
+ super(telemetryClient);
+ }
+
+ @Override
+ public void trackDependency(
+ String dependencyTypeName,
+ String target,
+ String dependencyName,
+ String data,
+ OffsetDateTime startTime,
+ Duration duration,
+ String resultCode,
+ boolean success)
+ {
+ super.trackDependency(dependencyName, target, dependencyName, data, startTime, duration, resultCode, success);
+ }
+
+ @Override
+ public void trackAvailability(
+ String name,
+ OffsetDateTime timeStamp,
+ Duration duration,
+ String runLocation,
+ boolean success,
+ String message,
+ Map properties,
+ Map metrics)
+ {
+ super.trackAvailability(name, timeStamp, duration, runLocation, success, message, properties, metrics);
+ }
+
+ @Override
+ public void trackEvent(
+ String eventName,
+ Map properties,
+ Map metrics)
+ {
+ super.trackEvent(eventName, properties, metrics);
+ }
+
+ @Override
+ public void trackException(
+ Exception exception,
+ Map properties,
+ Map metrics)
+ {
+ super.trackException(exception, properties, metrics);
+ }
+
+ @Override
+ public void trackTrace(
+ String message,
+ Severity severityLevel,
+ Map properties)
+ {
+ super.trackTrace(message, severityLevel, properties);
+ }
+
+ @Override
+ public void trackPageView(
+ String name,
+ Map properties,
+ Map metrics)
+ {
+ super.trackPageView(name, properties, metrics);
+ }
+
+ @Override
+ public void flush()
+ {
+ super.flush();
+ }
+}
diff --git a/libraries/bot-applicationinsights/src/test/java/com/microsoft/bot/applicationinsights/TelemetryInitializerTests.java b/libraries/bot-applicationinsights/src/test/java/com/microsoft/bot/applicationinsights/TelemetryInitializerTests.java
new file mode 100644
index 000000000..06592eef9
--- /dev/null
+++ b/libraries/bot-applicationinsights/src/test/java/com/microsoft/bot/applicationinsights/TelemetryInitializerTests.java
@@ -0,0 +1,132 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+package com.microsoft.bot.applicationinsights;
+
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.TimeUnit;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mockito;
+
+import com.microsoft.bot.applicationinsights.core.TelemetryInitializerMiddleware;
+import com.microsoft.bot.builder.BotTelemetryClient;
+import com.microsoft.bot.builder.TelemetryLoggerMiddleware;
+import com.microsoft.bot.builder.adapters.TestAdapter;
+import com.microsoft.bot.builder.adapters.TestFlow;
+import com.microsoft.bot.schema.Activity;
+import com.microsoft.bot.schema.ActivityTypes;
+import org.mockito.junit.MockitoJUnitRunner;
+
+@RunWith(MockitoJUnitRunner.class)
+public class TelemetryInitializerTests {
+
+ @Captor
+ ArgumentCaptor eventNameCaptor;
+
+ @Captor
+ ArgumentCaptor