testing inter service communication
Signed-off-by: Peter Siegmund <developer@mars3142.org>
This commit is contained in:
17
pom.xml
17
pom.xml
@@ -108,6 +108,10 @@
|
|||||||
<artifactId>vaadin-testbench-junit5</artifactId>
|
<artifactId>vaadin-testbench-junit5</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-bootstrap</artifactId>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.projectlombok</groupId>
|
<groupId>org.projectlombok</groupId>
|
||||||
<artifactId>lombok</artifactId>
|
<artifactId>lombok</artifactId>
|
||||||
@@ -117,6 +121,10 @@
|
|||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.modulith</groupId>
|
<groupId>org.springframework.modulith</groupId>
|
||||||
<artifactId>spring-modulith-starter-core</artifactId>
|
<artifactId>spring-modulith-starter-core</artifactId>
|
||||||
@@ -140,6 +148,15 @@
|
|||||||
<groupId>org.springframework.cloud</groupId>
|
<groupId>org.springframework.cloud</groupId>
|
||||||
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
|
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.ben-manes.caffeine</groupId>
|
||||||
|
<artifactId>caffeine</artifactId>
|
||||||
|
<version>3.1.8</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-config</artifactId>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
@@ -1,12 +0,0 @@
|
|||||||
package dev.mars3142.fhq.account;
|
|
||||||
|
|
||||||
public interface AccountService {
|
|
||||||
|
|
||||||
RegisterResponse register(String username, String email, String password);
|
|
||||||
|
|
||||||
LoginResponse login(String email, String password);
|
|
||||||
|
|
||||||
RefreshTokenResponse refreshToken(String token);
|
|
||||||
|
|
||||||
DeleteResponse delete(String token);
|
|
||||||
}
|
|
@@ -1,4 +0,0 @@
|
|||||||
package dev.mars3142.fhq.account;
|
|
||||||
|
|
||||||
public record DeleteResponse(boolean success) {
|
|
||||||
}
|
|
@@ -1,4 +0,0 @@
|
|||||||
package dev.mars3142.fhq.account;
|
|
||||||
|
|
||||||
public record DeletedCompleted(String localId) {
|
|
||||||
}
|
|
@@ -1,4 +0,0 @@
|
|||||||
package dev.mars3142.fhq.account;
|
|
||||||
|
|
||||||
public record LoginCompleted(String localId, String email, String displayName) {
|
|
||||||
}
|
|
@@ -1,5 +0,0 @@
|
|||||||
package dev.mars3142.fhq.account;
|
|
||||||
|
|
||||||
public record LoginResponse(String localId, String email, String displayName, String idToken, String registered,
|
|
||||||
String refreshToken, String expiresIn) {
|
|
||||||
}
|
|
@@ -1,4 +0,0 @@
|
|||||||
package dev.mars3142.fhq.account;
|
|
||||||
|
|
||||||
public record RefreshTokenCompleted(String localId, String token) {
|
|
||||||
}
|
|
@@ -1,5 +0,0 @@
|
|||||||
package dev.mars3142.fhq.account;
|
|
||||||
|
|
||||||
public record RefreshTokenResponse(String expiresIn, String tokenType, String refreshToken, String idToken, String userId,
|
|
||||||
String projectId) {
|
|
||||||
}
|
|
@@ -1,4 +0,0 @@
|
|||||||
package dev.mars3142.fhq.account;
|
|
||||||
|
|
||||||
public record RegisterResponse(String idToken, String email, String refreshToken, String expiresId, String localId) {
|
|
||||||
}
|
|
@@ -1,4 +0,0 @@
|
|||||||
package dev.mars3142.fhq.account;
|
|
||||||
|
|
||||||
public record RegistrationCompleted(String email, String localId) {
|
|
||||||
}
|
|
@@ -1,17 +0,0 @@
|
|||||||
package dev.mars3142.fhq.account.repositories;
|
|
||||||
|
|
||||||
import dev.mars3142.fhq.account.repositories.impl.responses.DeleteResponse;
|
|
||||||
import dev.mars3142.fhq.account.repositories.impl.responses.LoginResponse;
|
|
||||||
import dev.mars3142.fhq.account.repositories.impl.responses.RefreshTokenResponse;
|
|
||||||
import dev.mars3142.fhq.account.repositories.impl.responses.RegisterResponse;
|
|
||||||
|
|
||||||
public interface AccountRepository {
|
|
||||||
|
|
||||||
RegisterResponse register(String username, String email, String password);
|
|
||||||
|
|
||||||
LoginResponse login(String username, String password);
|
|
||||||
|
|
||||||
RefreshTokenResponse refreshToken(String token);
|
|
||||||
|
|
||||||
DeleteResponse delete(String token);
|
|
||||||
}
|
|
@@ -1,68 +0,0 @@
|
|||||||
package dev.mars3142.fhq.account.repositories.impl;
|
|
||||||
|
|
||||||
import dev.mars3142.fhq.account.repositories.AccountRepository;
|
|
||||||
import dev.mars3142.fhq.account.repositories.impl.requests.AccountDeleteRequest;
|
|
||||||
import dev.mars3142.fhq.account.repositories.impl.requests.AccountRegisterRequest;
|
|
||||||
import dev.mars3142.fhq.account.repositories.impl.requests.LoginRequest;
|
|
||||||
import dev.mars3142.fhq.account.repositories.impl.requests.RefreshTokenRequest;
|
|
||||||
import dev.mars3142.fhq.account.repositories.impl.responses.DeleteResponse;
|
|
||||||
import dev.mars3142.fhq.account.repositories.impl.responses.LoginResponse;
|
|
||||||
import dev.mars3142.fhq.account.repositories.impl.responses.RefreshTokenResponse;
|
|
||||||
import dev.mars3142.fhq.account.repositories.impl.responses.RegisterResponse;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import lombok.val;
|
|
||||||
import org.springframework.stereotype.Repository;
|
|
||||||
import org.springframework.web.client.RestClient;
|
|
||||||
|
|
||||||
@Repository
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
@Slf4j
|
|
||||||
public class AccountRepositoryImpl implements AccountRepository {
|
|
||||||
|
|
||||||
private final RestClient client;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public RegisterResponse register(String username, String email, String password) {
|
|
||||||
val request = new AccountRegisterRequest(username, email, password);
|
|
||||||
return client
|
|
||||||
.post()
|
|
||||||
.uri("/v1/account/register")
|
|
||||||
.body(request)
|
|
||||||
.retrieve()
|
|
||||||
.body(RegisterResponse.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LoginResponse login(String email, String password) {
|
|
||||||
val request = new LoginRequest(email, password);
|
|
||||||
return client
|
|
||||||
.post()
|
|
||||||
.uri("/v1/account/login")
|
|
||||||
.body(request)
|
|
||||||
.retrieve()
|
|
||||||
.body(LoginResponse.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public RefreshTokenResponse refreshToken(String token) {
|
|
||||||
val request = new RefreshTokenRequest(token);
|
|
||||||
return client
|
|
||||||
.post()
|
|
||||||
.uri("/v1/token/refresh")
|
|
||||||
.body(request)
|
|
||||||
.retrieve()
|
|
||||||
.body(RefreshTokenResponse.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DeleteResponse delete(String token) {
|
|
||||||
val request = new AccountDeleteRequest(token);
|
|
||||||
return client
|
|
||||||
.post()
|
|
||||||
.uri("/v1/account/delete")
|
|
||||||
.body(request)
|
|
||||||
.retrieve()
|
|
||||||
.body(DeleteResponse.class);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,4 +0,0 @@
|
|||||||
package dev.mars3142.fhq.account.repositories.impl.requests;
|
|
||||||
|
|
||||||
public record AccountDeleteRequest(String token) {
|
|
||||||
}
|
|
@@ -1,4 +0,0 @@
|
|||||||
package dev.mars3142.fhq.account.repositories.impl.requests;
|
|
||||||
|
|
||||||
public record AccountRegisterRequest(String username, String email, String password) {
|
|
||||||
}
|
|
@@ -1,4 +0,0 @@
|
|||||||
package dev.mars3142.fhq.account.repositories.impl.requests;
|
|
||||||
|
|
||||||
public record LoginRequest(String email, String password) {
|
|
||||||
}
|
|
@@ -1,4 +0,0 @@
|
|||||||
package dev.mars3142.fhq.account.repositories.impl.requests;
|
|
||||||
|
|
||||||
public record RefreshTokenRequest(String token) {
|
|
||||||
}
|
|
@@ -1,4 +0,0 @@
|
|||||||
package dev.mars3142.fhq.account.repositories.impl.responses;
|
|
||||||
|
|
||||||
public record DeleteResponse(boolean deleted) {
|
|
||||||
}
|
|
@@ -1,5 +0,0 @@
|
|||||||
package dev.mars3142.fhq.account.repositories.impl.responses;
|
|
||||||
|
|
||||||
public record LoginResponse(String localId, String email, String displayName, String idToken, String registered,
|
|
||||||
String refreshToken, String expiresIn) {
|
|
||||||
}
|
|
@@ -1,5 +0,0 @@
|
|||||||
package dev.mars3142.fhq.account.repositories.impl.responses;
|
|
||||||
|
|
||||||
public record RefreshTokenResponse(String expiresIn, String tokenType, String refreshToken, String idToken, String userId,
|
|
||||||
String projectId) {
|
|
||||||
}
|
|
@@ -1,4 +0,0 @@
|
|||||||
package dev.mars3142.fhq.account.repositories.impl.responses;
|
|
||||||
|
|
||||||
public record RegisterResponse(String idToken, String email, String refreshToken, String expiresId, String localId) {
|
|
||||||
}
|
|
@@ -1,44 +0,0 @@
|
|||||||
package dev.mars3142.fhq.account.services.impl;
|
|
||||||
|
|
||||||
import dev.mars3142.fhq.account.*;
|
|
||||||
import dev.mars3142.fhq.account.repositories.AccountRepository;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import lombok.val;
|
|
||||||
import org.springframework.context.ApplicationEventPublisher;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
@Service
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public class AccountServiceImpl implements AccountService {
|
|
||||||
|
|
||||||
private final ApplicationEventPublisher events;
|
|
||||||
private final AccountRepository repository;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public RegisterResponse register(String username, String email, String password) {
|
|
||||||
val response = repository.register(username, email, password);
|
|
||||||
events.publishEvent(new RegistrationCompleted(response.email(), response.localId()));
|
|
||||||
return new RegisterResponse(response.idToken(), response.email(), response.refreshToken(), response.expiresId(), response.localId());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LoginResponse login(String email, String password) {
|
|
||||||
val response = repository.login(email, password);
|
|
||||||
events.publishEvent(new LoginCompleted(response.localId(), response.email(), response.displayName()));
|
|
||||||
return new LoginResponse(response.localId(), response.email(), response.displayName(), response.idToken(), response.registered(), response.refreshToken(), response.expiresIn());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public RefreshTokenResponse refreshToken(String token) {
|
|
||||||
val response = repository.refreshToken(token);
|
|
||||||
events.publishEvent(new RefreshTokenCompleted(response.userId(), response.idToken()));
|
|
||||||
return new RefreshTokenResponse(response.expiresIn(), response.tokenType(), response.refreshToken(), response.idToken(), response.userId(), response.projectId());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DeleteResponse delete(String token) {
|
|
||||||
val response = repository.delete(token);
|
|
||||||
events.publishEvent(new DeletedCompleted(""));
|
|
||||||
return new DeleteResponse(response.deleted());
|
|
||||||
}
|
|
||||||
}
|
|
@@ -0,0 +1,9 @@
|
|||||||
|
package dev.mars3142.fhq.client;
|
||||||
|
|
||||||
|
import org.springframework.web.service.annotation.GetExchange;
|
||||||
|
|
||||||
|
public interface TimeZoneClient {
|
||||||
|
|
||||||
|
@GetExchange("/v1/timezone")
|
||||||
|
String getTimeZone();
|
||||||
|
}
|
@@ -1,18 +0,0 @@
|
|||||||
package dev.mars3142.fhq.config;
|
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
import org.springframework.web.client.RestClient;
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
public class AppConfig {
|
|
||||||
|
|
||||||
@Value("${backend.uri}")
|
|
||||||
private String baseUri;
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public RestClient restClient() {
|
|
||||||
return RestClient.builder().baseUrl(baseUri).build();
|
|
||||||
}
|
|
||||||
}
|
|
38
src/main/java/dev/mars3142/fhq/config/RestClientConfig.java
Normal file
38
src/main/java/dev/mars3142/fhq/config/RestClientConfig.java
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
package dev.mars3142.fhq.config;
|
||||||
|
|
||||||
|
import dev.mars3142.fhq.client.TimeZoneClient;
|
||||||
|
import org.springframework.boot.web.client.ClientHttpRequestFactories;
|
||||||
|
import org.springframework.boot.web.client.ClientHttpRequestFactorySettings;
|
||||||
|
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.http.client.ClientHttpRequestFactory;
|
||||||
|
import org.springframework.web.client.RestClient;
|
||||||
|
import org.springframework.web.client.support.RestClientAdapter;
|
||||||
|
import org.springframework.web.service.invoker.HttpServiceProxyFactory;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class RestClientConfig {
|
||||||
|
|
||||||
|
@LoadBalanced
|
||||||
|
@Bean
|
||||||
|
RestClient.Builder restClientBuilder() {
|
||||||
|
return RestClient.builder();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public TimeZoneClient timeZoneClient(RestClient.Builder restClientBuilder) {
|
||||||
|
RestClient restClient = restClientBuilder
|
||||||
|
.baseUrl("http://timezone-service")
|
||||||
|
.requestFactory(getClientRequestFactory())
|
||||||
|
.build();
|
||||||
|
var restClientAdapter = RestClientAdapter.create(restClient);
|
||||||
|
var httpServiceProxyFactory = HttpServiceProxyFactory.builderFor(restClientAdapter).build();
|
||||||
|
return httpServiceProxyFactory.createClient(TimeZoneClient.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ClientHttpRequestFactory getClientRequestFactory() {
|
||||||
|
ClientHttpRequestFactorySettings clientHttpRequestFactorySettings = ClientHttpRequestFactorySettings.DEFAULTS;
|
||||||
|
return ClientHttpRequestFactories.get(clientHttpRequestFactorySettings);
|
||||||
|
}
|
||||||
|
}
|
@@ -1,17 +1,24 @@
|
|||||||
package dev.mars3142.fhq.views.landing_page;
|
package dev.mars3142.fhq.views.landing_page;
|
||||||
|
|
||||||
import com.vaadin.flow.component.Composite;
|
import com.vaadin.flow.component.Composite;
|
||||||
|
import com.vaadin.flow.component.Text;
|
||||||
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
|
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
|
||||||
import com.vaadin.flow.router.PageTitle;
|
import com.vaadin.flow.router.PageTitle;
|
||||||
import com.vaadin.flow.router.Route;
|
import com.vaadin.flow.router.Route;
|
||||||
|
import dev.mars3142.fhq.client.TimeZoneClient;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import lombok.val;
|
||||||
|
|
||||||
@PageTitle("Firmware HQ")
|
@PageTitle("Firmware HQ")
|
||||||
@Route(value = "", layout = LandingPageLayout.class)
|
@Route(value = "", layout = LandingPageLayout.class)
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class LandingPageView extends Composite<VerticalLayout> {
|
public class LandingPageView extends Composite<VerticalLayout> {
|
||||||
|
|
||||||
public LandingPageView() {
|
public LandingPageView(TimeZoneClient client) {
|
||||||
|
val timeZone = client.getTimeZone();
|
||||||
|
val verticalLayout = new VerticalLayout();
|
||||||
|
verticalLayout.setSizeFull();
|
||||||
|
verticalLayout.add(new Text(timeZone));
|
||||||
|
getContent().add(verticalLayout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
16
src/main/resources/bootstrap.yml
Normal file
16
src/main/resources/bootstrap.yml
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
eureka:
|
||||||
|
client:
|
||||||
|
register-with-eureka: true
|
||||||
|
fetch-registry: true
|
||||||
|
service-url:
|
||||||
|
defaultZone: ${EUREKA}
|
||||||
|
|
||||||
|
spring:
|
||||||
|
application:
|
||||||
|
name: website
|
||||||
|
cloud:
|
||||||
|
config:
|
||||||
|
discovery:
|
||||||
|
enabled: true
|
||||||
|
serviceId: config-service
|
||||||
|
fail-fast: true
|
Reference in New Issue
Block a user