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

fix: enable component client for integration tests #1744

Merged
merged 2 commits into from
Jul 26, 2023
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
@@ -1,24 +1,26 @@
package customer.api;


import com.google.protobuf.any.Any;
import customer.Main;
import customer.api.CustomerEntity.Confirm;
import customer.domain.Address;
import customer.domain.Customer;
import customer.view.CustomerView;
import kalix.javasdk.DeferredCall;
import kalix.spring.testkit.KalixIntegrationTestKitSupport;
import org.hamcrest.core.IsEqual;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

import java.time.Duration;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import static java.time.temporal.ChronoUnit.SECONDS;
import static org.awaitility.Awaitility.await;
Expand All @@ -27,7 +29,6 @@
@SpringBootTest(classes = Main.class)
public class CustomerIntegrationTest extends KalixIntegrationTestKitSupport {


@Autowired
private WebClient webClient;

Expand All @@ -38,15 +39,11 @@ public void create() {
String id = UUID.randomUUID().toString();
Customer customer = new Customer("[email protected]", "Johanna", null);

ResponseEntity<CustomerEntity.Confirm> response =
webClient.post()
.uri("/customer/" + id + "/create")
.bodyValue(customer)
.retrieve()
.toEntity(CustomerEntity.Confirm.class)
.block(timeout);
Confirm response = execute(componentClient.forEventSourcedEntity(id)
.call(CustomerEntity::create)
.params(customer));

Assertions.assertEquals(HttpStatus.OK, response.getStatusCode());
Assertions.assertEquals(Confirm.done, response);
Assertions.assertEquals("Johanna", getCustomerById(id).name());
}

Expand All @@ -55,25 +52,18 @@ public void changeName() {
String id = UUID.randomUUID().toString();
Customer customer = new Customer("[email protected]", "Johanna", null);

ResponseEntity<CustomerEntity.Confirm> resCreation =
webClient.post()
.uri("/customer/" + id + "/create")
.body(Mono.just(customer), Customer.class)
.retrieve()
.toEntity(CustomerEntity.Confirm.class)
.block(timeout);
Confirm response = execute(componentClient.forEventSourcedEntity(id)
.call(CustomerEntity::create)
.params(customer));

Assertions.assertEquals(HttpStatus.OK, resCreation.getStatusCode());
Assertions.assertEquals(Confirm.done, response);

ResponseEntity<CustomerEntity.Confirm> resUpdate =
webClient.post()
.uri("/customer/" + id + "/changeName/" + "Katarina")
.retrieve()
.toEntity(CustomerEntity.Confirm.class)
.block(timeout);
Confirm resUpdate = execute(componentClient.forEventSourcedEntity(id)
.call(CustomerEntity::changeName)
.params("Katarina"));


Assertions.assertEquals(HttpStatus.OK, resUpdate.getStatusCode());
Assertions.assertEquals(Confirm.done, resUpdate);
Assertions.assertEquals("Katarina", getCustomerById(id).name());
}

Expand All @@ -82,27 +72,19 @@ public void changeAddress() {
String id = UUID.randomUUID().toString();
Customer customer = new Customer("[email protected]", "Johanna", null);

ResponseEntity<CustomerEntity.Confirm> resCreation =
webClient.post()
.uri("/customer/" + id + "/create")
.body(Mono.just(customer), Customer.class)
.retrieve()
.toEntity(CustomerEntity.Confirm.class)
.block(timeout);
Confirm response = execute(componentClient.forEventSourcedEntity(id)
.call(CustomerEntity::create)
.params(customer));

Assertions.assertEquals(HttpStatus.OK, resCreation.getStatusCode());
Assertions.assertEquals(Confirm.done, response);

Address address = new Address("Elm st. 5", "New Orleans");
ResponseEntity<CustomerEntity.Confirm> resUpdate =
webClient.post()
.uri("/customer/" + id + "/changeAddress")
.body(Mono.just(address), Address.class)
.retrieve()
.toEntity(CustomerEntity.Confirm.class)
.block(timeout);

Confirm resUpdate = execute(componentClient.forEventSourcedEntity(id)
.call(CustomerEntity::changeAddress)
.params(address));

Assertions.assertEquals(HttpStatus.OK, resUpdate.getStatusCode());
Assertions.assertEquals(Confirm.done, resUpdate);
Assertions.assertEquals("Elm st. 5", getCustomerById(id).address().street());
}

Expand All @@ -111,23 +93,19 @@ public void changeAddress() {
public void findByName() {
String id = UUID.randomUUID().toString();
Customer customer = new Customer("[email protected]", "Foo", null);
ResponseEntity<CustomerEntity.Confirm> response =
webClient.post()
.uri("/customer/" + id + "/create")
.bodyValue(customer)
.retrieve()
.toEntity(CustomerEntity.Confirm.class)
.block(timeout);
Confirm response = execute(componentClient.forEventSourcedEntity(id)
.call(CustomerEntity::create)
.params(customer));

Assertions.assertEquals(HttpStatus.OK, response.getStatusCode());
Assertions.assertEquals(Confirm.done, response);

// the view is eventually updated
await()
.ignoreExceptions()
.atMost(20, TimeUnit.SECONDS)
.until(() ->
webClient.get()
.uri("/customer/by_name/Foo")
.ignoreExceptions()
.atMost(20, TimeUnit.SECONDS)
.until(() ->
webClient.get()
.uri("/customer/by_name/Foo")
.retrieve()
.bodyToMono(CustomerView.class)
.block(timeout)
Expand All @@ -140,38 +118,38 @@ public void findByName() {
public void findByEmail() {
String id = UUID.randomUUID().toString();
Customer customer = new Customer("[email protected]", "Bar", null);
ResponseEntity<CustomerEntity.Confirm> response =
webClient.post()
.uri("/customer/" + id + "/create")
.bodyValue(customer)
.retrieve()
.toEntity(CustomerEntity.Confirm.class)
.block(timeout);
Confirm response = execute(componentClient.forEventSourcedEntity(id)
.call(CustomerEntity::create)
.params(customer));

Assertions.assertEquals(HttpStatus.OK, response.getStatusCode());
Assertions.assertEquals(Confirm.done, response);

// the view is eventually updated
await()
.ignoreExceptions()
.atMost(20, TimeUnit.SECONDS)
.until(() ->
webClient.get()
.uri("/customer/by_email/[email protected]")
.retrieve()
.bodyToMono(CustomerView.class)
.block(timeout)
.name(),
new IsEqual("Bar")
);
.ignoreExceptions()
.atMost(20, TimeUnit.SECONDS)
.until(() ->
webClient.get()
.uri("/customer/by_email/[email protected]")
.retrieve()
.bodyToMono(CustomerView.class)
.block(timeout)
.name(),
new IsEqual("Bar")
);
}

private Customer getCustomerById(String customerId) {
return webClient
.get()
.uri("/customer/" + customerId)
.retrieve()
.bodyToMono(Customer.class)
.block(timeout);
return execute(componentClient.forEventSourcedEntity(customerId)
.call(CustomerEntity::getCustomer));
}

protected <T> T execute(DeferredCall<Any, T> deferredCall) {
try {
return deferredCall.execute().toCompletableFuture().get(timeout.toMillis(), TimeUnit.MILLISECONDS);
} catch (InterruptedException | ExecutionException | TimeoutException e) {
throw new RuntimeException(e);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,18 @@

package kalix.spring.testkit;

import com.typesafe.config.Config;
import kalix.javasdk.client.ComponentClient;
import kalix.javasdk.testkit.KalixTestKit;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.TestInstance;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.time.Duration;

import static java.time.temporal.ChronoUnit.SECONDS;

/**
* This class provided the necessary infrastructure to run Kalix integration test for projects built
* with the Java SDK. Users should let their test classes extends this class.
Expand All @@ -44,7 +47,13 @@ public abstract class KalixIntegrationTestKitSupport {

private Logger logger = LoggerFactory.getLogger(getClass());

@Autowired private KalixTestKit kalixTestKit;
@Autowired
private KalixTestKit kalixTestKit;
aludwiko marked this conversation as resolved.
Show resolved Hide resolved

@Autowired
protected ComponentClient componentClient;

protected Duration timeout = Duration.of(10, SECONDS);

@AfterAll
public void afterAll() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import com.typesafe.config.Config
import kalix.javasdk.JsonSupport
import kalix.javasdk.testkit.KalixTestKit
import kalix.spring.impl.KalixSpringApplication
import kalix.spring.impl.WebClientProviderHolder
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.autoconfigure.AutoConfiguration
Expand Down Expand Up @@ -76,6 +77,10 @@ class KalixConfigurationTest(applicationContext: ApplicationContext) extends Kal
logger.info(s"Starting Kalix TestKit with: $settings")
kalixTestKit.start(config)

val holder = WebClientProviderHolder.get(kalixTestKit.getRunner.system);
//when ComponentClient is used in integration test, we must initiate webclient before the first request
kalixSpringApplication.kalixClient.setWebClient(holder.webClientProvider.localWebClient)

logger.info(s"Kalix Proxy running on port: ${kalixTestKit.getPort}")
kalixTestKit
}
Expand Down