├── .gitignore
├── README.md
└── hexagonal-modules-v1
├── .gitignore
├── application
├── pom.xml
└── src
│ └── main
│ └── java
│ └── org
│ └── awesome
│ ├── Main.java
│ ├── dtos
│ ├── category
│ │ ├── CategoryResponse.java
│ │ ├── CreateCategoryRequest.java
│ │ └── UpdateCategoryRequest.java
│ └── product
│ │ ├── CreateProductRequest.java
│ │ └── ProductResponse.java
│ ├── mappers
│ ├── CategoryMapper.java
│ └── ProductMapper.java
│ ├── ports
│ ├── in
│ │ ├── category
│ │ │ ├── CreateCategoryUsesCase.java
│ │ │ └── GetCategoryUsesCase.java
│ │ └── product
│ │ │ ├── CreateProductUseCase.java
│ │ │ └── GetProductUsesCase.java
│ └── out
│ │ └── persistence
│ │ └── ProductRepositoryPort.java
│ └── services
│ ├── category
│ └── CategoryService.java
│ └── product
│ └── ProductService.java
├── domain
├── pom.xml
└── src
│ └── main
│ └── java
│ └── org
│ └── awesome
│ ├── Main.java
│ ├── models
│ ├── Category.java
│ └── Product.java
│ └── valueObjects
│ └── Price.java
├── infrastructure
├── .gitattributes
├── .mvn
│ └── wrapper
│ │ └── maven-wrapper.properties
├── HELP.md
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── org
│ │ │ └── awesome
│ │ │ └── Infrastructure
│ │ │ ├── Adapters
│ │ │ ├── in
│ │ │ │ └── rest
│ │ │ │ │ ├── Exceptions
│ │ │ │ │ └── GlobalExceptionHandler.java
│ │ │ │ │ └── controllers
│ │ │ │ │ ├── CategoryController.java
│ │ │ │ │ └── ProductController.java
│ │ │ └── out
│ │ │ │ └── persistence
│ │ │ │ └── entities
│ │ │ │ └── ProductEntity.java
│ │ │ ├── Configs
│ │ │ ├── ApplicationConfig.java
│ │ │ ├── CategoryConfig.java
│ │ │ └── ProductConfig.java
│ │ │ └── InfrastructureApplication.java
│ └── resources
│ │ └── application.properties
│ └── test
│ └── java
│ └── org
│ └── awesome
│ └── Infrastructure
│ └── InfrastructureApplicationTests.java
├── pom.xml
└── src
└── main
└── java
└── org
└── awesome
└── Main.java
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled class files
2 | *.class
3 |
4 | # Log files
5 | *.log
6 |
7 | # BlueJ files
8 | *.ctxt
9 |
10 | # Mobile Tools for Java (J2ME)
11 | .mtj.tmp/
12 |
13 | # Package Files #
14 | *.jar
15 | *.war
16 | *.ear
17 |
18 | # Maven target folder
19 | /target/
20 |
21 | # Gradle build folder
22 | /build/
23 |
24 | # Eclipse files
25 | .project
26 | .classpath
27 | .settings/
28 | bin/
29 |
30 | # IntelliJ IDEA files
31 | *.iml
32 | *.iws
33 | .idea/
34 | out/
35 |
36 | # VS Code files
37 | .vscode/
38 |
39 | # Mac system files
40 | .DS_Store
41 |
42 | # Windows system files
43 | Thumbs.db
44 | ehthumbs.db
45 |
46 | # Spring Boot specific
47 | spring.log
48 | spring-boot-*.jar
49 |
50 | # Dependency directories
51 | /node_modules/
52 | bower_components/
53 |
54 | # Generated files
55 | /generated/
56 |
57 | # Others
58 | *.swp
59 | *~
60 |
61 | # Environment files
62 | .env
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Ejemplo de Arquitectura Hexagonal en Java con Spring Boot
2 |
3 | Este proyecto es un ejemplo práctico y sencillo para entender y aplicar la **Arquitectura Hexagonal (Ports and Adapters)** usando Java y Spring Boot. Está pensado para desarrolladores que comienzan a trabajar con arquitectura limpia, DDD y patrones modernos en el ecosistema Java.
4 |
5 | ---
6 |
7 | ## 🚀 ¿Qué encontrarás en este proyecto?
8 |
9 | - **Estructura modular y limpia** siguiendo la arquitectura hexagonal, separando claramente las capas de dominio, aplicación e infraestructura.
10 | - **Modelo de dominio** con entidades y lógica de negocio (Product y Category).
11 | - **Implementaciones de adaptadores** para persistencia en memoria y base de datos MySQL con Spring Data JPA.
12 | - **Validación de entradas** con anotaciones estándar de Bean Validation (Jakarta Validation).
13 | - **Mapeo de objetos** con MapStruct para transformar entre entidades, modelos y DTOs.
14 | - Aplicación de **principios SOLID** y buenas prácticas para mantener el código desacoplado y testable.
15 | - Uso de **DTOs específicos para request y response**, modularizando los contratos de entrada y salida.
16 | - Configuración del proyecto con **Maven**.
17 |
18 | ## 📚 Descripción de las capas
19 |
20 | - **Dominio:** Aquí están las entidades y interfaces que representan las reglas y lógica de negocio pura. Esta capa no depende de ningún framework.
21 | - **Aplicación:** Contiene casos de uso, servicios, DTOs de entrada y salida, validaciones y mapeos entre modelos y DTOs.
22 | - **Infraestructura:** Configuraciones, adapters y implementaciones concretas de puertos (por ejemplo, repositorios de datos). Aquí se manejan detalles como JPA, conexiones a BD, o almacenamiento en memoria clases relacionadas con Spring Boot, seguridad, configuración de beans, etc.
23 |
24 | ---
25 |
26 | ## ✔️ Buenas prácticas y tecnologías aplicadas
27 |
28 | - **Separación clara de responsabilidades** para facilitar el mantenimiento y escalabilidad.
29 | - Uso de **DTOs específicos** para cada operación (crear, actualizar, listar).
30 | - Validación declarativa con **Bean Validation (Jakarta Validation)**.
31 | - Mapeo automático y limpio con **MapStruct**.
32 | - Aplicación de **principios SOLID** para un diseño flexible.
33 | - Arquitectura modular para facilitar **pruebas unitarias y de integración**.
34 |
35 | ---
36 |
37 |
38 | ### Requisitos
39 |
40 | - Java 17 o superior
41 | - Maven 3.6+
42 | - MySQL (si usas la persistencia con base de datos)
43 | - IDE como IntelliJ IDEA, Eclipse o VSCode
44 |
45 | ### Pasos para clonar
46 |
47 | ```bash
48 | git clone https://github.com/Ivanproyectos/template-hexagonal-java-spring.git
49 |
50 | cd hexagonal-modules-v1
51 |
52 | # Para compilar el proyecto
53 | mvn clean install
54 |
55 | ```
56 |
57 | # Para ejecutar la aplicación Spring Boot
58 |
59 | Configuración para ejecutar la aplicación
60 | Antes de ejecutar, configura la Run/Debug Configuration en IntelliJ:
61 |
62 | Name: InfrastructureApplication
63 |
64 | JDK: Java 21
65 |
66 | Classpath (-cp): selecciona el módulo Infrastructure
67 |
68 | Main class: org.awesome.Infrastructure.InfrastructureApplication
69 |
70 | Working directory: apunta al directorio del módulo hexagonal-module
71 |
72 | (Opcional) Añade variables de entorno si es necesario.
73 |
74 | Guarda y ejecuta la configuración para iniciar la aplicación.
75 |
76 | 
77 |
--------------------------------------------------------------------------------
/hexagonal-modules-v1/.gitignore:
--------------------------------------------------------------------------------
1 | target/
2 | !.mvn/wrapper/maven-wrapper.jar
3 | !**/src/main/**/target/
4 | !**/src/test/**/target/
5 |
6 | ### IntelliJ IDEA ###
7 | .idea/modules.xml
8 | .idea/jarRepositories.xml
9 | .idea/compiler.xml
10 | .idea/libraries/
11 | *.iws
12 | *.iml
13 | *.ipr
14 |
15 | ### Eclipse ###
16 | .apt_generated
17 | .classpath
18 | .factorypath
19 | .project
20 | .settings
21 | .springBeans
22 | .sts4-cache
23 |
24 | ### NetBeans ###
25 | /nbproject/private/
26 | /nbbuild/
27 | /dist/
28 | /nbdist/
29 | /.nb-gradle/
30 | build/
31 | !**/src/main/**/build/
32 | !**/src/test/**/build/
33 |
34 | ### VS Code ###
35 | .vscode/
36 |
37 | ### Mac OS ###
38 | .DS_Store
--------------------------------------------------------------------------------
/hexagonal-modules-v1/application/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | org.awesome
8 | hexagonal-modules-v1
9 | 1.0-SNAPSHOT
10 |
11 |
12 | Application
13 |
14 |
15 | 21
16 | 21
17 | UTF-8
18 |
19 |
20 |
21 |
22 | org.awesome
23 | Domain
24 | 1.0-SNAPSHOT
25 | compile
26 |
27 |
28 |
29 | org.mapstruct
30 | mapstruct
31 | 1.5.5.Final
32 |
33 |
34 |
35 | jakarta.validation
36 | jakarta.validation-api
37 | 3.0.2
38 |
39 |
40 | jakarta.validation
41 | jakarta.validation-api
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | org.apache.maven.plugins
50 | maven-compiler-plugin
51 |
52 |
53 |
54 | org.projectlombok
55 | lombok
56 |
57 |
58 | org.mapstruct
59 | mapstruct-processor
60 | 1.5.2.Final
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/hexagonal-modules-v1/application/src/main/java/org/awesome/Main.java:
--------------------------------------------------------------------------------
1 | package org.awesome;
2 |
3 | public class Main {
4 | public static void main(String[] args) {
5 | System.out.println("Hello, World!");
6 | }
7 | }
--------------------------------------------------------------------------------
/hexagonal-modules-v1/application/src/main/java/org/awesome/dtos/category/CategoryResponse.java:
--------------------------------------------------------------------------------
1 | package org.awesome.dtos.category;
2 |
3 | import java.util.UUID;
4 |
5 | public record CategoryResponse(
6 | UUID id,
7 | String name,
8 | String imageUrl,
9 | Boolean isActive
10 | ) {
11 | }
12 |
--------------------------------------------------------------------------------
/hexagonal-modules-v1/application/src/main/java/org/awesome/dtos/category/CreateCategoryRequest.java:
--------------------------------------------------------------------------------
1 | package org.awesome.dtos.category;
2 |
3 | public record CreateCategoryRequest(
4 | String name,
5 | String description,
6 | String imageUrl,
7 | boolean isActive
8 | ) {
9 | }
10 |
--------------------------------------------------------------------------------
/hexagonal-modules-v1/application/src/main/java/org/awesome/dtos/category/UpdateCategoryRequest.java:
--------------------------------------------------------------------------------
1 | package org.awesome.dtos.category;
2 |
3 | public record UpdateCategoryRequest(
4 | String name,
5 | String description,
6 | String imageUrl,
7 | boolean isActive
8 | ) {
9 | }
10 |
--------------------------------------------------------------------------------
/hexagonal-modules-v1/application/src/main/java/org/awesome/dtos/product/CreateProductRequest.java:
--------------------------------------------------------------------------------
1 | package org.awesome.dtos.product;
2 |
3 | import jakarta.validation.constraints.NotNull;
4 | import jakarta.validation.constraints.Size;
5 |
6 | import java.util.UUID;
7 |
8 | public record CreateProductRequest(
9 | @NotNull
10 | @Size(min = 3, max = 50)
11 | String name,
12 | @NotNull
13 | @Size(min = 3, max = 500)
14 | String description,
15 | @NotNull
16 | Double price,
17 | @NotNull
18 | UUID categoryId
19 | ) {
20 | }
21 |
--------------------------------------------------------------------------------
/hexagonal-modules-v1/application/src/main/java/org/awesome/dtos/product/ProductResponse.java:
--------------------------------------------------------------------------------
1 | package org.awesome.dtos.product;
2 |
3 | import org.awesome.dtos.category.CategoryResponse;
4 | import org.awesome.models.Category;
5 |
6 | import java.util.UUID;
7 |
8 | public record ProductResponse(
9 | UUID id,
10 | String name,
11 | String description,
12 | Double price,
13 | CategoryResponse category
14 |
15 |
16 | ) {
17 | }
18 |
--------------------------------------------------------------------------------
/hexagonal-modules-v1/application/src/main/java/org/awesome/mappers/CategoryMapper.java:
--------------------------------------------------------------------------------
1 | package org.awesome.mappers;
2 |
3 | import org.awesome.dtos.category.CategoryResponse;
4 | import org.awesome.dtos.category.CreateCategoryRequest;
5 | import org.awesome.models.Category;
6 | import org.mapstruct.Mapper;
7 | import org.mapstruct.factory.Mappers;
8 |
9 | import java.util.List;
10 |
11 | @Mapper
12 | public interface CategoryMapper {
13 |
14 | CategoryMapper INSTANCE = Mappers.getMapper(CategoryMapper.class);
15 |
16 | CategoryResponse toDTO(Category category);
17 | List toDTOs(List categories);
18 | Category toDomain(CreateCategoryRequest dto);
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/hexagonal-modules-v1/application/src/main/java/org/awesome/mappers/ProductMapper.java:
--------------------------------------------------------------------------------
1 | package org.awesome.mappers;
2 |
3 | import org.awesome.dtos.product.CreateProductRequest;
4 | import org.awesome.dtos.product.ProductResponse;
5 | import org.awesome.models.Product;
6 | import org.mapstruct.Mapper;
7 | import org.mapstruct.Mapping;
8 | import org.mapstruct.factory.Mappers;
9 |
10 | import java.util.List;
11 |
12 | @Mapper
13 | public interface ProductMapper {
14 | ProductMapper INSTANCE = Mappers.getMapper(ProductMapper.class);
15 |
16 | @Mapping(target = "price", expression = "java(product.getPrice() != null ? product.getPrice().value() : null)")
17 | ProductResponse toDTO(Product product);
18 |
19 | List toDTOs(List products);
20 |
21 | @Mapping(target = "price", expression = "java(dto.price() != null ? new Price(dto.price()) : null)")
22 | Product toDomain(CreateProductRequest dto);
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/hexagonal-modules-v1/application/src/main/java/org/awesome/ports/in/category/CreateCategoryUsesCase.java:
--------------------------------------------------------------------------------
1 | package org.awesome.ports.in.category;
2 |
3 | import org.awesome.dtos.category.CategoryResponse;
4 | import org.awesome.dtos.category.CreateCategoryRequest;
5 |
6 | public interface CreateCategoryUsesCase {
7 | public CategoryResponse createCategory(CreateCategoryRequest category);
8 | }
9 |
--------------------------------------------------------------------------------
/hexagonal-modules-v1/application/src/main/java/org/awesome/ports/in/category/GetCategoryUsesCase.java:
--------------------------------------------------------------------------------
1 | package org.awesome.ports.in.category;
2 |
3 | import org.awesome.dtos.category.CategoryResponse;
4 |
5 | import java.util.List;
6 | import java.util.UUID;
7 |
8 | public interface GetCategoryUsesCase {
9 | public CategoryResponse getCategoryById(UUID id);
10 |
11 | public List getCategories();
12 | }
13 |
--------------------------------------------------------------------------------
/hexagonal-modules-v1/application/src/main/java/org/awesome/ports/in/product/CreateProductUseCase.java:
--------------------------------------------------------------------------------
1 | package org.awesome.ports.in.product;
2 |
3 | import org.awesome.dtos.product.CreateProductRequest;
4 | import org.awesome.dtos.product.ProductResponse;
5 | import org.awesome.models.Product;
6 |
7 | public interface CreateProductUseCase {
8 | public ProductResponse createProduct (CreateProductRequest product);
9 | }
10 |
--------------------------------------------------------------------------------
/hexagonal-modules-v1/application/src/main/java/org/awesome/ports/in/product/GetProductUsesCase.java:
--------------------------------------------------------------------------------
1 | package org.awesome.ports.in.product;
2 |
3 | import org.awesome.dtos.product.ProductResponse;
4 | import org.awesome.models.Product;
5 |
6 | import java.util.List;
7 |
8 | public interface GetProductUsesCase {
9 | List getProduct();
10 | }
11 |
--------------------------------------------------------------------------------
/hexagonal-modules-v1/application/src/main/java/org/awesome/ports/out/persistence/ProductRepositoryPort.java:
--------------------------------------------------------------------------------
1 | package org.awesome.ports.out.persistence;
2 |
3 | import org.awesome.models.Product;
4 |
5 | import java.util.List;
6 |
7 | public interface ProductRepositoryPort {
8 | List findAll();
9 | public Product save(Product product);
10 | }
11 |
--------------------------------------------------------------------------------
/hexagonal-modules-v1/application/src/main/java/org/awesome/services/category/CategoryService.java:
--------------------------------------------------------------------------------
1 | package org.awesome.services.category;
2 |
3 | import org.awesome.dtos.category.CategoryResponse;
4 | import org.awesome.dtos.category.CreateCategoryRequest;
5 | import org.awesome.mappers.CategoryMapper;
6 | import org.awesome.ports.in.category.CreateCategoryUsesCase;
7 | import org.awesome.ports.in.category.GetCategoryUsesCase;
8 | import org.awesome.ports.out.persistence.CategoryRepositoryPort;
9 | import org.awesome.models.Category;
10 |
11 | import java.util.List;
12 | import java.util.UUID;
13 |
14 | public class CategoryService implements CreateCategoryUsesCase, GetCategoryUsesCase {
15 |
16 | private final CategoryMapper categoryMapper = CategoryMapper.INSTANCE;
17 | private final CategoryRepositoryPort categoryRepositoryPort;
18 |
19 | public CategoryService(CategoryRepositoryPort categoryRepositoryPort) {
20 | this.categoryRepositoryPort = categoryRepositoryPort;
21 | }
22 |
23 | @Override
24 | public CategoryResponse createCategory(CreateCategoryRequest createCategory) {
25 | var category = categoryMapper.toDomain(createCategory);
26 | category.setId(UUID.randomUUID());
27 |
28 | var categoryCreated = categoryRepositoryPort.save(category);
29 |
30 | return categoryMapper.toDTO(categoryCreated);
31 | }
32 | @Override
33 | public CategoryResponse getCategoryById(UUID id) {
34 | var category = categoryRepositoryPort.findById(id);
35 | if (category == null) {
36 | return null;
37 | }
38 | return categoryMapper.toDTO(category);
39 | }
40 |
41 | @Override
42 | public List getCategories() {
43 | var categories = categoryRepositoryPort.findAll();
44 | return categoryMapper.toDTOs(categories);
45 |
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/hexagonal-modules-v1/application/src/main/java/org/awesome/services/product/ProductService.java:
--------------------------------------------------------------------------------
1 | package org.awesome.services.product;
2 |
3 | import org.awesome.dtos.product.CreateProductRequest;
4 | import org.awesome.dtos.product.ProductResponse;
5 | import org.awesome.mappers.ProductMapper;
6 | import org.awesome.models.Category;
7 | import org.awesome.models.Product;
8 | import org.awesome.ports.in.product.CreateProductUseCase;
9 | import org.awesome.ports.in.product.GetProductUsesCase;
10 | import org.awesome.ports.out.persistence.ProductRepositoryPort;
11 | import org.awesome.valueObjects.Price;
12 |
13 | import java.util.List;
14 | import java.util.UUID;
15 |
16 | public class ProductService implements GetProductUsesCase, CreateProductUseCase {
17 | private final ProductMapper productMapper = ProductMapper.INSTANCE;
18 | private final ProductRepositoryPort productRepositoryPort;
19 |
20 | public ProductService(ProductRepositoryPort productRepositoryPort) {
21 | this.productRepositoryPort = productRepositoryPort;
22 | }
23 | @Override
24 | public ProductResponse createProduct(CreateProductRequest createProductRequest) {
25 | var category = new Category(createProductRequest.categoryId(), null, null, null);
26 | var product = new Product(
27 | UUID.randomUUID(),
28 | createProductRequest.name(),
29 | createProductRequest.description(),
30 | new Price(createProductRequest.price()),
31 | category);
32 |
33 | var savedProduct = productRepositoryPort.save(product);
34 | return productMapper.toDTO(savedProduct);
35 | }
36 |
37 | @Override
38 | public List getProduct() {
39 | var products = productRepositoryPort.findAll();
40 | return productMapper.toDTOs(products);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/hexagonal-modules-v1/domain/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | org.awesome
8 | hexagonal-modules-v1
9 | 1.0-SNAPSHOT
10 |
11 |
12 | Domain
13 |
14 |
15 | 21
16 | 21
17 | UTF-8
18 |
19 |
20 |
21 |
22 | org.projectlombok
23 | lombok
24 | true
25 |
26 |
27 |
28 |
29 |
30 | org.apache.maven.plugins
31 | maven-compiler-plugin
32 |
33 |
34 |
35 | org.projectlombok
36 | lombok
37 |
38 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/hexagonal-modules-v1/domain/src/main/java/org/awesome/Main.java:
--------------------------------------------------------------------------------
1 | package org.awesome;
2 |
3 | public class Main {
4 | public static void main(String[] args) {
5 | System.out.println("Hello, World!");
6 | }
7 | }
--------------------------------------------------------------------------------
/hexagonal-modules-v1/domain/src/main/java/org/awesome/models/Category.java:
--------------------------------------------------------------------------------
1 | package org.awesome.models;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Data;
5 |
6 | import java.util.UUID;
7 |
8 | @Data
9 | public class Category {
10 | private UUID id;
11 | private String name;
12 | private String imageUrl;
13 | private Boolean isActive;
14 |
15 | public Category(UUID id,
16 | String name,
17 | String imageUrl,
18 | Boolean isActive) {
19 | this.id = id;
20 | this.name = name;
21 | this.imageUrl = imageUrl;
22 | this.isActive = isActive;
23 | }
24 |
25 | public static Category createCategory(String name, String description, String imageUrl, Boolean isActive) {
26 | return new Category(UUID.randomUUID(), name, imageUrl, isActive);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/hexagonal-modules-v1/domain/src/main/java/org/awesome/models/Product.java:
--------------------------------------------------------------------------------
1 | package org.awesome.models;
2 |
3 | import lombok.Data;
4 | import org.awesome.valueObjects.Price;
5 |
6 | import java.util.UUID;
7 |
8 | @Data
9 | public class Product {
10 | private UUID id;
11 | private String name;
12 | private String description;
13 | private Price price;
14 | private Category category;
15 | public Product(UUID id,
16 | String name,
17 | String description,
18 | Price price,
19 | Category category) {
20 | this.id = id;
21 | this.name = name;
22 | this.description = description;
23 | this.price = price;
24 | this.category = category;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/hexagonal-modules-v1/domain/src/main/java/org/awesome/valueObjects/Price.java:
--------------------------------------------------------------------------------
1 | package org.awesome.valueObjects;
2 |
3 | public record Price(double value) {
4 | public Price {
5 | if (value < 0) {
6 | throw new IllegalArgumentException("Price cannot be negative");
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/hexagonal-modules-v1/infrastructure/.gitattributes:
--------------------------------------------------------------------------------
1 | /mvnw text eol=lf
2 | *.cmd text eol=crlf
3 |
--------------------------------------------------------------------------------
/hexagonal-modules-v1/infrastructure/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one
2 | # or more contributor license agreements. See the NOTICE file
3 | # distributed with this work for additional information
4 | # regarding copyright ownership. The ASF licenses this file
5 | # to you under the Apache License, Version 2.0 (the
6 | # "License"); you may not use this file except in compliance
7 | # with the License. You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing,
12 | # software distributed under the License is distributed on an
13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | # KIND, either express or implied. See the License for the
15 | # specific language governing permissions and limitations
16 | # under the License.
17 | wrapperVersion=3.3.2
18 | distributionType=only-script
19 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip
20 |
--------------------------------------------------------------------------------
/hexagonal-modules-v1/infrastructure/HELP.md:
--------------------------------------------------------------------------------
1 | # Getting Started
2 |
3 | ### Reference Documentation
4 | For further reference, please consider the following sections:
5 |
6 | * [Official Apache Maven documentation](https://maven.apache.org/guides/index.html)
7 | * [Spring Boot Maven Plugin Reference Guide](https://docs.spring.io/spring-boot/3.4.5/maven-plugin)
8 | * [Create an OCI image](https://docs.spring.io/spring-boot/3.4.5/maven-plugin/build-image.html)
9 | * [Spring Web](https://docs.spring.io/spring-boot/3.4.5/reference/web/servlet.html)
10 | * [Spring Data JPA](https://docs.spring.io/spring-boot/3.4.5/reference/data/sql.html#data.sql.jpa-and-spring-data)
11 |
12 | ### Guides
13 | The following guides illustrate how to use some features concretely:
14 |
15 | * [Building a RESTful Web Service](https://spring.io/guides/gs/rest-service/)
16 | * [Serving Web Content with Spring MVC](https://spring.io/guides/gs/serving-web-content/)
17 | * [Building REST services with Spring](https://spring.io/guides/tutorials/rest/)
18 | * [Accessing Data with JPA](https://spring.io/guides/gs/accessing-data-jpa/)
19 | * [Accessing data with MySQL](https://spring.io/guides/gs/accessing-data-mysql/)
20 |
21 | ### Maven Parent overrides
22 |
23 | Due to Maven's design, elements are inherited from the parent POM to the project POM.
24 | While most of the inheritance is fine, it also inherits unwanted elements like `` and `` from the parent.
25 | To prevent this, the project POM contains empty overrides for these elements.
26 | If you manually switch to a different parent and actually want the inheritance, you need to remove those overrides.
27 |
28 |
--------------------------------------------------------------------------------
/hexagonal-modules-v1/infrastructure/mvnw:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # ----------------------------------------------------------------------------
3 | # Licensed to the Apache Software Foundation (ASF) under one
4 | # or more contributor license agreements. See the NOTICE file
5 | # distributed with this work for additional information
6 | # regarding copyright ownership. The ASF licenses this file
7 | # to you under the Apache License, Version 2.0 (the
8 | # "License"); you may not use this file except in compliance
9 | # with the License. You may obtain a copy of the License at
10 | #
11 | # http://www.apache.org/licenses/LICENSE-2.0
12 | #
13 | # Unless required by applicable law or agreed to in writing,
14 | # software distributed under the License is distributed on an
15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 | # KIND, either express or implied. See the License for the
17 | # specific language governing permissions and limitations
18 | # under the License.
19 | # ----------------------------------------------------------------------------
20 |
21 | # ----------------------------------------------------------------------------
22 | # Apache Maven Wrapper startup batch script, version 3.3.2
23 | #
24 | # Optional ENV vars
25 | # -----------------
26 | # JAVA_HOME - location of a JDK home dir, required when download maven via java source
27 | # MVNW_REPOURL - repo url base for downloading maven distribution
28 | # MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven
29 | # MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output
30 | # ----------------------------------------------------------------------------
31 |
32 | set -euf
33 | [ "${MVNW_VERBOSE-}" != debug ] || set -x
34 |
35 | # OS specific support.
36 | native_path() { printf %s\\n "$1"; }
37 | case "$(uname)" in
38 | CYGWIN* | MINGW*)
39 | [ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")"
40 | native_path() { cygpath --path --windows "$1"; }
41 | ;;
42 | esac
43 |
44 | # set JAVACMD and JAVACCMD
45 | set_java_home() {
46 | # For Cygwin and MinGW, ensure paths are in Unix format before anything is touched
47 | if [ -n "${JAVA_HOME-}" ]; then
48 | if [ -x "$JAVA_HOME/jre/sh/java" ]; then
49 | # IBM's JDK on AIX uses strange locations for the executables
50 | JAVACMD="$JAVA_HOME/jre/sh/java"
51 | JAVACCMD="$JAVA_HOME/jre/sh/javac"
52 | else
53 | JAVACMD="$JAVA_HOME/bin/java"
54 | JAVACCMD="$JAVA_HOME/bin/javac"
55 |
56 | if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then
57 | echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2
58 | echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2
59 | return 1
60 | fi
61 | fi
62 | else
63 | JAVACMD="$(
64 | 'set' +e
65 | 'unset' -f command 2>/dev/null
66 | 'command' -v java
67 | )" || :
68 | JAVACCMD="$(
69 | 'set' +e
70 | 'unset' -f command 2>/dev/null
71 | 'command' -v javac
72 | )" || :
73 |
74 | if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then
75 | echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2
76 | return 1
77 | fi
78 | fi
79 | }
80 |
81 | # hash string like Java String::hashCode
82 | hash_string() {
83 | str="${1:-}" h=0
84 | while [ -n "$str" ]; do
85 | char="${str%"${str#?}"}"
86 | h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296))
87 | str="${str#?}"
88 | done
89 | printf %x\\n $h
90 | }
91 |
92 | verbose() { :; }
93 | [ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; }
94 |
95 | die() {
96 | printf %s\\n "$1" >&2
97 | exit 1
98 | }
99 |
100 | trim() {
101 | # MWRAPPER-139:
102 | # Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds.
103 | # Needed for removing poorly interpreted newline sequences when running in more
104 | # exotic environments such as mingw bash on Windows.
105 | printf "%s" "${1}" | tr -d '[:space:]'
106 | }
107 |
108 | # parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties
109 | while IFS="=" read -r key value; do
110 | case "${key-}" in
111 | distributionUrl) distributionUrl=$(trim "${value-}") ;;
112 | distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;;
113 | esac
114 | done <"${0%/*}/.mvn/wrapper/maven-wrapper.properties"
115 | [ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in ${0%/*}/.mvn/wrapper/maven-wrapper.properties"
116 |
117 | case "${distributionUrl##*/}" in
118 | maven-mvnd-*bin.*)
119 | MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/
120 | case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in
121 | *AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;;
122 | :Darwin*x86_64) distributionPlatform=darwin-amd64 ;;
123 | :Darwin*arm64) distributionPlatform=darwin-aarch64 ;;
124 | :Linux*x86_64*) distributionPlatform=linux-amd64 ;;
125 | *)
126 | echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2
127 | distributionPlatform=linux-amd64
128 | ;;
129 | esac
130 | distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip"
131 | ;;
132 | maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;;
133 | *) MVN_CMD="mvn${0##*/mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;;
134 | esac
135 |
136 | # apply MVNW_REPOURL and calculate MAVEN_HOME
137 | # maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/
138 | [ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}"
139 | distributionUrlName="${distributionUrl##*/}"
140 | distributionUrlNameMain="${distributionUrlName%.*}"
141 | distributionUrlNameMain="${distributionUrlNameMain%-bin}"
142 | MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}"
143 | MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")"
144 |
145 | exec_maven() {
146 | unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || :
147 | exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD"
148 | }
149 |
150 | if [ -d "$MAVEN_HOME" ]; then
151 | verbose "found existing MAVEN_HOME at $MAVEN_HOME"
152 | exec_maven "$@"
153 | fi
154 |
155 | case "${distributionUrl-}" in
156 | *?-bin.zip | *?maven-mvnd-?*-?*.zip) ;;
157 | *) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;;
158 | esac
159 |
160 | # prepare tmp dir
161 | if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then
162 | clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; }
163 | trap clean HUP INT TERM EXIT
164 | else
165 | die "cannot create temp dir"
166 | fi
167 |
168 | mkdir -p -- "${MAVEN_HOME%/*}"
169 |
170 | # Download and Install Apache Maven
171 | verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
172 | verbose "Downloading from: $distributionUrl"
173 | verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
174 |
175 | # select .zip or .tar.gz
176 | if ! command -v unzip >/dev/null; then
177 | distributionUrl="${distributionUrl%.zip}.tar.gz"
178 | distributionUrlName="${distributionUrl##*/}"
179 | fi
180 |
181 | # verbose opt
182 | __MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR=''
183 | [ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v
184 |
185 | # normalize http auth
186 | case "${MVNW_PASSWORD:+has-password}" in
187 | '') MVNW_USERNAME='' MVNW_PASSWORD='' ;;
188 | has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;;
189 | esac
190 |
191 | if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then
192 | verbose "Found wget ... using wget"
193 | wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl"
194 | elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then
195 | verbose "Found curl ... using curl"
196 | curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl"
197 | elif set_java_home; then
198 | verbose "Falling back to use Java to download"
199 | javaSource="$TMP_DOWNLOAD_DIR/Downloader.java"
200 | targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName"
201 | cat >"$javaSource" <<-END
202 | public class Downloader extends java.net.Authenticator
203 | {
204 | protected java.net.PasswordAuthentication getPasswordAuthentication()
205 | {
206 | return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() );
207 | }
208 | public static void main( String[] args ) throws Exception
209 | {
210 | setDefault( new Downloader() );
211 | java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() );
212 | }
213 | }
214 | END
215 | # For Cygwin/MinGW, switch paths to Windows format before running javac and java
216 | verbose " - Compiling Downloader.java ..."
217 | "$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java"
218 | verbose " - Running Downloader.java ..."
219 | "$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")"
220 | fi
221 |
222 | # If specified, validate the SHA-256 sum of the Maven distribution zip file
223 | if [ -n "${distributionSha256Sum-}" ]; then
224 | distributionSha256Result=false
225 | if [ "$MVN_CMD" = mvnd.sh ]; then
226 | echo "Checksum validation is not supported for maven-mvnd." >&2
227 | echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2
228 | exit 1
229 | elif command -v sha256sum >/dev/null; then
230 | if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c >/dev/null 2>&1; then
231 | distributionSha256Result=true
232 | fi
233 | elif command -v shasum >/dev/null; then
234 | if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then
235 | distributionSha256Result=true
236 | fi
237 | else
238 | echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2
239 | echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2
240 | exit 1
241 | fi
242 | if [ $distributionSha256Result = false ]; then
243 | echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2
244 | echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2
245 | exit 1
246 | fi
247 | fi
248 |
249 | # unzip and move
250 | if command -v unzip >/dev/null; then
251 | unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip"
252 | else
253 | tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar"
254 | fi
255 | printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/mvnw.url"
256 | mv -- "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME"
257 |
258 | clean || :
259 | exec_maven "$@"
260 |
--------------------------------------------------------------------------------
/hexagonal-modules-v1/infrastructure/mvnw.cmd:
--------------------------------------------------------------------------------
1 | <# : batch portion
2 | @REM ----------------------------------------------------------------------------
3 | @REM Licensed to the Apache Software Foundation (ASF) under one
4 | @REM or more contributor license agreements. See the NOTICE file
5 | @REM distributed with this work for additional information
6 | @REM regarding copyright ownership. The ASF licenses this file
7 | @REM to you under the Apache License, Version 2.0 (the
8 | @REM "License"); you may not use this file except in compliance
9 | @REM with the License. You may obtain a copy of the License at
10 | @REM
11 | @REM http://www.apache.org/licenses/LICENSE-2.0
12 | @REM
13 | @REM Unless required by applicable law or agreed to in writing,
14 | @REM software distributed under the License is distributed on an
15 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 | @REM KIND, either express or implied. See the License for the
17 | @REM specific language governing permissions and limitations
18 | @REM under the License.
19 | @REM ----------------------------------------------------------------------------
20 |
21 | @REM ----------------------------------------------------------------------------
22 | @REM Apache Maven Wrapper startup batch script, version 3.3.2
23 | @REM
24 | @REM Optional ENV vars
25 | @REM MVNW_REPOURL - repo url base for downloading maven distribution
26 | @REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven
27 | @REM MVNW_VERBOSE - true: enable verbose log; others: silence the output
28 | @REM ----------------------------------------------------------------------------
29 |
30 | @IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0)
31 | @SET __MVNW_CMD__=
32 | @SET __MVNW_ERROR__=
33 | @SET __MVNW_PSMODULEP_SAVE=%PSModulePath%
34 | @SET PSModulePath=
35 | @FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @(
36 | IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B)
37 | )
38 | @SET PSModulePath=%__MVNW_PSMODULEP_SAVE%
39 | @SET __MVNW_PSMODULEP_SAVE=
40 | @SET __MVNW_ARG0_NAME__=
41 | @SET MVNW_USERNAME=
42 | @SET MVNW_PASSWORD=
43 | @IF NOT "%__MVNW_CMD__%"=="" (%__MVNW_CMD__% %*)
44 | @echo Cannot start maven from wrapper >&2 && exit /b 1
45 | @GOTO :EOF
46 | : end batch / begin powershell #>
47 |
48 | $ErrorActionPreference = "Stop"
49 | if ($env:MVNW_VERBOSE -eq "true") {
50 | $VerbosePreference = "Continue"
51 | }
52 |
53 | # calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties
54 | $distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl
55 | if (!$distributionUrl) {
56 | Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties"
57 | }
58 |
59 | switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) {
60 | "maven-mvnd-*" {
61 | $USE_MVND = $true
62 | $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip"
63 | $MVN_CMD = "mvnd.cmd"
64 | break
65 | }
66 | default {
67 | $USE_MVND = $false
68 | $MVN_CMD = $script -replace '^mvnw','mvn'
69 | break
70 | }
71 | }
72 |
73 | # apply MVNW_REPOURL and calculate MAVEN_HOME
74 | # maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/
75 | if ($env:MVNW_REPOURL) {
76 | $MVNW_REPO_PATTERN = if ($USE_MVND) { "/org/apache/maven/" } else { "/maven/mvnd/" }
77 | $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace '^.*'+$MVNW_REPO_PATTERN,'')"
78 | }
79 | $distributionUrlName = $distributionUrl -replace '^.*/',''
80 | $distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$',''
81 | $MAVEN_HOME_PARENT = "$HOME/.m2/wrapper/dists/$distributionUrlNameMain"
82 | if ($env:MAVEN_USER_HOME) {
83 | $MAVEN_HOME_PARENT = "$env:MAVEN_USER_HOME/wrapper/dists/$distributionUrlNameMain"
84 | }
85 | $MAVEN_HOME_NAME = ([System.Security.Cryptography.MD5]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join ''
86 | $MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME"
87 |
88 | if (Test-Path -Path "$MAVEN_HOME" -PathType Container) {
89 | Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME"
90 | Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"
91 | exit $?
92 | }
93 |
94 | if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) {
95 | Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl"
96 | }
97 |
98 | # prepare tmp dir
99 | $TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile
100 | $TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir"
101 | $TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null
102 | trap {
103 | if ($TMP_DOWNLOAD_DIR.Exists) {
104 | try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
105 | catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
106 | }
107 | }
108 |
109 | New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null
110 |
111 | # Download and Install Apache Maven
112 | Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
113 | Write-Verbose "Downloading from: $distributionUrl"
114 | Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
115 |
116 | $webclient = New-Object System.Net.WebClient
117 | if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) {
118 | $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD)
119 | }
120 | [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
121 | $webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null
122 |
123 | # If specified, validate the SHA-256 sum of the Maven distribution zip file
124 | $distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum
125 | if ($distributionSha256Sum) {
126 | if ($USE_MVND) {
127 | Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties."
128 | }
129 | Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash
130 | if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) {
131 | Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property."
132 | }
133 | }
134 |
135 | # unzip and move
136 | Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null
137 | Rename-Item -Path "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" -NewName $MAVEN_HOME_NAME | Out-Null
138 | try {
139 | Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null
140 | } catch {
141 | if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) {
142 | Write-Error "fail to move MAVEN_HOME"
143 | }
144 | } finally {
145 | try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
146 | catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
147 | }
148 |
149 | Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"
150 |
--------------------------------------------------------------------------------
/hexagonal-modules-v1/infrastructure/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 |
7 | org.awesome
8 | hexagonal-modules-v1
9 | 1.0-SNAPSHOT
10 |
11 |
12 | Infrastructure
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 | 21
29 |
30 |
31 |
35 |
36 | org.springframework.boot
37 | spring-boot-starter-web
38 |
39 |
40 |
45 |
46 | org.springdoc
47 | springdoc-openapi-starter-webmvc-ui
48 | 2.8.6
49 |
50 |
51 | org.projectlombok
52 | lombok
53 | true
54 |
55 |
56 | org.springframework.boot
57 | spring-boot-starter-test
58 | test
59 |
60 |
61 | org.awesome
62 | Application
63 | 1.0-SNAPSHOT
64 | compile
65 |
66 |
67 | org.awesome
68 | Domain
69 | 1.0-SNAPSHOT
70 | compile
71 |
72 |
73 |
74 |
75 |
76 |
77 | org.apache.maven.plugins
78 | maven-compiler-plugin
79 |
80 |
81 |
82 | org.projectlombok
83 | lombok
84 |
85 |
86 |
87 |
88 |
89 | org.springframework.boot
90 | spring-boot-maven-plugin
91 |
92 |
93 |
94 | org.projectlombok
95 | lombok
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
--------------------------------------------------------------------------------
/hexagonal-modules-v1/infrastructure/src/main/java/org/awesome/Infrastructure/Adapters/in/rest/Exceptions/GlobalExceptionHandler.java:
--------------------------------------------------------------------------------
1 | package org.awesome.Infrastructure.Adapters.in.rest.Exceptions;
2 |
3 | import org.springframework.http.HttpStatus;
4 | import org.springframework.http.ResponseEntity;
5 | import org.springframework.web.bind.MethodArgumentNotValidException;
6 | import org.springframework.web.bind.annotation.ExceptionHandler;
7 | import org.springframework.web.bind.annotation.RestControllerAdvice;
8 |
9 | import java.util.HashMap;
10 | import java.util.Map;
11 |
12 | @RestControllerAdvice
13 | public class GlobalExceptionHandler {
14 | //Captura errores de validación con @Valid
15 | @ExceptionHandler(MethodArgumentNotValidException.class)
16 | public ResponseEntity