From 5680da03f4432b2d80f630ddf5864f87d8dd8c9e Mon Sep 17 00:00:00 2001 From: Matt Bemis Date: Tue, 10 Dec 2024 09:24:00 -0500 Subject: [PATCH] [JN-1533] mixpanel integration tab (#1322) --- .../api/admin/service/ConfigExtService.java | 12 ++++++-- .../admin/service/ConfigExtServiceTests.java | 20 ++++++++++--- .../core/service/logging/MixpanelService.java | 15 ++++++++++ ui-admin/src/api/api.tsx | 1 + .../src/integration/IntegrationDashboard.tsx | 3 ++ .../MixpanelIntegrationDashboard.tsx | 28 +++++++++++++++++++ 6 files changed, 73 insertions(+), 6 deletions(-) create mode 100644 ui-admin/src/integration/MixpanelIntegrationDashboard.tsx diff --git a/api-admin/src/main/java/bio/terra/pearl/api/admin/service/ConfigExtService.java b/api-admin/src/main/java/bio/terra/pearl/api/admin/service/ConfigExtService.java index f289f23382..1a03535b54 100644 --- a/api-admin/src/main/java/bio/terra/pearl/api/admin/service/ConfigExtService.java +++ b/api-admin/src/main/java/bio/terra/pearl/api/admin/service/ConfigExtService.java @@ -7,6 +7,7 @@ import bio.terra.pearl.core.service.address.AddressValidationConfig; import bio.terra.pearl.core.service.export.integration.AirtableExporter; import bio.terra.pearl.core.service.kit.pepper.LivePepperDSMClient; +import bio.terra.pearl.core.service.logging.MixpanelService; import bio.terra.pearl.core.shared.ApplicationRoutingPaths; import java.util.Map; import org.apache.commons.lang3.StringUtils; @@ -21,18 +22,21 @@ public class ConfigExtService { private final LivePepperDSMClient.PepperDSMConfig pepperDSMConfig; private final AddressValidationConfig addressValidationConfig; private final AirtableExporter.AirtableConfig airtableConfig; + private final MixpanelService.MixpanelConfig mixpanelConfig; public ConfigExtService( B2CConfiguration b2CConfiguration, ApplicationRoutingPaths applicationRoutingPaths, LivePepperDSMClient.PepperDSMConfig pepperDSMConfig, AddressValidationConfig addressValidationConfig, - AirtableExporter.AirtableConfig airtableConfig) { + AirtableExporter.AirtableConfig airtableConfig, + MixpanelService.MixpanelConfig mixpanelConfig) { this.b2CConfiguration = b2CConfiguration; this.pepperDSMConfig = pepperDSMConfig; this.applicationRoutingPaths = applicationRoutingPaths; this.addressValidationConfig = addressValidationConfig; this.airtableConfig = airtableConfig; + this.mixpanelConfig = mixpanelConfig; configMap = buildConfigMap(); } @@ -85,7 +89,11 @@ private Map buildConfigMap() { "smartyAuthId", addressValidationConfig.getAuthId(), "smartyAuthToken", maskSecret(addressValidationConfig.getAuthToken())), "airtable", - Map.of("authToken", maskSecret(airtableConfig.getAuthToken()))); + Map.of("authToken", maskSecret(airtableConfig.getAuthToken())), + "mixpanel", + Map.of( + "enabled", mixpanelConfig.getEnabled(), + "token", mixpanelConfig.getToken())); return internalConfigMap; } diff --git a/api-admin/src/test/java/bio/terra/pearl/api/admin/service/ConfigExtServiceTests.java b/api-admin/src/test/java/bio/terra/pearl/api/admin/service/ConfigExtServiceTests.java index e8ed0f6bd7..69fb1b582a 100644 --- a/api-admin/src/test/java/bio/terra/pearl/api/admin/service/ConfigExtServiceTests.java +++ b/api-admin/src/test/java/bio/terra/pearl/api/admin/service/ConfigExtServiceTests.java @@ -13,6 +13,7 @@ import bio.terra.pearl.core.service.address.AddressValidationConfig; import bio.terra.pearl.core.service.export.integration.AirtableExporter; import bio.terra.pearl.core.service.kit.pepper.LivePepperDSMClient; +import bio.terra.pearl.core.service.logging.MixpanelService; import bio.terra.pearl.core.shared.ApplicationRoutingPaths; import java.util.List; import java.util.Map; @@ -32,6 +33,7 @@ public class ConfigExtServiceTests { @MockBean private LivePepperDSMClient.PepperDSMConfig pepperDSMConfig; @MockBean private AddressValidationConfig addressValidationConfig; @MockBean private AirtableExporter.AirtableConfig airtableConfig; + @MockBean private MixpanelService.MixpanelConfig mixpanelConfig; @Test public void testAllMethodsAnnotated() { @@ -41,7 +43,8 @@ public void testAllMethodsAnnotated() { applicationRoutingPaths, pepperDSMConfig, addressValidationConfig, - airtableConfig), + airtableConfig, + mixpanelConfig), Map.of( "maskSecret", AuthAnnotationSpec.withPublicAnnotation(), @@ -66,7 +69,8 @@ public void testConfigMap() { applicationRoutingPaths, pepperDSMConfig, addressValidationConfig, - airtableConfig); + airtableConfig, + mixpanelConfig); Map configMap = configExtService.getConfigMap(); Assertions.assertEquals("something.org", configMap.get("participantUiHostname")); } @@ -81,19 +85,24 @@ public void testInternalConfigMap() { .withProperty("env.dsm.secret", "superSecret") .withProperty("env.addrValidation.addrValidationServiceClass", "someClass") .withProperty("env.addrValidation.smartyAuthId", "sm_id") - .withProperty("env.addrValidation.smartyAuthToken", "sm_token"); + .withProperty("env.addrValidation.smartyAuthToken", "sm_token") + .withProperty("env.mixpanel.enabled", "true") + .withProperty("env.mixpanel.token", "mp_token"); LivePepperDSMClient.PepperDSMConfig testPepperConfig = new LivePepperDSMClient.PepperDSMConfig(mockEnvironment); AddressValidationConfig testAddrConfig = new AddressValidationConfig(mockEnvironment); + MixpanelService.MixpanelConfig testMixpanelConfig = + new MixpanelService.MixpanelConfig(mockEnvironment); ConfigExtService configExtService = new ConfigExtService( b2CConfiguration, applicationRoutingPaths, testPepperConfig, testAddrConfig, - airtableConfig); + airtableConfig, + testMixpanelConfig); @SuppressWarnings("unchecked") Map dsmConfigMap = (Map) @@ -113,6 +122,9 @@ public void testInternalConfigMap() { assertThat(addressValidationConfigMap.get("addrValidationServiceClass"), equalTo("someClass")); assertThat(addressValidationConfigMap.get("smartyAuthId"), equalTo("sm_id")); assertThat(addressValidationConfigMap.get("smartyAuthToken"), equalTo("sm...")); + + assertThat(testMixpanelConfig.getEnabled(), equalTo("true")); + assertThat(testMixpanelConfig.getToken(), equalTo("mp_token")); } @Test diff --git a/core/src/main/java/bio/terra/pearl/core/service/logging/MixpanelService.java b/core/src/main/java/bio/terra/pearl/core/service/logging/MixpanelService.java index dd924710ea..4874e607a9 100644 --- a/core/src/main/java/bio/terra/pearl/core/service/logging/MixpanelService.java +++ b/core/src/main/java/bio/terra/pearl/core/service/logging/MixpanelService.java @@ -3,10 +3,13 @@ import com.mixpanel.mixpanelapi.ClientDelivery; import com.mixpanel.mixpanelapi.MessageBuilder; import com.mixpanel.mixpanelapi.MixpanelAPI; +import lombok.Getter; +import lombok.Setter; import lombok.extern.slf4j.Slf4j; import org.json.JSONArray; import org.json.JSONObject; import org.springframework.core.env.Environment; +import org.springframework.stereotype.Component; import org.springframework.stereotype.Service; import java.io.IOException; @@ -86,4 +89,16 @@ protected void deliverEvents(ClientDelivery delivery) { } } + @Component + @Getter @Setter + public static class MixpanelConfig { + private String token; + private String enabled; + + public MixpanelConfig(Environment environment) { + this.token = environment.getProperty("env.mixpanel.token"); + this.enabled = environment.getProperty("env.mixpanel.enabled"); + } + } + } diff --git a/ui-admin/src/api/api.tsx b/ui-admin/src/api/api.tsx index 7129e6a25a..74ede650d8 100644 --- a/ui-admin/src/api/api.tsx +++ b/ui-admin/src/api/api.tsx @@ -338,6 +338,7 @@ export type InternalConfig = { pepperDsmConfig: Record addrValidationConfig: Record airtable: Record + mixpanel: Record } export type ParticipantTaskUpdateDto = { diff --git a/ui-admin/src/integration/IntegrationDashboard.tsx b/ui-admin/src/integration/IntegrationDashboard.tsx index c807b2f331..ac1287253e 100644 --- a/ui-admin/src/integration/IntegrationDashboard.tsx +++ b/ui-admin/src/integration/IntegrationDashboard.tsx @@ -5,6 +5,7 @@ import AddressValidationIntegrationDashboard from './AddressValidationIntegratio import { navDivStyle, navLinkStyleFunc, navListItemStyle } from 'util/subNavStyles' import { renderPageHeader } from 'util/pageUtils' import AirtableIntegrationDashboard from './AirtableIntegrationDashboard' +import MixpanelIntegrationDashboard from './MixpanelIntegrationDashboard' /** shows links to the populate control panels, and handles the routing for them */ export default function IntegrationDashboard() { @@ -17,6 +18,7 @@ export default function IntegrationDashboard() {
  • Address Validation
  • Airtable
  • +
  • Mixpanel
  • @@ -24,6 +26,7 @@ export default function IntegrationDashboard() { }/> }/> }/> + }/>
    diff --git a/ui-admin/src/integration/MixpanelIntegrationDashboard.tsx b/ui-admin/src/integration/MixpanelIntegrationDashboard.tsx new file mode 100644 index 0000000000..be92b48057 --- /dev/null +++ b/ui-admin/src/integration/MixpanelIntegrationDashboard.tsx @@ -0,0 +1,28 @@ +import React, { useState } from 'react' +import { useLoadingEffect } from 'api/api-utils' +import Api, { InternalConfig } from 'api/api' +import LoadingSpinner from 'util/LoadingSpinner' + + +export default function MixpanelIntegrationDashboard() { + const [config, setConfig] = useState() + + const { isLoading } = useLoadingEffect(async () => { + const response = await Api.fetchInternalConfig() + setConfig(response) + }) + + return
    +

    Mixpanel

    +
    +

    Config

    + {!isLoading &&
    +
    enabled
    +
    {config?.mixpanel.enabled}
    +
    token
    +
    {config?.mixpanel.token}
    +
    } + {isLoading && } +
    +
    +}