├── .gitignore ├── .project ├── README.md ├── pom.xml ├── spring-ddd-application ├── .classpath ├── .project ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── rogelioorts │ └── training │ └── spring │ └── ddd │ ├── exceptions │ └── BadRequestException.java │ └── services │ └── MoviesService.java ├── spring-ddd-boot ├── .classpath ├── .project ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── rogelioorts │ │ └── training │ │ └── spring │ │ └── ddd │ │ └── MainApplication.java │ └── resources │ ├── META-INF │ └── additional-spring-configuration-metadata.json │ └── application.yml ├── spring-ddd-domain ├── .classpath ├── .project ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── rogelioorts │ └── training │ └── spring │ └── ddd │ ├── entities │ └── Movie.java │ ├── factories │ └── FiltersFactory.java │ ├── repositories │ └── MoviesRepository.java │ └── value │ └── objects │ ├── CensoringLevel.java │ ├── Filter.java │ └── impl │ ├── CensoringFilter.java │ └── FiltersData.java ├── spring-ddd-infrastructure ├── .classpath ├── .project ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── rogelioorts │ └── training │ └── spring │ └── ddd │ ├── ConfigFeign.java │ ├── entities │ ├── FeignMovie.java │ └── PageFeignMovie.java │ ├── mappers │ └── MoviesFeignMapper.java │ └── repositories │ ├── MoviesFeignRepository.java │ └── impl │ └── MoviesFeignRepositoryImpl.java └── spring-ddd-presentation-rest ├── .classpath ├── .project ├── pom.xml └── src └── main └── java └── com └── rogelioorts └── training └── spring └── ddd ├── config └── CustomExceptionHandler.java ├── controllers └── MoviesController.java ├── entities ├── ErrorResponse.java ├── FiltersDataApi.java └── MovieApi.java └── mappers ├── FiltersApiMapper.java └── MoviesApiMapper.java /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | 3 | # ------ Maven 4 | 5 | target/ 6 | pom.xml.tag 7 | pom.xml.releaseBackup 8 | pom.xml.versionsBackup 9 | pom.xml.next 10 | release.properties 11 | dependency-reduced-pom.xml 12 | buildNumber.properties 13 | .mvn/timing.properties 14 | 15 | # Avoid ignoring Maven wrapper jar file (.jar files are usually ignored) 16 | !/.mvn/wrapper/maven-wrapper.jar 17 | 18 | # ------ Java 19 | 20 | # Compiled class file 21 | *.class 22 | 23 | # Log file 24 | *.log 25 | 26 | # BlueJ files 27 | *.ctxt 28 | 29 | # Mobile Tools for Java (J2ME) 30 | .mtj.tmp/ 31 | 32 | # Package Files # 33 | *.jar 34 | *.war 35 | *.nar 36 | *.ear 37 | *.zip 38 | *.tar.gz 39 | *.rar 40 | 41 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 42 | hs_err_pid* 43 | 44 | # ------ Eclipse 45 | 46 | .metadata 47 | bin/ 48 | tmp/ 49 | *.tmp 50 | *.bak 51 | *.swp 52 | *~.nib 53 | local.properties 54 | .settings/ 55 | .loadpath 56 | .recommenders 57 | 58 | # External tool builders 59 | .externalToolBuilders/ 60 | 61 | # Locally stored "Eclipse launch configurations" 62 | *.launch 63 | 64 | # PyDev specific (Python IDE for Eclipse) 65 | *.pydevproject 66 | 67 | # CDT-specific (C/C++ Development Tooling) 68 | .cproject 69 | 70 | # CDT- autotools 71 | .autotools 72 | 73 | # Java annotation processor (APT) 74 | .factorypath 75 | 76 | # PDT-specific (PHP Development Tools) 77 | .buildpath 78 | 79 | # sbteclipse plugin 80 | .target 81 | 82 | # Tern plugin 83 | .tern-project 84 | 85 | # TeXlipse plugin 86 | .texlipse 87 | 88 | # STS (Spring Tool Suite) 89 | .springBeans 90 | 91 | # Code Recommenders 92 | .recommenders/ 93 | 94 | # Scala IDE specific (Scala & Java development for Eclipse) 95 | .cache-main 96 | .scala_dependencies 97 | .worksheet 98 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | spring-ddd 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.m2e.core.maven2Builder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.m2e.core.maven2Nature 16 | 17 | 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Spring Boot & Layered Architecture 2 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | com.rogelioorts.training 4 | spring-ddd 5 | 0.0.1-SNAPSHOT 6 | pom 7 | 8 | 9 | 1.8 10 | 1.8 11 | 12 | 4.3.18.RELEASE 13 | 1.5.14.RELEASE 14 | 1.4.4.RELEASE 15 | 16 | 1.18.0 17 | 1.2.0.Final 18 | 19 | 20 | 21 | spring-ddd-boot 22 | spring-ddd-presentation-rest 23 | spring-ddd-application 24 | spring-ddd-domain 25 | spring-ddd-infrastructure 26 | 27 | 28 | 29 | 30 | org.projectlombok 31 | lombok 32 | ${lombok.version} 33 | provided 34 | 35 | 36 | 37 | 38 | 39 | 40 | com.rogelioorts.training 41 | spring-ddd-boot 42 | ${project.version} 43 | 44 | 45 | com.rogelioorts.training 46 | spring-ddd-presentation-rest 47 | ${project.version} 48 | 49 | 50 | com.rogelioorts.training 51 | spring-ddd-application 52 | ${project.version} 53 | 54 | 55 | com.rogelioorts.training 56 | spring-ddd-domain 57 | ${project.version} 58 | 59 | 60 | com.rogelioorts.training 61 | spring-ddd-infrastructure 62 | ${project.version} 63 | 64 | 65 | 66 | org.springframework 67 | spring-core 68 | ${spring.version} 69 | 70 | 71 | org.springframework 72 | spring-web 73 | ${spring.version} 74 | 75 | 76 | org.springframework 77 | spring-webmvc 78 | ${spring.version} 79 | 80 | 81 | org.springframework 82 | spring-beans 83 | ${spring.version} 84 | 85 | 86 | org.springframework 87 | spring-context 88 | ${spring.version} 89 | 90 | 91 | org.springframework.boot 92 | spring-boot 93 | ${spring.boot.version} 94 | 95 | 96 | org.springframework.boot 97 | spring-boot-autoconfigure 98 | ${spring.boot.version} 99 | 100 | 101 | org.springframework.boot 102 | spring-boot-starter-undertow 103 | ${spring.boot.version} 104 | 105 | 106 | org.springframework.cloud 107 | spring-cloud-starter-openfeign 108 | ${openfeign.version} 109 | 110 | 111 | 112 | org.mapstruct 113 | mapstruct-jdk8 114 | ${mapstruct.version} 115 | 116 | 117 | 118 | -------------------------------------------------------------------------------- /spring-ddd-application/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /spring-ddd-application/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | spring-ddd-application 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.wst.common.project.facet.core.builder 10 | 11 | 12 | 13 | 14 | org.eclipse.jdt.core.javabuilder 15 | 16 | 17 | 18 | 19 | org.springframework.ide.eclipse.core.springbuilder 20 | 21 | 22 | 23 | 24 | org.springframework.ide.eclipse.boot.validation.springbootbuilder 25 | 26 | 27 | 28 | 29 | org.eclipse.m2e.core.maven2Builder 30 | 31 | 32 | 33 | 34 | 35 | org.springframework.ide.eclipse.core.springnature 36 | org.eclipse.jdt.core.javanature 37 | org.eclipse.m2e.core.maven2Nature 38 | org.eclipse.wst.common.project.facet.core.nature 39 | 40 | 41 | -------------------------------------------------------------------------------- /spring-ddd-application/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | com.rogelioorts.training 5 | spring-ddd 6 | 0.0.1-SNAPSHOT 7 | 8 | spring-ddd-application 9 | 10 | 11 | 12 | com.rogelioorts.training 13 | spring-ddd-domain 14 | 15 | 16 | 17 | org.springframework 18 | spring-context 19 | 20 | 21 | -------------------------------------------------------------------------------- /spring-ddd-application/src/main/java/com/rogelioorts/training/spring/ddd/exceptions/BadRequestException.java: -------------------------------------------------------------------------------- 1 | package com.rogelioorts.training.spring.ddd.exceptions; 2 | 3 | public class BadRequestException extends Exception { 4 | 5 | private static final long serialVersionUID = 1L; 6 | 7 | public BadRequestException(String msg) { 8 | super(msg); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /spring-ddd-application/src/main/java/com/rogelioorts/training/spring/ddd/services/MoviesService.java: -------------------------------------------------------------------------------- 1 | package com.rogelioorts.training.spring.ddd.services; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.stereotype.Service; 8 | 9 | import com.rogelioorts.training.spring.ddd.entities.Movie; 10 | import com.rogelioorts.training.spring.ddd.exceptions.BadRequestException; 11 | import com.rogelioorts.training.spring.ddd.factories.FiltersFactory; 12 | import com.rogelioorts.training.spring.ddd.repositories.MoviesRepository; 13 | import com.rogelioorts.training.spring.ddd.value.objects.Filter; 14 | import com.rogelioorts.training.spring.ddd.value.objects.impl.FiltersData; 15 | 16 | @Service 17 | public class MoviesService { 18 | 19 | @Autowired 20 | private MoviesRepository moviesRepository; 21 | 22 | public List findAll(List filtersIds, FiltersData filterData) throws BadRequestException { 23 | List movies = moviesRepository.findAll(); 24 | 25 | if(filtersIds != null) { 26 | for(Filter filter: getFilters(filtersIds, filterData)) { 27 | movies = filter.apply(movies); 28 | } 29 | } 30 | 31 | return movies; 32 | } 33 | 34 | private List getFilters(List filtersIds, FiltersData filterData) throws BadRequestException { 35 | List result = new ArrayList<>(); 36 | 37 | for(String filterId : filtersIds) { 38 | result.add(getFilter(filterId, filterData)); 39 | } 40 | 41 | return result; 42 | } 43 | 44 | private Filter getFilter(String filterId, FiltersData filterData) throws BadRequestException { 45 | if(Filter.CENSORING.equals(filterId)) { 46 | if(filterData == null || filterData.getCensoringLevel() == null) { 47 | throw new BadRequestException("Censoring level cannot be empty if there is a \"censoring\" filter."); 48 | } 49 | 50 | return FiltersFactory.censoringFilter(filterData.getCensoringLevel()); 51 | } else { 52 | throw new BadRequestException("Not valid filter \"" + filterId + "\""); 53 | } 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /spring-ddd-boot/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /spring-ddd-boot/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | spring-ddd-boot 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.wst.common.project.facet.core.builder 10 | 11 | 12 | 13 | 14 | org.eclipse.jdt.core.javabuilder 15 | 16 | 17 | 18 | 19 | org.springframework.ide.eclipse.boot.validation.springbootbuilder 20 | 21 | 22 | 23 | 24 | org.springframework.ide.eclipse.core.springbuilder 25 | 26 | 27 | 28 | 29 | org.eclipse.m2e.core.maven2Builder 30 | 31 | 32 | 33 | 34 | 35 | org.springframework.ide.eclipse.core.springnature 36 | org.eclipse.jdt.core.javanature 37 | org.eclipse.m2e.core.maven2Nature 38 | org.eclipse.wst.common.project.facet.core.nature 39 | 40 | 41 | -------------------------------------------------------------------------------- /spring-ddd-boot/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | com.rogelioorts.training 5 | spring-ddd 6 | 0.0.1-SNAPSHOT 7 | 8 | spring-ddd-boot 9 | 10 | 11 | 12 | com.rogelioorts.training 13 | spring-ddd-presentation-rest 14 | 15 | 16 | com.rogelioorts.training 17 | spring-ddd-application 18 | 19 | 20 | com.rogelioorts.training 21 | spring-ddd-domain 22 | 23 | 24 | com.rogelioorts.training 25 | spring-ddd-infrastructure 26 | 27 | 28 | 29 | org.springframework 30 | spring-core 31 | 32 | 33 | org.springframework 34 | spring-beans 35 | 36 | 37 | org.springframework 38 | spring-context 39 | 40 | 41 | org.springframework.boot 42 | spring-boot 43 | 44 | 45 | org.springframework.boot 46 | spring-boot-autoconfigure 47 | 48 | 49 | org.springframework.boot 50 | spring-boot-starter-undertow 51 | 52 | 53 | -------------------------------------------------------------------------------- /spring-ddd-boot/src/main/java/com/rogelioorts/training/spring/ddd/MainApplication.java: -------------------------------------------------------------------------------- 1 | package com.rogelioorts.training.spring.ddd; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class MainApplication { 8 | 9 | public static void main(final String[] args) { 10 | SpringApplication.run(MainApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /spring-ddd-boot/src/main/resources/META-INF/additional-spring-configuration-metadata.json: -------------------------------------------------------------------------------- 1 | {"properties": [{ 2 | "name": "movies-server.url", 3 | "type": "java.lang.String", 4 | "description": "The base URL of the server to retrieve the movies." 5 | }]} -------------------------------------------------------------------------------- /spring-ddd-boot/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | movies-server: 2 | url: https://de1e2a9b-a4e8-406f-abf3-747cfff8c873.mock.pstmn.io -------------------------------------------------------------------------------- /spring-ddd-domain/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /spring-ddd-domain/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | spring-ddd-domain 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.m2e.core.maven2Builder 15 | 16 | 17 | 18 | 19 | org.springframework.ide.eclipse.boot.validation.springbootbuilder 20 | 21 | 22 | 23 | 24 | 25 | org.eclipse.jdt.core.javanature 26 | org.eclipse.m2e.core.maven2Nature 27 | 28 | 29 | -------------------------------------------------------------------------------- /spring-ddd-domain/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | com.rogelioorts.training 5 | spring-ddd 6 | 0.0.1-SNAPSHOT 7 | 8 | spring-ddd-domain 9 | -------------------------------------------------------------------------------- /spring-ddd-domain/src/main/java/com/rogelioorts/training/spring/ddd/entities/Movie.java: -------------------------------------------------------------------------------- 1 | package com.rogelioorts.training.spring.ddd.entities; 2 | 3 | import com.rogelioorts.training.spring.ddd.value.objects.CensoringLevel; 4 | 5 | import lombok.EqualsAndHashCode; 6 | import lombok.Getter; 7 | import lombok.Setter; 8 | 9 | @Getter 10 | @Setter 11 | @EqualsAndHashCode(onlyExplicitlyIncluded = true) 12 | public class Movie { 13 | 14 | @EqualsAndHashCode.Include 15 | private String movieId; 16 | 17 | private String title; 18 | 19 | private String image; 20 | 21 | private String description; 22 | 23 | private String streamUrl; 24 | 25 | private double punctuation; 26 | 27 | private CensoringLevel censoringLevel; 28 | 29 | } 30 | -------------------------------------------------------------------------------- /spring-ddd-domain/src/main/java/com/rogelioorts/training/spring/ddd/factories/FiltersFactory.java: -------------------------------------------------------------------------------- 1 | package com.rogelioorts.training.spring.ddd.factories; 2 | 3 | import com.rogelioorts.training.spring.ddd.value.objects.CensoringLevel; 4 | import com.rogelioorts.training.spring.ddd.value.objects.Filter; 5 | import com.rogelioorts.training.spring.ddd.value.objects.impl.CensoringFilter; 6 | 7 | public class FiltersFactory { 8 | 9 | public static Filter censoringFilter(CensoringLevel level) { 10 | return new CensoringFilter(level); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /spring-ddd-domain/src/main/java/com/rogelioorts/training/spring/ddd/repositories/MoviesRepository.java: -------------------------------------------------------------------------------- 1 | package com.rogelioorts.training.spring.ddd.repositories; 2 | 3 | import java.util.List; 4 | 5 | import com.rogelioorts.training.spring.ddd.entities.Movie; 6 | 7 | public interface MoviesRepository { 8 | 9 | List findAll(); 10 | 11 | } 12 | -------------------------------------------------------------------------------- /spring-ddd-domain/src/main/java/com/rogelioorts/training/spring/ddd/value/objects/CensoringLevel.java: -------------------------------------------------------------------------------- 1 | package com.rogelioorts.training.spring.ddd.value.objects; 2 | 3 | public enum CensoringLevel { 4 | CENSORED, UNCENSORED; 5 | } 6 | -------------------------------------------------------------------------------- /spring-ddd-domain/src/main/java/com/rogelioorts/training/spring/ddd/value/objects/Filter.java: -------------------------------------------------------------------------------- 1 | package com.rogelioorts.training.spring.ddd.value.objects; 2 | 3 | import java.util.List; 4 | 5 | import com.rogelioorts.training.spring.ddd.entities.Movie; 6 | 7 | public interface Filter { 8 | 9 | public static final String CENSORING = "censoring"; 10 | 11 | List apply(List movies); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /spring-ddd-domain/src/main/java/com/rogelioorts/training/spring/ddd/value/objects/impl/CensoringFilter.java: -------------------------------------------------------------------------------- 1 | package com.rogelioorts.training.spring.ddd.value.objects.impl; 2 | 3 | import java.util.List; 4 | import java.util.stream.Collectors; 5 | 6 | import com.rogelioorts.training.spring.ddd.entities.Movie; 7 | import com.rogelioorts.training.spring.ddd.value.objects.CensoringLevel; 8 | import com.rogelioorts.training.spring.ddd.value.objects.Filter; 9 | 10 | import lombok.AllArgsConstructor; 11 | import lombok.EqualsAndHashCode; 12 | 13 | @EqualsAndHashCode 14 | @AllArgsConstructor 15 | public class CensoringFilter implements Filter { 16 | 17 | private CensoringLevel level; 18 | 19 | @Override 20 | public List apply(List movies) { 21 | return movies.stream().filter(this::checkMovieFilter).collect(Collectors.toList()); 22 | } 23 | 24 | private boolean checkMovieFilter(Movie movie) { 25 | return level == null || level.equals(movie.getCensoringLevel()); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /spring-ddd-domain/src/main/java/com/rogelioorts/training/spring/ddd/value/objects/impl/FiltersData.java: -------------------------------------------------------------------------------- 1 | package com.rogelioorts.training.spring.ddd.value.objects.impl; 2 | 3 | import com.rogelioorts.training.spring.ddd.value.objects.CensoringLevel; 4 | 5 | import lombok.EqualsAndHashCode; 6 | import lombok.Getter; 7 | import lombok.Setter; 8 | 9 | @EqualsAndHashCode 10 | @Getter 11 | @Setter 12 | public class FiltersData { 13 | 14 | private CensoringLevel censoringLevel; 15 | 16 | } 17 | -------------------------------------------------------------------------------- /spring-ddd-infrastructure/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /spring-ddd-infrastructure/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | spring-ddd-infrastructure 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.wst.common.project.facet.core.builder 10 | 11 | 12 | 13 | 14 | org.eclipse.jdt.core.javabuilder 15 | 16 | 17 | 18 | 19 | org.springframework.ide.eclipse.boot.validation.springbootbuilder 20 | 21 | 22 | 23 | 24 | org.springframework.ide.eclipse.core.springbuilder 25 | 26 | 27 | 28 | 29 | org.eclipse.m2e.core.maven2Builder 30 | 31 | 32 | 33 | 34 | 35 | org.springframework.ide.eclipse.core.springnature 36 | org.eclipse.jdt.core.javanature 37 | org.eclipse.m2e.core.maven2Nature 38 | org.eclipse.wst.common.project.facet.core.nature 39 | 40 | 41 | -------------------------------------------------------------------------------- /spring-ddd-infrastructure/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | com.rogelioorts.training 5 | spring-ddd 6 | 0.0.1-SNAPSHOT 7 | 8 | spring-ddd-infrastructure 9 | 10 | 11 | 12 | com.rogelioorts.training 13 | spring-ddd-domain 14 | 15 | 16 | 17 | org.springframework.cloud 18 | spring-cloud-starter-openfeign 19 | 20 | 21 | -------------------------------------------------------------------------------- /spring-ddd-infrastructure/src/main/java/com/rogelioorts/training/spring/ddd/ConfigFeign.java: -------------------------------------------------------------------------------- 1 | package com.rogelioorts.training.spring.ddd; 2 | 3 | import org.springframework.cloud.netflix.feign.EnableFeignClients; 4 | import org.springframework.context.annotation.Configuration; 5 | 6 | @EnableFeignClients 7 | @Configuration 8 | public class ConfigFeign { 9 | 10 | } 11 | -------------------------------------------------------------------------------- /spring-ddd-infrastructure/src/main/java/com/rogelioorts/training/spring/ddd/entities/FeignMovie.java: -------------------------------------------------------------------------------- 1 | package com.rogelioorts.training.spring.ddd.entities; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | 6 | @Getter 7 | @Setter 8 | public class FeignMovie { 9 | 10 | private long id; 11 | 12 | private String tit; 13 | 14 | private String poster; 15 | 16 | private String desc; 17 | 18 | private String url; 19 | 20 | private double punc; 21 | 22 | private String level; 23 | 24 | } 25 | -------------------------------------------------------------------------------- /spring-ddd-infrastructure/src/main/java/com/rogelioorts/training/spring/ddd/entities/PageFeignMovie.java: -------------------------------------------------------------------------------- 1 | package com.rogelioorts.training.spring.ddd.entities; 2 | 3 | import java.util.List; 4 | 5 | import lombok.Getter; 6 | import lombok.Setter; 7 | 8 | @Getter 9 | @Setter 10 | public class PageFeignMovie { 11 | 12 | private List movies; 13 | 14 | } 15 | -------------------------------------------------------------------------------- /spring-ddd-infrastructure/src/main/java/com/rogelioorts/training/spring/ddd/mappers/MoviesFeignMapper.java: -------------------------------------------------------------------------------- 1 | package com.rogelioorts.training.spring.ddd.mappers; 2 | 3 | import org.springframework.stereotype.Component; 4 | 5 | import com.rogelioorts.training.spring.ddd.entities.FeignMovie; 6 | import com.rogelioorts.training.spring.ddd.entities.Movie; 7 | import com.rogelioorts.training.spring.ddd.value.objects.CensoringLevel; 8 | 9 | @Component 10 | public class MoviesFeignMapper { 11 | 12 | public Movie map(FeignMovie in) { 13 | Movie out = new Movie(); 14 | out.setMovieId(String.valueOf(in.getId())); 15 | out.setTitle(in.getTit()); 16 | out.setImage(in.getPoster()); 17 | out.setDescription(in.getDesc()); 18 | out.setStreamUrl(in.getUrl()); 19 | out.setPunctuation(in.getPunc()); 20 | out.setCensoringLevel(mapCensoringLevel(in.getLevel())); 21 | 22 | return out; 23 | } 24 | 25 | private CensoringLevel mapCensoringLevel(String rawLevel) { 26 | if(rawLevel == null) { 27 | return null; 28 | } 29 | 30 | switch(rawLevel) { 31 | case "censored": 32 | return CensoringLevel.CENSORED; 33 | case "uncensored": 34 | return CensoringLevel.UNCENSORED; 35 | default: 36 | return null; 37 | } 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /spring-ddd-infrastructure/src/main/java/com/rogelioorts/training/spring/ddd/repositories/MoviesFeignRepository.java: -------------------------------------------------------------------------------- 1 | package com.rogelioorts.training.spring.ddd.repositories; 2 | 3 | import org.springframework.cloud.netflix.feign.FeignClient; 4 | import org.springframework.web.bind.annotation.RequestMapping; 5 | import org.springframework.web.bind.annotation.RequestMethod; 6 | 7 | import com.rogelioorts.training.spring.ddd.entities.PageFeignMovie; 8 | 9 | @FeignClient(name = "MoviesFeign", url = "${movies-server.url}") 10 | public interface MoviesFeignRepository { 11 | 12 | @RequestMapping(method = RequestMethod.GET, path = "/movies") 13 | PageFeignMovie getPage(); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /spring-ddd-infrastructure/src/main/java/com/rogelioorts/training/spring/ddd/repositories/impl/MoviesFeignRepositoryImpl.java: -------------------------------------------------------------------------------- 1 | package com.rogelioorts.training.spring.ddd.repositories.impl; 2 | 3 | import java.util.List; 4 | import java.util.stream.Collectors; 5 | 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.stereotype.Repository; 8 | 9 | import com.rogelioorts.training.spring.ddd.entities.Movie; 10 | import com.rogelioorts.training.spring.ddd.mappers.MoviesFeignMapper; 11 | import com.rogelioorts.training.spring.ddd.repositories.MoviesFeignRepository; 12 | import com.rogelioorts.training.spring.ddd.repositories.MoviesRepository; 13 | 14 | @Repository 15 | public class MoviesFeignRepositoryImpl implements MoviesRepository { 16 | 17 | @Autowired 18 | private MoviesFeignRepository repository; 19 | 20 | @Autowired 21 | private MoviesFeignMapper mapper; 22 | 23 | @Override 24 | public List findAll() { 25 | return repository.getPage().getMovies().stream().map(mapper::map).collect(Collectors.toList()); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /spring-ddd-presentation-rest/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /spring-ddd-presentation-rest/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | spring-ddd-presentation-rest 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.wst.common.project.facet.core.builder 10 | 11 | 12 | 13 | 14 | org.eclipse.jdt.core.javabuilder 15 | 16 | 17 | 18 | 19 | org.springframework.ide.eclipse.core.springbuilder 20 | 21 | 22 | 23 | 24 | org.springframework.ide.eclipse.boot.validation.springbootbuilder 25 | 26 | 27 | 28 | 29 | org.eclipse.m2e.core.maven2Builder 30 | 31 | 32 | 33 | 34 | 35 | org.springframework.ide.eclipse.core.springnature 36 | org.eclipse.jdt.core.javanature 37 | org.eclipse.m2e.core.maven2Nature 38 | org.eclipse.wst.common.project.facet.core.nature 39 | 40 | 41 | -------------------------------------------------------------------------------- /spring-ddd-presentation-rest/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | com.rogelioorts.training 5 | spring-ddd 6 | 0.0.1-SNAPSHOT 7 | 8 | spring-ddd-presentation-rest 9 | 10 | 11 | 12 | com.rogelioorts.training 13 | spring-ddd-application 14 | 15 | 16 | com.rogelioorts.training 17 | spring-ddd-domain 18 | 19 | 20 | 21 | org.springframework 22 | spring-web 23 | 24 | 25 | org.springframework 26 | spring-webmvc 27 | 28 | 29 | org.springframework 30 | spring-beans 31 | 32 | 33 | 34 | org.mapstruct 35 | mapstruct-jdk8 36 | 37 | 38 | 39 | 40 | 41 | 42 | org.apache.maven.plugins 43 | maven-compiler-plugin 44 | 3.7.0 45 | 46 | 1.8 47 | 1.8 48 | 49 | 50 | org.mapstruct 51 | mapstruct-processor 52 | ${mapstruct.version} 53 | 54 | 55 | org.projectlombok 56 | lombok 57 | ${lombok.version} 58 | 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /spring-ddd-presentation-rest/src/main/java/com/rogelioorts/training/spring/ddd/config/CustomExceptionHandler.java: -------------------------------------------------------------------------------- 1 | package com.rogelioorts.training.spring.ddd.config; 2 | 3 | import org.springframework.web.bind.annotation.ControllerAdvice; 4 | import org.springframework.web.bind.annotation.ExceptionHandler; 5 | import org.springframework.web.bind.annotation.ResponseBody; 6 | 7 | import com.rogelioorts.training.spring.ddd.entities.ErrorResponse; 8 | import com.rogelioorts.training.spring.ddd.exceptions.BadRequestException; 9 | 10 | import lombok.extern.slf4j.Slf4j; 11 | 12 | @ControllerAdvice 13 | @Slf4j 14 | public class CustomExceptionHandler { 15 | 16 | @ExceptionHandler(BadRequestException.class) 17 | public @ResponseBody ErrorResponse badRequestException(BadRequestException exception) { 18 | return new ErrorResponse("BAD_REQUEST", exception.getMessage()); 19 | } 20 | 21 | @ExceptionHandler 22 | public @ResponseBody ErrorResponse defaultHandler(Exception ex) { 23 | log.error("Error handled in controller: " + ex.getMessage(), ex); 24 | return new ErrorResponse("INTERNAL_SERVER", ex.getMessage()); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /spring-ddd-presentation-rest/src/main/java/com/rogelioorts/training/spring/ddd/controllers/MoviesController.java: -------------------------------------------------------------------------------- 1 | package com.rogelioorts.training.spring.ddd.controllers; 2 | 3 | import java.util.List; 4 | import java.util.stream.Collectors; 5 | 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.http.MediaType; 8 | import org.springframework.web.bind.annotation.RequestMapping; 9 | import org.springframework.web.bind.annotation.RequestMethod; 10 | import org.springframework.web.bind.annotation.RequestParam; 11 | import org.springframework.web.bind.annotation.RestController; 12 | 13 | import com.rogelioorts.training.spring.ddd.entities.FiltersDataApi; 14 | import com.rogelioorts.training.spring.ddd.entities.Movie; 15 | import com.rogelioorts.training.spring.ddd.entities.MovieApi; 16 | import com.rogelioorts.training.spring.ddd.exceptions.BadRequestException; 17 | import com.rogelioorts.training.spring.ddd.mappers.FiltersApiMapper; 18 | import com.rogelioorts.training.spring.ddd.mappers.MoviesApiMapper; 19 | import com.rogelioorts.training.spring.ddd.services.MoviesService; 20 | 21 | @RestController 22 | @RequestMapping("/movies") 23 | public class MoviesController { 24 | 25 | @Autowired 26 | private MoviesService moviesService; 27 | 28 | @Autowired 29 | private MoviesApiMapper moviesMapper; 30 | 31 | @Autowired 32 | private FiltersApiMapper filtersApiMapper; 33 | 34 | @RequestMapping(method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) 35 | public List findAll(@RequestParam(required = false) List filters, FiltersDataApi data) throws BadRequestException { 36 | List movies = moviesService.findAll(filters, filtersApiMapper.map(data)); 37 | 38 | return movies.stream().map(moviesMapper::map).collect(Collectors.toList()); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /spring-ddd-presentation-rest/src/main/java/com/rogelioorts/training/spring/ddd/entities/ErrorResponse.java: -------------------------------------------------------------------------------- 1 | package com.rogelioorts.training.spring.ddd.entities; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | 6 | @Getter 7 | @Setter 8 | public class ErrorResponse { 9 | 10 | private boolean error; 11 | 12 | private String errorCode; 13 | 14 | private String message; 15 | 16 | public ErrorResponse(String errorCode, String message) { 17 | this.error = true; 18 | this.errorCode = errorCode; 19 | this.message = message; 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /spring-ddd-presentation-rest/src/main/java/com/rogelioorts/training/spring/ddd/entities/FiltersDataApi.java: -------------------------------------------------------------------------------- 1 | package com.rogelioorts.training.spring.ddd.entities; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | 6 | @Getter 7 | @Setter 8 | public class FiltersDataApi { 9 | 10 | private String level; 11 | 12 | } 13 | -------------------------------------------------------------------------------- /spring-ddd-presentation-rest/src/main/java/com/rogelioorts/training/spring/ddd/entities/MovieApi.java: -------------------------------------------------------------------------------- 1 | package com.rogelioorts.training.spring.ddd.entities; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | 6 | @Getter 7 | @Setter 8 | public class MovieApi { 9 | 10 | private String id; 11 | 12 | private String title; 13 | 14 | private String image; 15 | 16 | private String description; 17 | 18 | private double punctuation; 19 | 20 | private String censoringLevel; 21 | 22 | } 23 | -------------------------------------------------------------------------------- /spring-ddd-presentation-rest/src/main/java/com/rogelioorts/training/spring/ddd/mappers/FiltersApiMapper.java: -------------------------------------------------------------------------------- 1 | package com.rogelioorts.training.spring.ddd.mappers; 2 | 3 | import org.mapstruct.Mapper; 4 | import org.mapstruct.Mapping; 5 | 6 | import com.rogelioorts.training.spring.ddd.entities.FiltersDataApi; 7 | import com.rogelioorts.training.spring.ddd.value.objects.CensoringLevel; 8 | import com.rogelioorts.training.spring.ddd.value.objects.impl.FiltersData; 9 | 10 | @Mapper(componentModel = "spring") 11 | public interface FiltersApiMapper { 12 | 13 | @Mapping(source = "level", target = "censoringLevel") 14 | FiltersData map(FiltersDataApi data); 15 | 16 | default CensoringLevel map(String value) { 17 | if (value == null) { 18 | return null; 19 | } 20 | 21 | switch(value) { 22 | case "censored": 23 | return CensoringLevel.CENSORED; 24 | case "uncensored": 25 | return CensoringLevel.UNCENSORED; 26 | default: 27 | return null; 28 | } 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /spring-ddd-presentation-rest/src/main/java/com/rogelioorts/training/spring/ddd/mappers/MoviesApiMapper.java: -------------------------------------------------------------------------------- 1 | package com.rogelioorts.training.spring.ddd.mappers; 2 | 3 | import org.mapstruct.Mapper; 4 | import org.mapstruct.Mapping; 5 | 6 | import com.rogelioorts.training.spring.ddd.entities.Movie; 7 | import com.rogelioorts.training.spring.ddd.entities.MovieApi; 8 | 9 | @Mapper(componentModel = "spring") 10 | public interface MoviesApiMapper { 11 | 12 | @Mapping(source = "movieId", target = "id") 13 | MovieApi map(Movie movie); 14 | 15 | } 16 | --------------------------------------------------------------------------------