diff --git a/.circleci/config.yml b/.circleci/config.yml index 45ccc25179..9a5e62c2e8 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -17,19 +17,19 @@ commands: parent: main install-java-11: - description: install openjdk-11 + description: install openjdk-17 steps: - run: - name: Install java 11 + name: Install java 17 command: | - wget https://github.com/AdoptOpenJDK/openjdk11-binaries/releases/download/jdk-11.0.8%2B10/OpenJDK11U-jdk_x64_linux_hotspot_11.0.8_10.tar.gz -O /tmp/openjdk-11.tar.gz + wget https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.4.1%2B1/OpenJDK17U-jdk_x64_linux_hotspot_17.0.4.1_1.tar.gz -O /tmp/openjdk-17.tar.gz sudo mkdir -p /usr/lib/jvm - sudo tar xfvz /tmp/openjdk-11.tar.gz --directory /usr/lib/jvm - rm -f /tmp/openjdk-11.tar.gz + sudo tar xfvz /tmp/openjdk-17.tar.gz --directory /usr/lib/jvm + rm -f /tmp/openjdk-17.tar.gz - sudo sh -c 'for bin in /usr/lib/jvm/jdk-11.0.8+10/bin/*; do update-alternatives --install /usr/bin/$(basename $bin) $(basename $bin) $bin 100; done' - sudo sh -c 'for bin in /usr/lib/jvm/jdk-11.0.8+10/bin/*; do update-alternatives --set $(basename $bin) $bin; done' + sudo sh -c 'for bin in /usr/lib/jvm/jdk-17.0.4.1+1/bin/*; do update-alternatives --install /usr/bin/$(basename $bin) $(basename $bin) $bin 100; done' + sudo sh -c 'for bin in /usr/lib/jvm/jdk-17.0.4.1+1/bin/*; do update-alternatives --set $(basename $bin) $bin; done' setup_sbt: description: "Set up sbt" diff --git a/build.sbt b/build.sbt index d2c5032ba2..925b602aa0 100644 --- a/build.sbt +++ b/build.sbt @@ -65,7 +65,6 @@ lazy val sdkJava = project "-Xdoclint:none", "-overview", ((Compile / javaSource).value / "overview.html").getAbsolutePath, - "--no-module-directories", "-notimestamp", "-doctitle", "Kalix Java SDK", diff --git a/maven-java/kalix-spring-boot-archetype/src/main/resources/archetype-resources/pom.xml b/maven-java/kalix-spring-boot-archetype/src/main/resources/archetype-resources/pom.xml index fdc13f9a35..3e5b812540 100644 --- a/maven-java/kalix-spring-boot-archetype/src/main/resources/archetype-resources/pom.xml +++ b/maven-java/kalix-spring-boot-archetype/src/main/resources/archetype-resources/pom.xml @@ -16,7 +16,7 @@ yyyyMMddHHmmss ${package}.Main - 11 + 17 UTF-8 @project.version@ @@ -91,7 +91,7 @@ ${dockerImage}:%l - docker.io/library/adoptopenjdk:${jdk.target}-jre-hotspot + docker.io/library/eclipse-temurin:${D}{jdk.target}-alpine linux/amd64 diff --git a/samples/spring-customer-registry-views-quickstart/pom.xml b/samples/spring-customer-registry-views-quickstart/pom.xml index fd94004a5b..090eaf4596 100644 --- a/samples/spring-customer-registry-views-quickstart/pom.xml +++ b/samples/spring-customer-registry-views-quickstart/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.example - spring-customer-registry + spring-customer-registry-views 1.0-SNAPSHOT jar @@ -16,7 +16,7 @@ yyyyMMddHHmmss customer.Main - 11 + 17 UTF-8 1.0.8 @@ -123,7 +123,7 @@ ${dockerImage}:%l - docker.io/library/adoptopenjdk:${jdk.target}-jre-hotspot + docker.io/library/eclipse-temurin:${jdk.target}-alpine linux/amd64 diff --git a/samples/spring-customer-registry-views-quickstart/src/it/java/customer/api/CustomerIntegrationTest.java b/samples/spring-customer-registry-views-quickstart/src/it/java/customer/api/CustomerIntegrationTest.java index 703aa2d8bb..0e0e65a8ad 100644 --- a/samples/spring-customer-registry-views-quickstart/src/it/java/customer/api/CustomerIntegrationTest.java +++ b/samples/spring-customer-registry-views-quickstart/src/it/java/customer/api/CustomerIntegrationTest.java @@ -46,7 +46,7 @@ public void create() throws InterruptedException { .block(timeout); Assertions.assertEquals(HttpStatus.OK, response.getStatusCode()); - Assertions.assertEquals("Johanna", getCustomerById(id).name); + Assertions.assertEquals("Johanna", getCustomerById(id).name()); } @Test @@ -73,7 +73,7 @@ public void changeName() throws InterruptedException { Assertions.assertEquals(HttpStatus.OK, resUpdate.getStatusCode()); - Assertions.assertEquals("Katarina", getCustomerById(id).name); + Assertions.assertEquals("Katarina", getCustomerById(id).name()); } @Test @@ -102,7 +102,7 @@ public void changeAddress() throws InterruptedException { Assertions.assertEquals(HttpStatus.OK, resUpdate.getStatusCode()); - Assertions.assertEquals("Elm st. 5", getCustomerById(id).address.street); + Assertions.assertEquals("Elm st. 5", getCustomerById(id).address().street()); } @@ -131,7 +131,7 @@ public void findByName() throws Exception { .retrieve() .bodyToMono(Customer.class) .block(timeout) - .name, + .name(), new IsEqual("Foo") ); } @@ -160,7 +160,7 @@ public void findByEmail() throws Exception { .retrieve() .bodyToMono(Customer.class) .block(timeout) - .name, + .name(), new IsEqual("Bar") ); } diff --git a/samples/spring-customer-registry-views-quickstart/src/main/java/customer/api/Address.java b/samples/spring-customer-registry-views-quickstart/src/main/java/customer/api/Address.java index 2edb2e73d9..7a828e9a6f 100644 --- a/samples/spring-customer-registry-views-quickstart/src/main/java/customer/api/Address.java +++ b/samples/spring-customer-registry-views-quickstart/src/main/java/customer/api/Address.java @@ -3,16 +3,5 @@ * Copyright (C) 2009-2022 Lightbend Inc. */ -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; - -public class Address { - public String street; - public String city; - - @JsonCreator - public Address(@JsonProperty("street") String street, @JsonProperty("city") String city) { - this.street = street; - this.city = city; - } +public record Address(String street, String city) { } diff --git a/samples/spring-customer-registry-views-quickstart/src/main/java/customer/api/Customer.java b/samples/spring-customer-registry-views-quickstart/src/main/java/customer/api/Customer.java index 15142a10e2..ab9480f735 100644 --- a/samples/spring-customer-registry-views-quickstart/src/main/java/customer/api/Customer.java +++ b/samples/spring-customer-registry-views-quickstart/src/main/java/customer/api/Customer.java @@ -3,29 +3,13 @@ * Copyright (C) 2009-2022 Lightbend Inc. */ -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; +public record Customer(String customerId, String email, String name, Address address) { -public class Customer { - public String customerId; - public String email; - public String name; - public Address address; - - // TODO: remove JsonCreator and JsonProperty - // this should not be needed and it's not when running the application - // however, the integration tests seems to need it. - // Probably related to how the compiler is configured for the tests? - @JsonCreator - public Customer(@JsonProperty("customerId") String customerId, - @JsonProperty("email") String email, - @JsonProperty("name") String name, - @JsonProperty("address") Address address) { - this.customerId = customerId; - this.email = email; - this.name = name; - this.address = address; + public Customer withName(String newName){ + return new Customer(customerId, email, newName, address); } - + public Customer withAddress(Address newAddress){ + return new Customer(customerId, email, name, newAddress); + } } diff --git a/samples/spring-customer-registry-views-quickstart/src/main/java/customer/api/CustomerEntity.java b/samples/spring-customer-registry-views-quickstart/src/main/java/customer/api/CustomerEntity.java index f8232190f8..9cf5305c6b 100644 --- a/samples/spring-customer-registry-views-quickstart/src/main/java/customer/api/CustomerEntity.java +++ b/samples/spring-customer-registry-views-quickstart/src/main/java/customer/api/CustomerEntity.java @@ -36,16 +36,14 @@ public ValueEntity.Effect getCustomer() { @PostMapping("/changeName/{newName}") public Effect changeName(@PathVariable String newName) { - Customer customer = currentState(); - customer.name = newName; - return effects().updateState(customer).thenReply("OK"); + Customer updatedCustomer = currentState().withName(newName); + return effects().updateState(updatedCustomer).thenReply("OK"); } @PostMapping("/changeAddress") public Effect changeAddress(@RequestBody Address newAddress) { - Customer customer = currentState(); - customer.address = newAddress; - return effects().updateState(customer).thenReply("OK"); + Customer updatedCustomer = currentState().withAddress(newAddress); + return effects().updateState(updatedCustomer).thenReply("OK"); } } diff --git a/samples/spring-customer-registry-views-quickstart/src/test/java/customer/api/CustomerEntityTest.java b/samples/spring-customer-registry-views-quickstart/src/test/java/customer/api/CustomerEntityTest.java index 163fde6ad9..efc941da97 100644 --- a/samples/spring-customer-registry-views-quickstart/src/test/java/customer/api/CustomerEntityTest.java +++ b/samples/spring-customer-registry-views-quickstart/src/test/java/customer/api/CustomerEntityTest.java @@ -25,7 +25,7 @@ public void testCustomerNameChange() { { ValueEntityResult result = testKit.call(e -> e.changeName("FooBar")); assertEquals("OK", result.getReply()); - assertEquals("FooBar", testKit.getState().name); + assertEquals("FooBar", testKit.getState().name()); } } @@ -43,8 +43,8 @@ public void testCustomerAddressChange() { Address newAddress = new Address("Sesame Street", "Sesame City"); ValueEntityResult result = testKit.call(e -> e.changeAddress(newAddress)); assertEquals("OK", result.getReply()); - assertEquals("Sesame Street", testKit.getState().address.street); - assertEquals("Sesame City", testKit.getState().address.city); + assertEquals("Sesame Street", testKit.getState().address().street()); + assertEquals("Sesame City", testKit.getState().address().city()); } } diff --git a/samples/spring-eventsourced-counter/README.md b/samples/spring-eventsourced-counter/README.md index f50749a93d..e031d7ccaa 100644 --- a/samples/spring-eventsourced-counter/README.md +++ b/samples/spring-eventsourced-counter/README.md @@ -38,17 +38,17 @@ With both the proxy and your application running, once you have defined endpoint - increase (or create) a counter named `hello` with value `10` ```shell -curl -i -XPOST localhost:9000/counter/hello/increase/10 +curl -XPOST localhost:9000/counter/hello/increase/10 ``` - retrieve the value of a counter named `hello` ```shell -curl -i -XGET localhost:9000/counter/hello +curl -XGET localhost:9000/counter/hello ``` - multiply existing counter named `hello` by value `5` ```shell -curl -i -XPOST localhost:9000/counter/hello/multiply/5 +curl -XPOST localhost:9000/counter/hello/multiply/5 ``` ### Deploy diff --git a/samples/spring-eventsourced-counter/pom.xml b/samples/spring-eventsourced-counter/pom.xml index 1b2a97f9dd..fa5e65b0f5 100644 --- a/samples/spring-eventsourced-counter/pom.xml +++ b/samples/spring-eventsourced-counter/pom.xml @@ -16,7 +16,7 @@ yyyyMMddHHmmss com.example.Main - 11 + 17 UTF-8 1.0.8 @@ -91,7 +91,7 @@ ${dockerImage}:%l - docker.io/library/adoptopenjdk:${jdk.target}-jre-hotspot + docker.io/library/eclipse-temurin:${jdk.target}-alpine linux/amd64 diff --git a/samples/spring-eventsourced-counter/src/main/java/com/example/Counter.java b/samples/spring-eventsourced-counter/src/main/java/com/example/Counter.java index 7187844a40..ce3b5d2b6c 100644 --- a/samples/spring-eventsourced-counter/src/main/java/com/example/Counter.java +++ b/samples/spring-eventsourced-counter/src/main/java/com/example/Counter.java @@ -26,6 +26,9 @@ import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; +import static com.example.CounterEvent.ValueIncreased; +import static com.example.CounterEvent.ValueMultiplied; + @Entity(entityKey = "id", entityType = "counter") @RequestMapping("/counter/{id}") public class Counter extends EventSourcedEntity { @@ -58,12 +61,12 @@ public Effect multiply(@PathVariable Integer value) { @EventHandler public Integer handleIncrease(ValueIncreased value) { - return currentState() + value.value; + return currentState() + value.value(); } @EventHandler public Integer handleMultiply(ValueMultiplied value) { - return currentState() * value.value; + return currentState() * value.value(); } } diff --git a/samples/spring-eventsourced-counter/src/main/java/com/example/CounterEvent.java b/samples/spring-eventsourced-counter/src/main/java/com/example/CounterEvent.java new file mode 100644 index 0000000000..0b53318247 --- /dev/null +++ b/samples/spring-eventsourced-counter/src/main/java/com/example/CounterEvent.java @@ -0,0 +1,21 @@ +package com.example; + +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; + +import static com.example.CounterEvent.*; + +@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type") +@JsonSubTypes( + { + @JsonSubTypes.Type(value = ValueIncreased.class, name = "value-increased"), + @JsonSubTypes.Type(value = ValueMultiplied.class, name = "value-multiplied"), + }) +public sealed interface CounterEvent { + + record ValueIncreased(int value) implements CounterEvent { + } + + record ValueMultiplied(int value) implements CounterEvent { + } +} diff --git a/samples/spring-eventsourced-counter/src/main/java/com/example/ValueIncreased.java b/samples/spring-eventsourced-counter/src/main/java/com/example/ValueIncreased.java deleted file mode 100644 index abac9507ae..0000000000 --- a/samples/spring-eventsourced-counter/src/main/java/com/example/ValueIncreased.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2021 Lightbend Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.example; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; - -public class ValueIncreased { - - public final int value; - - @JsonCreator - public ValueIncreased(@JsonProperty int value) { - this.value = value; - } -} diff --git a/samples/spring-eventsourced-counter/src/main/java/com/example/ValueMultiplied.java b/samples/spring-eventsourced-counter/src/main/java/com/example/ValueMultiplied.java deleted file mode 100644 index d464626764..0000000000 --- a/samples/spring-eventsourced-counter/src/main/java/com/example/ValueMultiplied.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2021 Lightbend Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.example; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; - -public class ValueMultiplied { - public final int value; - - @JsonCreator - public ValueMultiplied(@JsonProperty Integer value) { - this.value = value; - } -} diff --git a/samples/spring-eventsourced-counter/src/test/java/com/example/CounterTest.java b/samples/spring-eventsourced-counter/src/test/java/com/example/CounterTest.java index d6ac5bd0df..0714c64583 100644 --- a/samples/spring-eventsourced-counter/src/test/java/com/example/CounterTest.java +++ b/samples/spring-eventsourced-counter/src/test/java/com/example/CounterTest.java @@ -2,9 +2,10 @@ import kalix.javasdk.testkit.EventSourcedResult; import kalix.springsdk.testkit.EventSourcedTestKit; -import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import static com.example.CounterEvent.ValueIncreased; +import static com.example.CounterEvent.ValueMultiplied; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; diff --git a/samples/spring-eventsourced-customer-registry/pom.xml b/samples/spring-eventsourced-customer-registry/pom.xml index fd94004a5b..603bd6359d 100644 --- a/samples/spring-eventsourced-customer-registry/pom.xml +++ b/samples/spring-eventsourced-customer-registry/pom.xml @@ -1,9 +1,10 @@ - + 4.0.0 com.example - spring-customer-registry + spring-eventsourced-customer-registry 1.0-SNAPSHOT jar @@ -16,7 +17,7 @@ yyyyMMddHHmmss customer.Main - 11 + 17 UTF-8 1.0.8 @@ -123,7 +124,7 @@ ${dockerImage}:%l - docker.io/library/adoptopenjdk:${jdk.target}-jre-hotspot + docker.io/library/eclipse-temurin:${jdk.target}-alpine linux/amd64 diff --git a/samples/spring-eventsourced-customer-registry/src/it/java/customer/api/CustomerIntegrationTest.java b/samples/spring-eventsourced-customer-registry/src/it/java/customer/api/CustomerIntegrationTest.java index 01c6e5fc2d..3169dbf3bf 100644 --- a/samples/spring-eventsourced-customer-registry/src/it/java/customer/api/CustomerIntegrationTest.java +++ b/samples/spring-eventsourced-customer-registry/src/it/java/customer/api/CustomerIntegrationTest.java @@ -34,7 +34,7 @@ public class CustomerIntegrationTest extends KalixIntegrationTestKitSupport { private Duration timeout = Duration.of(5, SECONDS); @Test - public void create() throws InterruptedException { + public void create() { String id = UUID.randomUUID().toString(); Customer customer = new Customer(id, "foo@example.com", "Johanna", null); @@ -47,11 +47,11 @@ public void create() throws InterruptedException { .block(timeout); Assertions.assertEquals(HttpStatus.OK, response.getStatusCode()); - Assertions.assertEquals("Johanna", getCustomerById(id).name); + Assertions.assertEquals("Johanna", getCustomerById(id).name()); } @Test - public void changeName() throws InterruptedException { + public void changeName() { String id = UUID.randomUUID().toString(); Customer customer = new Customer(id, "foo@example.com", "Johanna", null); @@ -74,11 +74,11 @@ public void changeName() throws InterruptedException { Assertions.assertEquals(HttpStatus.OK, resUpdate.getStatusCode()); - Assertions.assertEquals("Katarina", getCustomerById(id).name); + Assertions.assertEquals("Katarina", getCustomerById(id).name()); } @Test - public void changeAddress() throws InterruptedException { + public void changeAddress() { String id = UUID.randomUUID().toString(); Customer customer = new Customer(id, "foo@example.com", "Johanna", null); @@ -103,12 +103,12 @@ public void changeAddress() throws InterruptedException { Assertions.assertEquals(HttpStatus.OK, resUpdate.getStatusCode()); - Assertions.assertEquals("Elm st. 5", getCustomerById(id).address.street); + Assertions.assertEquals("Elm st. 5", getCustomerById(id).address().street()); } @Test - public void findByName() throws Exception { + public void findByName() { String id = UUID.randomUUID().toString(); Customer customer = new Customer(id, "foo@example.com", "Foo", null); ResponseEntity response = @@ -131,13 +131,13 @@ public void findByName() throws Exception { .retrieve() .bodyToMono(CustomerView.class) .block(timeout) - .name, + .name(), new IsEqual("Foo") ); } @Test - public void findByEmail() throws Exception { + public void findByEmail() { String id = UUID.randomUUID().toString(); Customer customer = new Customer(id, "bar@example.com", "Bar", null); ResponseEntity response = @@ -160,7 +160,7 @@ public void findByEmail() throws Exception { .retrieve() .bodyToMono(CustomerView.class) .block(timeout) - .name, + .name(), new IsEqual("Bar") ); } diff --git a/samples/spring-eventsourced-customer-registry/src/main/java/customer/api/Address.java b/samples/spring-eventsourced-customer-registry/src/main/java/customer/api/Address.java index 2edb2e73d9..fbee3c8080 100644 --- a/samples/spring-eventsourced-customer-registry/src/main/java/customer/api/Address.java +++ b/samples/spring-eventsourced-customer-registry/src/main/java/customer/api/Address.java @@ -3,16 +3,4 @@ * Copyright (C) 2009-2022 Lightbend Inc. */ -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; - -public class Address { - public String street; - public String city; - - @JsonCreator - public Address(@JsonProperty("street") String street, @JsonProperty("city") String city) { - this.street = street; - this.city = city; - } -} +public record Address(String street, String city) {} diff --git a/samples/spring-eventsourced-customer-registry/src/main/java/customer/api/AddressChanged.java b/samples/spring-eventsourced-customer-registry/src/main/java/customer/api/AddressChanged.java deleted file mode 100644 index b03e124948..0000000000 --- a/samples/spring-eventsourced-customer-registry/src/main/java/customer/api/AddressChanged.java +++ /dev/null @@ -1,15 +0,0 @@ -package customer.api; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; - -public class AddressChanged implements CustomerEvent { - - final public Address address; - - - @JsonCreator - public AddressChanged(@JsonProperty Address address) { - this.address = address; - } -} diff --git a/samples/spring-eventsourced-customer-registry/src/main/java/customer/api/Customer.java b/samples/spring-eventsourced-customer-registry/src/main/java/customer/api/Customer.java index ce59838338..5476a6de3d 100644 --- a/samples/spring-eventsourced-customer-registry/src/main/java/customer/api/Customer.java +++ b/samples/spring-eventsourced-customer-registry/src/main/java/customer/api/Customer.java @@ -3,30 +3,7 @@ * Copyright (C) 2009-2022 Lightbend Inc. */ -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; - -public class Customer { - public String customerId; - public String email; - public String name; - public Address address; - - // TODO: remove JsonCreator and JsonProperty - // this should not be needed and it's not when running the application - // however, the integration tests seems to need it. - // Probably related to how the compiler is configured for the tests? - @JsonCreator - public Customer(@JsonProperty("customerId") String customerId, - @JsonProperty("email") String email, - @JsonProperty("name") String name, - @JsonProperty("address") Address address) { - this.customerId = customerId; - this.email = email; - this.name = name; - this.address = address; - } - +public record Customer(String customerId, String email, String name, Address address) { public Customer withName(String newName) { return new Customer(customerId, email, newName, address); diff --git a/samples/spring-eventsourced-customer-registry/src/main/java/customer/api/CustomerCreated.java b/samples/spring-eventsourced-customer-registry/src/main/java/customer/api/CustomerCreated.java deleted file mode 100644 index 2865f859f8..0000000000 --- a/samples/spring-eventsourced-customer-registry/src/main/java/customer/api/CustomerCreated.java +++ /dev/null @@ -1,17 +0,0 @@ -package customer.api; - -import com.fasterxml.jackson.annotation.JsonCreator; - -public class CustomerCreated implements CustomerEvent { - - final public String email; - final public String name; - final public Address address; - - @JsonCreator - public CustomerCreated(String email, String name, Address address) { - this.email = email; - this.name = name; - this.address = address;{} - } -} diff --git a/samples/spring-eventsourced-customer-registry/src/main/java/customer/api/CustomerEntity.java b/samples/spring-eventsourced-customer-registry/src/main/java/customer/api/CustomerEntity.java index 07c33dbe20..a286e36c82 100644 --- a/samples/spring-eventsourced-customer-registry/src/main/java/customer/api/CustomerEntity.java +++ b/samples/spring-eventsourced-customer-registry/src/main/java/customer/api/CustomerEntity.java @@ -18,11 +18,12 @@ import kalix.javasdk.eventsourcedentity.EventSourcedEntity; import kalix.javasdk.eventsourcedentity.EventSourcedEntityContext; -import kalix.javasdk.valueentity.ValueEntity; import kalix.springsdk.annotations.Entity; import kalix.springsdk.annotations.EventHandler; import org.springframework.web.bind.annotation.*; +import static customer.api.CustomerEvent.*; + @Entity(entityKey = "id", entityType = "customer") @RequestMapping("/customer/{id}") public class CustomerEntity extends EventSourcedEntity { @@ -41,13 +42,13 @@ public Effect getCustomer() { @PostMapping("/create") public Effect create(@RequestBody Customer customer) { return effects() - .emitEvent(new CustomerCreated(customer.email, customer.name, customer.address)) + .emitEvent(new CustomerCreated(customer.email(), customer.name(), customer.address())) .thenReply(__ -> "OK"); } @EventHandler public Customer onEvent(CustomerCreated created) { - return new Customer(entityId, created.email, created.name, created.address); + return new Customer(entityId, created.email(), created.name(), created.address()); } @@ -61,7 +62,7 @@ public Effect changeName(@PathVariable String newName) { @EventHandler public Customer onEvent(NameChanged nameChanged) { - return currentState().withName(nameChanged.newName); + return currentState().withName(nameChanged.newName()); } @@ -73,7 +74,7 @@ public Effect changeAddress(@RequestBody Address newAddress) { } @EventHandler - public Customer onEvents(AddressChanged addressChanged){ - return currentState().withAddress(addressChanged.address); + public Customer onEvents(AddressChanged addressChanged) { + return currentState().withAddress(addressChanged.address()); } } diff --git a/samples/spring-eventsourced-customer-registry/src/main/java/customer/api/CustomerEvent.java b/samples/spring-eventsourced-customer-registry/src/main/java/customer/api/CustomerEvent.java index e71b358edf..aa8eacad23 100644 --- a/samples/spring-eventsourced-customer-registry/src/main/java/customer/api/CustomerEvent.java +++ b/samples/spring-eventsourced-customer-registry/src/main/java/customer/api/CustomerEvent.java @@ -3,6 +3,9 @@ import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeName; + +import static customer.api.CustomerEvent.*; @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type") @JsonSubTypes( @@ -11,5 +14,14 @@ @JsonSubTypes.Type(value = NameChanged.class, name = "name-changed"), @JsonSubTypes.Type(value = AddressChanged.class, name = "address-changed") }) -public interface CustomerEvent { +public sealed interface CustomerEvent { + + record CustomerCreated(String email, String name, Address address) implements CustomerEvent { + } + + record NameChanged(String newName) implements CustomerEvent { + } + + record AddressChanged(Address address) implements CustomerEvent { + } } diff --git a/samples/spring-eventsourced-customer-registry/src/main/java/customer/api/NameChanged.java b/samples/spring-eventsourced-customer-registry/src/main/java/customer/api/NameChanged.java deleted file mode 100644 index 76ad15a08b..0000000000 --- a/samples/spring-eventsourced-customer-registry/src/main/java/customer/api/NameChanged.java +++ /dev/null @@ -1,14 +0,0 @@ -package customer.api; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; - -public class NameChanged implements CustomerEvent { - - final public String newName; - - @JsonCreator - public NameChanged(@JsonProperty String newName) { - this.newName = newName; - } -} diff --git a/samples/spring-eventsourced-customer-registry/src/main/java/customer/view/CustomerView.java b/samples/spring-eventsourced-customer-registry/src/main/java/customer/view/CustomerView.java index c76186531a..24acda4be4 100644 --- a/samples/spring-eventsourced-customer-registry/src/main/java/customer/view/CustomerView.java +++ b/samples/spring-eventsourced-customer-registry/src/main/java/customer/view/CustomerView.java @@ -1,30 +1,20 @@ package customer.view; -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -import customer.api.*; +import customer.api.Address; +import customer.api.CustomerEvent; import java.util.Optional; -public class CustomerView { - final public String email; - final public String name; - final public Address address; - - @JsonCreator - public CustomerView(@JsonProperty("email") String email, @JsonProperty("name") String name, @JsonProperty("address") Address address) { - this.email = email; - this.name = name; - this.address = address; - } +import static customer.api.CustomerEvent.*; +public record CustomerView(String email, String name, Address address) { public CustomerView withName(String newName) { - return new CustomerView( email, newName, address); + return new CustomerView(email, newName, address); } public CustomerView withAddress(Address newAddress) { - return new CustomerView( email, name, newAddress); + return new CustomerView(email, name, newAddress); } /** @@ -35,18 +25,15 @@ public static Optional onEvent(CustomerView state, CustomerEvent e if (state == null) { // the only event we can receive when state is null is the CustomerCreated - if (event instanceof CustomerCreated) { - CustomerCreated created = (CustomerCreated) event; - return Optional.of(new CustomerView(created.email, created.name, created.address)); + if (event instanceof CustomerCreated created) { + return Optional.of(new CustomerView(created.email(), created.name(), created.address())); } } else { // when not null, we can receive the other events - if (event instanceof NameChanged) { - NameChanged nameChanged = (NameChanged) event; - return Optional.of(state.withName(nameChanged.newName)); - } else if (event instanceof AddressChanged) { - AddressChanged addressChanged = (AddressChanged) event; - return Optional.of(state.withAddress(addressChanged.address)); + if (event instanceof NameChanged nameChanged) { + return Optional.of(state.withName(nameChanged.newName())); + } else if (event instanceof AddressChanged addressChanged) { + return Optional.of(state.withAddress(addressChanged.address())); } } @@ -54,6 +41,4 @@ public static Optional onEvent(CustomerView state, CustomerEvent e // That case won't happen as the delivery ordering is guaranteed, but we need to keep the compiler happy return Optional.empty(); } - - } diff --git a/samples/spring-eventsourced-customer-registry/src/test/java/customer/api/CustomerEntityTest.java b/samples/spring-eventsourced-customer-registry/src/test/java/customer/api/CustomerEntityTest.java index 37c8ffaeee..5a9678dcfd 100644 --- a/samples/spring-eventsourced-customer-registry/src/test/java/customer/api/CustomerEntityTest.java +++ b/samples/spring-eventsourced-customer-registry/src/test/java/customer/api/CustomerEntityTest.java @@ -4,6 +4,7 @@ import kalix.springsdk.testkit.EventSourcedTestKit; import org.junit.jupiter.api.Test; +import static customer.api.CustomerEvent.*; import static org.junit.jupiter.api.Assertions.assertEquals; public class CustomerEntityTest { @@ -25,7 +26,7 @@ public void testCustomerNameChange() { { EventSourcedResult result = testKit.call(e -> e.changeName("FooBar")); assertEquals("OK", result.getReply()); - assertEquals("FooBar", testKit.getState().name); + assertEquals("FooBar", testKit.getState().name()); result.getNextEventOfType(NameChanged.class); } @@ -45,8 +46,8 @@ public void testCustomerAddressChange() { Address newAddress = new Address("Sesame Street", "Sesame City"); EventSourcedResult result = testKit.call(e -> e.changeAddress(newAddress)); assertEquals("OK", result.getReply()); - assertEquals("Sesame Street", testKit.getState().address.street); - assertEquals("Sesame City", testKit.getState().address.city); + assertEquals("Sesame Street", testKit.getState().address().street()); + assertEquals("Sesame City", testKit.getState().address().city()); result.getNextEventOfType(AddressChanged.class); } diff --git a/samples/spring-fibonacci-action/pom.xml b/samples/spring-fibonacci-action/pom.xml index 957390d26d..6c7a8484a5 100644 --- a/samples/spring-fibonacci-action/pom.xml +++ b/samples/spring-fibonacci-action/pom.xml @@ -16,7 +16,7 @@ yyyyMMddHHmmss com.example.Main - 11 + 17 UTF-8 1.0.8 @@ -123,7 +123,7 @@ ${dockerImage}:%l - docker.io/library/adoptopenjdk:${jdk.target}-jre-hotspot + docker.io/library/eclipse-temurin:${jdk.target}-alpine linux/amd64 diff --git a/samples/spring-fibonacci-action/src/it/java/com/example/fibonacci/FibonacciActionIntegrationTest.java b/samples/spring-fibonacci-action/src/it/java/com/example/fibonacci/FibonacciActionIntegrationTest.java index bc355dd83f..ccfd9fd24d 100644 --- a/samples/spring-fibonacci-action/src/it/java/com/example/fibonacci/FibonacciActionIntegrationTest.java +++ b/samples/spring-fibonacci-action/src/it/java/com/example/fibonacci/FibonacciActionIntegrationTest.java @@ -30,33 +30,33 @@ public class FibonacciActionIntegrationTest extends KalixIntegrationTestKitSuppo private WebClient webClient; @Test - public void calculateNextNumber() throws Exception { + public void calculateNextNumber() { Mono response = webClient.get() .uri("/fibonacci/5/next") .retrieve().bodyToMono(Number.class); - long next = response.block(Duration.of(5, SECONDS)).value; + long next = response.block(Duration.of(5, SECONDS)).value(); Assertions.assertEquals(8, next); } @Test - public void calculateNextNumberWithLimitedFibo() throws Exception { + public void calculateNextNumberWithLimitedFibo() { Mono response = webClient.get() .uri("/limitedfibonacci/5/next") .retrieve().bodyToMono(Number.class); - long next = response.block(Duration.of(5, SECONDS)).value; + long next = response.block(Duration.of(5, SECONDS)).value(); Assertions.assertEquals(8, next); } @Test - public void wrongNumberReturnsError() throws Exception { + public void wrongNumberReturnsError() { try { diff --git a/samples/spring-fibonacci-action/src/main/java/com/example/fibonacci/FibonacciAction.java b/samples/spring-fibonacci-action/src/main/java/com/example/fibonacci/FibonacciAction.java index 75ddb4f73f..3341826fe8 100644 --- a/samples/spring-fibonacci-action/src/main/java/com/example/fibonacci/FibonacciAction.java +++ b/samples/spring-fibonacci-action/src/main/java/com/example/fibonacci/FibonacciAction.java @@ -28,7 +28,7 @@ public Effect nextNumber(@PathVariable Long number) { @PostMapping("/next") public Effect nextNumber(@RequestBody Number number) { - long num = number.value; + long num = number.value(); if (isFibonacci(num)) { return effects().reply(new Number(nextFib(num))); } else { diff --git a/samples/spring-fibonacci-action/src/main/java/com/example/fibonacci/LimitedFibonacciAction.java b/samples/spring-fibonacci-action/src/main/java/com/example/fibonacci/LimitedFibonacciAction.java index d72448c557..d09c419200 100644 --- a/samples/spring-fibonacci-action/src/main/java/com/example/fibonacci/LimitedFibonacciAction.java +++ b/samples/spring-fibonacci-action/src/main/java/com/example/fibonacci/LimitedFibonacciAction.java @@ -37,10 +37,10 @@ public Effect nextNumber(@PathVariable Long number) { @PostMapping("/next") public Effect nextNumber(@RequestBody Number number) { - if (number.value < 0 || number.value > 10000) { + if (number.value() < 0 || number.value() > 10000) { return effects().error("Only numbers between 0 and 10k are allowed", Status.Code.INVALID_ARGUMENT); } else { - logger.info("Executing POST call to real /fibonacci = " + number.value); + logger.info("Executing POST call to real /fibonacci = " + number.value()); var serviceCall = kalixClient.post("/fibonacci/next", number, Number.class).execute(); return effects().asyncReply(serviceCall); diff --git a/samples/spring-fibonacci-action/src/main/java/com/example/fibonacci/Number.java b/samples/spring-fibonacci-action/src/main/java/com/example/fibonacci/Number.java index 7ff2db5e91..1a49904bb4 100644 --- a/samples/spring-fibonacci-action/src/main/java/com/example/fibonacci/Number.java +++ b/samples/spring-fibonacci-action/src/main/java/com/example/fibonacci/Number.java @@ -1,14 +1,4 @@ package com.example.fibonacci; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -public class Number { - - public final long value; - - @JsonCreator - public Number(@JsonProperty("value") long value) { - this.value = value; - } +public record Number(long value) { } diff --git a/samples/spring-fibonacci-action/src/test/java/com/example/fibonacci/FibonacciActionTest.java b/samples/spring-fibonacci-action/src/test/java/com/example/fibonacci/FibonacciActionTest.java index f262a7c4f0..b9f4e271fa 100644 --- a/samples/spring-fibonacci-action/src/test/java/com/example/fibonacci/FibonacciActionTest.java +++ b/samples/spring-fibonacci-action/src/test/java/com/example/fibonacci/FibonacciActionTest.java @@ -14,7 +14,7 @@ public void testNextFib() { ActionTestkit testkit = ActionTestkit.of(FibonacciAction::new); ActionResult result = testkit.call(a -> a.nextNumber(3L)); assertTrue(result.isReply()); - assertEquals(5L, result.getReply().value); + assertEquals(5L, result.getReply().value()); } @Test