This repository has been archived by the owner on Jan 10, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathkalix-es-java-iot-digital-twin.xml
94 lines (94 loc) · 16.5 KB
/
kalix-es-java-iot-digital-twin.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
<templateSet group="kalix-es-java-iot-digital-twin">
<template name="aheader" value="syntax = "proto3"; package com.example.digitaltwin; import "kalix/annotations.proto"; import "google/api/annotations.proto"; import "google/protobuf/empty.proto"; option java_outer_classname = "DigitalTwinApi";" description="" toReformat="false" toShortenFQNames="true">
<context>
<option name="PROTO" value="true" />
<option name="PROTOTEXT" value="true" />
</context>
</template>
<template name="astate" value="message DigitalTwinState { bool metric_alert_active = 1; }" description="" toReformat="false" toShortenFQNames="true">
<context>
<option name="PROTO" value="true" />
<option name="PROTOTEXT" value="true" />
</context>
</template>
<template name="acmds" value="message CreateCommand { string dt_id = 1 [(kalix.field).entity_key = true]; string name = 2; int64 metric_value_alert_threshold = 3; } message AddMetricCommand { string dt_id = 1 [(kalix.field).entity_key = true]; int64 metric_value = 2; } message GetDigitalTwinStateCommand { string dt_id = 1 [(kalix.field).entity_key = true]; }" description="" toReformat="false" toShortenFQNames="true">
<context>
<option name="PROTO" value="true" />
<option name="PROTOTEXT" value="true" />
</context>
</template>
<template name="asrv" value="service DigitalTwinService { }" description="" toReformat="false" toShortenFQNames="true">
<context>
<option name="PROTO" value="true" />
<option name="PROTOTEXT" value="true" />
</context>
</template>
<template name="afunc" value="rpc Create (CreateCommand) returns (google.protobuf.Empty) { option (google.api.http) = { post: "/digitaltwin/{dt_id}/create" body: "*" }; } rpc AddMetric (AddMetricCommand) returns (google.protobuf.Empty) { option (google.api.http) = { post: "/digitaltwin/{dt_id}/add-metric" body: "*" }; } rpc GetDigitalTwinState (GetDigitalTwinStateCommand) returns (DigitalTwinState) { option (google.api.http) = { get: "/digitaltwin/{dt_id}" }; }" description="" toReformat="false" toShortenFQNames="true">
<context>
<option name="PROTO" value="true" />
<option name="PROTOTEXT" value="true" />
</context>
</template>
<template name="acodegen" value="option (kalix.codegen) = { event_sourced_entity: { name: "com.example.digitaltwin.domain.DigitalTwin" entity_type: "digitaltwin" state: "com.example.digitaltwin.domain.DigitalTwinDomainState" events: [ "com.example.digitaltwin.domain.Created", "com.example.digitaltwin.domain.AlertTriggered", "com.example.digitaltwin.domain.AlertCanceled"] } };" description="" toReformat="false" toShortenFQNames="true">
<context>
<option name="PROTO" value="true" />
<option name="PROTOTEXT" value="true" />
</context>
</template>
<template name="dheader" value="syntax = "proto3"; package com.example.digitaltwin.domain; option java_outer_classname = "DigitalTwinDomain";" description="" toReformat="false" toShortenFQNames="true">
<context>
<option name="PROTO" value="true" />
<option name="PROTOTEXT" value="true" />
</context>
</template>
<template name="devts" value="message Created { string name = 1; int64 metric_value_alert_threshold = 2; } message AlertTriggered { int64 metric_value = 1; } message AlertCanceled {}" description="" toReformat="false" toShortenFQNames="true">
<context>
<option name="PROTO" value="true" />
<option name="PROTOTEXT" value="true" />
</context>
</template>
<template name="dstate" value="message DigitalTwinDomainState { string name = 1; int64 metric_value_alert_threshold = 2; bool metric_alert_active = 3; int64 metric_value_for_alert = 4; }" description="" toReformat="false" toShortenFQNames="true">
<context>
<option name="PROTO" value="true" />
<option name="PROTOTEXT" value="true" />
</context>
</template>
<template name="eall" value="@Override public DigitalTwinDomain.DigitalTwinDomainState emptyState() { return DigitalTwinDomain.DigitalTwinDomainState.getDefaultInstance(); } @Override public Effect<Empty> create(DigitalTwinDomain.DigitalTwinDomainState currentState, DigitalTwinApi.CreateCommand createCommand) { DigitalTwinDomain.Created event = DigitalTwinDomain.Created.newBuilder() .setName(createCommand.getName()) .setMetricValueAlertThreshold(createCommand.getMetricValueAlertThreshold()) .build(); return effects() .emitEvent(event) .thenReply(newState -> Empty.getDefaultInstance()); } @Override public Effect<Empty> addMetric(DigitalTwinDomain.DigitalTwinDomainState currentState, DigitalTwinApi.AddMetricCommand addMetricCommand) { if(currentState.equals(DigitalTwinDomain.DigitalTwinDomainState.getDefaultInstance())){ return effects().error("Not found"); } if(!currentState.getMetricAlertActive() && addMetricCommand.getMetricValue() >= currentState.getMetricValueAlertThreshold()) { DigitalTwinDomain.AlertTriggered event = DigitalTwinDomain.AlertTriggered.newBuilder() .setMetricValue(addMetricCommand.getMetricValue()) .build(); return effects() .emitEvent(event) .thenReply(newState -> Empty.getDefaultInstance()); } else if(currentState.getMetricAlertActive() && addMetricCommand.getMetricValue() < currentState.getMetricValueAlertThreshold()) { DigitalTwinDomain.AlertCanceled event = DigitalTwinDomain.AlertCanceled.newBuilder().build(); return effects() .emitEvent(event) .thenReply(newState -> Empty.getDefaultInstance()); } else { return effects().reply(Empty.getDefaultInstance()); } } @Override public Effect<DigitalTwinApi.DigitalTwinState> getDigitalTwinState(DigitalTwinDomain.DigitalTwinDomainState currentState, DigitalTwinApi.GetDigitalTwinStateCommand getDigitalTwinStateCommand) { if(currentState.equals(DigitalTwinDomain.DigitalTwinDomainState.getDefaultInstance())){ return effects().error("Not found"); } return effects().reply(map(currentState)); } private DigitalTwinApi.DigitalTwinState map (DigitalTwinDomain.DigitalTwinDomainState domainState){ DigitalTwinApi.DigitalTwinState apiState = DigitalTwinApi.DigitalTwinState.newBuilder() .setMetricAlertActive(domainState.getMetricAlertActive()) .build(); return apiState; } @Override public DigitalTwinDomain.DigitalTwinDomainState created(DigitalTwinDomain.DigitalTwinDomainState currentState, DigitalTwinDomain.Created created) { return currentState.toBuilder() .setName(created.getName()) .setMetricValueAlertThreshold(created.getMetricValueAlertThreshold()) .build(); } @Override public DigitalTwinDomain.DigitalTwinDomainState alertTriggered(DigitalTwinDomain.DigitalTwinDomainState currentState, DigitalTwinDomain.AlertTriggered alarmTriggered) { return currentState.toBuilder() .setMetricAlertActive(true) .setMetricValueForAlert(alarmTriggered.getMetricValue()) .build(); } @Override public DigitalTwinDomain.DigitalTwinDomainState alertCanceled(DigitalTwinDomain.DigitalTwinDomainState currentState, DigitalTwinDomain.AlertCanceled alarmCanceled) { return currentState.toBuilder() .setMetricAlertActive(false) .setMetricValueForAlert(0) .build(); }" description="" toReformat="false" toShortenFQNames="true">
<context>
<option name="JAVA_CODE" value="true" />
</context>
</template>
<template name="ut" value="@Test public void happyPath() { String dtId = java.util.UUID.randomUUID().toString(); String name = "name"; long metricValueAlertThreshold = 10l; long metricValueOk = 5; long metricValueAlert = 11; DigitalTwinTestKit testKit = DigitalTwinTestKit.of(dtId, DigitalTwin::new); DigitalTwinApi.CreateCommand create = DigitalTwinApi.CreateCommand.newBuilder() .setDtId(dtId) .setMetricValueAlertThreshold(metricValueAlertThreshold) .setName(name) .build(); EventSourcedResult<Empty> result = testKit.create(create); assertEquals(true, result.didEmitEvents()); DigitalTwinDomain.Created createdEvent = result.getNextEventOfType(DigitalTwinDomain.Created.class); assertEquals(name, createdEvent.getName()); DigitalTwinApi.AddMetricCommand addOk = DigitalTwinApi.AddMetricCommand.newBuilder() .setDtId(dtId) .setMetricValue(metricValueOk) .build(); result = testKit.addMetric(addOk); assertEquals(false, result.didEmitEvents()); DigitalTwinApi.AddMetricCommand addAlert = DigitalTwinApi.AddMetricCommand.newBuilder() .setDtId(dtId) .setMetricValue(metricValueAlert) .build(); result = testKit.addMetric(addAlert); assertEquals(true, result.didEmitEvents()); DigitalTwinDomain.AlertTriggered alertTriggeredEvent = result.getNextEventOfType(DigitalTwinDomain.AlertTriggered.class); assertEquals(metricValueAlert,alertTriggeredEvent.getMetricValue()); DigitalTwinApi.GetDigitalTwinStateCommand get = DigitalTwinApi.GetDigitalTwinStateCommand.newBuilder().setDtId(dtId).build(); EventSourcedResult<DigitalTwinApi.DigitalTwinState> getResult = testKit.getDigitalTwinState(get); assertEquals(true, getResult.getReply().getMetricAlertActive()); result = testKit.addMetric(addOk); assertEquals(true, result.didEmitEvents()); DigitalTwinDomain.AlertCanceled alertCanceledEvent = result.getNextEventOfType(DigitalTwinDomain.AlertCanceled.class); get = DigitalTwinApi.GetDigitalTwinStateCommand.newBuilder().setDtId(dtId).build(); getResult = testKit.getDigitalTwinState(get); assertEquals(false, getResult.getReply().getMetricAlertActive()); }" description="" toReformat="false" toShortenFQNames="true">
<context>
<option name="JAVA_CODE" value="true" />
</context>
</template>
<template name="it" value="@Test public void happyPath() throws Exception { String dtId = java.util.UUID.randomUUID().toString(); String name = "name"; long metricValueAlertThreshold = 10l; long metricValueOk = 5; long metricValueAlert = 11; DigitalTwinApi.CreateCommand create = DigitalTwinApi.CreateCommand.newBuilder() .setDtId(dtId) .setMetricValueAlertThreshold(metricValueAlertThreshold) .setName(name) .build(); client.create(create).toCompletableFuture().get(); DigitalTwinApi.GetDigitalTwinStateCommand get = DigitalTwinApi.GetDigitalTwinStateCommand.newBuilder().setDtId(dtId).build(); DigitalTwinApi.DigitalTwinState state = client.getDigitalTwinState(get).toCompletableFuture().get(); org.junit.Assert.assertEquals(false, state.getMetricAlertActive()); DigitalTwinApi.AddMetricCommand addOk = DigitalTwinApi.AddMetricCommand.newBuilder() .setDtId(dtId) .setMetricValue(metricValueOk) .build(); client.addMetric(addOk); state = client.getDigitalTwinState(get).toCompletableFuture().get(); org.junit.Assert.assertEquals(false, state.getMetricAlertActive()); DigitalTwinApi.AddMetricCommand addAlert = DigitalTwinApi.AddMetricCommand.newBuilder() .setDtId(dtId) .setMetricValue(metricValueAlert) .build(); client.addMetric(addAlert); state = client.getDigitalTwinState(get).toCompletableFuture().get(); org.junit.Assert.assertEquals(true, state.getMetricAlertActive()); }" description="" toReformat="false" toShortenFQNames="true">
<context>
<option name="JAVA_CODE" value="true" />
</context>
</template>
<template name="theader" value="syntax = "proto3"; package com.example.digitaltwin; import "akkaserverless/annotations.proto"; import "google/api/annotations.proto"; import "google/protobuf/empty.proto"; import "google/protobuf/any.proto"; import "com/example/digitaltwin/domain/digitaltwin_domain.proto"; option java_outer_classname = "DigitalTwinTopicApi";" description="" toReformat="false" toShortenFQNames="true">
<context>
<option name="PROTO" value="true" />
<option name="PROTOTEXT" value="true" />
</context>
</template>
<template name="tevts" value="message AlertTriggeredTopicEvent{ string dt_id = 1; int64 metric_value = 2; } message AlertCanceledTopicEvent{ string dt_id = 1; }" description="" toReformat="false" toShortenFQNames="true">
<context>
<option name="PROTO" value="true" />
<option name="PROTOTEXT" value="true" />
</context>
</template>
<template name="tsrv" value="service DigitalTwinToTopic { option (akkaserverless.codegen) = { action: {} }; rpc AlertTriggered (com.example.digitaltwin.domain.AlertTriggered) returns (AlertTriggeredTopicEvent) { option (akkaserverless.method).eventing.in = { event_sourced_entity: "digitaltwin" }; option (akkaserverless.method).eventing.out = { topic: "digitaltwin-topic" }; } rpc AlertCanceled (com.example.digitaltwin.domain.AlertCanceled) returns (AlertCanceledTopicEvent) { option (akkaserverless.method).eventing.in = { event_sourced_entity: "digitaltwin" }; option (akkaserverless.method).eventing.out = { topic: "digitaltwin-topic" }; } rpc Ignore(google.protobuf.Any) returns (google.protobuf.Empty) { option (akkaserverless.method).eventing.in = { event_sourced_entity: "digitaltwin" }; } }" description="" toReformat="false" toShortenFQNames="true">
<context>
<option name="PROTO" value="true" />
<option name="PROTOTEXT" value="true" />
</context>
</template>
<template name="tall" value="@Override public Effect<DigitalTwinTopicApi.AlertTriggeredTopicEvent> alertTriggered(DigitalTwinDomain.AlertTriggered alertTriggered) { DigitalTwinTopicApi.AlertTriggeredTopicEvent topicEvent = DigitalTwinTopicApi.AlertTriggeredTopicEvent.newBuilder() .setDtId(actionContext().eventSubject().get()) .setMetricValue(alertTriggered.getMetricValue()) .build(); return effects().reply(topicEvent); } @Override public Effect<DigitalTwinTopicApi.AlertCanceledTopicEvent> alertCanceled(DigitalTwinDomain.AlertCanceled alertCanceled) { DigitalTwinTopicApi.AlertCanceledTopicEvent topicEvent = DigitalTwinTopicApi.AlertCanceledTopicEvent.newBuilder() .setDtId(actionContext().eventSubject().get()) .build(); return effects().reply(topicEvent); } @Override public Effect<Empty> ignore(Any any) { return effects().reply(Empty.getDefaultInstance()); }" description="" toReformat="false" toShortenFQNames="true">
<context>
<option name="JAVA_CODE" value="true" />
</context>
</template>
</templateSet>