Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[JN-1533] mixpanel integration tab #1322

Merged
merged 3 commits into from
Dec 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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();
}
Expand Down Expand Up @@ -85,7 +89,11 @@ private Map<String, String> 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;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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() {
Expand All @@ -41,7 +43,8 @@ public void testAllMethodsAnnotated() {
applicationRoutingPaths,
pepperDSMConfig,
addressValidationConfig,
airtableConfig),
airtableConfig,
mixpanelConfig),
Map.of(
"maskSecret",
AuthAnnotationSpec.withPublicAnnotation(),
Expand All @@ -66,7 +69,8 @@ public void testConfigMap() {
applicationRoutingPaths,
pepperDSMConfig,
addressValidationConfig,
airtableConfig);
airtableConfig,
mixpanelConfig);
Map<String, String> configMap = configExtService.getConfigMap();
Assertions.assertEquals("something.org", configMap.get("participantUiHostname"));
}
Expand All @@ -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<String, ?> dsmConfigMap =
(Map<String, ?>)
Expand All @@ -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
Expand Down
2 changes: 2 additions & 0 deletions api-participant/src/main/resources/application-gcp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ env:
addrValidation:
smartyAuthId: ${sm://${SMARTY_AUTH_ID_SECRET_ID}}
smartyAuthToken: ${sm://${SMARTY_AUTH_TOKEN_SECRET_ID}}
mixpanel:
token: ${sm://${MIXPANEL_TOKEN_SECRET_ID}}
spring:
cloud:
gcp:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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");
}
}

}
1 change: 1 addition & 0 deletions ui-admin/src/api/api.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,7 @@ export type InternalConfig = {
pepperDsmConfig: Record<string, string>
addrValidationConfig: Record<string, string>
airtable: Record<string, string>
mixpanel: Record<string, string>
}

export type ParticipantTaskUpdateDto = {
Expand Down
3 changes: 3 additions & 0 deletions ui-admin/src/integration/IntegrationDashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand All @@ -17,13 +18,15 @@ export default function IntegrationDashboard() {
<li style={navListItemStyle}><NavLink to="addressValidation" style={navLinkStyleFunc}>Address
Validation</NavLink></li>
<li style={navListItemStyle}><NavLink to="airtable" style={navLinkStyleFunc}>Airtable</NavLink></li>
<li style={navListItemStyle}><NavLink to="mixpanel" style={navLinkStyleFunc}>Mixpanel</NavLink></li>
</ul>
</div>
<div className="px-3">
<Routes>
<Route path="kits" element={<KitIntegrationDashboard/>}/>
<Route path="addressValidation" element={<AddressValidationIntegrationDashboard/>}/>
<Route path="airtable" element={<AirtableIntegrationDashboard/>}/>
<Route path="mixpanel" element={<MixpanelIntegrationDashboard/>}/>
</Routes>
<Outlet/>
</div>
Expand Down
28 changes: 28 additions & 0 deletions ui-admin/src/integration/MixpanelIntegrationDashboard.tsx
Original file line number Diff line number Diff line change
@@ -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<InternalConfig>()

const { isLoading } = useLoadingEffect(async () => {
const response = await Api.fetchInternalConfig()
setConfig(response)
})

return <div>
<h2 className="h3">Mixpanel</h2>
<div className="mt-4">
<h3 className="h5">Config</h3>
{!isLoading && <dl>
<dt>enabled</dt>
<dd>{config?.mixpanel.enabled}</dd>
<dt>token</dt>
<dd>{config?.mixpanel.token}</dd>
</dl>}
{isLoading && <LoadingSpinner/>}
</div>
</div>
}
Loading