deps: Refactor dependencies (#3224)

* remove spring dep
move junit, logging, mockito under dep mgmt

* upgrade anti-corruption-layer deps

* async method invocation

* balking, bloc

* bridge to bytecode

* caching

* callback - cqrs

* component - health check

* hexagonal - metadata mapping

* rest of the patterns

* remove checkstyle, take spotless into use
This commit is contained in:
Ilkka Seppälä
2025-03-29 19:34:27 +02:00
committed by GitHub
parent 371439aeaa
commit 0ca162a55c
1863 changed files with 14403 additions and 17632 deletions
@@ -35,18 +35,18 @@ import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.stereotype.Component;
import service.CakeBakingService;
import view.CakeViewImpl;
/**
* The Runner class is the entry point of the application.
* It implements CommandLineRunner, which means it will execute the run method after the application context is loaded.
* The Runner class is the entry point of the application. It implements CommandLineRunner, which
* means it will execute the run method after the application context is loaded.
*
* <p>The Runner class is responsible for initializing the cake baking service with sample data and creating a view to render the cakes.
* It uses the CakeBakingService to save new layers and toppings and to bake new cakes.
* It also handles exceptions that might occur during the cake baking process.</p>
* <p>The Runner class is responsible for initializing the cake baking service with sample data and
* creating a view to render the cakes. It uses the CakeBakingService to save new layers and
* toppings and to bake new cakes. It also handles exceptions that might occur during the cake
* baking process.
*/
@EntityScan(basePackages = "entity")
@ComponentScan(basePackages = {"com.iluwatar.layers", "service", "dto", "exception", "view", "dao"})
@@ -63,7 +63,7 @@ public class Runner implements CommandLineRunner {
@Override
public void run(String... args) {
//initialize sample data
// initialize sample data
initializeData();
// create view and render it
var cakeView = new CakeViewImpl(cakeBakingService);
@@ -74,9 +74,7 @@ public class Runner implements CommandLineRunner {
SpringApplication.run(Runner.class, args);
}
/**
* Initializes the example data.
*/
/** Initializes the example data. */
private void initializeData() {
cakeBakingService.saveNewLayer(new CakeLayerInfo("chocolate", 1200));
cakeBakingService.saveNewLayer(new CakeLayerInfo("banana", 900));
@@ -88,17 +86,25 @@ public class Runner implements CommandLineRunner {
cakeBakingService.saveNewTopping(new CakeToppingInfo("candies", 350));
cakeBakingService.saveNewTopping(new CakeToppingInfo("cherry", 350));
var cake1 = new CakeInfo(new CakeToppingInfo("candies", 0),
List.of(new CakeLayerInfo("chocolate", 0), new CakeLayerInfo("banana", 0),
new CakeLayerInfo(STRAWBERRY, 0)));
var cake1 =
new CakeInfo(
new CakeToppingInfo("candies", 0),
List.of(
new CakeLayerInfo("chocolate", 0),
new CakeLayerInfo("banana", 0),
new CakeLayerInfo(STRAWBERRY, 0)));
try {
cakeBakingService.bakeNewCake(cake1);
} catch (CakeBakingException e) {
LOGGER.error("Cake baking exception", e);
}
var cake2 = new CakeInfo(new CakeToppingInfo("cherry", 0),
List.of(new CakeLayerInfo("vanilla", 0), new CakeLayerInfo("lemon", 0),
new CakeLayerInfo(STRAWBERRY, 0)));
var cake2 =
new CakeInfo(
new CakeToppingInfo("cherry", 0),
List.of(
new CakeLayerInfo("vanilla", 0),
new CakeLayerInfo("lemon", 0),
new CakeLayerInfo(STRAWBERRY, 0)));
try {
cakeBakingService.bakeNewCake(cake2);
} catch (CakeBakingException e) {
@@ -33,8 +33,8 @@ import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
/**
* The Layers pattern is a structural design pattern that organizes system architecture into
* distinct layers, each with a specific responsibility and abstraction level. This separation
* allows for increased modularity, facilitating independent development, maintenance, and reuse
* of each layer. Commonly, layers interact with each other through well-defined interfaces, with
* allows for increased modularity, facilitating independent development, maintenance, and reuse of
* each layer. Commonly, layers interact with each other through well-defined interfaces, with
* higher layers (more abstract) depending on lower layers (more concrete), but not vice versa,
* promoting a clear hierarchy and separation of concerns.
*/
@@ -46,7 +46,5 @@ public class LayersApp {
public static void main(String[] args) {
SpringApplication.run(LayersApp.class, args);
}
}
@@ -28,8 +28,6 @@ import entity.Cake;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
/**
* CRUD repository for cakes.
*/
/** CRUD repository for cakes. */
@Repository
public interface CakeDao extends JpaRepository<Cake, Long> {}
@@ -28,10 +28,6 @@ import entity.CakeLayer;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
/**
* CRUD repository for cake layers.
*/
/** CRUD repository for cake layers. */
@Repository
public interface CakeLayerDao extends JpaRepository<CakeLayer, Long> {
}
public interface CakeLayerDao extends JpaRepository<CakeLayer, Long> {}
@@ -24,16 +24,10 @@
*/
package dao;
import entity.CakeTopping;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
/**
* CRUD repository cake toppings.
*/
/** CRUD repository cake toppings. */
@Repository
public interface CakeToppingDao extends JpaRepository<CakeTopping, Long> {
}
public interface CakeToppingDao extends JpaRepository<CakeTopping, Long> {}
@@ -27,36 +27,28 @@ package dto;
import java.util.List;
/**
* DTO for cakes.
*/
/** DTO for cakes. */
public class CakeInfo {
public final Long id;
public final CakeToppingInfo cakeToppingInfo;
public final List<CakeLayerInfo> cakeLayerInfos;
/**
* Constructor.
*/
/** Constructor. */
public CakeInfo(Long id, CakeToppingInfo cakeToppingInfo, List<CakeLayerInfo> cakeLayerInfos) {
this.id = id;
this.cakeToppingInfo = cakeToppingInfo;
this.cakeLayerInfos = cakeLayerInfos;
}
/**
* Constructor.
*/
/** Constructor. */
public CakeInfo(CakeToppingInfo cakeToppingInfo, List<CakeLayerInfo> cakeLayerInfos) {
this.id = null;
this.cakeToppingInfo = cakeToppingInfo;
this.cakeLayerInfos = cakeLayerInfos;
}
/**
* Calculate calories.
*/
/** Calculate calories. */
public int calculateTotalCalories() {
var total = cakeToppingInfo != null ? cakeToppingInfo.calories : 0;
total += cakeLayerInfos.stream().mapToInt(c -> c.calories).sum();
@@ -65,7 +57,8 @@ public class CakeInfo {
@Override
public String toString() {
return String.format("CakeInfo id=%d topping=%s layers=%s totalCalories=%d", id,
cakeToppingInfo, cakeLayerInfos, calculateTotalCalories());
return String.format(
"CakeInfo id=%d topping=%s layers=%s totalCalories=%d",
id, cakeToppingInfo, cakeLayerInfos, calculateTotalCalories());
}
}
@@ -25,27 +25,21 @@
package dto;
/**
* DTO for cake layers.
*/
/** DTO for cake layers. */
public class CakeLayerInfo {
public final Long id;
public final String name;
public final int calories;
/**
* Constructor.
*/
/** Constructor. */
public CakeLayerInfo(Long id, String name, int calories) {
this.id = id;
this.name = name;
this.calories = calories;
}
/**
* Constructor.
*/
/** Constructor. */
public CakeLayerInfo(String name, int calories) {
this.id = null;
this.name = name;
@@ -25,27 +25,21 @@
package dto;
/**
* DTO for cake toppings.
*/
/** DTO for cake toppings. */
public class CakeToppingInfo {
public final Long id;
public final String name;
public final int calories;
/**
* Constructor.
*/
/** Constructor. */
public CakeToppingInfo(Long id, String name, int calories) {
this.id = id;
this.name = name;
this.calories = calories;
}
/**
* Constructor.
*/
/** Constructor. */
public CakeToppingInfo(String name, int calories) {
this.id = null;
this.name = name;
@@ -54,7 +48,6 @@ public class CakeToppingInfo {
@Override
public String toString() {
return String.format("CakeToppingInfo id=%d name=%s calories=%d", id, name,
calories);
return String.format("CakeToppingInfo id=%d name=%s calories=%d", id, name, calories);
}
}
@@ -37,17 +37,13 @@ import java.util.Set;
import lombok.Getter;
import lombok.Setter;
/**
* Cake entity.
*/
/** Cake entity. */
@Entity
@Getter
@Setter
public class Cake {
@Id
@GeneratedValue
private Long id;
@Id @GeneratedValue private Long id;
@OneToOne(cascade = CascadeType.REMOVE)
private CakeTopping topping;
@@ -25,7 +25,6 @@
package entity;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
@@ -38,9 +37,7 @@ import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
/**
* CakeLayer entity.
*/
/** CakeLayer entity. */
@Entity
@Getter
@Setter
@@ -50,9 +47,7 @@ import lombok.Setter;
@EqualsAndHashCode
public class CakeLayer {
@Id
@GeneratedValue
private Long id;
@Id @GeneratedValue private Long id;
private String name;
@@ -25,7 +25,6 @@
package entity;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
@@ -38,9 +37,7 @@ import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
/**
* CakeTopping entity.
*/
/** CakeTopping entity. */
@Entity
@Getter
@Setter
@@ -50,9 +47,7 @@ import lombok.Setter;
@EqualsAndHashCode
public class CakeTopping {
@Id
@GeneratedValue
private Long id;
@Id @GeneratedValue private Long id;
private String name;
@@ -70,5 +65,4 @@ public class CakeTopping {
public String toString() {
return String.format("id=%s name=%s calories=%d", id, name, calories);
}
}
@@ -28,17 +28,13 @@ package exception;
import java.io.Serial;
import org.springframework.stereotype.Component;
/**
* Custom exception used in cake baking.
*/
/** Custom exception used in cake baking. */
@Component
public class CakeBakingException extends Exception {
@Serial
private static final long serialVersionUID = 1L;
@Serial private static final long serialVersionUID = 1L;
public CakeBakingException() {
}
public CakeBakingException() {}
public CakeBakingException(String message) {
super(message);
@@ -32,40 +32,26 @@ import exception.CakeBakingException;
import java.util.List;
import org.springframework.stereotype.Service;
/**
* Service for cake baking operations.
*/
/** Service for cake baking operations. */
@Service
public interface CakeBakingService {
/**
* Bakes new cake according to parameters.
*/
/** Bakes new cake according to parameters. */
void bakeNewCake(CakeInfo cakeInfo) throws CakeBakingException;
/**
* Get all cakes.
*/
/** Get all cakes. */
List<CakeInfo> getAllCakes();
/**
* Store new cake topping.
*/
/** Store new cake topping. */
void saveNewTopping(CakeToppingInfo toppingInfo);
/**
* Get available cake toppings.
*/
/** Get available cake toppings. */
List<CakeToppingInfo> getAvailableToppings();
/**
* Add new cake layer.
*/
/** Add new cake layer. */
void saveNewLayer(CakeLayerInfo layerInfo);
/**
* Get available cake layers.
*/
/** Get available cake layers. */
List<CakeLayerInfo> getAvailableLayers();
void deleteAllCakes();
@@ -73,5 +59,4 @@ public interface CakeBakingService {
void deleteAllLayers();
void deleteAllToppings();
}
@@ -43,9 +43,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
* Implementation of CakeBakingService.
*/
/** Implementation of CakeBakingService. */
@Service
@Transactional
public class CakeBakingServiceImpl implements CakeBakingService {
@@ -62,8 +60,8 @@ public class CakeBakingServiceImpl implements CakeBakingService {
* @param cakeToppingDao the DAO for cake topping-related operations
*/
@Autowired
public CakeBakingServiceImpl(CakeDao cakeDao, CakeLayerDao cakeLayerDao,
CakeToppingDao cakeToppingDao) {
public CakeBakingServiceImpl(
CakeDao cakeDao, CakeLayerDao cakeLayerDao, CakeToppingDao cakeToppingDao) {
this.cakeDao = cakeDao;
this.cakeLayerDao = cakeLayerDao;
this.cakeToppingDao = cakeToppingDao;
@@ -73,7 +71,8 @@ public class CakeBakingServiceImpl implements CakeBakingService {
public void bakeNewCake(CakeInfo cakeInfo) throws CakeBakingException {
var allToppings = getAvailableToppingEntities();
var matchingToppings =
allToppings.stream().filter(t -> t.getName().equals(cakeInfo.cakeToppingInfo.name))
allToppings.stream()
.filter(t -> t.getName().equals(cakeInfo.cakeToppingInfo.name))
.toList();
if (matchingToppings.isEmpty()) {
throw new CakeBakingException(
@@ -184,7 +183,9 @@ public class CakeBakingServiceImpl implements CakeBakingService {
List<CakeInfo> result = new ArrayList<>();
for (Cake cake : cakeDao.findAll()) {
var cakeToppingInfo =
new CakeToppingInfo(cake.getTopping().getId(), cake.getTopping().getName(),
new CakeToppingInfo(
cake.getTopping().getId(),
cake.getTopping().getName(),
cake.getTopping().getCalories());
List<CakeLayerInfo> cakeLayerInfos = new ArrayList<>();
for (var layer : cake.getLayers()) {
@@ -29,9 +29,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import service.CakeBakingService;
/**
* View implementation for displaying cakes.
*/
/** View implementation for displaying cakes. */
public class CakeViewImpl implements View {
private final CakeBakingService cakeBakingService;
@@ -25,11 +25,8 @@
package view;
/**
* View interface.
*/
/** View interface. */
public interface View {
void render();
}
@@ -45,5 +45,4 @@ class LayersAppTests {
void contextLoads() {
assertNotNull(applicationContext);
}
}
@@ -38,9 +38,9 @@ import java.util.Set;
import org.junit.jupiter.api.Test;
/**
* This class contains unit tests for the Cake class.
* It tests the functionality of setting and getting the id, topping, and layers of a Cake object.
* It also tests the functionality of adding a layer to a Cake object and converting a Cake object to a string.
* This class contains unit tests for the Cake class. It tests the functionality of setting and
* getting the id, topping, and layers of a Cake object. It also tests the functionality of adding a
* layer to a Cake object and converting a Cake object to a string.
*/
class CakeTest {
@@ -70,8 +70,11 @@ class CakeTest {
assertNotNull(cake.getLayers());
assertTrue(cake.getLayers().isEmpty());
final var expectedLayers = Set.of(new CakeLayer("layer1", 1000), new CakeLayer("layer2", 2000),
new CakeLayer("layer3", 3000));
final var expectedLayers =
Set.of(
new CakeLayer("layer1", 1000),
new CakeLayer("layer2", 2000),
new CakeLayer("layer3", 3000));
cake.setLayers(expectedLayers);
assertEquals(expectedLayers, cake.getLayers());
}
@@ -112,10 +115,9 @@ class CakeTest {
cake.setTopping(topping);
cake.addLayer(layer);
final var expected = "id=1234 topping=id=2345 name=topping calories=20 "
+ "layers=[id=3456 name=layer calories=100]";
final var expected =
"id=1234 topping=id=2345 name=topping calories=20 "
+ "layers=[id=3456 name=layer calories=100]";
assertEquals(expected, cake.toString());
}
}
@@ -32,17 +32,15 @@ import exception.CakeBakingException;
import org.junit.jupiter.api.Test;
/**
* Tests for the {@link CakeBakingException} class.
* This class contains unit tests to verify the correct functionality
* of the {@code CakeBakingException} class constructors, including the default constructor
* and the constructor that accepts a message parameter.
* Tests for the {@link CakeBakingException} class. This class contains unit tests to verify the
* correct functionality of the {@code CakeBakingException} class constructors, including the
* default constructor and the constructor that accepts a message parameter.
*/
class CakeBakingExceptionTest {
/**
* Tests the default constructor of {@link CakeBakingException}.
* Ensures that an exception created with the default constructor has
* {@code null} as its message and cause.
* Tests the default constructor of {@link CakeBakingException}. Ensures that an exception created
* with the default constructor has {@code null} as its message and cause.
*/
@Test
void testConstructor() {
@@ -52,18 +50,20 @@ class CakeBakingExceptionTest {
}
/**
* Tests the constructor of {@link CakeBakingException} that accepts a message.
* Ensures that an exception created with this constructor correctly stores the provided message
* and has {@code null} as its cause.
* Tests the constructor of {@link CakeBakingException} that accepts a message. Ensures that an
* exception created with this constructor correctly stores the provided message and has {@code
* null} as its cause.
*/
@Test
void testConstructorWithMessage() {
final var expectedMessage = "message";
final var exception = new CakeBakingException(expectedMessage);
assertEquals(expectedMessage, exception.getMessage(),
assertEquals(
expectedMessage,
exception.getMessage(),
"The stored message should match the expected message.");
assertNull(exception.getCause(),
assertNull(
exception.getCause(),
"The cause should be null when an exception is created with only a message.");
}
}
@@ -44,10 +44,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import service.CakeBakingServiceImpl;
/**
* Constructs a new instance of CakeBakingServiceImplTest.
*
*/
/** Constructs a new instance of CakeBakingServiceImplTest. */
@SpringBootTest(classes = LayersApp.class)
class CakeBakingServiceImplTest {
@@ -65,7 +62,6 @@ class CakeBakingServiceImplTest {
cakeBakingService.deleteAllToppings();
}
@Test
void testLayers() {
final var initialLayers = cakeBakingService.getAvailableLayers();
@@ -84,7 +80,6 @@ class CakeBakingServiceImplTest {
assertNotNull(layer.toString());
assertTrue(layer.calories > 0);
}
}
@Test
@@ -105,7 +100,6 @@ class CakeBakingServiceImplTest {
assertNotNull(topping.toString());
assertTrue(topping.calories > 0);
}
}
@Test
@@ -141,7 +135,6 @@ class CakeBakingServiceImplTest {
assertFalse(cakeInfo.cakeLayerInfos.isEmpty());
assertTrue(cakeInfo.calculateTotalCalories() > 0);
}
}
@Test
@@ -152,7 +145,8 @@ class CakeBakingServiceImplTest {
cakeBakingService.saveNewLayer(layer2);
final var missingTopping = new CakeToppingInfo("Topping1", 1000);
assertThrows(CakeBakingException.class,
assertThrows(
CakeBakingException.class,
() -> cakeBakingService.bakeNewCake(new CakeInfo(missingTopping, List.of(layer1, layer2))));
}
@@ -169,7 +163,8 @@ class CakeBakingServiceImplTest {
cakeBakingService.saveNewLayer(layer1);
final var missingLayer = new CakeLayerInfo("Layer2", 2000);
assertThrows(CakeBakingException.class,
assertThrows(
CakeBakingException.class,
() -> cakeBakingService.bakeNewCake(new CakeInfo(topping1, List.of(layer1, missingLayer))));
}
@@ -190,8 +185,10 @@ class CakeBakingServiceImplTest {
cakeBakingService.saveNewLayer(layer2);
cakeBakingService.bakeNewCake(new CakeInfo(topping1, List.of(layer1, layer2)));
assertThrows(CakeBakingException.class, () -> cakeBakingService.bakeNewCake(
new CakeInfo(topping2, Collections.singletonList(layer2))));
assertThrows(
CakeBakingException.class,
() ->
cakeBakingService.bakeNewCake(
new CakeInfo(topping2, Collections.singletonList(layer2))));
}
}
@@ -45,9 +45,9 @@ import service.CakeBakingService;
import view.CakeViewImpl;
/**
* This class contains unit tests for the CakeViewImpl class.
* It tests the functionality of rendering cakes using the CakeViewImpl class.
* It also tests the logging functionality of the CakeViewImpl class.
* This class contains unit tests for the CakeViewImpl class. It tests the functionality of
* rendering cakes using the CakeViewImpl class. It also tests the logging functionality of the
* CakeViewImpl class.
*/
class CakeViewImplTest {
@@ -63,14 +63,15 @@ class CakeViewImplTest {
appender.stop();
}
/**
* Verify if the cake view renders the expected result.
*/
/** Verify if the cake view renders the expected result. */
@Test
void testRender() {
final var layers = List.of(new CakeLayerInfo("layer1", 1000), new CakeLayerInfo("layer2", 2000),
new CakeLayerInfo("layer3", 3000));
final var layers =
List.of(
new CakeLayerInfo("layer1", 1000),
new CakeLayerInfo("layer2", 2000),
new CakeLayerInfo("layer3", 3000));
final var cake = new CakeInfo(new CakeToppingInfo("topping", 1000), layers);
final var cakes = List.of(cake);
@@ -84,7 +85,6 @@ class CakeViewImplTest {
cakeView.render();
assertEquals(cake.toString(), appender.getLastMessage());
}
private static class InMemoryAppender extends AppenderBase<ILoggingEvent> {
@@ -109,5 +109,4 @@ class CakeViewImplTest {
return log.size();
}
}
}