- Examen
Where we will put the common used classes :
- add annotation to main dependency
@SpringBootApplication
@EnableEurekaServer
public class DiscoveryServiceApplication {
public static void main(String[] args) {
SpringApplication.run(DiscoveryServiceApplication.class, args);
}
}
- application.properties:
server.port=8761
eureka.instance.prefer-ip-address=true
eureka.client.fetch-registry=false
eureka.client.register-with-eureka=false
- Create GatewayConfig:
@Configuration
public class GatewayConfig {
@Bean
DiscoveryClientRouteDefinitionLocator discoveryClientRouteDefinitionLocator(ReactiveDiscoveryClient reactiveDiscoveryClient,
DiscoveryLocatorProperties discoveryLocatorProperties){
return new DiscoveryClientRouteDefinitionLocator(reactiveDiscoveryClient, discoveryLocatorProperties);
}
}
- application.properties:
eureka.client.register-with-eureka=true
server.port=7000
spring.application.name=GATEWAY-SERVICE
- eureka-client
- jpa
- web
- lombok
- MySQL
- Axon
- add Common-API to the dependencies
xml <dependency> <groupId>org.example</groupId> <artifactId>Common-API</artifactId> <version>1.0-SNAPSHOT</version> </dependency>
@RestController
@RequestMapping("/commands/client")
@AllArgsConstructor
public class ClientCommandController {
private final CommandGateway commandGateway;
private final EventStore eventStore;
@PostMapping("/create")
public CompletableFuture<String> createClient(@RequestBody CreateClientRequestDTO request) {
return commandGateway.send(new CreateClientCommand(
UUID.randomUUID().toString(),
request.getNom(),
request.getAdresse(),
request.getEmail(),
request.getTele()
));
}
@PutMapping("/update")
public CompletableFuture<String> updateClient(@RequestBody UpdateClientRequestDTO request) {
return commandGateway.send(new UpdateClientCommand(
request.getId(),
request.getNom(),
request.getAdresse(),
request.getEmail(),
request.getTele()
));
}
}
- CreateClientCommand
public class CreateClientCommand extends BaseCommand<String> {
@Getter private String nom;
@Getter private String adresse;
@Getter private String email;
@Getter private String tele;
public CreateClientCommand(String id, String nom, String adresse, String email, String tele) {
super(id);
this.nom = nom;
this.adresse = adresse;
this.email = email;
this.tele = tele;
}
}
- CreateClientDTO
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CreateClientRequestDTO {
private String nom;
private String adresse;
private String email;
private String tele;
}
- ClientCreatedEvent
public class ClientCreatedEvent extends BaseEvent<String> {
@Getter private String nom;
@Getter private String adresse;
@Getter private String email;
@Getter private String tele;
public ClientCreatedEvent(String id, String nom, String adresse, String email, String tele) {
super(id);
this.nom = nom;
this.adresse = adresse;
this.email = email;
this.tele = tele;
}
}
@Aggregate
public class ClientAggregate {
@AggregateIdentifier
private String id;
private String nom;
private String adresse;
private String email;
private String tele;
public ClientAggregate() {
}
@CommandHandler
public ClientAggregate(CreateClientCommand command) {
AggregateLifecycle.apply(new ClientCreatedEvent(
command.getId(),
command.getNom(),
command.getAdresse(),
command.getEmail(),
command.getTele()
));
}
@EventSourcingHandler
public void on(ClientCreatedEvent event) {
this.id = event.getId();
this.adresse= event.getAdresse();
this.email= event.getEmail();
this.nom= event.getNom();
this.tele= event.getTele();
}
@CommandHandler
public void handle(UpdateClientCommand command) {
AggregateLifecycle.apply(new ClientUpdatedEvent(
command.getId(),
command.getNom(),
command.getAdresse(),
command.getEmail(),
command.getTele()
));
}
@EventSourcingHandler
public void on(ClientUpdatedEvent event) {
this.id = event.getId();
this.adresse= event.getAdresse();
this.email= event.getEmail();
this.nom= event.getNom();
this.tele= event.getTele();
}
}
@RestController
@RequestMapping("/queries/client")
@AllArgsConstructor
@Slf4j
public class ClientQueryController {
private QueryGateway queryGateway;
@GetMapping("/allClients")
public List<Client> ClientsList() {
List<Client> response = queryGateway.query(new GetAllClientsQuery(), ResponseTypes.multipleInstancesOf(Client.class)).join();
return response;
}
@GetMapping("/byId/{id}")
public List<Client> ClientByIdList(@PathVariable String id){
List<Client> response = queryGateway.query(new GetClientByIdQuery(id), ResponseTypes.multipleInstancesOf(Client.class)).join();
return response;
}
}
@Entity
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Client {
@Id
private String id;
private String nom;
private String adresse;
private String email;
private String tele;
}
public interface ClientRepository extends JpaRepository<Client,String> {
}
@Service
@AllArgsConstructor
@Slf4j
@Transactional
public class ClientServiceHandler {
private ClientRepository clientRepository;
@EventHandler
public void on(ClientCreatedEvent event) {
log.info("ClientCreatedEvent received");
Client client = new Client();
client.setId(event.getId());
client.setAdresse(event.getAdresse());
client.setEmail(event.getEmail());
client.setNom(event.getNom());
client.setTele(event.getTele());
clientRepository.save(client);
}
@EventHandler
public void on(ClientUpdatedEvent event) {
log.info("ClientUpdatedEvent received");
Client client = clientRepository.findById(event.getId()).get();
client.setAdresse(event.getAdresse());
client.setEmail(event.getEmail());
client.setNom(event.getNom());
client.setTele(event.getTele());
clientRepository.save(client);
}
@QueryHandler
public List<Client> on(GetAllClientsQuery query){
return clientRepository.findAll();
}
@QueryHandler
public Client on(GetClientByIdQuery query){
return clientRepository.findById(query.getId()).get();
}
}
spring.application.name=CUSTOMER-SERVICE
spring.datasource.url=jdbc:mysql://${MYSQL_HOST:localhost}:${MYSQL_HOST:3306}/customerDB?createDatabaseIfNotExist=true
spring.datasource.username=${MYSQL_USER:root}
spring.datasource.password=${MYSQL_PASSWORD:}
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MariaDBDialect
server.port=7001
# default parameter :
axon.axonserver.servers=localhost
axon.axonserver.enabled=true
eureka.instance.prefer-ip-address=true
spring.cloud.discovery.enabled=true
the same method as the Customer Service :
@Entity
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Category {
@Id
private String category_id;
private String nom;
private String desc;
@OneToMany(mappedBy = "category")
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
private List<Produit> produits;
}
@Entity
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Produit {
@Id
private String id;
private String nom;
private double prix;
private int quantite;
@ManyToOne
private Category category;
}