From 6dc2d9407387268dcc0cc53fd8f1efbff73dcaa6 Mon Sep 17 00:00:00 2001 From: deepcloudlabs Date: Mon, 29 Jun 2020 02:51:28 +0300 Subject: [PATCH] initial commit --- .../pom.xml | 89 ++++++++++++ ...serviceEventSourcesingCqrsApplication.java | 18 +++ .../com/example/crm/config/SwaggerConfig.java | 74 ++++++++++ .../CustomerCommandRestController.java | 5 + .../CustomerQueryRestController.java | 5 + .../com/example/crm/document/Customer.java | 133 ++++++++++++++++++ .../example/crm/events/CustomerBaseEvent.java | 35 ++++- .../crm/events/CustomerCreatedEvent.java | 5 + .../crm/events/CustomerEmailChangedEvent.java | 5 + .../crm/events/CustomerPhotoChangedEvent.java | 5 + .../crm/events/CustomerRemovedEvent.java | 20 +++ .../crm/listener/BeforeSaveListener.java | 32 +++++ .../crm/repository/BaseEventRepository.java | 8 +- .../crm/repository/CustomerRepository.java | 14 ++ .../crm/service/CustomerCommandService.java | 5 + .../crm/service/CustomerQueryService.java | 5 + .../example/crm/service/CustomerService.java | 27 ++++ .../StandardCustomerCommandService.java | 22 ++- .../StandardCustomerQueryService.java | 70 +++++++++ .../src/main/resources/application.properties | 23 +++ crm-microservice/pom.xml | 11 +- .../crm/CrmMicroserviceApplication.java | 5 + .../controller/CustomerRestController.java | 65 +++++++++ .../crm/repository/CustomerRepository.java | 9 +- .../example/crm/service/CustomerService.java | 5 + .../StandardCustomerQueryService.java | 37 ----- .../business/StandardCustomerService.java | 88 ++++++++++++ .../src/main/resources/application.properties | 11 +- .../CrmReactiveMicroserviceApplication.java | 23 ++- .../CustomerReactiveRestController.java | 6 +- .../com/example/crm/document/Customer.java | 5 + .../CustomerReactiveRepository.java | 5 + .../crm/service/CustomerReactiveService.java | 5 + .../com/example/GatewayZuluApplication.java | 20 +++ .../src/main/resources/application.properties | 15 ++ lottery-microservice-v1/pom.xml | 80 +++++++++++ .../lottery/config/WebSecurityConfig.java | 51 +++++++ .../lottery/controller/LoginController.java | 39 +++++ .../controller/LotteryRestController.java | 34 +++++ .../example/lottery/dto/LotteryResponse.java | 28 ++++ .../java/com/example/lottery/dto/WebUser.java | 35 +++++ .../lottery/filter/JwtTokenFilter.java | 74 ++++++++++ .../lottery/provider/JwtTokenProvider.java | 36 +++++ .../lottery/service/LotteryService.java | 9 ++ .../business/SimpleLotteryService.java | 38 +++++ .../src/main/resources/application.properties | 22 +++ .../controller/LotteryRestController.java | 34 +++++ .../example/lottery/dto/LotteryResponse.java | 28 ++++ .../lottery/service/LotteryService.java | 9 ++ .../business/SimpleLotteryService.java | 38 +++++ .../src/main/resources/application.properties | 19 +++ reactive-gateway/pom.xml | 76 ++++++++++ .../src/main/resources/application.properties | 13 ++ 53 files changed, 1505 insertions(+), 68 deletions(-) create mode 100644 crm-microservice-event-sourcesing-cqrs/pom.xml create mode 100644 crm-microservice-event-sourcesing-cqrs/src/main/java/com/example/crm/CrmMicroserviceEventSourcesingCqrsApplication.java create mode 100644 crm-microservice-event-sourcesing-cqrs/src/main/java/com/example/crm/config/SwaggerConfig.java rename {crm-microservice => crm-microservice-event-sourcesing-cqrs}/src/main/java/com/example/crm/controller/CustomerCommandRestController.java (96%) rename {crm-microservice => crm-microservice-event-sourcesing-cqrs}/src/main/java/com/example/crm/controller/CustomerQueryRestController.java (95%) create mode 100644 crm-microservice-event-sourcesing-cqrs/src/main/java/com/example/crm/document/Customer.java rename {crm-microservice => crm-microservice-event-sourcesing-cqrs}/src/main/java/com/example/crm/events/CustomerBaseEvent.java (59%) rename {crm-microservice => crm-microservice-event-sourcesing-cqrs}/src/main/java/com/example/crm/events/CustomerCreatedEvent.java (86%) rename {crm-microservice => crm-microservice-event-sourcesing-cqrs}/src/main/java/com/example/crm/events/CustomerEmailChangedEvent.java (84%) rename {crm-microservice => crm-microservice-event-sourcesing-cqrs}/src/main/java/com/example/crm/events/CustomerPhotoChangedEvent.java (83%) create mode 100644 crm-microservice-event-sourcesing-cqrs/src/main/java/com/example/crm/events/CustomerRemovedEvent.java create mode 100644 crm-microservice-event-sourcesing-cqrs/src/main/java/com/example/crm/listener/BeforeSaveListener.java rename {crm-microservice => crm-microservice-event-sourcesing-cqrs}/src/main/java/com/example/crm/repository/BaseEventRepository.java (66%) create mode 100644 crm-microservice-event-sourcesing-cqrs/src/main/java/com/example/crm/repository/CustomerRepository.java rename {crm-microservice => crm-microservice-event-sourcesing-cqrs}/src/main/java/com/example/crm/service/CustomerCommandService.java (86%) rename {crm-microservice => crm-microservice-event-sourcesing-cqrs}/src/main/java/com/example/crm/service/CustomerQueryService.java (80%) create mode 100644 crm-microservice-event-sourcesing-cqrs/src/main/java/com/example/crm/service/CustomerService.java rename {crm-microservice => crm-microservice-event-sourcesing-cqrs}/src/main/java/com/example/crm/service/business/StandardCustomerCommandService.java (85%) create mode 100644 crm-microservice-event-sourcesing-cqrs/src/main/java/com/example/crm/service/business/StandardCustomerQueryService.java create mode 100644 crm-microservice-event-sourcesing-cqrs/src/main/resources/application.properties create mode 100644 crm-microservice/src/main/java/com/example/crm/controller/CustomerRestController.java delete mode 100644 crm-microservice/src/main/java/com/example/crm/service/business/StandardCustomerQueryService.java create mode 100644 crm-microservice/src/main/java/com/example/crm/service/business/StandardCustomerService.java create mode 100644 gateway-zulu/src/main/java/com/example/GatewayZuluApplication.java create mode 100644 gateway-zulu/src/main/resources/application.properties create mode 100644 lottery-microservice-v1/pom.xml create mode 100644 lottery-microservice-v1/src/main/java/com/example/lottery/config/WebSecurityConfig.java create mode 100644 lottery-microservice-v1/src/main/java/com/example/lottery/controller/LoginController.java create mode 100644 lottery-microservice-v1/src/main/java/com/example/lottery/controller/LotteryRestController.java create mode 100644 lottery-microservice-v1/src/main/java/com/example/lottery/dto/LotteryResponse.java create mode 100644 lottery-microservice-v1/src/main/java/com/example/lottery/dto/WebUser.java create mode 100644 lottery-microservice-v1/src/main/java/com/example/lottery/filter/JwtTokenFilter.java create mode 100644 lottery-microservice-v1/src/main/java/com/example/lottery/provider/JwtTokenProvider.java create mode 100644 lottery-microservice-v1/src/main/java/com/example/lottery/service/LotteryService.java create mode 100644 lottery-microservice-v1/src/main/java/com/example/lottery/service/business/SimpleLotteryService.java create mode 100644 lottery-microservice-v1/src/main/resources/application.properties create mode 100644 lottery-microservice-v2/src/main/java/com/example/lottery/controller/LotteryRestController.java create mode 100644 lottery-microservice-v2/src/main/java/com/example/lottery/dto/LotteryResponse.java create mode 100644 lottery-microservice-v2/src/main/java/com/example/lottery/service/LotteryService.java create mode 100644 lottery-microservice-v2/src/main/java/com/example/lottery/service/business/SimpleLotteryService.java create mode 100644 lottery-microservice-v2/src/main/resources/application.properties create mode 100644 reactive-gateway/pom.xml create mode 100644 reactive-gateway/src/main/resources/application.properties diff --git a/crm-microservice-event-sourcesing-cqrs/pom.xml b/crm-microservice-event-sourcesing-cqrs/pom.xml new file mode 100644 index 0000000..f3a183c --- /dev/null +++ b/crm-microservice-event-sourcesing-cqrs/pom.xml @@ -0,0 +1,89 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.3.1.RELEASE + + + com.example + crm-microservice-event-sourcesing-cqrs + 0.0.1-SNAPSHOT + crm-microservice-event-sourcesing-cqrs + Spring Cloud Gateway + + + 11 + + + + + org.springframework.boot + spring-boot-starter-data-mongodb + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.kafka + spring-kafka + + + + org.springframework.boot + spring-boot-devtools + runtime + true + + + org.springframework.boot + spring-boot-starter-test + test + + + org.junit.vintage + junit-vintage-engine + + + + + org.springframework.kafka + spring-kafka-test + test + + + io.springfox + springfox-swagger2 + 2.9.2 + + + org.hibernate + hibernate-validator + 6.1.5.Final + + + io.swagger + swagger-annotations + 1.5.24 + + + io.springfox + springfox-swagger-ui + 2.9.2 + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/crm-microservice-event-sourcesing-cqrs/src/main/java/com/example/crm/CrmMicroserviceEventSourcesingCqrsApplication.java b/crm-microservice-event-sourcesing-cqrs/src/main/java/com/example/crm/CrmMicroserviceEventSourcesingCqrsApplication.java new file mode 100644 index 0000000..7a5d471 --- /dev/null +++ b/crm-microservice-event-sourcesing-cqrs/src/main/java/com/example/crm/CrmMicroserviceEventSourcesingCqrsApplication.java @@ -0,0 +1,18 @@ +package com.example.crm; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * + * @author Binnur Kurt + * + */ +@SpringBootApplication +public class CrmMicroserviceEventSourcesingCqrsApplication { + + public static void main(String[] args) { + SpringApplication.run(CrmMicroserviceEventSourcesingCqrsApplication.class, args); + } + +} diff --git a/crm-microservice-event-sourcesing-cqrs/src/main/java/com/example/crm/config/SwaggerConfig.java b/crm-microservice-event-sourcesing-cqrs/src/main/java/com/example/crm/config/SwaggerConfig.java new file mode 100644 index 0000000..1e1fd22 --- /dev/null +++ b/crm-microservice-event-sourcesing-cqrs/src/main/java/com/example/crm/config/SwaggerConfig.java @@ -0,0 +1,74 @@ +package com.example.crm.config; + +import java.util.Date; + +import javax.servlet.ServletContext; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +import springfox.documentation.builders.ApiInfoBuilder; +import springfox.documentation.builders.PathSelectors; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.service.ApiInfo; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spring.web.paths.RelativePathProvider; +import springfox.documentation.spring.web.plugins.Docket; +import springfox.documentation.swagger2.annotations.EnableSwagger2; + +/** + * + * @author Binnur Kurt + * + */ +@Configuration +@EnableSwagger2 +public class SwaggerConfig implements WebMvcConfigurer { + @Value("${major.version}") + private String majorVersion; + @Value("${minor.version}") + private String minorVersion; + @Value("${timestamp}") + private long timestamp; + @Value("${server.servlet.context-path}") + private String contextPath; + @Value("${spring.mvc.servlet.path}") + private String servletPath; + + @Value("${server.address}") + private String host; + + @Value("${server.port}") + private long port; + + @Bean + public Docket api(ServletContext servletContext) { + return new Docket(DocumentationType.SWAGGER_2).select().apis(RequestHandlerSelectors.any()) + .paths(PathSelectors.any()).build().host(host.concat(":").concat(Long.toString(port))) + .pathProvider(new RelativePathProvider(servletContext) { + @Override + public String getApplicationBasePath() { + return contextPath; + } + }).apiInfo(apiInfo()); + } + + private ApiInfo apiInfo() { + + return new ApiInfoBuilder().title("Market Service") + .description("Client FrontEnd API

Updated: [" + (new Date(timestamp)).toString() + + " ]" + " ") + .version(majorVersion + "." + minorVersion).build(); + } + + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) { + registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/"); + + registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/"); + } +} diff --git a/crm-microservice/src/main/java/com/example/crm/controller/CustomerCommandRestController.java b/crm-microservice-event-sourcesing-cqrs/src/main/java/com/example/crm/controller/CustomerCommandRestController.java similarity index 96% rename from crm-microservice/src/main/java/com/example/crm/controller/CustomerCommandRestController.java rename to crm-microservice-event-sourcesing-cqrs/src/main/java/com/example/crm/controller/CustomerCommandRestController.java index d466337..0b063e3 100644 --- a/crm-microservice/src/main/java/com/example/crm/controller/CustomerCommandRestController.java +++ b/crm-microservice-event-sourcesing-cqrs/src/main/java/com/example/crm/controller/CustomerCommandRestController.java @@ -17,6 +17,11 @@ import com.example.crm.document.Customer; import com.example.crm.service.CustomerCommandService; +/** + * + * @author Binnur Kurt + * + */ @RestController @RequestScope @RequestMapping("customers") diff --git a/crm-microservice/src/main/java/com/example/crm/controller/CustomerQueryRestController.java b/crm-microservice-event-sourcesing-cqrs/src/main/java/com/example/crm/controller/CustomerQueryRestController.java similarity index 95% rename from crm-microservice/src/main/java/com/example/crm/controller/CustomerQueryRestController.java rename to crm-microservice-event-sourcesing-cqrs/src/main/java/com/example/crm/controller/CustomerQueryRestController.java index 5217724..20193d9 100644 --- a/crm-microservice/src/main/java/com/example/crm/controller/CustomerQueryRestController.java +++ b/crm-microservice-event-sourcesing-cqrs/src/main/java/com/example/crm/controller/CustomerQueryRestController.java @@ -14,6 +14,11 @@ import com.example.crm.document.Customer; import com.example.crm.service.CustomerQueryService; +/** + * + * @author Binnur Kurt + * + */ @RestController @RequestScope @RequestMapping("customers") diff --git a/crm-microservice-event-sourcesing-cqrs/src/main/java/com/example/crm/document/Customer.java b/crm-microservice-event-sourcesing-cqrs/src/main/java/com/example/crm/document/Customer.java new file mode 100644 index 0000000..52ea2ff --- /dev/null +++ b/crm-microservice-event-sourcesing-cqrs/src/main/java/com/example/crm/document/Customer.java @@ -0,0 +1,133 @@ +package com.example.crm.document; + +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.mapping.Document; + +/** + * + * @author Binnur Kurt + * + */ +@Document(collection = "customers") +public class Customer { + @Id + private String identity; + private String fullname; + private String homeAddress; + private String businessAddress; + private String email; + private String sms; + private int birthDay; + private String photo; + + public Customer() { + } + + public Customer(String identity, String fullname, String homeAddress, String businessAddress, String email, + String sms, int birthDay) { + this.identity = identity; + this.fullname = fullname; + this.homeAddress = homeAddress; + this.businessAddress = businessAddress; + this.email = email; + this.sms = sms; + this.birthDay = birthDay; + } + + public String getIdentity() { + return identity; + } + + public void setIdentity(String identity) { + this.identity = identity; + } + + public String getFullname() { + return fullname; + } + + public void setFullname(String fullname) { + this.fullname = fullname; + } + + public String getHomeAddress() { + return homeAddress; + } + + public void setHomeAddress(String homeAddress) { + this.homeAddress = homeAddress; + } + + public String getBusinessAddress() { + return businessAddress; + } + + public void setBusinessAddress(String businessAddress) { + this.businessAddress = businessAddress; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getSms() { + return sms; + } + + public void setSms(String sms) { + this.sms = sms; + } + + public int getBirthDay() { + return birthDay; + } + + public void setBirthDay(int birthDay) { + this.birthDay = birthDay; + } + + public String getPhoto() { + return photo; + } + + public void setPhoto(String photo) { + this.photo = photo; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((identity == null) ? 0 : identity.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Customer other = (Customer) obj; + if (identity == null) { + if (other.identity != null) + return false; + } else if (!identity.equals(other.identity)) + return false; + return true; + } + + @Override + public String toString() { + return "Customer [identity=" + identity + ", fullname=" + fullname + ", homeAddress=" + homeAddress + + ", businessAddress=" + businessAddress + ", email=" + email + ", sms=" + sms + ", birthDay=" + + birthDay + "]"; + } + +} diff --git a/crm-microservice/src/main/java/com/example/crm/events/CustomerBaseEvent.java b/crm-microservice-event-sourcesing-cqrs/src/main/java/com/example/crm/events/CustomerBaseEvent.java similarity index 59% rename from crm-microservice/src/main/java/com/example/crm/events/CustomerBaseEvent.java rename to crm-microservice-event-sourcesing-cqrs/src/main/java/com/example/crm/events/CustomerBaseEvent.java index 3769e64..dbac62b 100644 --- a/crm-microservice/src/main/java/com/example/crm/events/CustomerBaseEvent.java +++ b/crm-microservice-event-sourcesing-cqrs/src/main/java/com/example/crm/events/CustomerBaseEvent.java @@ -1,8 +1,19 @@ package com.example.crm.events; +import java.util.Date; + +import org.springframework.data.annotation.CreatedDate; import org.springframework.data.annotation.Id; +import org.springframework.data.annotation.LastModifiedDate; import org.springframework.data.mongodb.core.mapping.Document; +import com.fasterxml.jackson.annotation.JsonFormat; + +/** + * + * @author Binnur Kurt + * + */ @Document(collection = "events") public class CustomerBaseEvent { @Id @@ -11,7 +22,11 @@ public class CustomerBaseEvent { private long sequenceId; private String sourceId; private String identity; - + @LastModifiedDate + private Date lastModified; + @CreatedDate + private Date createdAt; + public CustomerBaseEvent() { } @@ -55,6 +70,24 @@ public void setIdentity(String identity) { this.identity = identity; } + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ") + public Date getLastModified() { + return lastModified; + } + + public void setLastModified(Date lastModified) { + this.lastModified = lastModified; + } + + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ") + public Date getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(Date createdAt) { + this.createdAt = createdAt; + } + @Override public String toString() { return "CustomerBaseEvent [eventId=" + eventId + ", conversationId=" + conversationId + ", sequenceId=" diff --git a/crm-microservice/src/main/java/com/example/crm/events/CustomerCreatedEvent.java b/crm-microservice-event-sourcesing-cqrs/src/main/java/com/example/crm/events/CustomerCreatedEvent.java similarity index 86% rename from crm-microservice/src/main/java/com/example/crm/events/CustomerCreatedEvent.java rename to crm-microservice-event-sourcesing-cqrs/src/main/java/com/example/crm/events/CustomerCreatedEvent.java index b89edc2..c4911e0 100644 --- a/crm-microservice/src/main/java/com/example/crm/events/CustomerCreatedEvent.java +++ b/crm-microservice-event-sourcesing-cqrs/src/main/java/com/example/crm/events/CustomerCreatedEvent.java @@ -2,6 +2,11 @@ import com.example.crm.document.Customer; +/** + * + * @author Binnur Kurt + * + */ public class CustomerCreatedEvent extends CustomerBaseEvent { private Customer customer; diff --git a/crm-microservice/src/main/java/com/example/crm/events/CustomerEmailChangedEvent.java b/crm-microservice-event-sourcesing-cqrs/src/main/java/com/example/crm/events/CustomerEmailChangedEvent.java similarity index 84% rename from crm-microservice/src/main/java/com/example/crm/events/CustomerEmailChangedEvent.java rename to crm-microservice-event-sourcesing-cqrs/src/main/java/com/example/crm/events/CustomerEmailChangedEvent.java index 4a26ef1..cb606ae 100644 --- a/crm-microservice/src/main/java/com/example/crm/events/CustomerEmailChangedEvent.java +++ b/crm-microservice-event-sourcesing-cqrs/src/main/java/com/example/crm/events/CustomerEmailChangedEvent.java @@ -1,5 +1,10 @@ package com.example.crm.events; +/** + * + * @author Binnur Kurt + * + */ public class CustomerEmailChangedEvent extends CustomerBaseEvent { private String email; diff --git a/crm-microservice/src/main/java/com/example/crm/events/CustomerPhotoChangedEvent.java b/crm-microservice-event-sourcesing-cqrs/src/main/java/com/example/crm/events/CustomerPhotoChangedEvent.java similarity index 83% rename from crm-microservice/src/main/java/com/example/crm/events/CustomerPhotoChangedEvent.java rename to crm-microservice-event-sourcesing-cqrs/src/main/java/com/example/crm/events/CustomerPhotoChangedEvent.java index e862d20..6b8ac52 100644 --- a/crm-microservice/src/main/java/com/example/crm/events/CustomerPhotoChangedEvent.java +++ b/crm-microservice-event-sourcesing-cqrs/src/main/java/com/example/crm/events/CustomerPhotoChangedEvent.java @@ -1,5 +1,10 @@ package com.example.crm.events; +/** + * + * @author Binnur Kurt + * + */ public class CustomerPhotoChangedEvent extends CustomerBaseEvent { private String photo; diff --git a/crm-microservice-event-sourcesing-cqrs/src/main/java/com/example/crm/events/CustomerRemovedEvent.java b/crm-microservice-event-sourcesing-cqrs/src/main/java/com/example/crm/events/CustomerRemovedEvent.java new file mode 100644 index 0000000..804059a --- /dev/null +++ b/crm-microservice-event-sourcesing-cqrs/src/main/java/com/example/crm/events/CustomerRemovedEvent.java @@ -0,0 +1,20 @@ +package com.example.crm.events; + +import com.example.crm.document.Customer; + +public class CustomerRemovedEvent extends CustomerBaseEvent { + private Customer customer; + + public Customer getCustomer() { + return customer; + } + + public void setCustomer(Customer customer) { + this.customer = customer; + } + + @Override + public String toString() { + return "CustomerRemovedEvent [customer=" + customer + "]"; + } +} diff --git a/crm-microservice-event-sourcesing-cqrs/src/main/java/com/example/crm/listener/BeforeSaveListener.java b/crm-microservice-event-sourcesing-cqrs/src/main/java/com/example/crm/listener/BeforeSaveListener.java new file mode 100644 index 0000000..419fb8d --- /dev/null +++ b/crm-microservice-event-sourcesing-cqrs/src/main/java/com/example/crm/listener/BeforeSaveListener.java @@ -0,0 +1,32 @@ +package com.example.crm.listener; + +import java.util.Date; + +import org.springframework.data.mongodb.core.mapping.event.AbstractMongoEventListener; +import org.springframework.data.mongodb.core.mapping.event.BeforeSaveEvent; +import org.springframework.stereotype.Component; + +import com.example.crm.events.CustomerBaseEvent; + +/** + * + * @author Binnur Kurt + * + */ +@Component +public class BeforeSaveListener extends AbstractMongoEventListener { + @Override + public void onBeforeSave(BeforeSaveEvent event) { + + Date timestamp = new Date(); + + // Add a timestamp to the created date if it does not yet exist + if (event.getSource().getCreatedAt() == null) + event.getSource().setCreatedAt(timestamp); + + // Update the timestamp to the current time + event.getSource().setLastModified(timestamp); + + super.onBeforeSave(event); + } +} diff --git a/crm-microservice/src/main/java/com/example/crm/repository/BaseEventRepository.java b/crm-microservice-event-sourcesing-cqrs/src/main/java/com/example/crm/repository/BaseEventRepository.java similarity index 66% rename from crm-microservice/src/main/java/com/example/crm/repository/BaseEventRepository.java rename to crm-microservice-event-sourcesing-cqrs/src/main/java/com/example/crm/repository/BaseEventRepository.java index cca2a16..42c04da 100644 --- a/crm-microservice/src/main/java/com/example/crm/repository/BaseEventRepository.java +++ b/crm-microservice-event-sourcesing-cqrs/src/main/java/com/example/crm/repository/BaseEventRepository.java @@ -2,12 +2,18 @@ import java.util.List; +import org.springframework.data.domain.PageRequest; import org.springframework.data.mongodb.repository.MongoRepository; import com.example.crm.events.CustomerBaseEvent; +/** + * + * @author Binnur Kurt + * + */ public interface BaseEventRepository extends MongoRepository { - + List findAll(PageRequest page); List findAllByIdentity(String identity); } diff --git a/crm-microservice-event-sourcesing-cqrs/src/main/java/com/example/crm/repository/CustomerRepository.java b/crm-microservice-event-sourcesing-cqrs/src/main/java/com/example/crm/repository/CustomerRepository.java new file mode 100644 index 0000000..f308842 --- /dev/null +++ b/crm-microservice-event-sourcesing-cqrs/src/main/java/com/example/crm/repository/CustomerRepository.java @@ -0,0 +1,14 @@ +package com.example.crm.repository; + +import org.springframework.data.mongodb.repository.MongoRepository; + +import com.example.crm.document.Customer; + +/** + * + * @author Binnur Kurt + * + */ +public interface CustomerRepository extends MongoRepository{ + +} diff --git a/crm-microservice/src/main/java/com/example/crm/service/CustomerCommandService.java b/crm-microservice-event-sourcesing-cqrs/src/main/java/com/example/crm/service/CustomerCommandService.java similarity index 86% rename from crm-microservice/src/main/java/com/example/crm/service/CustomerCommandService.java rename to crm-microservice-event-sourcesing-cqrs/src/main/java/com/example/crm/service/CustomerCommandService.java index 97d0ac9..7c66309 100644 --- a/crm-microservice/src/main/java/com/example/crm/service/CustomerCommandService.java +++ b/crm-microservice-event-sourcesing-cqrs/src/main/java/com/example/crm/service/CustomerCommandService.java @@ -4,6 +4,11 @@ import com.example.crm.document.Customer; +/** + * + * @author Binnur Kurt + * + */ public interface CustomerCommandService { Customer createCustomer(Customer customer); diff --git a/crm-microservice/src/main/java/com/example/crm/service/CustomerQueryService.java b/crm-microservice-event-sourcesing-cqrs/src/main/java/com/example/crm/service/CustomerQueryService.java similarity index 80% rename from crm-microservice/src/main/java/com/example/crm/service/CustomerQueryService.java rename to crm-microservice-event-sourcesing-cqrs/src/main/java/com/example/crm/service/CustomerQueryService.java index 1d3ccea..6882c0e 100644 --- a/crm-microservice/src/main/java/com/example/crm/service/CustomerQueryService.java +++ b/crm-microservice-event-sourcesing-cqrs/src/main/java/com/example/crm/service/CustomerQueryService.java @@ -4,6 +4,11 @@ import com.example.crm.document.Customer; +/** + * + * @author Binnur Kurt + * + */ public interface CustomerQueryService { List findAllCustomers(int pagesize, int pageno); diff --git a/crm-microservice-event-sourcesing-cqrs/src/main/java/com/example/crm/service/CustomerService.java b/crm-microservice-event-sourcesing-cqrs/src/main/java/com/example/crm/service/CustomerService.java new file mode 100644 index 0000000..33c26ac --- /dev/null +++ b/crm-microservice-event-sourcesing-cqrs/src/main/java/com/example/crm/service/CustomerService.java @@ -0,0 +1,27 @@ +package com.example.crm.service; + +import java.util.List; +import java.util.Map; + +import com.example.crm.document.Customer; + +/** + * + * @author Binnur Kurt + * + */ +public interface CustomerService { + + List findAllCustomers(int pagesize, int pageno); + + Customer findCustomerByIdentity(String identity); + + Customer createCustomer(Customer customer); + + Customer updateCustomerByIdentity(String identity, Customer customer); + + Customer updateCustomerByIdentity(String identity, Map request); + + Customer deleteCustomerByIdentity(String identity); + +} diff --git a/crm-microservice/src/main/java/com/example/crm/service/business/StandardCustomerCommandService.java b/crm-microservice-event-sourcesing-cqrs/src/main/java/com/example/crm/service/business/StandardCustomerCommandService.java similarity index 85% rename from crm-microservice/src/main/java/com/example/crm/service/business/StandardCustomerCommandService.java rename to crm-microservice-event-sourcesing-cqrs/src/main/java/com/example/crm/service/business/StandardCustomerCommandService.java index f51c300..5075287 100644 --- a/crm-microservice/src/main/java/com/example/crm/service/business/StandardCustomerCommandService.java +++ b/crm-microservice-event-sourcesing-cqrs/src/main/java/com/example/crm/service/business/StandardCustomerCommandService.java @@ -11,11 +11,17 @@ import com.example.crm.document.Customer; import com.example.crm.events.CustomerBaseEvent; import com.example.crm.events.CustomerCreatedEvent; +import com.example.crm.events.CustomerEmailChangedEvent; import com.example.crm.events.CustomerPhotoChangedEvent; import com.example.crm.repository.BaseEventRepository; import com.example.crm.repository.CustomerRepository; import com.example.crm.service.CustomerCommandService; +/** + * + * @author Binnur Kurt + * + */ @Service public class StandardCustomerCommandService implements CustomerCommandService { @@ -24,15 +30,15 @@ public class StandardCustomerCommandService implements CustomerCommandService { @Autowired private BaseEventRepository eventRepository; - + @Autowired - private KafkaTemplate kafkaTemplate; - + private KafkaTemplate kafkaTemplate; + @Override public Customer createCustomer(Customer customer) { String identity = customer.getIdentity(); var customerEvents = eventRepository.findAllByIdentity(identity); - if (customerEvents.size()>0) { + if (!customerEvents.isEmpty()) { throw new IllegalArgumentException("Customer already exists"); } customerRepository.save(customer); @@ -42,7 +48,7 @@ public Customer createCustomer(Customer customer) { customerEvent.setCustomer(customer); eventRepository.save(customerEvent); kafkaTemplate.send("customer-events", customerEvent); - return customer; + return customer; } @Override @@ -69,6 +75,12 @@ public Customer updateCustomerByIdentity(String identity, Map re event.setEventId(UUID.randomUUID().toString()); event.setPhoto(value.toString()); eventRepository.save(event); + } else if (field.equals("email")) { + CustomerEmailChangedEvent event = new CustomerEmailChangedEvent(); + event.setIdentity(identity); + event.setEventId(UUID.randomUUID().toString()); + event.setEmail(value.toString()); + eventRepository.save(event); } declaredField.setAccessible(true); declaredField.set(customer, value); diff --git a/crm-microservice-event-sourcesing-cqrs/src/main/java/com/example/crm/service/business/StandardCustomerQueryService.java b/crm-microservice-event-sourcesing-cqrs/src/main/java/com/example/crm/service/business/StandardCustomerQueryService.java new file mode 100644 index 0000000..dffca3a --- /dev/null +++ b/crm-microservice-event-sourcesing-cqrs/src/main/java/com/example/crm/service/business/StandardCustomerQueryService.java @@ -0,0 +1,70 @@ +package com.example.crm.service.business; + +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.data.mongodb.core.query.Query; +import org.springframework.stereotype.Service; + +import com.example.crm.document.Customer; +import com.example.crm.events.CustomerBaseEvent; +import com.example.crm.events.CustomerCreatedEvent; +import com.example.crm.events.CustomerEmailChangedEvent; +import com.example.crm.events.CustomerPhotoChangedEvent; +import com.example.crm.events.CustomerRemovedEvent; +import com.example.crm.repository.BaseEventRepository; +import com.example.crm.service.CustomerQueryService; + +/** + * + * @author Binnur Kurt + * + */ +@Service +public class StandardCustomerQueryService implements CustomerQueryService { + + @Autowired + private BaseEventRepository eventRepository; + @Autowired + private MongoTemplate mongoTemplate; + + @Override + public List findAllCustomers(int pagesize, int pageno) { + var pagination = new Query(); + pagination.with(PageRequest.of(pageno, pagesize)); + var events = mongoTemplate.query(CustomerBaseEvent.class).distinct("identity").matching(pagination) + .as(CustomerBaseEvent.class).all(); + return events.stream().map(event -> this.findCustomerByIdentity(event.getIdentity())) + .collect(Collectors.toList()); + } + + @Override + public Customer findCustomerByIdentity(String identity) { + var events = eventRepository.findAllByIdentity(identity); + Customer customer = null; + for (var event : events) { + if (event instanceof CustomerCreatedEvent) { + customer = CustomerCreatedEvent.class.cast(event).getCustomer(); + } else if (event instanceof CustomerEmailChangedEvent) { + var email = CustomerEmailChangedEvent.class.cast(event).getEmail(); + Objects.requireNonNull(customer); + customer.setEmail(email); + } else if (event instanceof CustomerPhotoChangedEvent) { + var photo = CustomerPhotoChangedEvent.class.cast(event).getPhoto(); + Objects.requireNonNull(customer); + customer.setPhoto(photo); + } else if (event instanceof CustomerRemovedEvent) { + Objects.requireNonNull(customer); + customer = null; + } + } + if (Objects.isNull(customer)) + throw new IllegalArgumentException("Cannot find customer"); + return customer; + } + +} diff --git a/crm-microservice-event-sourcesing-cqrs/src/main/resources/application.properties b/crm-microservice-event-sourcesing-cqrs/src/main/resources/application.properties new file mode 100644 index 0000000..daaa481 --- /dev/null +++ b/crm-microservice-event-sourcesing-cqrs/src/main/resources/application.properties @@ -0,0 +1,23 @@ +# REST API URL BASE +# http(s)://localhost:8101/crm/api/v1 +server.address=localhost +server.port=8400 +server.servlet.context-path=/crm +spring.mvc.servlet.path=/api/v1 + +major.version=1 +minor.version=0 +timestamp=1581420934 +#http://localhost:8100/crm/api/v1/swagger-ui.html + +#mongodb configuration +spring.data.mongodb.uri=mongodb://localhost:27017/crm + +# kafka configuration +spring.kafka.consumer.group-id=hr +spring.kafka.consumer.auto-offset-reset=earliest +spring.kafka.consumer.key-deserializer=org.apache.kafka.common.serialization.StringDeserializer +spring.kafka.consumer.value-deserializer=org.springframework.kafka.support.serializer.JsonDeserializer +spring.kafka.producer.key-serializer=org.apache.kafka.common.serialization.StringSerializer +spring.kafka.producer.value-serializer=org.springframework.kafka.support.serializer.JsonSerializer +spring.kafka.consumer.properties.spring.json.trusted.packages=* \ No newline at end of file diff --git a/crm-microservice/pom.xml b/crm-microservice/pom.xml index ca1e9ad..c1e4c6f 100644 --- a/crm-microservice/pom.xml +++ b/crm-microservice/pom.xml @@ -64,15 +64,8 @@ - - org.springframework.kafka - spring-kafka - - - org.springframework.kafka - spring-kafka-test - test - + + diff --git a/crm-microservice/src/main/java/com/example/crm/CrmMicroserviceApplication.java b/crm-microservice/src/main/java/com/example/crm/CrmMicroserviceApplication.java index 5984fef..d97dddc 100644 --- a/crm-microservice/src/main/java/com/example/crm/CrmMicroserviceApplication.java +++ b/crm-microservice/src/main/java/com/example/crm/CrmMicroserviceApplication.java @@ -3,6 +3,11 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +/** + * + * @author Binnur Kurt + * + */ @SpringBootApplication public class CrmMicroserviceApplication { diff --git a/crm-microservice/src/main/java/com/example/crm/controller/CustomerRestController.java b/crm-microservice/src/main/java/com/example/crm/controller/CustomerRestController.java new file mode 100644 index 0000000..151e23c --- /dev/null +++ b/crm-microservice/src/main/java/com/example/crm/controller/CustomerRestController.java @@ -0,0 +1,65 @@ +package com.example.crm.controller; + +import java.util.List; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PatchMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.context.annotation.RequestScope; + +import com.example.crm.document.Customer; +import com.example.crm.service.CustomerService; + +/** + * + * @author Binnur Kurt + * + */ +@RestController +@RequestScope +@RequestMapping("customers") +@CrossOrigin +public class CustomerRestController { + @Autowired + private CustomerService customerService; + + @GetMapping(params = { "pagesize", "pageno" }) + public List getAllCustomers(@RequestParam int pagesize, @RequestParam int pageno) { + return customerService.findAllCustomers(pagesize, pageno); + } + + @GetMapping("{identity}") + public Customer getCustomerByIdentity(@PathVariable String identity) { + return customerService.findCustomerByIdentity(identity); + } + + @PostMapping + public Customer createCustomer(@RequestBody Customer customer) { + return customerService.createCustomer(customer); + } + + @PutMapping("{identity}") + public Customer updateCustomer(@PathVariable String identity, @RequestBody Customer customer) { + return customerService.updateCustomerByIdentity(identity, customer); + } + + @PatchMapping("{identity}") + public Customer patchCustomer(@PathVariable String identity, @RequestBody Map request) { + return customerService.updateCustomerByIdentity(identity, request); + } + + @DeleteMapping("{identity}") + public Customer removeCustomerByIdentity(@PathVariable String identity) { + return customerService.deleteCustomerByIdentity(identity); + } +} diff --git a/crm-microservice/src/main/java/com/example/crm/repository/CustomerRepository.java b/crm-microservice/src/main/java/com/example/crm/repository/CustomerRepository.java index 3e33e41..53e13a4 100644 --- a/crm-microservice/src/main/java/com/example/crm/repository/CustomerRepository.java +++ b/crm-microservice/src/main/java/com/example/crm/repository/CustomerRepository.java @@ -4,6 +4,11 @@ import com.example.crm.document.Customer; -public interface CustomerRepository extends MongoRepository{ - +/** + * + * @author Binnur Kurt + * + */ +public interface CustomerRepository extends MongoRepository { + } diff --git a/crm-microservice/src/main/java/com/example/crm/service/CustomerService.java b/crm-microservice/src/main/java/com/example/crm/service/CustomerService.java index 935b069..33c26ac 100644 --- a/crm-microservice/src/main/java/com/example/crm/service/CustomerService.java +++ b/crm-microservice/src/main/java/com/example/crm/service/CustomerService.java @@ -5,6 +5,11 @@ import com.example.crm.document.Customer; +/** + * + * @author Binnur Kurt + * + */ public interface CustomerService { List findAllCustomers(int pagesize, int pageno); diff --git a/crm-microservice/src/main/java/com/example/crm/service/business/StandardCustomerQueryService.java b/crm-microservice/src/main/java/com/example/crm/service/business/StandardCustomerQueryService.java deleted file mode 100644 index 30719ef..0000000 --- a/crm-microservice/src/main/java/com/example/crm/service/business/StandardCustomerQueryService.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.example.crm.service.business; - -import java.util.List; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -import com.example.crm.document.Customer; -import com.example.crm.events.CustomerCreatedEvent; -import com.example.crm.repository.BaseEventRepository; -import com.example.crm.repository.CustomerRepository; -import com.example.crm.service.CustomerQueryService; - -@Service -public class StandardCustomerQueryService implements CustomerQueryService { - - @Autowired - private CustomerRepository customerRepository; - @Autowired - private BaseEventRepository eventRepository; - - @Override - public List findAllCustomers(int pagesize, int pageno) { - return customerRepository.findAll(); - } - - @Override - public Customer findCustomerByIdentity(String identity) { - var events = eventRepository.findAllByIdentity(identity); - if (events.isEmpty()) - throw new IllegalArgumentException("Cannot find customer"); - Customer customer = CustomerCreatedEvent.class.cast(events.get(0)).getCustomer(); - // TODO: use the remainings events to reconstruct final customer state - return customer; - } - -} diff --git a/crm-microservice/src/main/java/com/example/crm/service/business/StandardCustomerService.java b/crm-microservice/src/main/java/com/example/crm/service/business/StandardCustomerService.java new file mode 100644 index 0000000..2c8326a --- /dev/null +++ b/crm-microservice/src/main/java/com/example/crm/service/business/StandardCustomerService.java @@ -0,0 +1,88 @@ +package com.example.crm.service.business; + +import java.lang.reflect.Field; +import java.util.List; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.example.crm.document.Customer; +import com.example.crm.repository.CustomerRepository; +import com.example.crm.service.CustomerService; + +/** + * + * @author Binnur Kurt + * + */ +@Service +public class StandardCustomerService implements CustomerService { + + @Autowired + private CustomerRepository customerRepository; + + @Override + public Customer createCustomer(Customer customer) { + String identity = customer.getIdentity(); + var managedCustomer = customerRepository.findById(identity); + if (managedCustomer.isEmpty()) { + throw new IllegalArgumentException("Customer already exists"); + } + return customerRepository.save(customer); + } + + @Override + public Customer updateCustomerByIdentity(String identity, Customer customer) { + var managedCustomer = customerRepository.findById(identity); + if (managedCustomer.isPresent()) { + return customerRepository.save(customer); + } + throw new IllegalArgumentException("Customer does not exist"); + } + + @Override + public Customer updateCustomerByIdentity(String identity, Map request) { + var managedCustomer = customerRepository.findById(identity); + if (managedCustomer.isPresent()) { + var customer = managedCustomer.get(); + request.forEach((field, value) -> { + Field declaredField; + try { + declaredField = Customer.class.getDeclaredField(field); + declaredField.setAccessible(true); + declaredField.set(customer, value); + declaredField.setAccessible(false); + } catch (Exception e) { + System.err.println(e.getMessage()); + } + }); + return customerRepository.save(customer); + } + throw new IllegalArgumentException("Customer does not exist"); + } + + @Override + public Customer deleteCustomerByIdentity(String identity) { + var customer = customerRepository.findById(identity); + if (customer.isPresent()) { + Customer removedCustomer = customer.get(); + customerRepository.delete(removedCustomer); + return removedCustomer; + } + throw new IllegalArgumentException("Customer does not exist"); + } + + @Override + public List findAllCustomers(int pagesize, int pageno) { + return customerRepository.findAll(); + } + + @Override + public Customer findCustomerByIdentity(String identity) { + return customerRepository.findById(identity) + .orElseThrow(() -> new IllegalArgumentException("Customer does not exist")); + + } + +} diff --git a/crm-microservice/src/main/resources/application.properties b/crm-microservice/src/main/resources/application.properties index bf9d7da..619c127 100644 --- a/crm-microservice/src/main/resources/application.properties +++ b/crm-microservice/src/main/resources/application.properties @@ -11,13 +11,4 @@ timestamp=1581420934 #http://localhost:8100/crm/api/v1/swagger-ui.html #mongodb configuration -spring.data.mongodb.uri=mongodb://localhost:27017/crm - -# kafka configuration -spring.kafka.consumer.group-id=hr -spring.kafka.consumer.auto-offset-reset=earliest -spring.kafka.consumer.key-deserializer=org.apache.kafka.common.serialization.StringDeserializer -spring.kafka.consumer.value-deserializer=org.springframework.kafka.support.serializer.JsonDeserializer -spring.kafka.producer.key-serializer=org.apache.kafka.common.serialization.StringSerializer -spring.kafka.producer.value-serializer=org.springframework.kafka.support.serializer.JsonSerializer -spring.kafka.consumer.properties.spring.json.trusted.packages=* \ No newline at end of file +spring.data.mongodb.uri=mongodb://localhost:27017/crm \ No newline at end of file diff --git a/crm-reactive-microservice/src/main/java/com/example/crm/CrmReactiveMicroserviceApplication.java b/crm-reactive-microservice/src/main/java/com/example/crm/CrmReactiveMicroserviceApplication.java index e9a37ce..5e075dc 100644 --- a/crm-reactive-microservice/src/main/java/com/example/crm/CrmReactiveMicroserviceApplication.java +++ b/crm-reactive-microservice/src/main/java/com/example/crm/CrmReactiveMicroserviceApplication.java @@ -1,17 +1,36 @@ package com.example.crm; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.ApplicationArguments; +import org.springframework.boot.ApplicationRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.data.domain.PageRequest; import org.springframework.data.mongodb.repository.config.EnableReactiveMongoRepositories; import org.springframework.web.reactive.config.EnableWebFlux; +import com.example.crm.repository.CustomerReactiveRepository; + +/** + * + * @author Binnur Kurt + * + */ @SpringBootApplication @EnableWebFlux @EnableReactiveMongoRepositories -public class CrmReactiveMicroserviceApplication { - +public class CrmReactiveMicroserviceApplication implements ApplicationRunner { + @Autowired private CustomerReactiveRepository customerReactiveRepository; + public static void main(String[] args) { SpringApplication.run(CrmReactiveMicroserviceApplication.class, args); } + @Override + public void run(ApplicationArguments args) throws Exception { + customerReactiveRepository.findAllFlux(PageRequest.of(0, 10)) + .subscribe(System.err::println); + + } + } diff --git a/crm-reactive-microservice/src/main/java/com/example/crm/controller/CustomerReactiveRestController.java b/crm-reactive-microservice/src/main/java/com/example/crm/controller/CustomerReactiveRestController.java index 78012b8..a4ebf61 100644 --- a/crm-reactive-microservice/src/main/java/com/example/crm/controller/CustomerReactiveRestController.java +++ b/crm-reactive-microservice/src/main/java/com/example/crm/controller/CustomerReactiveRestController.java @@ -7,7 +7,6 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.context.annotation.RequestScope; import com.example.crm.document.Customer; import com.example.crm.service.CustomerReactiveService; @@ -15,6 +14,11 @@ import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; +/** + * + * @author Binnur Kurt + * + */ @RestController @RequestMapping("customers") @CrossOrigin diff --git a/crm-reactive-microservice/src/main/java/com/example/crm/document/Customer.java b/crm-reactive-microservice/src/main/java/com/example/crm/document/Customer.java index f45d5f7..52ea2ff 100644 --- a/crm-reactive-microservice/src/main/java/com/example/crm/document/Customer.java +++ b/crm-reactive-microservice/src/main/java/com/example/crm/document/Customer.java @@ -3,6 +3,11 @@ import org.springframework.data.annotation.Id; import org.springframework.data.mongodb.core.mapping.Document; +/** + * + * @author Binnur Kurt + * + */ @Document(collection = "customers") public class Customer { @Id diff --git a/crm-reactive-microservice/src/main/java/com/example/crm/repository/CustomerReactiveRepository.java b/crm-reactive-microservice/src/main/java/com/example/crm/repository/CustomerReactiveRepository.java index 153a303..cfc4c51 100644 --- a/crm-reactive-microservice/src/main/java/com/example/crm/repository/CustomerReactiveRepository.java +++ b/crm-reactive-microservice/src/main/java/com/example/crm/repository/CustomerReactiveRepository.java @@ -8,6 +8,11 @@ import reactor.core.publisher.Flux; +/** + * + * @author Binnur Kurt + * + */ public interface CustomerReactiveRepository extends ReactiveMongoRepository{ @Query("{}") diff --git a/crm-reactive-microservice/src/main/java/com/example/crm/service/CustomerReactiveService.java b/crm-reactive-microservice/src/main/java/com/example/crm/service/CustomerReactiveService.java index 232df3c..5c108eb 100644 --- a/crm-reactive-microservice/src/main/java/com/example/crm/service/CustomerReactiveService.java +++ b/crm-reactive-microservice/src/main/java/com/example/crm/service/CustomerReactiveService.java @@ -10,6 +10,11 @@ import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; +/** + * + * @author Binnur Kurt + * + */ @Service public class CustomerReactiveService { @Autowired diff --git a/gateway-zulu/src/main/java/com/example/GatewayZuluApplication.java b/gateway-zulu/src/main/java/com/example/GatewayZuluApplication.java new file mode 100644 index 0000000..e75bde9 --- /dev/null +++ b/gateway-zulu/src/main/java/com/example/GatewayZuluApplication.java @@ -0,0 +1,20 @@ +package com.example; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.netflix.zuul.EnableZuulProxy; + +/** + * + * @author Binnur Kurt + * + */ +@SpringBootApplication +@EnableZuulProxy +public class GatewayZuluApplication { + + public static void main(String[] args) { + SpringApplication.run(GatewayZuluApplication.class, args); + } + +} diff --git a/gateway-zulu/src/main/resources/application.properties b/gateway-zulu/src/main/resources/application.properties new file mode 100644 index 0000000..fc9d424 --- /dev/null +++ b/gateway-zulu/src/main/resources/application.properties @@ -0,0 +1,15 @@ +server.address=localhost +server.port=8700 + +spring.application.name=gateway-zuul + +# eureka client configuration +eureka.client.serviceUrl.defaultZone=http://localhost:4040/eureka +eureka.instance.lease-expiration-duration-in-seconds=1 +eureka.instance.lease-renewal-interval-in-seconds=2 +eureka.instance.hostname=localhost + +zuul.routes.loto1.path=/loto1/** +zuul.routes.loto1.service-id=lottery-v1 +zuul.routes.loto2.path=/loto2/** +zuul.routes.loto2.service-id=lottery-v2 \ No newline at end of file diff --git a/lottery-microservice-v1/pom.xml b/lottery-microservice-v1/pom.xml new file mode 100644 index 0000000..6dd9c7e --- /dev/null +++ b/lottery-microservice-v1/pom.xml @@ -0,0 +1,80 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.3.1.RELEASE + + + com.example + lottery-microservice-v1 + 0.0.1-SNAPSHOT + lottery-microservice-v1 + Lottery MicroService Version #1 + + + 11 + Hoxton.SR6 + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.cloud + spring-cloud-starter-netflix-eureka-client + + + io.jsonwebtoken + jjwt + 0.9.0 + + + org.springframework.boot + spring-boot-starter-test + test + + + org.junit.vintage + junit-vintage-engine + + + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.security + spring-security-test + test + + + + + + + org.springframework.cloud + spring-cloud-dependencies + ${spring-cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/lottery-microservice-v1/src/main/java/com/example/lottery/config/WebSecurityConfig.java b/lottery-microservice-v1/src/main/java/com/example/lottery/config/WebSecurityConfig.java new file mode 100644 index 0000000..2eb0972 --- /dev/null +++ b/lottery-microservice-v1/src/main/java/com/example/lottery/config/WebSecurityConfig.java @@ -0,0 +1,51 @@ +package com.example.lottery.config; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.provisioning.InMemoryUserDetailsManager; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; + +import com.example.lottery.filter.JwtTokenFilter; + +@Configuration +public class WebSecurityConfig extends WebSecurityConfigurerAdapter { + + @Autowired + private UserDetailsService userDetailsService; + @Value("${security.jwt.token.secret-key}") + private String secret; + + @Override + protected void configure(HttpSecurity http) throws Exception { + System.out.println("configurating security..."); + http.csrf().disable().authorizeRequests().antMatchers("/signin").permitAll().anyRequest().authenticated().and() + .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); + + + http.addFilterBefore(new JwtTokenFilter(userDetailsService, secret), UsernamePasswordAuthenticationFilter.class); + + } + + @Bean + @Override + public AuthenticationManager authenticationManagerBean() throws Exception { + return super.authenticationManagerBean(); + } + + @Bean + @Override + public UserDetailsService userDetailsService() { + UserDetails user = User.withUsername("user").password("{noop}secret").roles("USER").build(); + + return new InMemoryUserDetailsManager(user); + } +} diff --git a/lottery-microservice-v1/src/main/java/com/example/lottery/controller/LoginController.java b/lottery-microservice-v1/src/main/java/com/example/lottery/controller/LoginController.java new file mode 100644 index 0000000..be5889d --- /dev/null +++ b/lottery-microservice-v1/src/main/java/com/example/lottery/controller/LoginController.java @@ -0,0 +1,39 @@ +package com.example.lottery.controller; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.context.annotation.RequestScope; + +import com.example.lottery.dto.WebUser; +import com.example.lottery.provider.JwtTokenProvider; + +@RestController +@RequestScope +@RequestMapping("signin") +@CrossOrigin +public class LoginController { + @Autowired + private AuthenticationManager authMngr; + @Autowired + private JwtTokenProvider jwtTokenProvider; + + @PostMapping + public String signin(@RequestBody @Validated WebUser webuser) { + try { + UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken( + webuser.getUsername(), webuser.getPassword()); + authMngr.authenticate(authToken); + return jwtTokenProvider.createToken(webuser.getUsername()); + } catch (Exception e) { + System.err.println("Log in failed for user " + webuser.getUsername()); + } + return ""; + } +} diff --git a/lottery-microservice-v1/src/main/java/com/example/lottery/controller/LotteryRestController.java b/lottery-microservice-v1/src/main/java/com/example/lottery/controller/LotteryRestController.java new file mode 100644 index 0000000..04fac26 --- /dev/null +++ b/lottery-microservice-v1/src/main/java/com/example/lottery/controller/LotteryRestController.java @@ -0,0 +1,34 @@ +package com.example.lottery.controller; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.context.annotation.RequestScope; + +import com.example.lottery.dto.LotteryResponse; +import com.example.lottery.service.LotteryService; + +@RestController +@RequestScope +@RequestMapping("numbers") +@CrossOrigin +public class LotteryRestController { + @Autowired + private LotteryService lotteryService; + @Value("${server.address}") + private String host; + @Value("${server.port}") + private int port; + + // GET http://localhost:8001/lottery/api/v1/numbers?column=10 + @GetMapping(params = {"column"},produces = MediaType.APPLICATION_JSON_VALUE) + public LotteryResponse getNumbers(@RequestParam int column){ + System.err.println(String.format("Lottery Service @ %s:%d is serving now...",host,port)); + return new LotteryResponse(lotteryService.draw(column)); + } +} diff --git a/lottery-microservice-v1/src/main/java/com/example/lottery/dto/LotteryResponse.java b/lottery-microservice-v1/src/main/java/com/example/lottery/dto/LotteryResponse.java new file mode 100644 index 0000000..40c85ef --- /dev/null +++ b/lottery-microservice-v1/src/main/java/com/example/lottery/dto/LotteryResponse.java @@ -0,0 +1,28 @@ +package com.example.lottery.dto; + +import java.util.List; + +public class LotteryResponse { + private List> numbers; + + public LotteryResponse() { + } + + public LotteryResponse(List> numbers) { + this.numbers = numbers; + } + + public List> getNumbers() { + return numbers; + } + + public void setNumbers(List> numbers) { + this.numbers = numbers; + } + + @Override + public String toString() { + return "LotteryResponse [numbers=" + numbers + "]"; + } + +} diff --git a/lottery-microservice-v1/src/main/java/com/example/lottery/dto/WebUser.java b/lottery-microservice-v1/src/main/java/com/example/lottery/dto/WebUser.java new file mode 100644 index 0000000..83c4d7c --- /dev/null +++ b/lottery-microservice-v1/src/main/java/com/example/lottery/dto/WebUser.java @@ -0,0 +1,35 @@ +package com.example.lottery.dto; + +import javax.validation.constraints.NotNull; + +public class WebUser { + @NotNull + private String username; + @NotNull + private String password; + + public WebUser() { + } + + public WebUser(@NotNull String username, @NotNull String password) { + this.username = username; + this.password = password; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + +} diff --git a/lottery-microservice-v1/src/main/java/com/example/lottery/filter/JwtTokenFilter.java b/lottery-microservice-v1/src/main/java/com/example/lottery/filter/JwtTokenFilter.java new file mode 100644 index 0000000..d163563 --- /dev/null +++ b/lottery-microservice-v1/src/main/java/com/example/lottery/filter/JwtTokenFilter.java @@ -0,0 +1,74 @@ +package com.example.lottery.filter; + +import java.io.IOException; +import java.util.Base64; +import java.util.Date; +import java.util.Optional; +import java.util.function.Function; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; + +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; +import org.springframework.web.filter.GenericFilterBean; + +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; + +public class JwtTokenFilter extends GenericFilterBean { + private String secret; + + private static final String BEARER = "Bearer"; + + private UserDetailsService userDetailsService; + + public JwtTokenFilter(UserDetailsService userDetailsService, String secret) { + this.userDetailsService = userDetailsService; + this.secret = Base64.getEncoder().encodeToString(secret.getBytes()); + } + + @Override + public void doFilter(ServletRequest req, ServletResponse res, FilterChain filterChain) + throws IOException, ServletException { + System.err.println("doFilter()"); + String headerValue = ((HttpServletRequest)req).getHeader("Authorization"); + getBearerToken(headerValue).ifPresent(token-> { + String username = getClaimFromToken(token, Claims::getSubject); + UserDetails userDetails = userDetailsService.loadUserByUsername(username); + + if (username.equals(userDetails.getUsername()) && !isJwtExpired(token)) { + UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = + new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities()); + usernamePasswordAuthenticationToken.setDetails( + new WebAuthenticationDetailsSource().buildDetails((HttpServletRequest)req)); + SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken); + } + }); + + filterChain.doFilter(req, res); + } + + private Optional getBearerToken(String headerVal) { + if (headerVal != null && headerVal.startsWith(BEARER)) { + return Optional.of(headerVal.replace(BEARER, "").trim()); + } + return Optional.empty(); + } + + private T getClaimFromToken(String token, Function claimsResolver) { + final Claims claims = Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody(); + return claimsResolver.apply(claims); + } + + private Boolean isJwtExpired(String token) { + Date expirationDate = getClaimFromToken(token, Claims::getExpiration); + return expirationDate.before(new Date()); + } +} \ No newline at end of file diff --git a/lottery-microservice-v1/src/main/java/com/example/lottery/provider/JwtTokenProvider.java b/lottery-microservice-v1/src/main/java/com/example/lottery/provider/JwtTokenProvider.java new file mode 100644 index 0000000..e5f884a --- /dev/null +++ b/lottery-microservice-v1/src/main/java/com/example/lottery/provider/JwtTokenProvider.java @@ -0,0 +1,36 @@ +package com.example.lottery.provider; + +import java.util.Base64; +import java.util.Date; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; + +@Service +public class JwtTokenProvider { + + private String secretKey; + private long validityInMilliseconds; + + @Autowired + public JwtTokenProvider(@Value("${security.jwt.token.secret-key}") String secretKey, + @Value("${security.jwt.token.expiration}") long milliseconds) { + this.secretKey = Base64.getEncoder().encodeToString(secretKey.getBytes()); + this.validityInMilliseconds = milliseconds; + } + + public String createToken(String username) { + Claims claims = Jwts.claims().setSubject(username); + + // Build the Token + Date now = new Date(); + return Jwts.builder().setClaims(claims).setIssuedAt(now) + .setExpiration(new Date(now.getTime() + validityInMilliseconds)) + .signWith(SignatureAlgorithm.HS256, secretKey).compact(); + } +} diff --git a/lottery-microservice-v1/src/main/java/com/example/lottery/service/LotteryService.java b/lottery-microservice-v1/src/main/java/com/example/lottery/service/LotteryService.java new file mode 100644 index 0000000..a56f0c2 --- /dev/null +++ b/lottery-microservice-v1/src/main/java/com/example/lottery/service/LotteryService.java @@ -0,0 +1,9 @@ +package com.example.lottery.service; + +import java.util.List; + +public interface LotteryService { + + List> draw(int column); + +} diff --git a/lottery-microservice-v1/src/main/java/com/example/lottery/service/business/SimpleLotteryService.java b/lottery-microservice-v1/src/main/java/com/example/lottery/service/business/SimpleLotteryService.java new file mode 100644 index 0000000..609a09b --- /dev/null +++ b/lottery-microservice-v1/src/main/java/com/example/lottery/service/business/SimpleLotteryService.java @@ -0,0 +1,38 @@ +package com.example.lottery.service.business; + +import java.util.List; +import java.util.concurrent.ThreadLocalRandom; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import com.example.lottery.service.LotteryService; + +@Service +public class SimpleLotteryService implements LotteryService{ + @Value("${lottery.min}") + private int lotteryMin; + @Value("${lottery.max}") + private int lotteryMax; + @Value("${lottery.size}") + private int lotterySize; + + public List draw() { + return ThreadLocalRandom.current().ints(lotteryMin, lotteryMax) + .distinct() + .limit(lotterySize) + .sorted() + .boxed() + .collect(Collectors.toList()); + } + + @Override + public List> draw(int column) { + return IntStream.range(0, column) + .mapToObj(i -> this.draw()) + .collect(Collectors.toList()); + } + +} diff --git a/lottery-microservice-v1/src/main/resources/application.properties b/lottery-microservice-v1/src/main/resources/application.properties new file mode 100644 index 0000000..0808bff --- /dev/null +++ b/lottery-microservice-v1/src/main/resources/application.properties @@ -0,0 +1,22 @@ +#Rest API URL Design +server.address=localhost +server.port=6100 + +spring.application.name=lottery-v1 +spring.profiles.active=development + +# actuator +management.endpoints.web.exposure.include=* + +# eureka client configuration +eureka.client.serviceUrl.defaultZone=http://localhost:4040/eureka +eureka.instance.lease-expiration-duration-in-seconds=1 +eureka.instance.lease-renewal-interval-in-seconds=2 +eureka.instance.hostname=localhost + +lottery.min=1 +lottery.max=50 +lottery.size=6 + +security.jwt.token.secret-key=elma +security.jwt.token.expiration=60000 \ No newline at end of file diff --git a/lottery-microservice-v2/src/main/java/com/example/lottery/controller/LotteryRestController.java b/lottery-microservice-v2/src/main/java/com/example/lottery/controller/LotteryRestController.java new file mode 100644 index 0000000..04fac26 --- /dev/null +++ b/lottery-microservice-v2/src/main/java/com/example/lottery/controller/LotteryRestController.java @@ -0,0 +1,34 @@ +package com.example.lottery.controller; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.context.annotation.RequestScope; + +import com.example.lottery.dto.LotteryResponse; +import com.example.lottery.service.LotteryService; + +@RestController +@RequestScope +@RequestMapping("numbers") +@CrossOrigin +public class LotteryRestController { + @Autowired + private LotteryService lotteryService; + @Value("${server.address}") + private String host; + @Value("${server.port}") + private int port; + + // GET http://localhost:8001/lottery/api/v1/numbers?column=10 + @GetMapping(params = {"column"},produces = MediaType.APPLICATION_JSON_VALUE) + public LotteryResponse getNumbers(@RequestParam int column){ + System.err.println(String.format("Lottery Service @ %s:%d is serving now...",host,port)); + return new LotteryResponse(lotteryService.draw(column)); + } +} diff --git a/lottery-microservice-v2/src/main/java/com/example/lottery/dto/LotteryResponse.java b/lottery-microservice-v2/src/main/java/com/example/lottery/dto/LotteryResponse.java new file mode 100644 index 0000000..40c85ef --- /dev/null +++ b/lottery-microservice-v2/src/main/java/com/example/lottery/dto/LotteryResponse.java @@ -0,0 +1,28 @@ +package com.example.lottery.dto; + +import java.util.List; + +public class LotteryResponse { + private List> numbers; + + public LotteryResponse() { + } + + public LotteryResponse(List> numbers) { + this.numbers = numbers; + } + + public List> getNumbers() { + return numbers; + } + + public void setNumbers(List> numbers) { + this.numbers = numbers; + } + + @Override + public String toString() { + return "LotteryResponse [numbers=" + numbers + "]"; + } + +} diff --git a/lottery-microservice-v2/src/main/java/com/example/lottery/service/LotteryService.java b/lottery-microservice-v2/src/main/java/com/example/lottery/service/LotteryService.java new file mode 100644 index 0000000..a56f0c2 --- /dev/null +++ b/lottery-microservice-v2/src/main/java/com/example/lottery/service/LotteryService.java @@ -0,0 +1,9 @@ +package com.example.lottery.service; + +import java.util.List; + +public interface LotteryService { + + List> draw(int column); + +} diff --git a/lottery-microservice-v2/src/main/java/com/example/lottery/service/business/SimpleLotteryService.java b/lottery-microservice-v2/src/main/java/com/example/lottery/service/business/SimpleLotteryService.java new file mode 100644 index 0000000..609a09b --- /dev/null +++ b/lottery-microservice-v2/src/main/java/com/example/lottery/service/business/SimpleLotteryService.java @@ -0,0 +1,38 @@ +package com.example.lottery.service.business; + +import java.util.List; +import java.util.concurrent.ThreadLocalRandom; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import com.example.lottery.service.LotteryService; + +@Service +public class SimpleLotteryService implements LotteryService{ + @Value("${lottery.min}") + private int lotteryMin; + @Value("${lottery.max}") + private int lotteryMax; + @Value("${lottery.size}") + private int lotterySize; + + public List draw() { + return ThreadLocalRandom.current().ints(lotteryMin, lotteryMax) + .distinct() + .limit(lotterySize) + .sorted() + .boxed() + .collect(Collectors.toList()); + } + + @Override + public List> draw(int column) { + return IntStream.range(0, column) + .mapToObj(i -> this.draw()) + .collect(Collectors.toList()); + } + +} diff --git a/lottery-microservice-v2/src/main/resources/application.properties b/lottery-microservice-v2/src/main/resources/application.properties new file mode 100644 index 0000000..684541b --- /dev/null +++ b/lottery-microservice-v2/src/main/resources/application.properties @@ -0,0 +1,19 @@ +#Rest API URL Design +server.address=localhost +server.port=6200 + +spring.application.name=lottery-v2 +spring.profiles.active=development + +# actuator +management.endpoints.web.exposure.include=* + +# eureka client configuration +eureka.client.serviceUrl.defaultZone=http://localhost:4040/eureka +eureka.instance.lease-expiration-duration-in-seconds=1 +eureka.instance.lease-renewal-interval-in-seconds=2 +eureka.instance.hostname=localhost + +lottery.min=50 +lottery.max=100 +lottery.size=6 \ No newline at end of file diff --git a/reactive-gateway/pom.xml b/reactive-gateway/pom.xml new file mode 100644 index 0000000..bfdae73 --- /dev/null +++ b/reactive-gateway/pom.xml @@ -0,0 +1,76 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.3.1.RELEASE + + + com.example + reactive-gateway + 0.0.1-SNAPSHOT + reactive-gateway + Spring Cloud Gateway + + + 11 + Hoxton.SR6 + + + + + + org.springframework.cloud + spring-cloud-starter-gateway + + + org.springframework.cloud + spring-cloud-starter-netflix-eureka-client + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.junit.vintage + junit-vintage-engine + + + + + org.springframework.boot + spring-boot-starter-webflux + + + io.projectreactor + reactor-test + test + + + + + + + org.springframework.cloud + spring-cloud-dependencies + ${spring-cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/reactive-gateway/src/main/resources/application.properties b/reactive-gateway/src/main/resources/application.properties new file mode 100644 index 0000000..d3a9fad --- /dev/null +++ b/reactive-gateway/src/main/resources/application.properties @@ -0,0 +1,13 @@ +server.address=localhost +server.port=8800 + +spring.application.name=reactive-gateway + +# eureka client configuration +eureka.client.serviceUrl.defaultZone=http://localhost:4040/eureka +eureka.instance.lease-expiration-duration-in-seconds=1 +eureka.instance.lease-renewal-interval-in-seconds=2 +eureka.instance.hostname=localhost + +spring.cloud.gateway.discovery.locator.enabled=true +spring.cloud.gateway.discovery.locator.lower-case-service-id=true \ No newline at end of file