diff --git a/README.md b/README.md
index 608e8e31..cedc0b39 100644
--- a/README.md
+++ b/README.md
@@ -15,7 +15,7 @@ The API has the following endpoints:
- Type: `POST`
- Path: `/api/v1/feel/evaluate`
-Request:
+Request:
```json
{
@@ -41,7 +41,7 @@ Response:
- Type: `POST`
- Path: `/api/v1/feel-unary-tests/evaluate`
-Request:
+Request:
```json
{
@@ -89,6 +89,12 @@ kubectl create namespace feel
kubectl apply -f service.yaml -n feel
```
+To deploy the secrets, edit `secret.yaml` and set `mixpanel_project_token` to your Mixpanel project token. Then run the following:
+
+```shell
+kubectl apply -f secret.yaml -n feel
+```
+
To deploy the rest api, edit `deployment.yaml` and set `spec.template.spec.containers[0].img` to point
to the latest docker image. Then run the following:
diff --git a/k8s/deployment.yaml b/k8s/deployment.yaml
index c218bcdb..50751dd4 100644
--- a/k8s/deployment.yaml
+++ b/k8s/deployment.yaml
@@ -21,3 +21,9 @@ spec:
port: 8080
initialDelaySeconds: 10
timeoutSeconds: 5
+ env:
+ - name: MIXPANEL_PROJECT_TOKEN
+ valueFrom:
+ secretKeyRef:
+ name: feel-scala-playground-secret
+ key: mixpanel_project_token
diff --git a/k8s/secret.yaml b/k8s/secret.yaml
new file mode 100644
index 00000000..068161a2
--- /dev/null
+++ b/k8s/secret.yaml
@@ -0,0 +1,7 @@
+apiVersion: v1
+kind: Secret
+metadata:
+ name: feel-scala-playground-secret
+type: Opaque
+stringData:
+ mixpanel_project_token: x
diff --git a/pom.xml b/pom.xml
index d4c3b8ef..069902bc 100644
--- a/pom.xml
+++ b/pom.xml
@@ -39,6 +39,12 @@
${feel.version}
+
+ com.mixpanel
+ mixpanel-java
+ 1.5.2
+
+
@@ -59,6 +65,11 @@
spring-boot-starter-actuator
+
+ com.mixpanel
+ mixpanel-java
+
+
org.springframework.boot
spring-boot-starter-test
diff --git a/src/main/java/org/camunda/feel/playground/api/FeelEvaluationController.java b/src/main/java/org/camunda/feel/playground/api/FeelEvaluationController.java
index 85c1be6b..3b0eb7ae 100644
--- a/src/main/java/org/camunda/feel/playground/api/FeelEvaluationController.java
+++ b/src/main/java/org/camunda/feel/playground/api/FeelEvaluationController.java
@@ -4,6 +4,7 @@
import org.camunda.feel.playground.dto.FeelEvaluationResponse;
import org.camunda.feel.playground.dto.FeelUnaryTestsEvaluationRequest;
import org.camunda.feel.playground.sevice.FeelEvaluationService;
+import org.camunda.feel.playground.sevice.TrackingService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
@@ -22,9 +23,11 @@ public class FeelEvaluationController {
private static final Logger LOG = LoggerFactory.getLogger(FeelEvaluationController.class);
private final FeelEvaluationService evaluationService;
+ private final TrackingService trackingService;
- public FeelEvaluationController(final FeelEvaluationService evaluationService) {
+ public FeelEvaluationController(final FeelEvaluationService evaluationService, TrackingService trackingService) {
this.evaluationService = evaluationService;
+ this.trackingService = trackingService;
}
@PostMapping("/feel/evaluate")
@@ -40,6 +43,9 @@ public ResponseEntity evaluate(
} catch (Exception e) {
return new ResponseEntity<>(FeelEvaluationResponse.withError(e.getMessage()), HttpStatus.OK);
+
+ } finally {
+ trackingService.trackExpressionEvaluation(request.metadata);
}
}
@@ -58,6 +64,9 @@ public ResponseEntity evaluateUnaryTests(
} catch (Exception e) {
return new ResponseEntity<>(FeelEvaluationResponse.withError(e.getMessage()), HttpStatus.OK);
+
+ } finally {
+ trackingService.trackUnaryTestsExpressionEvaluation(request.metadata);
}
}
}
diff --git a/src/main/java/org/camunda/feel/playground/sevice/MixpanelProperties.java b/src/main/java/org/camunda/feel/playground/sevice/MixpanelProperties.java
new file mode 100644
index 00000000..1b9c04e5
--- /dev/null
+++ b/src/main/java/org/camunda/feel/playground/sevice/MixpanelProperties.java
@@ -0,0 +1,17 @@
+package org.camunda.feel.playground.sevice;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@ConditionalOnProperty(prefix = "playground.tracking", name = "enabled", havingValue = "true")
+public class MixpanelProperties {
+
+ @Value("${MIXPANEL_PROJECT_TOKEN}")
+ private String projectToken;
+
+ public String getProjectToken() {
+ return projectToken;
+ }
+}
diff --git a/src/main/java/org/camunda/feel/playground/sevice/MixpanelTrackingService.java b/src/main/java/org/camunda/feel/playground/sevice/MixpanelTrackingService.java
new file mode 100644
index 00000000..22a36786
--- /dev/null
+++ b/src/main/java/org/camunda/feel/playground/sevice/MixpanelTrackingService.java
@@ -0,0 +1,56 @@
+package org.camunda.feel.playground.sevice;
+
+import com.mixpanel.mixpanelapi.MessageBuilder;
+import com.mixpanel.mixpanelapi.MixpanelAPI;
+import org.json.JSONObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
+import org.springframework.stereotype.Component;
+
+import java.util.Map;
+import java.util.Optional;
+
+@Component
+@ConditionalOnBean(MixpanelProperties.class)
+public class MixpanelTrackingService implements TrackingService {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(MixpanelTrackingService.class);
+
+ private final MixpanelAPI mixpanelAPI = new MixpanelAPI();
+
+ private final MessageBuilder messageBuilder;
+
+ public MixpanelTrackingService(MixpanelProperties mixpanelProperties) {
+ messageBuilder = new MessageBuilder(mixpanelProperties.getProjectToken());
+ }
+
+ private void sendMixpanelEvent(EVENT_TYPE eventType, Map metadata) {
+
+ var properties = new JSONObject();
+ Optional.ofNullable(metadata).ifPresent(entry -> entry.forEach(properties::put));
+
+ var message = messageBuilder.event(null, eventType.name(), properties);
+
+ try {
+ mixpanelAPI.sendMessage(message);
+ } catch (Exception e) {
+ LOGGER.warn("Failed to send Mixpanel event.", e);
+ }
+ }
+
+ @Override
+ public void trackExpressionEvaluation(Map metadata) {
+ sendMixpanelEvent(EVENT_TYPE.FEEL_EXPRESSION_EVALUATION, metadata);
+ }
+
+ @Override
+ public void trackUnaryTestsExpressionEvaluation(Map metadata) {
+ sendMixpanelEvent(EVENT_TYPE.FEEL_UNARY_TESTS_EXPRESSION_EVALUATION, metadata);
+ }
+
+ private enum EVENT_TYPE {
+ FEEL_EXPRESSION_EVALUATION,
+ FEEL_UNARY_TESTS_EXPRESSION_EVALUATION
+ }
+}
diff --git a/src/main/java/org/camunda/feel/playground/sevice/NoopTrackingService.java b/src/main/java/org/camunda/feel/playground/sevice/NoopTrackingService.java
new file mode 100644
index 00000000..b9c37c9a
--- /dev/null
+++ b/src/main/java/org/camunda/feel/playground/sevice/NoopTrackingService.java
@@ -0,0 +1,21 @@
+package org.camunda.feel.playground.sevice;
+
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.stereotype.Component;
+
+import java.util.Map;
+
+@Component
+@ConditionalOnMissingBean(MixpanelProperties.class)
+public class NoopTrackingService implements TrackingService {
+
+ @Override
+ public void trackExpressionEvaluation(Map metadata) {
+ // no-op
+ }
+
+ @Override
+ public void trackUnaryTestsExpressionEvaluation(Map metadata) {
+ // no-op
+ }
+}
diff --git a/src/main/java/org/camunda/feel/playground/sevice/TrackingService.java b/src/main/java/org/camunda/feel/playground/sevice/TrackingService.java
new file mode 100644
index 00000000..99d74ef7
--- /dev/null
+++ b/src/main/java/org/camunda/feel/playground/sevice/TrackingService.java
@@ -0,0 +1,11 @@
+package org.camunda.feel.playground.sevice;
+
+import java.util.Map;
+
+public interface TrackingService {
+
+ void trackExpressionEvaluation(Map metadata);
+
+ void trackUnaryTestsExpressionEvaluation(Map metadata);
+
+}
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index d90e718b..eafe1af4 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -1,2 +1,3 @@
server.port=${PORT:8080}
+playground.tracking.enabled=true
diff --git a/src/test/resources/application.properties b/src/test/resources/application.properties
new file mode 100644
index 00000000..bb1ceb6a
--- /dev/null
+++ b/src/test/resources/application.properties
@@ -0,0 +1,3 @@
+server.port=${PORT:8080}
+
+playground.tracking.enabled=false