Skip to content
This repository has been archived by the owner on Jul 26, 2024. It is now read-only.

Commit

Permalink
Merge pull request #4 from ralf-ueberfuhr-ars/feature/events
Browse files Browse the repository at this point in the history
Add customer event logger
  • Loading branch information
ralf-ueberfuhr-ars authored Jun 25, 2024
2 parents 7b96d6e + 59fc3d0 commit 272893d
Show file tree
Hide file tree
Showing 8 changed files with 121 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
package de.sample.schulung.accounts.domain;

import de.sample.schulung.accounts.domain.Customer.CustomerState;
import de.sample.schulung.accounts.domain.events.CustomerCreatedEvent;
import de.sample.schulung.accounts.domain.events.CustomerDeletedEvent;
import de.sample.schulung.accounts.domain.events.CustomerReplacedEvent;
import de.sample.schulung.accounts.domain.sink.CustomersSink;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

Expand All @@ -18,6 +22,7 @@
public class CustomersService {

private final CustomersSink sink;
private final ApplicationEventPublisher eventPublisher;

public Stream<Customer> getCustomers() {
return sink.getCustomers();
Expand All @@ -29,6 +34,7 @@ public Stream<Customer> getCustomersByState(@NotNull CustomerState state) {

public void createCustomer(@Valid Customer customer) {
sink.createCustomer(customer);
eventPublisher.publishEvent(new CustomerCreatedEvent(customer));
}

public Optional<Customer> findCustomerById(@NotNull UUID uuid) {
Expand All @@ -37,10 +43,12 @@ public Optional<Customer> findCustomerById(@NotNull UUID uuid) {

public void replaceCustomer(@Valid Customer customer) {
sink.replaceCustomer(customer);
eventPublisher.publishEvent(new CustomerReplacedEvent(customer));
}

public void deleteCustomer(@NotNull UUID uuid) {
sink.deleteCustomer(uuid);
eventPublisher.publishEvent(new CustomerDeletedEvent(uuid));
}

public boolean exists(UUID uuid) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package de.sample.schulung.accounts.domain.events;

import de.sample.schulung.accounts.domain.Customer;

public record CustomerCreatedEvent(
Customer customer
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package de.sample.schulung.accounts.domain.events;

import java.util.UUID;

public record CustomerDeletedEvent(
UUID uuid
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package de.sample.schulung.accounts.domain.events;

import de.sample.schulung.accounts.domain.Customer;

public record CustomerReplacedEvent(
Customer customer
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package de.sample.schulung.accounts.domain.logging;

import de.sample.schulung.accounts.domain.Customer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

@Component
@Slf4j
public class CustomerEventLogger {

public void logCustomerCreated(Customer customer) {
log.info("Customer created with UUID {}", customer.getUuid());
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package de.sample.schulung.accounts.domain.logging;

import de.sample.schulung.accounts.domain.events.CustomerCreatedEvent;
import lombok.RequiredArgsConstructor;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;

@Component
@RequiredArgsConstructor
public class CustomerEventObserver {

private final CustomerEventLogger customerEventLogger;

@EventListener
public void handle(CustomerCreatedEvent event) {
customerEventLogger.logCustomerCreated(event.customer());
}

}
Original file line number Diff line number Diff line change
@@ -1,18 +1,27 @@
package de.sample.schulung.accounts.domain;

import de.sample.schulung.accounts.domain.events.CustomerCreatedEvent;
import de.sample.schulung.accounts.domain.logging.CustomerEventLogger;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.event.ApplicationEvents;

import java.time.LocalDate;
import java.time.Month;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.Mockito.verify;

@DomainLayerTest
public class CustomersServiceTest {

@Autowired
CustomersService service;
@Autowired
CustomerEventLogger customerEventLogger;
@Autowired
ApplicationEvents events;

@Test
void shouldNotCreateInvalidCustomer() {
Expand All @@ -38,5 +47,36 @@ void shouldNotCreateCustomerThatIsNoAdult() {

}

@Test
void shouldLogEventWhenCustomerIsCreated() {

var customer = new Customer();
customer.setName("Tom Mayer");
customer.setState(Customer.CustomerState.ACTIVE);
customer.setDateOfBirth(LocalDate.of(2000, Month.DECEMBER, 20));

service.createCustomer(customer);

verify(customerEventLogger).logCustomerCreated(customer);

}

@Test
void shouldPublishEventWhenCustomerIsCreated() {

var customer = new Customer();
customer.setName("Tom Mayer");
customer.setState(Customer.CustomerState.ACTIVE);
customer.setDateOfBirth(LocalDate.of(2000, Month.DECEMBER, 20));

service.createCustomer(customer);

assertThat(events.stream(CustomerCreatedEvent.class))
.hasSize(1)
.first()
.extracting(CustomerCreatedEvent::customer)
.isSameAs(customer);

}

}
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
package de.sample.schulung.accounts.domain;

import de.sample.schulung.accounts.config.InitializationProperty;
import de.sample.schulung.accounts.domain.logging.CustomerEventLogger;
import de.sample.schulung.accounts.domain.sink.CustomersSink;
import de.sample.schulung.accounts.domain.sink.CustomersSinkInMemoryImpl;
import org.junit.jupiter.api.Tag;
import org.mockito.Mockito;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockReset;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.annotation.AliasFor;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.event.RecordApplicationEvents;

import java.lang.annotation.*;

Expand All @@ -31,6 +35,7 @@
HibernateJpaAutoConfiguration.class
})
@InitializationProperty
@RecordApplicationEvents
// optional
@ActiveProfiles({"test", "domain-test"})
@Tag("integration-test")
Expand All @@ -50,6 +55,16 @@ CustomersSink testCustomerSink() {
return new CustomersSinkInMemoryImpl();
}

@Primary
@Bean
CustomerEventLogger testCustomerEventLogger() {
// Mock or DefaultImpl?
return Mockito.mock(
CustomerEventLogger.class,
MockReset.withSettings(MockReset.AFTER)
);
}

}


Expand Down

0 comments on commit 272893d

Please sign in to comment.