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 2
/
Copy pathkalix-es-java-shoppingcart.xml
135 lines (135 loc) · 19.4 KB
/
kalix-es-java-shoppingcart.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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
<templateSet group="kalix-es-java-shoppingcart">
<template name="aheader" value="syntax = "proto3"; package com.example.shoppingcart; import "kalix/annotations.proto"; import "google/api/annotations.proto"; import "google/protobuf/empty.proto"; option java_outer_classname = "ShoppingCartApi";" description="" toReformat="false" toShortenFQNames="true" deactivated="true">
<context>
<option name="PROTO" value="true" />
<option name="PROTOTEXT" value="true" />
</context>
</template>
<template name="acmd" value="message AddLineItem { string cart_id = 1 [(kalix.field).entity_key = true]; string product_id = 2; string name = 3; int32 quantity = 4; } message GetShoppingCart { string cart_id = 1 [(kalix.field).entity_key = true]; } message CheckOutShoppingCart { string cart_id = 1 [(kalix.field).entity_key = true]; }" description="" toReformat="false" toShortenFQNames="true" deactivated="true">
<context>
<option name="PROTO" value="true" />
<option name="PROTOTEXT" value="true" />
</context>
</template>
<template name="astate" value="message Cart { repeated LineItem items = 1; } message LineItem { string product_id = 1; string name = 2; int32 quantity = 3; }" description="" toReformat="false" toShortenFQNames="true" deactivated="true">
<context>
<option name="PROTO" value="true" />
<option name="PROTOTEXT" value="true" />
</context>
</template>
<template name="asrv" value="service ShoppingCartService { }" description="" toReformat="false" toShortenFQNames="true" deactivated="true">
<context>
<option name="PROTO" value="true" />
<option name="PROTOTEXT" value="true" />
</context>
</template>
<template name="afunc" value=" rpc AddItem (AddLineItem) returns (google.protobuf.Empty) { option (google.api.http) = { post: "/cart/{cart_id}/items/add" body: "*" }; } rpc CheckOutCart (CheckOutShoppingCart) returns (google.protobuf.Empty) { option (google.api.http).post = "/cart/{cart_id}/checkout"; } rpc GetCart (GetShoppingCart) returns (Cart) { option (google.api.http) = { get: "/carts/{cart_id}" additional_bindings: { get: "/carts/{cart_id}/items" response_body: "items" } }; }" description="" toReformat="false" toShortenFQNames="true" deactivated="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.shoppingcart.domain.ShoppingCart" entity_type: "shopping-cart" state: "com.example.shoppingcart.domain.Cart" events: [ "com.example.shoppingcart.domain.ItemAdded", "com.example.shoppingcart.domain.CheckedOut"] } };" description="" toReformat="false" toShortenFQNames="true" deactivated="true">
<context>
<option name="PROTO" value="true" />
<option name="PROTOTEXT" value="true" />
</context>
</template>
<template name="dheader" value="syntax = "proto3"; package com.example.shoppingcart.domain; option java_outer_classname = "ShoppingCartDomain"; " description="" toReformat="false" toShortenFQNames="true" deactivated="true">
<context>
<option name="PROTO" value="true" />
<option name="PROTOTEXT" value="true" />
</context>
</template>
<template name="dstate" value="message Cart { repeated LineItem items = 1; bool checked_out = 2; } message LineItem { string productId = 1; string name = 2; int32 quantity = 3; }" description="" toReformat="false" toShortenFQNames="true" deactivated="true">
<context>
<option name="PROTO" value="true" />
<option name="PROTOTEXT" value="true" />
</context>
</template>
<template name="devts" value="// The item added event. message ItemAdded { LineItem item = 1; } // The checked out event. message CheckedOut { int64 checked_out_timestamp = 1; }" description="" toReformat="false" toShortenFQNames="true" deactivated="true">
<context>
<option name="PROTO" value="true" />
<option name="PROTOTEXT" value="true" />
</context>
</template>
<template name="eestate" value="return ShoppingCartDomain.Cart.getDefaultInstance();" description="" toReformat="false" toShortenFQNames="true" deactivated="true">
<context>
<option name="JAVA_CODE" value="true" />
</context>
</template>
<template name="ecadd" value="if (addLineItem.getQuantity() <= 0) { return effects().error("Quantity for item " + addLineItem.getProductId() + " must be greater than zero."); } if(currentState.getCheckedOut()) { return effects().error("Cart already checked out."); } ShoppingCartDomain.ItemAdded event = ShoppingCartDomain.ItemAdded.newBuilder() .setItem( ShoppingCartDomain.LineItem.newBuilder() .setProductId(addLineItem.getProductId()) .setName(addLineItem.getName()) .setQuantity(addLineItem.getQuantity()) .build()) .build(); return effects() .emitEvent(event) .thenReply(newState -> Empty.getDefaultInstance());" description="" toReformat="false" toShortenFQNames="true" deactivated="true">
<context>
<option name="JAVA_CODE" value="true" />
</context>
</template>
<template name="ecget" value="@Override public Effect<ShoppingCartApi.Cart> getCart(ShoppingCartDomain.Cart currentState, ShoppingCartApi.GetShoppingCart getShoppingCart) { List<ShoppingCartApi.LineItem> apiItems = currentState.getItemsList().stream() .map(this::convert) .sorted(Comparator.comparing(ShoppingCartApi.LineItem::getProductId)) .collect(Collectors.toList()); ShoppingCartApi.Cart apiCart = ShoppingCartApi.Cart.newBuilder().addAllItems(apiItems).build(); // <2> return effects().reply(apiCart); } private ShoppingCartApi.LineItem convert(ShoppingCartDomain.LineItem item) { return ShoppingCartApi.LineItem.newBuilder() .setProductId(item.getProductId()) .setName(item.getName()) .setQuantity(item.getQuantity()) .build(); }" description="" toReformat="false" toShortenFQNames="true" deactivated="true">
<context>
<option name="JAVA_CODE" value="true" />
</context>
</template>
<template name="eeadded" value="ShoppingCartDomain.LineItem item = itemAdded.getItem(); return currentState.toBuilder().addItems(item).build();" description="" toReformat="false" toShortenFQNames="true" deactivated="true">
<context>
<option name="JAVA_CODE" value="true" />
</context>
</template>
<template name="ut" value="@Test public void addItemTest() { ShoppingCartTestKit testKit = ShoppingCartTestKit.of(ShoppingCart::new); // <1> ShoppingCartApi.AddLineItem apples = ShoppingCartApi.AddLineItem.newBuilder().setProductId("idA") .setName("apples").setQuantity(1).build(); EventSourcedResult<Empty> addingApplesResult = testKit.addItem(apples); // <2> ShoppingCartApi.AddLineItem bananas = ShoppingCartApi.AddLineItem.newBuilder().setProductId("idB") .setName("bananas").setQuantity(2).build(); testKit.addItem(bananas); // <3> assertEquals(1, addingApplesResult.getAllEvents().size()); // <4> assertEquals(2, testKit.getAllEvents().size()); // <5> ShoppingCartDomain.ItemAdded addedApples = addingApplesResult.getNextEventOfType(ShoppingCartDomain.ItemAdded.class); // <6> assertEquals("apples", addedApples.getItem().getName()); assertThrows(java.util.NoSuchElementException.class, () -> addingApplesResult.getNextEventOfType(ShoppingCartDomain.ItemAdded.class)); // <7> assertEquals(Empty.getDefaultInstance(), addingApplesResult.getReply()); // <8> ShoppingCartDomain.LineItem expectedApples = ShoppingCartDomain.LineItem.newBuilder().setProductId("idA") .setName("apples").setQuantity(1).build(); ShoppingCartDomain.LineItem expectedBananas = ShoppingCartDomain.LineItem.newBuilder().setProductId("idB") .setName("bananas").setQuantity(2).build(); ShoppingCartDomain.Cart expectedState = ShoppingCartDomain.Cart.newBuilder() .addItems(expectedApples) .addItems(expectedBananas) .build(); assertEquals(expectedState, testKit.getState()); // <9> }" description="" toReformat="false" toShortenFQNames="true" deactivated="true">
<context>
<option name="JAVA_CODE" value="true" />
</context>
</template>
<template name="it" value=" void addItem(String cartId, String productId, String name, int quantity) throws Exception { client .addItem( ShoppingCartApi.AddLineItem.newBuilder() .setCartId(cartId) .setProductId(productId) .setName(name) .setQuantity(quantity) .build()) .toCompletableFuture() .get(); } ShoppingCartApi.LineItem item(String productId, String name, int quantity) { return ShoppingCartApi.LineItem.newBuilder() .setProductId(productId) .setName(name) .setQuantity(quantity) .build(); } ShoppingCartApi.Cart getCart(String cartId) throws Exception { return client .getCart(ShoppingCartApi.GetShoppingCart.newBuilder().setCartId(cartId).build()) .toCompletableFuture() .get(); } @Test public void addItemsToCart() throws Exception { addItem("cart2", "a", "Apple", 1); addItem("cart2", "b", "Banana", 2); addItem("cart2", "c", "Cantaloupe", 3); ShoppingCartApi.Cart cart = getCart("cart2"); org.junit.Assert.assertEquals("shopping cart should have 3 items", 3, cart.getItemsCount()); org.junit.Assert.assertEquals( "shopping cart should have expected items", cart.getItemsList(), java.util.List.of(item("a", "Apple", 1), item("b", "Banana", 2), item("c", "Cantaloupe", 3)) ); }" description="" toReformat="false" toShortenFQNames="true" deactivated="true">
<context>
<option name="JAVA_CODE" value="true" />
</context>
</template>
<template name="eall" value="@Override public ShoppingCartDomain.Cart emptyState() { return ShoppingCartDomain.Cart.getDefaultInstance(); } @Override public Effect<Empty> addItem(ShoppingCartDomain.Cart currentState, ShoppingCartApi.AddLineItem addLineItem) { if (addLineItem.getQuantity() <= 0) { return effects().error("Quantity for item " + addLineItem.getProductId() + " must be greater than zero."); } if(currentState.getCheckedOut()) { return effects().error("Cart already checked out."); } ShoppingCartDomain.ItemAdded event = ShoppingCartDomain.ItemAdded.newBuilder() .setItem( ShoppingCartDomain.LineItem.newBuilder() .setProductId(addLineItem.getProductId()) .setName(addLineItem.getName()) .setQuantity(addLineItem.getQuantity()) .build()) .build(); return effects() .emitEvent(event) .thenReply(newState -> Empty.getDefaultInstance()); } @Override public Effect<Empty> checkOutCart(ShoppingCartDomain.Cart currentState, ShoppingCartApi.CheckOutShoppingCart checkOutShoppingCart) { if(currentState.getCheckedOut()) { return effects().reply(Empty.getDefaultInstance()); }else if(currentState.getItemsList().isEmpty()){ return effects().error("Cart empty."); }else{ ShoppingCartDomain.CheckedOut event = ShoppingCartDomain.CheckedOut.newBuilder() .setCheckedOutTimestamp(System.currentTimeMillis()) .build(); return effects() .emitEvent(event) .thenReply(newState -> Empty.getDefaultInstance()); } } @Override public Effect<ShoppingCartApi.Cart> getCart(ShoppingCartDomain.Cart currentState, ShoppingCartApi.GetShoppingCart getShoppingCart) { java.util.List<ShoppingCartApi.LineItem> apiItems = currentState.getItemsList().stream() .map(this::convert) .sorted(java.util.Comparator.comparing(ShoppingCartApi.LineItem::getProductId)) .collect(java.util.stream.Collectors.toList()); ShoppingCartApi.Cart apiCart = ShoppingCartApi.Cart.newBuilder().addAllItems(apiItems).build(); // <2> return effects().reply(apiCart); } private ShoppingCartApi.LineItem convert(ShoppingCartDomain.LineItem item) { return ShoppingCartApi.LineItem.newBuilder() .setProductId(item.getProductId()) .setName(item.getName()) .setQuantity(item.getQuantity()) .build(); } @Override public ShoppingCartDomain.Cart itemAdded(ShoppingCartDomain.Cart currentState, ShoppingCartDomain.ItemAdded itemAdded) { ShoppingCartDomain.LineItem item = itemAdded.getItem(); return currentState.toBuilder().addItems(item).build(); } @Override public ShoppingCartDomain.Cart checkedOut(ShoppingCartDomain.Cart currentState, ShoppingCartDomain.CheckedOut checkedOut) { return currentState.toBuilder().setCheckedOut(true).build(); }" description="" toReformat="false" toShortenFQNames="true" deactivated="true">
<context>
<option name="JAVA_CODE" value="true" />
</context>
</template>
<template name="eccheckout" value="if(currentState.getCheckedOut()) { return effects().reply(Empty.getDefaultInstance()); }else if(currentState.getItemsList().isEmpty()){ return effects().error("Cart empty."); }else{ ShoppingCartDomain.CheckedOut event = ShoppingCartDomain.CheckedOut.newBuilder() .setCheckedOutTimestamp(System.currentTimeMillis()) .build(); return effects() .emitEvent(event) .thenReply(newState -> Empty.getDefaultInstance()); }" description="" toReformat="false" toShortenFQNames="true" deactivated="true">
<context>
<option name="JAVA_CODE" value="true" />
</context>
</template>
<template name="eecheckouted" value="return currentState.toBuilder().setCheckedOut(true).build();" description="" toReformat="false" toShortenFQNames="true" deactivated="true">
<context>
<option name="JAVA_CODE" value="true" />
</context>
</template>
<template name="maction" value=", ShoppingCartToTopicAction::new" description="" toReformat="false" toShortenFQNames="true" deactivated="true">
<context>
<option name="JAVA_CODE" value="true" />
</context>
</template>
<template name="theader" value="syntax = "proto3"; package com.example.shoppingcart; import "kalix/annotations.proto"; import "google/api/annotations.proto"; import "google/protobuf/empty.proto"; import "google/protobuf/any.proto"; import "com/example/shoppingcart/domain/shoppingcart_domain.proto"; option java_outer_classname = "ShoppingCartTopicApi";" description="" toReformat="false" toShortenFQNames="true" deactivated="true">
<context>
<option name="PROTO" value="true" />
<option name="PROTOTEXT" value="true" />
</context>
</template>
<template name="tevts" value="message CheckedOutTopicEvent{ string cart_id = 1; int64 checked_out_timestamp = 2; }" description="" toReformat="false" toShortenFQNames="true" deactivated="true">
<context>
<option name="PROTO" value="true" />
<option name="PROTOTEXT" value="true" />
</context>
</template>
<template name="tsrv" value="service ShoppingCartToTopic { }" description="" toReformat="false" toShortenFQNames="true" deactivated="true">
<context>
<option name="PROTO" value="true" />
<option name="PROTOTEXT" value="true" />
</context>
</template>
<template name="tfunc" value="option (kalix.codegen) = { action: {} }; rpc CheckedOut (com.example.shoppingcart.domain.CheckedOut) returns (CheckedOutTopicEvent) { option (kalix.method).eventing.in = { event_sourced_entity: "shopping-cart" }; option (kalix.method).eventing.out = { topic: "shopping-cart-topic" }; } rpc Ignore(google.protobuf.Any) returns (google.protobuf.Empty) { option (kalix.method).eventing.in = { event_sourced_entity: "shopping-cart" }; }" description="" toReformat="false" toShortenFQNames="true" deactivated="true">
<context>
<option name="PROTO" value="true" />
<option name="PROTOTEXT" value="true" />
</context>
</template>
<template name="tall" value="@Override public Effect<ShoppingCartTopicApi.CheckedOutTopicEvent> checkedOut(ShoppingCartDomain.CheckedOut checkedOut) { ShoppingCartTopicApi.CheckedOutTopicEvent topicEvent = ShoppingCartTopicApi.CheckedOutTopicEvent .newBuilder() .setCartId(actionContext().eventSubject().get()) .setCheckedOutTimestamp(checkedOut.getCheckedOutTimestamp()) .build(); return effects().reply(topicEvent); } @Override public Effect<Empty> ignore(Any any) { return effects().reply(Empty.getDefaultInstance()); }" description="" toReformat="false" toShortenFQNames="true" useStaticImport="true" deactivated="true">
<context>
<option name="JAVA_CODE" value="true" />
</context>
</template>
</templateSet>