From 91e50545f814f41001d99191ca5c9c0e0e909647 Mon Sep 17 00:00:00 2001 From: caroline Date: Mon, 14 Jan 2019 19:56:19 +0100 Subject: [PATCH 01/28] Source Code for hexagonal architecture article. --- patterns/hexagonal-design-pattern/.gitignore | 5 ++ patterns/hexagonal-design-pattern/pom.xml | 80 +++++++++++++++++++ .../com/baeldung/hexagonal/Application.java | 13 +++ .../adapter/controller/UserController.java | 31 +++++++ .../adapter/data/UserDataAdapter.java | 11 +++ .../adapter/data/UserDataAdapterImpl.java | 27 +++++++ .../adapter/data/entity/UserEntity.java | 39 +++++++++ .../adapter/data/mapper/ModelMapper.java | 41 ++++++++++ .../data/repository/UserRepository.java | 8 ++ .../hexagonal/config/PersistenceConfig.java | 24 ++++++ .../hexagonal/core/contract/User.java | 34 ++++++++ .../hexagonal/core/contract/UserService.java | 10 +++ .../hexagonal/core/contract/dto/UserDTO.java | 24 ++++++ .../core/mapper/CoreModelMapper.java | 41 ++++++++++ .../core/service/UserServiceImpl.java | 28 +++++++ .../src/main/resources/application.properties | 5 ++ .../src/main/resources/logback.xml | 13 +++ .../src/main/resources/myData.sql | 1 + .../src/main/resources/mySchema.sql | 1 + .../hexagonal/test/UserControllerTest.java | 54 +++++++++++++ patterns/pom.xml | 1 + 21 files changed, 491 insertions(+) create mode 100644 patterns/hexagonal-design-pattern/.gitignore create mode 100644 patterns/hexagonal-design-pattern/pom.xml create mode 100644 patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/Application.java create mode 100644 patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/adapter/controller/UserController.java create mode 100644 patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/adapter/data/UserDataAdapter.java create mode 100644 patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/adapter/data/UserDataAdapterImpl.java create mode 100644 patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/adapter/data/entity/UserEntity.java create mode 100644 patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/adapter/data/mapper/ModelMapper.java create mode 100644 patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/adapter/data/repository/UserRepository.java create mode 100644 patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/config/PersistenceConfig.java create mode 100644 patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/core/contract/User.java create mode 100644 patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/core/contract/UserService.java create mode 100644 patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/core/contract/dto/UserDTO.java create mode 100644 patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/core/mapper/CoreModelMapper.java create mode 100644 patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/core/service/UserServiceImpl.java create mode 100644 patterns/hexagonal-design-pattern/src/main/resources/application.properties create mode 100644 patterns/hexagonal-design-pattern/src/main/resources/logback.xml create mode 100644 patterns/hexagonal-design-pattern/src/main/resources/myData.sql create mode 100644 patterns/hexagonal-design-pattern/src/main/resources/mySchema.sql create mode 100644 patterns/hexagonal-design-pattern/src/test/java/com/baeldung/hexagonal/test/UserControllerTest.java diff --git a/patterns/hexagonal-design-pattern/.gitignore b/patterns/hexagonal-design-pattern/.gitignore new file mode 100644 index 0000000000..aceea512a2 --- /dev/null +++ b/patterns/hexagonal-design-pattern/.gitignore @@ -0,0 +1,5 @@ +/target/ +.settings/ +.classpath +.project +/bin/ diff --git a/patterns/hexagonal-design-pattern/pom.xml b/patterns/hexagonal-design-pattern/pom.xml new file mode 100644 index 0000000000..1552859a65 --- /dev/null +++ b/patterns/hexagonal-design-pattern/pom.xml @@ -0,0 +1,80 @@ + + 4.0.0 + com.baeldung + hexagonal-design-pattern + 0.0.1-SNAPSHOT + hexagonal-design-pattern + war + + + org.springframework.boot + spring-boot-starter-parent + 1.5.3.RELEASE + + + + + ma.glasnost.orika + orika-core + 1.4.6 + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-data-jpa + + + com.h2database + h2 + + + org.springframework.boot + spring-boot-starter-actuator + + + org.springframework.boot + spring-boot-starter-test + + + + + + + maven-compiler-plugin + + + maven-war-plugin + + WebContent + + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + com.baeldung.hexagonal.Application + ${project.basedir}/docker + + + + + + + + + + 8.0.43 + UTF-8 + 1.8 + + + diff --git a/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/Application.java b/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/Application.java new file mode 100644 index 0000000000..772a8ad9fd --- /dev/null +++ b/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/Application.java @@ -0,0 +1,13 @@ +package com.baeldung.hexagonal; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + +} diff --git a/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/adapter/controller/UserController.java b/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/adapter/controller/UserController.java new file mode 100644 index 0000000000..1d4dda510e --- /dev/null +++ b/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/adapter/controller/UserController.java @@ -0,0 +1,31 @@ +package com.baeldung.hexagonal.adapter.controller; + +import java.util.List; + +import com.baeldung.hexagonal.core.contract.UserService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.http.HttpStatus; +import com.baeldung.hexagonal.core.contract.User; + +@RestController +public class UserController { + + @Autowired + private UserService userService; + + @PostMapping("/users") + @ResponseStatus(HttpStatus.CREATED) + public void addUser(@RequestBody User user) { + userService.addUser(user); + } + + @GetMapping("/users") + public List getUsers() { + return userService.getUsers(); + } +} diff --git a/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/adapter/data/UserDataAdapter.java b/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/adapter/data/UserDataAdapter.java new file mode 100644 index 0000000000..38a0e08468 --- /dev/null +++ b/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/adapter/data/UserDataAdapter.java @@ -0,0 +1,11 @@ +package com.baeldung.hexagonal.adapter.data; + +import com.baeldung.hexagonal.core.contract.dto.UserDTO; +import java.util.List; + +public interface UserDataAdapter { + + void addUser(UserDTO user); + + List getUsers(); +} \ No newline at end of file diff --git a/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/adapter/data/UserDataAdapterImpl.java b/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/adapter/data/UserDataAdapterImpl.java new file mode 100644 index 0000000000..fe100b1ce0 --- /dev/null +++ b/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/adapter/data/UserDataAdapterImpl.java @@ -0,0 +1,27 @@ +package com.baeldung.hexagonal.adapter.data; + +import com.baeldung.hexagonal.adapter.data.entity.UserEntity; +import com.baeldung.hexagonal.adapter.data.mapper.ModelMapper; +import com.baeldung.hexagonal.adapter.data.repository.UserRepository; +import com.baeldung.hexagonal.core.contract.dto.UserDTO; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import java.util.List; + +@Component +public class UserDataAdapterImpl implements UserDataAdapter { + + @Autowired + private UserRepository userRepository; + + @Autowired + private ModelMapper modelMapper; + + public void addUser(UserDTO user) { + userRepository.save(modelMapper.map(user, UserEntity.class)); + } + + public List getUsers() { + return modelMapper.mapAsList(userRepository.findAll(), UserDTO.class); + } +} \ No newline at end of file diff --git a/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/adapter/data/entity/UserEntity.java b/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/adapter/data/entity/UserEntity.java new file mode 100644 index 0000000000..91f80efa90 --- /dev/null +++ b/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/adapter/data/entity/UserEntity.java @@ -0,0 +1,39 @@ +package com.baeldung.hexagonal.adapter.data.entity; + +import javax.persistence.*; + +@Entity(name = "user") +@Table(name = "user") +public class UserEntity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long id; + + private String name; + + public UserEntity() { + } + + public UserEntity(long id, String name) { + super(); + this.id = id; + this.name = name; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + +} diff --git a/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/adapter/data/mapper/ModelMapper.java b/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/adapter/data/mapper/ModelMapper.java new file mode 100644 index 0000000000..f451781b06 --- /dev/null +++ b/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/adapter/data/mapper/ModelMapper.java @@ -0,0 +1,41 @@ +package com.baeldung.hexagonal.adapter.data.mapper; + +import com.baeldung.hexagonal.adapter.data.entity.UserEntity; +import com.baeldung.hexagonal.core.contract.dto.UserDTO; +import ma.glasnost.orika.CustomMapper; +import ma.glasnost.orika.MapperFactory; +import ma.glasnost.orika.MappingContext; +import ma.glasnost.orika.impl.ConfigurableMapper; +import org.springframework.stereotype.Component; + +@Component +public class ModelMapper extends ConfigurableMapper { + + public void configure(MapperFactory factory) { + super.configure(factory); + + factory.registerClassMap(factory.classMap(UserDTO.class, UserEntity.class) + .customize(new CustomMapper() { + @Override + public void mapAtoB(UserDTO userDTO, UserEntity userEntity, MappingContext context) { + userEntity.setId(userDTO.getId()); + userEntity.setName(userDTO.getName()); + } + }) + .byDefault() + .toClassMap()); + + factory.registerClassMap(factory.classMap(UserEntity.class, UserDTO.class) + .customize(new CustomMapper() { + @Override + public void mapAtoB(UserEntity userEntity, UserDTO userDTO, MappingContext context) { + userDTO.setId(userEntity.getId()); + userDTO.setName(userEntity.getName()); + } + }) + .byDefault() + .toClassMap()); + + } + +} \ No newline at end of file diff --git a/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/adapter/data/repository/UserRepository.java b/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/adapter/data/repository/UserRepository.java new file mode 100644 index 0000000000..937be19056 --- /dev/null +++ b/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/adapter/data/repository/UserRepository.java @@ -0,0 +1,8 @@ +package com.baeldung.hexagonal.adapter.data.repository; + +import com.baeldung.hexagonal.adapter.data.entity.UserEntity; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface UserRepository extends JpaRepository { + +} diff --git a/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/config/PersistenceConfig.java b/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/config/PersistenceConfig.java new file mode 100644 index 0000000000..b9a5f9d556 --- /dev/null +++ b/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/config/PersistenceConfig.java @@ -0,0 +1,24 @@ +package com.baeldung.hexagonal.config; + +import javax.sql.DataSource; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; + +@Configuration +public class PersistenceConfig { + + @Bean + public DataSource dataSource() { + EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder(); + EmbeddedDatabase db = builder.setType(EmbeddedDatabaseType.H2) + .addScript("mySchema.sql") + .addScript("myData.sql") + .build(); + return db; + } + +} \ No newline at end of file diff --git a/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/core/contract/User.java b/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/core/contract/User.java new file mode 100644 index 0000000000..2013c2a88e --- /dev/null +++ b/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/core/contract/User.java @@ -0,0 +1,34 @@ +package com.baeldung.hexagonal.core.contract; + +public class User { + + private long id; + + private String name; + + public User() { + } + + public User(long id, String name) { + super(); + this.id = id; + this.name = name; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + +} diff --git a/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/core/contract/UserService.java b/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/core/contract/UserService.java new file mode 100644 index 0000000000..2b0867872a --- /dev/null +++ b/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/core/contract/UserService.java @@ -0,0 +1,10 @@ +package com.baeldung.hexagonal.core.contract; + +import java.util.List; + +public interface UserService { + + void addUser(User user); + + List getUsers(); +} diff --git a/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/core/contract/dto/UserDTO.java b/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/core/contract/dto/UserDTO.java new file mode 100644 index 0000000000..a92851310b --- /dev/null +++ b/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/core/contract/dto/UserDTO.java @@ -0,0 +1,24 @@ +package com.baeldung.hexagonal.core.contract.dto; + +public class UserDTO { + + private long id; + + private String name; + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} \ No newline at end of file diff --git a/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/core/mapper/CoreModelMapper.java b/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/core/mapper/CoreModelMapper.java new file mode 100644 index 0000000000..1cb569d109 --- /dev/null +++ b/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/core/mapper/CoreModelMapper.java @@ -0,0 +1,41 @@ +package com.baeldung.hexagonal.core.mapper; + +import com.baeldung.hexagonal.core.contract.dto.UserDTO; +import com.baeldung.hexagonal.core.contract.User; +import ma.glasnost.orika.CustomMapper; +import ma.glasnost.orika.MapperFactory; +import ma.glasnost.orika.MappingContext; +import ma.glasnost.orika.impl.ConfigurableMapper; +import org.springframework.stereotype.Component; + +@Component +public class CoreModelMapper extends ConfigurableMapper { + + public void configure(MapperFactory factory) { + super.configure(factory); + + factory.registerClassMap(factory.classMap(UserDTO.class, User.class) + .customize(new CustomMapper() { + @Override + public void mapAtoB(UserDTO userDTO, User user, MappingContext context) { + user.setId(userDTO.getId()); + user.setName(userDTO.getName()); + } + }) + .byDefault() + .toClassMap()); + + factory.registerClassMap(factory.classMap(User.class, UserDTO.class) + .customize(new CustomMapper() { + @Override + public void mapAtoB(User user, UserDTO userDTO, MappingContext context) { + userDTO.setId(user.getId()); + userDTO.setName(user.getName()); + } + }) + .byDefault() + .toClassMap()); + + } + +} \ No newline at end of file diff --git a/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/core/service/UserServiceImpl.java b/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/core/service/UserServiceImpl.java new file mode 100644 index 0000000000..3b4800cffc --- /dev/null +++ b/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/core/service/UserServiceImpl.java @@ -0,0 +1,28 @@ +package com.baeldung.hexagonal.core.service; + +import com.baeldung.hexagonal.adapter.data.UserDataAdapter; +import com.baeldung.hexagonal.core.contract.UserService; +import com.baeldung.hexagonal.core.contract.dto.UserDTO; +import com.baeldung.hexagonal.core.mapper.CoreModelMapper; +import com.baeldung.hexagonal.core.contract.User; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import java.util.List; + +@Service +public class UserServiceImpl implements UserService { + + @Autowired + private UserDataAdapter userDataAdapter; + + @Autowired + private CoreModelMapper coreModelMapper; + + public void addUser(User user) { + userDataAdapter.addUser(coreModelMapper.map(user, UserDTO.class)); + } + + public List getUsers() { + return coreModelMapper.mapAsList(userDataAdapter.getUsers(), User.class); + } +} \ No newline at end of file diff --git a/patterns/hexagonal-design-pattern/src/main/resources/application.properties b/patterns/hexagonal-design-pattern/src/main/resources/application.properties new file mode 100644 index 0000000000..4420285967 --- /dev/null +++ b/patterns/hexagonal-design-pattern/src/main/resources/application.properties @@ -0,0 +1,5 @@ +server.port=8081 +server.contextPath=/hexagonaldesignapp +logging.level.org.springframework.web: INFO + +spring.jpa.hibernate.ddl-auto=update \ No newline at end of file diff --git a/patterns/hexagonal-design-pattern/src/main/resources/logback.xml b/patterns/hexagonal-design-pattern/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/patterns/hexagonal-design-pattern/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/patterns/hexagonal-design-pattern/src/main/resources/myData.sql b/patterns/hexagonal-design-pattern/src/main/resources/myData.sql new file mode 100644 index 0000000000..21353649ba --- /dev/null +++ b/patterns/hexagonal-design-pattern/src/main/resources/myData.sql @@ -0,0 +1 @@ +insert into user(name) values ('ana'); \ No newline at end of file diff --git a/patterns/hexagonal-design-pattern/src/main/resources/mySchema.sql b/patterns/hexagonal-design-pattern/src/main/resources/mySchema.sql new file mode 100644 index 0000000000..d561e4f8b2 --- /dev/null +++ b/patterns/hexagonal-design-pattern/src/main/resources/mySchema.sql @@ -0,0 +1 @@ +create table user(id int identity primary key, name varchar(30)); \ No newline at end of file diff --git a/patterns/hexagonal-design-pattern/src/test/java/com/baeldung/hexagonal/test/UserControllerTest.java b/patterns/hexagonal-design-pattern/src/test/java/com/baeldung/hexagonal/test/UserControllerTest.java new file mode 100644 index 0000000000..3b0c849e3b --- /dev/null +++ b/patterns/hexagonal-design-pattern/src/test/java/com/baeldung/hexagonal/test/UserControllerTest.java @@ -0,0 +1,54 @@ +package com.baeldung.hexagonal.test; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.context.web.WebAppConfiguration; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; + +import static org.hamcrest.Matchers.*; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +import com.baeldung.hexagonal.Application; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = Application.class) +@WebAppConfiguration +public class UserControllerTest { + + private static final String CONTENT_TYPE = "application/json;charset=UTF-8"; + + private MockMvc mockMvc; + + @Autowired + private WebApplicationContext webApplicationContext; + + @Before + public void setup() throws Exception { + this.mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext) + .build(); + } + + @Test + public void whenCreateGetUser_thenOk() throws Exception { + String userJson = "{\"name\":\"john\"}"; + + this.mockMvc.perform(post("/users").contentType(CONTENT_TYPE) + .content(userJson)) + .andExpect(status().isCreated()); + + this.mockMvc.perform(get("/users")) + .andExpect(status().isOk()) + .andExpect(content().contentType(CONTENT_TYPE)) + .andExpect(jsonPath("$", hasSize(2))) + .andExpect(jsonPath("$[0].name", is("ana"))) + .andExpect(jsonPath("$[1].name", is("john"))); + } +} diff --git a/patterns/pom.xml b/patterns/pom.xml index bc1f5173e2..795b4c64db 100644 --- a/patterns/pom.xml +++ b/patterns/pom.xml @@ -17,6 +17,7 @@ front-controller intercepting-filter design-patterns + hexagonal-design-pattern From ab4b3368bd50734f24d00a1eacae3e7b24fe1154 Mon Sep 17 00:00:00 2001 From: caroline Date: Tue, 15 Jan 2019 21:06:57 +0100 Subject: [PATCH 02/28] Source Code for hexagonal architecture article. --- .../hexagonal/core/contract/UserDataAdapter.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/core/contract/UserDataAdapter.java diff --git a/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/core/contract/UserDataAdapter.java b/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/core/contract/UserDataAdapter.java new file mode 100644 index 0000000000..b89410e139 --- /dev/null +++ b/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/core/contract/UserDataAdapter.java @@ -0,0 +1,12 @@ +package com.baeldung.hexagonal.core.contract; + +import com.baeldung.hexagonal.core.contract.dto.UserDTO; + +import java.util.List; + +public interface UserDataAdapter { + + void addUser(UserDTO user); + + List getUsers(); +} \ No newline at end of file From f4871c9c5745b66280198f177ce21857838f3a02 Mon Sep 17 00:00:00 2001 From: Juan Vaccari Date: Mon, 21 Jan 2019 15:10:29 +0000 Subject: [PATCH 03/28] BAEL-2514 - Added unit test for Map processing --- .../baeldung/stream/StreamMapUnitTest.java | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 java-streams/src/test/java/com/baeldung/stream/StreamMapUnitTest.java diff --git a/java-streams/src/test/java/com/baeldung/stream/StreamMapUnitTest.java b/java-streams/src/test/java/com/baeldung/stream/StreamMapUnitTest.java new file mode 100644 index 0000000000..15f1e8a517 --- /dev/null +++ b/java-streams/src/test/java/com/baeldung/stream/StreamMapUnitTest.java @@ -0,0 +1,65 @@ +package com.baeldung.stream; + +import org.junit.Before; +import org.junit.Test; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +import static org.junit.Assert.assertEquals; + +public class StreamMapUnitTest { + + private Map books; + + @Before + public void setup() { + books = new HashMap<>(); + books.put("978-0201633610", "Design patterns : elements of reusable object-oriented software"); + books.put("978-1617291999", "Java 8 in Action: Lambdas, Streams, and functional-style programming"); + books.put("978-0134685991", "Effective Java"); + } + + + @Test + public void whenOptionalVersionCalledForExistingTitle_thenReturnOptionalWithISBN() { + Optional optionalIsbn = books.entrySet().stream() + .filter(e -> "Effective Java".equals(e.getValue())) + .map(Map.Entry::getKey).findFirst(); + + assertEquals("978-0134685991", optionalIsbn.get()); + } + + @Test + public void whenOptionalVersionCalledForNonExistingTitle_thenReturnEmptyOptionalForISBN() { + Optional optionalIsbn = books.entrySet().stream() + .filter(e -> "Non Existent Title".equals(e.getValue())) + .map(Map.Entry::getKey).findFirst(); + + assertEquals(false, optionalIsbn.isPresent()); + } + + @Test + public void whenStringVersionCalledForExistingTitle_thenReturnISBN() { + String isbn = books.entrySet().stream() + .filter(e -> "Effective Java".equals(e.getValue())) + .map(Map.Entry::getKey) + .findFirst() + .orElse(null); + + assertEquals("978-0134685991", isbn); + } + + @Test + public void whenStringVersionCalledForNonExistingTitle_thenReturnNull() { + String isbn = books.entrySet().stream() + .filter(e -> "Non Existent Title".equals(e.getValue())) + .map(Map.Entry::getKey) + .findFirst() + .orElse(null); + + assertEquals(null, isbn); + } + +} From 04626e522a0b5ecd0b8b033c3c850a38d73008f2 Mon Sep 17 00:00:00 2001 From: Juan Vaccari Date: Wed, 23 Jan 2019 19:07:06 +0000 Subject: [PATCH 04/28] BAEL-2514 - Added unit tests for multiple values --- .../baeldung/stream/StreamMapUnitTest.java | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/java-streams/src/test/java/com/baeldung/stream/StreamMapUnitTest.java b/java-streams/src/test/java/com/baeldung/stream/StreamMapUnitTest.java index 15f1e8a517..45694bc59f 100644 --- a/java-streams/src/test/java/com/baeldung/stream/StreamMapUnitTest.java +++ b/java-streams/src/test/java/com/baeldung/stream/StreamMapUnitTest.java @@ -4,10 +4,13 @@ import org.junit.Before; import org.junit.Test; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.stream.Collectors; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; public class StreamMapUnitTest { @@ -62,4 +65,27 @@ public class StreamMapUnitTest { assertEquals(null, isbn); } + @Test + public void whenMultipleResultsVersionCalledForExistingTitle_aCollectionWithMultipleValuesIsReturned() { + books.put("978-0321356680", "Effective Java: Second Edition"); + + List isbnCodes = books.entrySet().stream() + .filter(e -> e.getValue().startsWith("Effective Java")) + .map(Map.Entry::getKey) + .collect(Collectors.toList()); + + assertTrue(isbnCodes.contains("978-0321356680")); + assertTrue(isbnCodes.contains("978-0134685991")); + } + + @Test + public void whenMultipleResultsVersionCalledForNonExistingTitle_aCollectionWithNoValuesIsReturned() { + List isbnCodes = books.entrySet().stream() + .filter(e -> e.getValue().startsWith("Spring")) + .map(Map.Entry::getKey) + .collect(Collectors.toList()); + + assertTrue(isbnCodes.isEmpty()); + } + } From 73f2a12c4e2a18105f92491027d7d91d6e1b91b2 Mon Sep 17 00:00:00 2001 From: caroline Date: Tue, 29 Jan 2019 22:52:53 +0100 Subject: [PATCH 05/28] Source Code for BAEL-2534 : Determine if all elements are the same in a Java list --- core-java-collections-list/pom.xml | 7 + .../VerifyAllEqualListElements.java | 43 +++++ .../VerifyAllEqualListElementsUnitTest.java | 181 ++++++++++++++++++ 3 files changed, 231 insertions(+) create mode 100644 core-java-collections-list/src/main/java/com/baeldung/allequalelements/VerifyAllEqualListElements.java create mode 100644 core-java-collections-list/src/test/java/com/baeldung/allequalelements/VerifyAllEqualListElementsUnitTest.java diff --git a/core-java-collections-list/pom.xml b/core-java-collections-list/pom.xml index ee99e470d0..103508b948 100644 --- a/core-java-collections-list/pom.xml +++ b/core-java-collections-list/pom.xml @@ -36,6 +36,12 @@ ${lombok.version} provided + + org.junit.jupiter + junit-jupiter-api + ${junit-jupiter.version} + test + @@ -44,5 +50,6 @@ 1.7.0 3.11.1 1.16.12 + 5.0.0-M4 diff --git a/core-java-collections-list/src/main/java/com/baeldung/allequalelements/VerifyAllEqualListElements.java b/core-java-collections-list/src/main/java/com/baeldung/allequalelements/VerifyAllEqualListElements.java new file mode 100644 index 0000000000..033245f239 --- /dev/null +++ b/core-java-collections-list/src/main/java/com/baeldung/allequalelements/VerifyAllEqualListElements.java @@ -0,0 +1,43 @@ +package com.baeldung.allequalelements; + +import java.util.List; +import org.apache.commons.collections4.IterableUtils; +import com.google.common.base.Predicate; +import com.google.common.collect.Iterables; + +public class VerifyAllEqualListElements { + + public boolean verifyAllEqualUsingALoop(List list) { + for (String s : list) { + if(!s.equals(list.get(0))) + return false; + } + return true; + } + + public boolean verifyAllEqualUsingStream(List list) { + return list.stream().distinct().limit(2).count() <= 1; + } + + public boolean verifyAllEqualAnotherUsingStream(List list) { + return list.isEmpty() || list.stream().allMatch(list.get(0)::equals); + } + + + public boolean verifyAllEqualUsingGuava(List list) { + return Iterables.all(list, new Predicate() { + public boolean apply(String s) { + return s.equals(list.get(0)); + } + }); + } + + public boolean verifyAllEqualUsingApacheCommon(List list) { + return IterableUtils.matchesAll(list, new org.apache.commons.collections4.Predicate() { + public boolean evaluate(String s) { + return s.equals(list.get(0)); + } + }); + } + +} \ No newline at end of file diff --git a/core-java-collections-list/src/test/java/com/baeldung/allequalelements/VerifyAllEqualListElementsUnitTest.java b/core-java-collections-list/src/test/java/com/baeldung/allequalelements/VerifyAllEqualListElementsUnitTest.java new file mode 100644 index 0000000000..6ebb724580 --- /dev/null +++ b/core-java-collections-list/src/test/java/com/baeldung/allequalelements/VerifyAllEqualListElementsUnitTest.java @@ -0,0 +1,181 @@ +package com.baeldung.allequalelements; + +import org.junit.Test; +import java.util.ArrayList; +import java.util.List; +import static org.junit.Assert.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class VerifyAllEqualListElementsUnitTest { + + private static List distinctList = new ArrayList<>(); + + static { + distinctList.add(new String("Jack")); + distinctList.add(new String("James")); + distinctList.add(new String("Sam")); + } + + private static List notAllEqualList = new ArrayList<>(); + + static { + notAllEqualList.add(new String("Jack")); + notAllEqualList.add(new String("James")); + notAllEqualList.add(new String("Sam")); + notAllEqualList.add(new String("James")); + } + + private static List emptyList = new ArrayList<>(); + + private static List allEqualList = new ArrayList<>(); + + static { + allEqualList.add(new String("Jack")); + allEqualList.add(new String("Jack")); + allEqualList.add(new String("Jack")); + allEqualList.add(new String("Jack")); + } + + private static VerifyAllEqualListElements verifyAllEqualListElements = new VerifyAllEqualListElements(); + + @Test + public void verifyAllEqualUsingALoop_whenUsingDistinctList_thenReturnFalse() { + boolean allEqual = verifyAllEqualListElements.verifyAllEqualUsingALoop(distinctList); + + assertFalse(allEqual); + } + + @Test + public void verifyAllEqualUsingALoop_whenNotAllEqualList_thenReturnFalse() { + boolean allEqual = verifyAllEqualListElements.verifyAllEqualUsingALoop(notAllEqualList); + + assertFalse(allEqual); + } + + @Test + public void verifyAllEqualUsingALoop_whenEmptyList_thenReturnTrue() { + boolean allEqual = verifyAllEqualListElements.verifyAllEqualUsingALoop(emptyList); + + assertTrue(allEqual); + } + + @Test + public void verifyAllEqualUsingALoop_whenAllEqualList_thenReturnTrue() { + boolean allEqual = verifyAllEqualListElements.verifyAllEqualUsingALoop(allEqualList); + + assertTrue(allEqual); + } + + @Test + public void verifyAllEqualUsingStream_whenUsingDistinctList_thenReturnFalse() { + boolean allEqual = verifyAllEqualListElements.verifyAllEqualUsingStream(distinctList); + + assertFalse(allEqual); + } + + @Test + public void verifyAllEqualUsingStream_whenNotAllEqualList_thenReturnFalse() { + boolean allEqual = verifyAllEqualListElements.verifyAllEqualUsingStream(notAllEqualList); + + assertFalse(allEqual); + } + + @Test + public void verifyAllEqualUsingStream_whenEmptyList_thenReturnTrue() { + boolean allEqual = verifyAllEqualListElements.verifyAllEqualUsingStream(emptyList); + + assertTrue(allEqual); + } + + @Test + public void verifyAllEqualUsingStream_whenAllEqualList_thenReturnTrue() { + boolean allEqual = verifyAllEqualListElements.verifyAllEqualUsingStream(allEqualList); + + assertTrue(allEqual); + } + + @Test + public void verifyAllEqualAnotherUsingStream_whenUsingDistinctList_thenReturnFalse() { + boolean allEqual = verifyAllEqualListElements.verifyAllEqualAnotherUsingStream(distinctList); + + assertFalse(allEqual); + } + + @Test + public void verifyAllEqualAnotherUsingStream_whenNotAllEqualList_thenReturnFalse() { + boolean allEqual = verifyAllEqualListElements.verifyAllEqualAnotherUsingStream(notAllEqualList); + + assertFalse(allEqual); + } + + @Test + public void verifyAllEqualAnotherUsingStream_whenEmptyList_thenReturnTrue() { + boolean allEqual = verifyAllEqualListElements.verifyAllEqualAnotherUsingStream(emptyList); + + assertTrue(allEqual); + } + + @Test + public void verifyAllEqualAnotherUsingStream_whenAllEqualList_thenReturnTrue() { + boolean allEqual = verifyAllEqualListElements.verifyAllEqualAnotherUsingStream(allEqualList); + + assertTrue(allEqual); + } + + + @Test + public void verifyAllEqualUsingGuava_whenUsingDistinctList_thenReturnFalse() { + boolean allEqual = verifyAllEqualListElements.verifyAllEqualUsingGuava(distinctList); + + assertFalse(allEqual); + } + + @Test + public void verifyAllEqualUsingGuava_whenNotAllEqualList_thenReturnFalse() { + boolean allEqual = verifyAllEqualListElements.verifyAllEqualUsingGuava(notAllEqualList); + + assertFalse(allEqual); + } + + @Test + public void verifyAllEqualUsingGuava_whenEmptyList_thenReturnTrue() { + boolean allEqual = verifyAllEqualListElements.verifyAllEqualUsingGuava(emptyList); + + assertTrue(allEqual); + } + + @Test + public void verifyAllEqualUsingGuava_whenAllEqualList_thenReturnTrue() { + boolean allEqual = verifyAllEqualListElements.verifyAllEqualUsingGuava(allEqualList); + + assertTrue(allEqual); + } + + @Test + public void verifyAllEqualUsingApacheCommon_whenUsingDistinctList_thenReturnFalse() { + boolean allEqual = verifyAllEqualListElements.verifyAllEqualUsingApacheCommon(distinctList); + + assertFalse(allEqual); + } + + @Test + public void verifyAllEqualUsingApacheCommon_whenNotAllEqualList_thenReturnFalse() { + boolean allEqual = verifyAllEqualListElements.verifyAllEqualUsingApacheCommon(notAllEqualList); + + assertFalse(allEqual); + } + + @Test + public void verifyAllEqualUsingApacheCommon_whenEmptyList_thenReturnTrue() { + boolean allEqual = verifyAllEqualListElements.verifyAllEqualUsingApacheCommon(emptyList); + + assertTrue(allEqual); + } + + @Test + public void verifyAllEqualUsingApacheCommon_whenAllEqualList_thenReturnTrue() { + boolean allEqual = verifyAllEqualListElements.verifyAllEqualUsingApacheCommon(allEqualList); + + assertTrue(allEqual); + } +} From 555409b78ed9bbfa43734ac9764f2b29fbcf4490 Mon Sep 17 00:00:00 2001 From: caroline Date: Fri, 1 Feb 2019 21:34:08 +0100 Subject: [PATCH 06/28] Source Code for BAEL-2534 : Determine if all elements are the same in a Java list --- core-java-collections-list/pom.xml | 7 -- .../VerifyAllEqualListElements.java | 21 ++++- .../VerifyAllEqualListElementsUnitTest.java | 79 ++++++++++++++----- 3 files changed, 78 insertions(+), 29 deletions(-) diff --git a/core-java-collections-list/pom.xml b/core-java-collections-list/pom.xml index 103508b948..ee99e470d0 100644 --- a/core-java-collections-list/pom.xml +++ b/core-java-collections-list/pom.xml @@ -36,12 +36,6 @@ ${lombok.version} provided - - org.junit.jupiter - junit-jupiter-api - ${junit-jupiter.version} - test - @@ -50,6 +44,5 @@ 1.7.0 3.11.1 1.16.12 - 5.0.0-M4 diff --git a/core-java-collections-list/src/main/java/com/baeldung/allequalelements/VerifyAllEqualListElements.java b/core-java-collections-list/src/main/java/com/baeldung/allequalelements/VerifyAllEqualListElements.java index 033245f239..7c9b4a5b9f 100644 --- a/core-java-collections-list/src/main/java/com/baeldung/allequalelements/VerifyAllEqualListElements.java +++ b/core-java-collections-list/src/main/java/com/baeldung/allequalelements/VerifyAllEqualListElements.java @@ -1,5 +1,7 @@ package com.baeldung.allequalelements; +import java.util.Collections; +import java.util.HashSet; import java.util.List; import org.apache.commons.collections4.IterableUtils; import com.google.common.base.Predicate; @@ -9,21 +11,32 @@ public class VerifyAllEqualListElements { public boolean verifyAllEqualUsingALoop(List list) { for (String s : list) { - if(!s.equals(list.get(0))) + if (!s.equals(list.get(0))) return false; } return true; } + public boolean verifyAllEqualUsingHashSet(List list) { + return new HashSet(list).size() <= 1; + } + + public boolean verifyAllEqualUsingFrequency(List list) { + return list.isEmpty() || Collections.frequency(list, list.get(0)) == list.size(); + } + public boolean verifyAllEqualUsingStream(List list) { - return list.stream().distinct().limit(2).count() <= 1; + return list.stream() + .distinct() + .limit(2) + .count() <= 1; } public boolean verifyAllEqualAnotherUsingStream(List list) { - return list.isEmpty() || list.stream().allMatch(list.get(0)::equals); + return list.isEmpty() || list.stream() + .allMatch(list.get(0)::equals); } - public boolean verifyAllEqualUsingGuava(List list) { return Iterables.all(list, new Predicate() { public boolean apply(String s) { diff --git a/core-java-collections-list/src/test/java/com/baeldung/allequalelements/VerifyAllEqualListElementsUnitTest.java b/core-java-collections-list/src/test/java/com/baeldung/allequalelements/VerifyAllEqualListElementsUnitTest.java index 6ebb724580..12c9b0ebeb 100644 --- a/core-java-collections-list/src/test/java/com/baeldung/allequalelements/VerifyAllEqualListElementsUnitTest.java +++ b/core-java-collections-list/src/test/java/com/baeldung/allequalelements/VerifyAllEqualListElementsUnitTest.java @@ -2,6 +2,7 @@ package com.baeldung.allequalelements; import org.junit.Test; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import static org.junit.Assert.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -10,30 +11,17 @@ public class VerifyAllEqualListElementsUnitTest { private static List distinctList = new ArrayList<>(); - static { - distinctList.add(new String("Jack")); - distinctList.add(new String("James")); - distinctList.add(new String("Sam")); - } - private static List notAllEqualList = new ArrayList<>(); - static { - notAllEqualList.add(new String("Jack")); - notAllEqualList.add(new String("James")); - notAllEqualList.add(new String("Sam")); - notAllEqualList.add(new String("James")); - } - private static List emptyList = new ArrayList<>(); private static List allEqualList = new ArrayList<>(); static { - allEqualList.add(new String("Jack")); - allEqualList.add(new String("Jack")); - allEqualList.add(new String("Jack")); - allEqualList.add(new String("Jack")); + distinctList = Arrays.asList("Jack", "James", "Sam"); + notAllEqualList = Arrays.asList("Jack", "James", "Sam", "James"); + emptyList = Arrays.asList(); + allEqualList = Arrays.asList("Jack", "Jack", "Jack", "Jack"); } private static VerifyAllEqualListElements verifyAllEqualListElements = new VerifyAllEqualListElements(); @@ -66,6 +54,62 @@ public class VerifyAllEqualListElementsUnitTest { assertTrue(allEqual); } + @Test + public void verifyAllEqualUsingHashSet_whenUsingDistinctList_thenReturnFalse() { + boolean allEqual = verifyAllEqualListElements.verifyAllEqualUsingHashSet(distinctList); + + assertFalse(allEqual); + } + + @Test + public void verifyAllEqualUsingHashSet_whenNotAllEqualList_thenReturnFalse() { + boolean allEqual = verifyAllEqualListElements.verifyAllEqualUsingHashSet(notAllEqualList); + + assertFalse(allEqual); + } + + @Test + public void verifyAllEqualUsingHashSet_whenEmptyList_thenReturnTrue() { + boolean allEqual = verifyAllEqualListElements.verifyAllEqualUsingHashSet(emptyList); + + assertTrue(allEqual); + } + + @Test + public void verifyAllEqualUsingHashSet_whenAllEqualList_thenReturnTrue() { + boolean allEqual = verifyAllEqualListElements.verifyAllEqualUsingHashSet(allEqualList); + + assertTrue(allEqual); + } + + @Test + public void verifyAllEqualUsingFrequency_whenUsingDistinctList_thenReturnFalse() { + boolean allEqual = verifyAllEqualListElements.verifyAllEqualUsingFrequency(distinctList); + + assertFalse(allEqual); + } + + @Test + public void verifyAllEqualUsingFrequency_whenNotAllEqualList_thenReturnFalse() { + boolean allEqual = verifyAllEqualListElements.verifyAllEqualUsingFrequency(notAllEqualList); + + assertFalse(allEqual); + } + + @Test + public void verifyAllEqualUsingFrequency_whenEmptyList_thenReturnTrue() { + boolean allEqual = verifyAllEqualListElements.verifyAllEqualUsingFrequency(emptyList); + + assertTrue(allEqual); + } + + @Test + public void verifyAllEqualUsingFrequency_whenAllEqualList_thenReturnTrue() { + boolean allEqual = verifyAllEqualListElements.verifyAllEqualUsingFrequency(allEqualList); + + assertTrue(allEqual); + } + @Test public void verifyAllEqualUsingStream_whenUsingDistinctList_thenReturnFalse() { boolean allEqual = verifyAllEqualListElements.verifyAllEqualUsingStream(distinctList); @@ -122,7 +166,6 @@ public class VerifyAllEqualListElementsUnitTest { assertTrue(allEqual); } - @Test public void verifyAllEqualUsingGuava_whenUsingDistinctList_thenReturnFalse() { boolean allEqual = verifyAllEqualListElements.verifyAllEqualUsingGuava(distinctList); From 0a4e783bf552dfd6f462b2c14f1691deb1619556 Mon Sep 17 00:00:00 2001 From: caroline Date: Fri, 1 Feb 2019 21:56:40 +0100 Subject: [PATCH 07/28] Removing code done for demo on Hexagonal Design Pattern. --- patterns/hexagonal-design-pattern/.gitignore | 5 -- patterns/hexagonal-design-pattern/pom.xml | 80 ------------------- .../com/baeldung/hexagonal/Application.java | 13 --- .../adapter/controller/UserController.java | 31 ------- .../adapter/data/UserDataAdapter.java | 11 --- .../adapter/data/UserDataAdapterImpl.java | 27 ------- .../adapter/data/entity/UserEntity.java | 39 --------- .../adapter/data/mapper/ModelMapper.java | 41 ---------- .../data/repository/UserRepository.java | 8 -- .../hexagonal/config/PersistenceConfig.java | 24 ------ .../hexagonal/core/contract/User.java | 34 -------- .../core/contract/UserDataAdapter.java | 12 --- .../hexagonal/core/contract/UserService.java | 10 --- .../hexagonal/core/contract/dto/UserDTO.java | 24 ------ .../core/mapper/CoreModelMapper.java | 41 ---------- .../core/service/UserServiceImpl.java | 28 ------- .../src/main/resources/application.properties | 5 -- .../src/main/resources/logback.xml | 13 --- .../src/main/resources/myData.sql | 1 - .../src/main/resources/mySchema.sql | 1 - .../hexagonal/test/UserControllerTest.java | 54 ------------- patterns/pom.xml | 1 - 22 files changed, 503 deletions(-) delete mode 100644 patterns/hexagonal-design-pattern/.gitignore delete mode 100644 patterns/hexagonal-design-pattern/pom.xml delete mode 100644 patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/Application.java delete mode 100644 patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/adapter/controller/UserController.java delete mode 100644 patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/adapter/data/UserDataAdapter.java delete mode 100644 patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/adapter/data/UserDataAdapterImpl.java delete mode 100644 patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/adapter/data/entity/UserEntity.java delete mode 100644 patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/adapter/data/mapper/ModelMapper.java delete mode 100644 patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/adapter/data/repository/UserRepository.java delete mode 100644 patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/config/PersistenceConfig.java delete mode 100644 patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/core/contract/User.java delete mode 100644 patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/core/contract/UserDataAdapter.java delete mode 100644 patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/core/contract/UserService.java delete mode 100644 patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/core/contract/dto/UserDTO.java delete mode 100644 patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/core/mapper/CoreModelMapper.java delete mode 100644 patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/core/service/UserServiceImpl.java delete mode 100644 patterns/hexagonal-design-pattern/src/main/resources/application.properties delete mode 100644 patterns/hexagonal-design-pattern/src/main/resources/logback.xml delete mode 100644 patterns/hexagonal-design-pattern/src/main/resources/myData.sql delete mode 100644 patterns/hexagonal-design-pattern/src/main/resources/mySchema.sql delete mode 100644 patterns/hexagonal-design-pattern/src/test/java/com/baeldung/hexagonal/test/UserControllerTest.java diff --git a/patterns/hexagonal-design-pattern/.gitignore b/patterns/hexagonal-design-pattern/.gitignore deleted file mode 100644 index aceea512a2..0000000000 --- a/patterns/hexagonal-design-pattern/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -/target/ -.settings/ -.classpath -.project -/bin/ diff --git a/patterns/hexagonal-design-pattern/pom.xml b/patterns/hexagonal-design-pattern/pom.xml deleted file mode 100644 index 1552859a65..0000000000 --- a/patterns/hexagonal-design-pattern/pom.xml +++ /dev/null @@ -1,80 +0,0 @@ - - 4.0.0 - com.baeldung - hexagonal-design-pattern - 0.0.1-SNAPSHOT - hexagonal-design-pattern - war - - - org.springframework.boot - spring-boot-starter-parent - 1.5.3.RELEASE - - - - - ma.glasnost.orika - orika-core - 1.4.6 - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter-data-jpa - - - com.h2database - h2 - - - org.springframework.boot - spring-boot-starter-actuator - - - org.springframework.boot - spring-boot-starter-test - - - - - - - maven-compiler-plugin - - - maven-war-plugin - - WebContent - - - - org.springframework.boot - spring-boot-maven-plugin - - - - repackage - - - com.baeldung.hexagonal.Application - ${project.basedir}/docker - - - - - - - - - - 8.0.43 - UTF-8 - 1.8 - - - diff --git a/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/Application.java b/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/Application.java deleted file mode 100644 index 772a8ad9fd..0000000000 --- a/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/Application.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.baeldung.hexagonal; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -@SpringBootApplication -public class Application { - - public static void main(String[] args) { - SpringApplication.run(Application.class, args); - } - -} diff --git a/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/adapter/controller/UserController.java b/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/adapter/controller/UserController.java deleted file mode 100644 index 1d4dda510e..0000000000 --- a/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/adapter/controller/UserController.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.baeldung.hexagonal.adapter.controller; - -import java.util.List; - -import com.baeldung.hexagonal.core.contract.UserService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.ResponseStatus; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.http.HttpStatus; -import com.baeldung.hexagonal.core.contract.User; - -@RestController -public class UserController { - - @Autowired - private UserService userService; - - @PostMapping("/users") - @ResponseStatus(HttpStatus.CREATED) - public void addUser(@RequestBody User user) { - userService.addUser(user); - } - - @GetMapping("/users") - public List getUsers() { - return userService.getUsers(); - } -} diff --git a/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/adapter/data/UserDataAdapter.java b/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/adapter/data/UserDataAdapter.java deleted file mode 100644 index 38a0e08468..0000000000 --- a/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/adapter/data/UserDataAdapter.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.baeldung.hexagonal.adapter.data; - -import com.baeldung.hexagonal.core.contract.dto.UserDTO; -import java.util.List; - -public interface UserDataAdapter { - - void addUser(UserDTO user); - - List getUsers(); -} \ No newline at end of file diff --git a/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/adapter/data/UserDataAdapterImpl.java b/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/adapter/data/UserDataAdapterImpl.java deleted file mode 100644 index fe100b1ce0..0000000000 --- a/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/adapter/data/UserDataAdapterImpl.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.baeldung.hexagonal.adapter.data; - -import com.baeldung.hexagonal.adapter.data.entity.UserEntity; -import com.baeldung.hexagonal.adapter.data.mapper.ModelMapper; -import com.baeldung.hexagonal.adapter.data.repository.UserRepository; -import com.baeldung.hexagonal.core.contract.dto.UserDTO; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; -import java.util.List; - -@Component -public class UserDataAdapterImpl implements UserDataAdapter { - - @Autowired - private UserRepository userRepository; - - @Autowired - private ModelMapper modelMapper; - - public void addUser(UserDTO user) { - userRepository.save(modelMapper.map(user, UserEntity.class)); - } - - public List getUsers() { - return modelMapper.mapAsList(userRepository.findAll(), UserDTO.class); - } -} \ No newline at end of file diff --git a/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/adapter/data/entity/UserEntity.java b/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/adapter/data/entity/UserEntity.java deleted file mode 100644 index 91f80efa90..0000000000 --- a/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/adapter/data/entity/UserEntity.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.baeldung.hexagonal.adapter.data.entity; - -import javax.persistence.*; - -@Entity(name = "user") -@Table(name = "user") -public class UserEntity { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private long id; - - private String name; - - public UserEntity() { - } - - public UserEntity(long id, String name) { - super(); - this.id = id; - this.name = name; - } - - public long getId() { - return id; - } - - public void setId(long id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - -} diff --git a/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/adapter/data/mapper/ModelMapper.java b/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/adapter/data/mapper/ModelMapper.java deleted file mode 100644 index f451781b06..0000000000 --- a/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/adapter/data/mapper/ModelMapper.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.baeldung.hexagonal.adapter.data.mapper; - -import com.baeldung.hexagonal.adapter.data.entity.UserEntity; -import com.baeldung.hexagonal.core.contract.dto.UserDTO; -import ma.glasnost.orika.CustomMapper; -import ma.glasnost.orika.MapperFactory; -import ma.glasnost.orika.MappingContext; -import ma.glasnost.orika.impl.ConfigurableMapper; -import org.springframework.stereotype.Component; - -@Component -public class ModelMapper extends ConfigurableMapper { - - public void configure(MapperFactory factory) { - super.configure(factory); - - factory.registerClassMap(factory.classMap(UserDTO.class, UserEntity.class) - .customize(new CustomMapper() { - @Override - public void mapAtoB(UserDTO userDTO, UserEntity userEntity, MappingContext context) { - userEntity.setId(userDTO.getId()); - userEntity.setName(userDTO.getName()); - } - }) - .byDefault() - .toClassMap()); - - factory.registerClassMap(factory.classMap(UserEntity.class, UserDTO.class) - .customize(new CustomMapper() { - @Override - public void mapAtoB(UserEntity userEntity, UserDTO userDTO, MappingContext context) { - userDTO.setId(userEntity.getId()); - userDTO.setName(userEntity.getName()); - } - }) - .byDefault() - .toClassMap()); - - } - -} \ No newline at end of file diff --git a/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/adapter/data/repository/UserRepository.java b/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/adapter/data/repository/UserRepository.java deleted file mode 100644 index 937be19056..0000000000 --- a/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/adapter/data/repository/UserRepository.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.baeldung.hexagonal.adapter.data.repository; - -import com.baeldung.hexagonal.adapter.data.entity.UserEntity; -import org.springframework.data.jpa.repository.JpaRepository; - -public interface UserRepository extends JpaRepository { - -} diff --git a/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/config/PersistenceConfig.java b/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/config/PersistenceConfig.java deleted file mode 100644 index b9a5f9d556..0000000000 --- a/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/config/PersistenceConfig.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.baeldung.hexagonal.config; - -import javax.sql.DataSource; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase; -import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; -import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; - -@Configuration -public class PersistenceConfig { - - @Bean - public DataSource dataSource() { - EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder(); - EmbeddedDatabase db = builder.setType(EmbeddedDatabaseType.H2) - .addScript("mySchema.sql") - .addScript("myData.sql") - .build(); - return db; - } - -} \ No newline at end of file diff --git a/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/core/contract/User.java b/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/core/contract/User.java deleted file mode 100644 index 2013c2a88e..0000000000 --- a/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/core/contract/User.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.baeldung.hexagonal.core.contract; - -public class User { - - private long id; - - private String name; - - public User() { - } - - public User(long id, String name) { - super(); - this.id = id; - this.name = name; - } - - public long getId() { - return id; - } - - public void setId(long id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - -} diff --git a/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/core/contract/UserDataAdapter.java b/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/core/contract/UserDataAdapter.java deleted file mode 100644 index b89410e139..0000000000 --- a/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/core/contract/UserDataAdapter.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.baeldung.hexagonal.core.contract; - -import com.baeldung.hexagonal.core.contract.dto.UserDTO; - -import java.util.List; - -public interface UserDataAdapter { - - void addUser(UserDTO user); - - List getUsers(); -} \ No newline at end of file diff --git a/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/core/contract/UserService.java b/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/core/contract/UserService.java deleted file mode 100644 index 2b0867872a..0000000000 --- a/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/core/contract/UserService.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.baeldung.hexagonal.core.contract; - -import java.util.List; - -public interface UserService { - - void addUser(User user); - - List getUsers(); -} diff --git a/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/core/contract/dto/UserDTO.java b/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/core/contract/dto/UserDTO.java deleted file mode 100644 index a92851310b..0000000000 --- a/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/core/contract/dto/UserDTO.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.baeldung.hexagonal.core.contract.dto; - -public class UserDTO { - - private long id; - - private String name; - - public long getId() { - return id; - } - - public void setId(long id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } -} \ No newline at end of file diff --git a/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/core/mapper/CoreModelMapper.java b/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/core/mapper/CoreModelMapper.java deleted file mode 100644 index 1cb569d109..0000000000 --- a/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/core/mapper/CoreModelMapper.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.baeldung.hexagonal.core.mapper; - -import com.baeldung.hexagonal.core.contract.dto.UserDTO; -import com.baeldung.hexagonal.core.contract.User; -import ma.glasnost.orika.CustomMapper; -import ma.glasnost.orika.MapperFactory; -import ma.glasnost.orika.MappingContext; -import ma.glasnost.orika.impl.ConfigurableMapper; -import org.springframework.stereotype.Component; - -@Component -public class CoreModelMapper extends ConfigurableMapper { - - public void configure(MapperFactory factory) { - super.configure(factory); - - factory.registerClassMap(factory.classMap(UserDTO.class, User.class) - .customize(new CustomMapper() { - @Override - public void mapAtoB(UserDTO userDTO, User user, MappingContext context) { - user.setId(userDTO.getId()); - user.setName(userDTO.getName()); - } - }) - .byDefault() - .toClassMap()); - - factory.registerClassMap(factory.classMap(User.class, UserDTO.class) - .customize(new CustomMapper() { - @Override - public void mapAtoB(User user, UserDTO userDTO, MappingContext context) { - userDTO.setId(user.getId()); - userDTO.setName(user.getName()); - } - }) - .byDefault() - .toClassMap()); - - } - -} \ No newline at end of file diff --git a/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/core/service/UserServiceImpl.java b/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/core/service/UserServiceImpl.java deleted file mode 100644 index 3b4800cffc..0000000000 --- a/patterns/hexagonal-design-pattern/src/main/java/com/baeldung/hexagonal/core/service/UserServiceImpl.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.baeldung.hexagonal.core.service; - -import com.baeldung.hexagonal.adapter.data.UserDataAdapter; -import com.baeldung.hexagonal.core.contract.UserService; -import com.baeldung.hexagonal.core.contract.dto.UserDTO; -import com.baeldung.hexagonal.core.mapper.CoreModelMapper; -import com.baeldung.hexagonal.core.contract.User; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import java.util.List; - -@Service -public class UserServiceImpl implements UserService { - - @Autowired - private UserDataAdapter userDataAdapter; - - @Autowired - private CoreModelMapper coreModelMapper; - - public void addUser(User user) { - userDataAdapter.addUser(coreModelMapper.map(user, UserDTO.class)); - } - - public List getUsers() { - return coreModelMapper.mapAsList(userDataAdapter.getUsers(), User.class); - } -} \ No newline at end of file diff --git a/patterns/hexagonal-design-pattern/src/main/resources/application.properties b/patterns/hexagonal-design-pattern/src/main/resources/application.properties deleted file mode 100644 index 4420285967..0000000000 --- a/patterns/hexagonal-design-pattern/src/main/resources/application.properties +++ /dev/null @@ -1,5 +0,0 @@ -server.port=8081 -server.contextPath=/hexagonaldesignapp -logging.level.org.springframework.web: INFO - -spring.jpa.hibernate.ddl-auto=update \ No newline at end of file diff --git a/patterns/hexagonal-design-pattern/src/main/resources/logback.xml b/patterns/hexagonal-design-pattern/src/main/resources/logback.xml deleted file mode 100644 index 7d900d8ea8..0000000000 --- a/patterns/hexagonal-design-pattern/src/main/resources/logback.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n - - - - - - - - \ No newline at end of file diff --git a/patterns/hexagonal-design-pattern/src/main/resources/myData.sql b/patterns/hexagonal-design-pattern/src/main/resources/myData.sql deleted file mode 100644 index 21353649ba..0000000000 --- a/patterns/hexagonal-design-pattern/src/main/resources/myData.sql +++ /dev/null @@ -1 +0,0 @@ -insert into user(name) values ('ana'); \ No newline at end of file diff --git a/patterns/hexagonal-design-pattern/src/main/resources/mySchema.sql b/patterns/hexagonal-design-pattern/src/main/resources/mySchema.sql deleted file mode 100644 index d561e4f8b2..0000000000 --- a/patterns/hexagonal-design-pattern/src/main/resources/mySchema.sql +++ /dev/null @@ -1 +0,0 @@ -create table user(id int identity primary key, name varchar(30)); \ No newline at end of file diff --git a/patterns/hexagonal-design-pattern/src/test/java/com/baeldung/hexagonal/test/UserControllerTest.java b/patterns/hexagonal-design-pattern/src/test/java/com/baeldung/hexagonal/test/UserControllerTest.java deleted file mode 100644 index 3b0c849e3b..0000000000 --- a/patterns/hexagonal-design-pattern/src/test/java/com/baeldung/hexagonal/test/UserControllerTest.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.baeldung.hexagonal.test; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.test.context.web.WebAppConfiguration; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.setup.MockMvcBuilders; -import org.springframework.web.context.WebApplicationContext; - -import static org.hamcrest.Matchers.*; - -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; - -import com.baeldung.hexagonal.Application; - -@RunWith(SpringRunner.class) -@SpringBootTest(classes = Application.class) -@WebAppConfiguration -public class UserControllerTest { - - private static final String CONTENT_TYPE = "application/json;charset=UTF-8"; - - private MockMvc mockMvc; - - @Autowired - private WebApplicationContext webApplicationContext; - - @Before - public void setup() throws Exception { - this.mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext) - .build(); - } - - @Test - public void whenCreateGetUser_thenOk() throws Exception { - String userJson = "{\"name\":\"john\"}"; - - this.mockMvc.perform(post("/users").contentType(CONTENT_TYPE) - .content(userJson)) - .andExpect(status().isCreated()); - - this.mockMvc.perform(get("/users")) - .andExpect(status().isOk()) - .andExpect(content().contentType(CONTENT_TYPE)) - .andExpect(jsonPath("$", hasSize(2))) - .andExpect(jsonPath("$[0].name", is("ana"))) - .andExpect(jsonPath("$[1].name", is("john"))); - } -} diff --git a/patterns/pom.xml b/patterns/pom.xml index 795b4c64db..bc1f5173e2 100644 --- a/patterns/pom.xml +++ b/patterns/pom.xml @@ -17,7 +17,6 @@ front-controller intercepting-filter design-patterns - hexagonal-design-pattern From d56efcfa9760f434cc0549e45191ff4cf4d57ea3 Mon Sep 17 00:00:00 2001 From: Juan Vaccari Date: Sat, 2 Feb 2019 17:19:28 +0000 Subject: [PATCH 08/28] BAEL-2514 - Added a new test for retrieving values based on key patterns --- .../com/baeldung/stream/StreamMapUnitTest.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/java-streams/src/test/java/com/baeldung/stream/StreamMapUnitTest.java b/java-streams/src/test/java/com/baeldung/stream/StreamMapUnitTest.java index 45694bc59f..2d23f758e6 100644 --- a/java-streams/src/test/java/com/baeldung/stream/StreamMapUnitTest.java +++ b/java-streams/src/test/java/com/baeldung/stream/StreamMapUnitTest.java @@ -3,11 +3,14 @@ package com.baeldung.stream; import org.junit.Before; import org.junit.Test; +import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.Set; import java.util.stream.Collectors; +import java.util.stream.Stream; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -88,4 +91,18 @@ public class StreamMapUnitTest { assertTrue(isbnCodes.isEmpty()); } + @Test + public void ValuesFromMapBasedOnPattern() { + Map authorToYearOfBirth = new HashMap<>(); + authorToYearOfBirth.put("Asimov, Isaac", 1920); + authorToYearOfBirth.put("Adams, Douglas", 1952); + authorToYearOfBirth.put("Bradbury, Ray", 1920); + authorToYearOfBirth.put("Clarke, Arthur", 1917); + + List yearOfBirthAuthorsStartingWithA = authorToYearOfBirth.entrySet().stream().filter(e -> e.getKey().startsWith("A")).map(Map.Entry::getValue).collect(Collectors.toList()); + assertEquals(2, yearOfBirthAuthorsStartingWithA.size()); + + } + + } From ff01e708c9ee609389a0493227d44f4715a4bfcb Mon Sep 17 00:00:00 2001 From: Raghav Jha Date: Mon, 4 Feb 2019 04:36:27 +0530 Subject: [PATCH 09/28] BAEL-2456 Hibernate Query Plan Cache --- persistence-modules/hibernate5/pom.xml | 6 + .../com/baeldung/hibernate/HibernateUtil.java | 12 +- .../QueryPlanCacheUnitTest.java | 105 ++++++++++++++++++ 3 files changed, 121 insertions(+), 2 deletions(-) create mode 100644 persistence-modules/hibernate5/src/test/java/com/baeldung/hibernate/queryplancache/QueryPlanCacheUnitTest.java diff --git a/persistence-modules/hibernate5/pom.xml b/persistence-modules/hibernate5/pom.xml index af94025a73..6b9a9abbe5 100644 --- a/persistence-modules/hibernate5/pom.xml +++ b/persistence-modules/hibernate5/pom.xml @@ -73,6 +73,11 @@ hibernate-jpamodelgen ${hibernate.version} + + io.dropwizard.metrics + metrics-core + ${dropwizard-metrics.version} + @@ -92,6 +97,7 @@ 1.4.196 3.8.0 2.9.7 + 4.0.5 diff --git a/persistence-modules/hibernate5/src/main/java/com/baeldung/hibernate/HibernateUtil.java b/persistence-modules/hibernate5/src/main/java/com/baeldung/hibernate/HibernateUtil.java index e0d1de591b..ea0af97d5a 100644 --- a/persistence-modules/hibernate5/src/main/java/com/baeldung/hibernate/HibernateUtil.java +++ b/persistence-modules/hibernate5/src/main/java/com/baeldung/hibernate/HibernateUtil.java @@ -68,6 +68,11 @@ public class HibernateUtil { return sessionFactory; } + public static SessionFactory getSessionFactoryByProperties(Properties properties) throws IOException { + ServiceRegistry serviceRegistry = configureServiceRegistry(properties); + return makeSessionFactory(serviceRegistry); + } + private static SessionFactory makeSessionFactory(ServiceRegistry serviceRegistry) { MetadataSources metadataSources = new MetadataSources(serviceRegistry); @@ -119,12 +124,15 @@ public class HibernateUtil { } private static ServiceRegistry configureServiceRegistry() throws IOException { - Properties properties = getProperties(); + return configureServiceRegistry(getProperties()); + } + + private static ServiceRegistry configureServiceRegistry(Properties properties) throws IOException { return new StandardServiceRegistryBuilder().applySettings(properties) .build(); } - private static Properties getProperties() throws IOException { + public static Properties getProperties() throws IOException { Properties properties = new Properties(); URL propertiesURL = Thread.currentThread() .getContextClassLoader() diff --git a/persistence-modules/hibernate5/src/test/java/com/baeldung/hibernate/queryplancache/QueryPlanCacheUnitTest.java b/persistence-modules/hibernate5/src/test/java/com/baeldung/hibernate/queryplancache/QueryPlanCacheUnitTest.java new file mode 100644 index 0000000000..68325c559f --- /dev/null +++ b/persistence-modules/hibernate5/src/test/java/com/baeldung/hibernate/queryplancache/QueryPlanCacheUnitTest.java @@ -0,0 +1,105 @@ +package com.baeldung.hibernate.queryplancache; + +import com.baeldung.hibernate.HibernateUtil; +import com.codahale.metrics.Timer; +import com.codahale.metrics.UniformReservoir; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.jpa.QueryHints; +import org.hibernate.query.Query; +import org.junit.Ignore; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; +import java.util.concurrent.TimeUnit; + +@RunWith(Parameterized.class) +public class QueryPlanCacheUnitTest { + + private static final Logger LOGGER = LoggerFactory.getLogger(QueryPlanCacheUnitTest.class); + + @Parameterized.Parameters + public static List planCacheSize() { + List planCacheSizes = new ArrayList<>(); + + planCacheSizes.add(new Integer[]{1}); + planCacheSizes.add(new Integer[]{2}); + planCacheSizes.add(new Integer[]{3}); + + + return planCacheSizes; + } + + private Timer timer = new Timer(new UniformReservoir(9900)); + + private int planCacheSize; + + public QueryPlanCacheUnitTest(int planCacheSize) { + this.planCacheSize = planCacheSize; + } + + @Test + @Ignore + public void givenQueryPlanCacheSize_thenCompileQueries() throws IOException { + Session session = initSession(); + + //warm-up + for (int i = 0; i < 9900; i++) { + createFindEmployeesByDepartmentNameQuery(session); + createFindEmployeesByDesignationQuery(session); + createFindDepartmentOfAnEmployeeQuery(session); + } + + for (int i = 0; i < 3300; i++) { + long startTime = System.nanoTime(); + createFindEmployeesByDepartmentNameQuery(session); + timer.update(System.nanoTime() - startTime, TimeUnit.NANOSECONDS); + + startTime = System.nanoTime(); + createFindEmployeesByDesignationQuery(session); + timer.update(System.nanoTime() - startTime, TimeUnit.NANOSECONDS); + + startTime = System.nanoTime(); + createFindDepartmentOfAnEmployeeQuery(session); + timer.update(System.nanoTime() - startTime, TimeUnit.NANOSECONDS); + } + + LOGGER.info("Query Plan Cache Size - {}, Time(Nanoseconds) - {}", planCacheSize, timer.getSnapshot().get95thPercentile()); + + } + + private Session initSession() throws IOException { + Properties properties = HibernateUtil.getProperties(); + properties.put("hibernate.query.plan_cache_max_size", planCacheSize); + properties.put("hibernate.query.plan_parameter_metadata_max_size", planCacheSize); + SessionFactory sessionFactory = HibernateUtil.getSessionFactoryByProperties(properties); + return sessionFactory.openSession(); + } + + private Query createFindEmployeesByDepartmentNameQuery(Session session) { + return session.createQuery("SELECT e FROM DeptEmployee e " + + "JOIN e.department WHERE e.department.name = :deptName") + .setMaxResults(30) + .setHint(QueryHints.HINT_FETCH_SIZE, 30); + } + + private Query createFindEmployeesByDesignationQuery(Session session) { + return session.createQuery("SELECT e FROM DeptEmployee e " + + "WHERE e.title = :designation") + .setHint(QueryHints.SPEC_HINT_TIMEOUT, 1000); + } + + private Query createFindDepartmentOfAnEmployeeQuery(Session session) { + return session.createQuery("SELECT e.department FROM DeptEmployee e " + + "JOIN e.department WHERE e.employeeNumber = :empId"); + + } + +} From 6faaedddb44637d9470986d301709cfccdd3666b Mon Sep 17 00:00:00 2001 From: caroline Date: Mon, 4 Feb 2019 21:52:56 +0100 Subject: [PATCH 10/28] Changes after editor's review --- .../VerifyAllEqualListElements.java | 1 - .../VerifyAllEqualListElementsUnitTest.java | 94 +++++-------------- 2 files changed, 21 insertions(+), 74 deletions(-) diff --git a/core-java-collections-list/src/main/java/com/baeldung/allequalelements/VerifyAllEqualListElements.java b/core-java-collections-list/src/main/java/com/baeldung/allequalelements/VerifyAllEqualListElements.java index 7c9b4a5b9f..936e89893c 100644 --- a/core-java-collections-list/src/main/java/com/baeldung/allequalelements/VerifyAllEqualListElements.java +++ b/core-java-collections-list/src/main/java/com/baeldung/allequalelements/VerifyAllEqualListElements.java @@ -28,7 +28,6 @@ public class VerifyAllEqualListElements { public boolean verifyAllEqualUsingStream(List list) { return list.stream() .distinct() - .limit(2) .count() <= 1; } diff --git a/core-java-collections-list/src/test/java/com/baeldung/allequalelements/VerifyAllEqualListElementsUnitTest.java b/core-java-collections-list/src/test/java/com/baeldung/allequalelements/VerifyAllEqualListElementsUnitTest.java index 12c9b0ebeb..698725591c 100644 --- a/core-java-collections-list/src/test/java/com/baeldung/allequalelements/VerifyAllEqualListElementsUnitTest.java +++ b/core-java-collections-list/src/test/java/com/baeldung/allequalelements/VerifyAllEqualListElementsUnitTest.java @@ -9,8 +9,6 @@ import static org.junit.jupiter.api.Assertions.assertTrue; public class VerifyAllEqualListElementsUnitTest { - private static List distinctList = new ArrayList<>(); - private static List notAllEqualList = new ArrayList<>(); private static List emptyList = new ArrayList<>(); @@ -18,7 +16,6 @@ public class VerifyAllEqualListElementsUnitTest { private static List allEqualList = new ArrayList<>(); static { - distinctList = Arrays.asList("Jack", "James", "Sam"); notAllEqualList = Arrays.asList("Jack", "James", "Sam", "James"); emptyList = Arrays.asList(); allEqualList = Arrays.asList("Jack", "Jack", "Jack", "Jack"); @@ -27,196 +24,147 @@ public class VerifyAllEqualListElementsUnitTest { private static VerifyAllEqualListElements verifyAllEqualListElements = new VerifyAllEqualListElements(); @Test - public void verifyAllEqualUsingALoop_whenUsingDistinctList_thenReturnFalse() { - boolean allEqual = verifyAllEqualListElements.verifyAllEqualUsingALoop(distinctList); - - assertFalse(allEqual); - } - - @Test - public void verifyAllEqualUsingALoop_whenNotAllEqualList_thenReturnFalse() { + public void givenNotAllEqualList_whenUsingALoop_thenReturnFalse() { boolean allEqual = verifyAllEqualListElements.verifyAllEqualUsingALoop(notAllEqualList); assertFalse(allEqual); } @Test - public void verifyAllEqualUsingALoop_whenEmptyList_thenReturnTrue() { + public void givenEmptyList_whenUsingALoop_thenReturnTrue() { boolean allEqual = verifyAllEqualListElements.verifyAllEqualUsingALoop(emptyList); assertTrue(allEqual); } @Test - public void verifyAllEqualUsingALoop_whenAllEqualList_thenReturnTrue() { + public void givenAllEqualList_whenUsingALoop_thenReturnTrue() { boolean allEqual = verifyAllEqualListElements.verifyAllEqualUsingALoop(allEqualList); assertTrue(allEqual); } @Test - public void verifyAllEqualUsingHashSet_whenUsingDistinctList_thenReturnFalse() { - boolean allEqual = verifyAllEqualListElements.verifyAllEqualUsingHashSet(distinctList); - - assertFalse(allEqual); - } - - @Test - public void verifyAllEqualUsingHashSet_whenNotAllEqualList_thenReturnFalse() { + public void givenNotAllEqualList_whenUsingHashSet_thenReturnFalse() { boolean allEqual = verifyAllEqualListElements.verifyAllEqualUsingHashSet(notAllEqualList); assertFalse(allEqual); } @Test - public void verifyAllEqualUsingHashSet_whenEmptyList_thenReturnTrue() { + public void givenEmptyList_whenUsingHashSet_thenReturnTrue() { boolean allEqual = verifyAllEqualListElements.verifyAllEqualUsingHashSet(emptyList); assertTrue(allEqual); } @Test - public void verifyAllEqualUsingHashSet_whenAllEqualList_thenReturnTrue() { + public void givenAllEqualList_whenUsingHashSet_thenReturnTrue() { boolean allEqual = verifyAllEqualListElements.verifyAllEqualUsingHashSet(allEqualList); assertTrue(allEqual); } @Test - public void verifyAllEqualUsingFrequency_whenUsingDistinctList_thenReturnFalse() { - boolean allEqual = verifyAllEqualListElements.verifyAllEqualUsingFrequency(distinctList); - - assertFalse(allEqual); - } - - @Test - public void verifyAllEqualUsingFrequency_whenNotAllEqualList_thenReturnFalse() { + public void givenNotAllEqualList_whenUsingFrequency_thenReturnFalse() { boolean allEqual = verifyAllEqualListElements.verifyAllEqualUsingFrequency(notAllEqualList); assertFalse(allEqual); } @Test - public void verifyAllEqualUsingFrequency_whenEmptyList_thenReturnTrue() { + public void givenEmptyList_whenUsingFrequency_thenReturnTrue() { boolean allEqual = verifyAllEqualListElements.verifyAllEqualUsingFrequency(emptyList); assertTrue(allEqual); } @Test - public void verifyAllEqualUsingFrequency_whenAllEqualList_thenReturnTrue() { + public void givenAllEqualList_whenUsingFrequency_thenReturnTrue() { boolean allEqual = verifyAllEqualListElements.verifyAllEqualUsingFrequency(allEqualList); assertTrue(allEqual); } @Test - public void verifyAllEqualUsingStream_whenUsingDistinctList_thenReturnFalse() { - boolean allEqual = verifyAllEqualListElements.verifyAllEqualUsingStream(distinctList); - - assertFalse(allEqual); - } - - @Test - public void verifyAllEqualUsingStream_whenNotAllEqualList_thenReturnFalse() { + public void givenNotAllEqualList_whenUsingStream_thenReturnFalse() { boolean allEqual = verifyAllEqualListElements.verifyAllEqualUsingStream(notAllEqualList); assertFalse(allEqual); } @Test - public void verifyAllEqualUsingStream_whenEmptyList_thenReturnTrue() { + public void givenEmptyList_whenUsingStream_thenReturnTrue() { boolean allEqual = verifyAllEqualListElements.verifyAllEqualUsingStream(emptyList); assertTrue(allEqual); } @Test - public void verifyAllEqualUsingStream_whenAllEqualList_thenReturnTrue() { + public void givenAllEqualList_whenUsingStream_thenReturnTrue() { boolean allEqual = verifyAllEqualListElements.verifyAllEqualUsingStream(allEqualList); assertTrue(allEqual); } @Test - public void verifyAllEqualAnotherUsingStream_whenUsingDistinctList_thenReturnFalse() { - boolean allEqual = verifyAllEqualListElements.verifyAllEqualAnotherUsingStream(distinctList); - - assertFalse(allEqual); - } - - @Test - public void verifyAllEqualAnotherUsingStream_whenNotAllEqualList_thenReturnFalse() { + public void givenNotAllEqualList_whenUsingAnotherStream_thenReturnFalse() { boolean allEqual = verifyAllEqualListElements.verifyAllEqualAnotherUsingStream(notAllEqualList); assertFalse(allEqual); } @Test - public void verifyAllEqualAnotherUsingStream_whenEmptyList_thenReturnTrue() { + public void givenEmptyList_whenUsingAnotherStream_thenReturnTrue() { boolean allEqual = verifyAllEqualListElements.verifyAllEqualAnotherUsingStream(emptyList); assertTrue(allEqual); } @Test - public void verifyAllEqualAnotherUsingStream_whenAllEqualList_thenReturnTrue() { + public void givenAllEqualList_whenUsingAnotherStream_thenReturnTrue() { boolean allEqual = verifyAllEqualListElements.verifyAllEqualAnotherUsingStream(allEqualList); assertTrue(allEqual); } @Test - public void verifyAllEqualUsingGuava_whenUsingDistinctList_thenReturnFalse() { - boolean allEqual = verifyAllEqualListElements.verifyAllEqualUsingGuava(distinctList); - - assertFalse(allEqual); - } - - @Test - public void verifyAllEqualUsingGuava_whenNotAllEqualList_thenReturnFalse() { + public void givenNotAllEqualList_whenUsingGuava_thenReturnFalse() { boolean allEqual = verifyAllEqualListElements.verifyAllEqualUsingGuava(notAllEqualList); assertFalse(allEqual); } @Test - public void verifyAllEqualUsingGuava_whenEmptyList_thenReturnTrue() { + public void givenEmptyList_whenUsingGuava_thenReturnTrue() { boolean allEqual = verifyAllEqualListElements.verifyAllEqualUsingGuava(emptyList); assertTrue(allEqual); } @Test - public void verifyAllEqualUsingGuava_whenAllEqualList_thenReturnTrue() { + public void givenAllEqualList_whenUsingGuava_thenReturnTrue() { boolean allEqual = verifyAllEqualListElements.verifyAllEqualUsingGuava(allEqualList); assertTrue(allEqual); } @Test - public void verifyAllEqualUsingApacheCommon_whenUsingDistinctList_thenReturnFalse() { - boolean allEqual = verifyAllEqualListElements.verifyAllEqualUsingApacheCommon(distinctList); - - assertFalse(allEqual); - } - - @Test - public void verifyAllEqualUsingApacheCommon_whenNotAllEqualList_thenReturnFalse() { + public void givenNotAllEqualList_whenUsingApacheCommon_thenReturnFalse() { boolean allEqual = verifyAllEqualListElements.verifyAllEqualUsingApacheCommon(notAllEqualList); assertFalse(allEqual); } @Test - public void verifyAllEqualUsingApacheCommon_whenEmptyList_thenReturnTrue() { + public void givenEmptyList_whenUsingApacheCommon_thenReturnTrue() { boolean allEqual = verifyAllEqualListElements.verifyAllEqualUsingApacheCommon(emptyList); assertTrue(allEqual); } @Test - public void verifyAllEqualUsingApacheCommon_whenAllEqualList_thenReturnTrue() { + public void givenAllEqualList_whenUsingApacheCommon_thenReturnTrue() { boolean allEqual = verifyAllEqualListElements.verifyAllEqualUsingApacheCommon(allEqualList); assertTrue(allEqual); From a0ff77a3fd8fb9105c21f9bffc018b3f430e323c Mon Sep 17 00:00:00 2001 From: TINO Date: Tue, 5 Feb 2019 00:11:09 +0300 Subject: [PATCH 11/28] BAEL-2226 --- spring-security-cors/pom.xml | 70 +++++++++++++++++++ .../SpringBootSecurityApplication.java | 14 ++++ .../basicauth/config/WebSecurityConfig.java | 33 +++++++++ .../controller/ResourceController.java | 17 +++++ .../src/main/resources/application.properties | 3 + .../src/main/resources/logback.xml | 13 ++++ ...BasicAuthConfigurationIntegrationTest.java | 33 +++++++++ 7 files changed, 183 insertions(+) create mode 100644 spring-security-cors/pom.xml create mode 100644 spring-security-cors/src/main/java/com/baeldung/springbootsecuritycors/basicauth/SpringBootSecurityApplication.java create mode 100644 spring-security-cors/src/main/java/com/baeldung/springbootsecuritycors/basicauth/config/WebSecurityConfig.java create mode 100644 spring-security-cors/src/main/java/com/baeldung/springbootsecuritycors/controller/ResourceController.java create mode 100644 spring-security-cors/src/main/resources/application.properties create mode 100644 spring-security-cors/src/main/resources/logback.xml create mode 100644 spring-security-cors/src/test/java/com/baeldung/springbootsecurityrest/BasicAuthConfigurationIntegrationTest.java diff --git a/spring-security-cors/pom.xml b/spring-security-cors/pom.xml new file mode 100644 index 0000000000..1f12c908c6 --- /dev/null +++ b/spring-security-cors/pom.xml @@ -0,0 +1,70 @@ + + + 4.0.0 + com.baeldung + spring-security-cors + 0.0.1-SNAPSHOT + jar + spring-security-cors + Spring Security CORS + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + + + + + org.springframework.boot + spring-boot-dependencies + 2.1.2.RELEASE + pom + import + + + + + + + + + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.security + spring-security-test + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + UTF-8 + UTF-8 + + + diff --git a/spring-security-cors/src/main/java/com/baeldung/springbootsecuritycors/basicauth/SpringBootSecurityApplication.java b/spring-security-cors/src/main/java/com/baeldung/springbootsecuritycors/basicauth/SpringBootSecurityApplication.java new file mode 100644 index 0000000000..89bf0dde5d --- /dev/null +++ b/spring-security-cors/src/main/java/com/baeldung/springbootsecuritycors/basicauth/SpringBootSecurityApplication.java @@ -0,0 +1,14 @@ +package com.baeldung.springbootsecuritycors.basicauth; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication(scanBasePackages = "com.baeldung.springbootsecuritycors") +@EnableAutoConfiguration +public class SpringBootSecurityApplication { + + public static void main(String[] args) { + SpringApplication.run(SpringBootSecurityApplication.class, args); + } +} diff --git a/spring-security-cors/src/main/java/com/baeldung/springbootsecuritycors/basicauth/config/WebSecurityConfig.java b/spring-security-cors/src/main/java/com/baeldung/springbootsecuritycors/basicauth/config/WebSecurityConfig.java new file mode 100644 index 0000000000..faa803cde9 --- /dev/null +++ b/spring-security-cors/src/main/java/com/baeldung/springbootsecuritycors/basicauth/config/WebSecurityConfig.java @@ -0,0 +1,33 @@ +package com.baeldung.springbootsecuritycors.basicauth.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; + +@Configuration +@EnableWebSecurity +public class WebSecurityConfig extends WebSecurityConfigurerAdapter { + + @Override + protected void configure(AuthenticationManagerBuilder auth) throws Exception { + auth + .inMemoryAuthentication() + .withUser("user") + .password("{noop}password") + .roles("USER"); + } + +@Override +protected void configure(HttpSecurity http) throws Exception { + http + .csrf().disable() + .cors().and() //disable this line to reproduce the CORS 401 + .authorizeRequests() + .anyRequest() + .authenticated() + .and() + .httpBasic(); +} +} diff --git a/spring-security-cors/src/main/java/com/baeldung/springbootsecuritycors/controller/ResourceController.java b/spring-security-cors/src/main/java/com/baeldung/springbootsecuritycors/controller/ResourceController.java new file mode 100644 index 0000000000..d86c25e223 --- /dev/null +++ b/spring-security-cors/src/main/java/com/baeldung/springbootsecuritycors/controller/ResourceController.java @@ -0,0 +1,17 @@ +package com.baeldung.springbootsecuritycors.controller; + +import javax.servlet.http.HttpServletRequest; + +import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@CrossOrigin +public class ResourceController { + + @RequestMapping("/user") + public String user(HttpServletRequest request) { + return request.getUserPrincipal().getName(); + } +} diff --git a/spring-security-cors/src/main/resources/application.properties b/spring-security-cors/src/main/resources/application.properties new file mode 100644 index 0000000000..4835515744 --- /dev/null +++ b/spring-security-cors/src/main/resources/application.properties @@ -0,0 +1,3 @@ +server.port=8080 + + diff --git a/spring-security-cors/src/main/resources/logback.xml b/spring-security-cors/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-security-cors/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-security-cors/src/test/java/com/baeldung/springbootsecurityrest/BasicAuthConfigurationIntegrationTest.java b/spring-security-cors/src/test/java/com/baeldung/springbootsecurityrest/BasicAuthConfigurationIntegrationTest.java new file mode 100644 index 0000000000..483e578ed4 --- /dev/null +++ b/spring-security-cors/src/test/java/com/baeldung/springbootsecurityrest/BasicAuthConfigurationIntegrationTest.java @@ -0,0 +1,33 @@ +package com.baeldung.springbootsecurityrest; + +import static org.junit.Assert.assertEquals; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.net.URL; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.web.client.RestClientException; + +import com.baeldung.springbootsecuritycors.basicauth.SpringBootSecurityApplication; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = RANDOM_PORT, classes = SpringBootSecurityApplication.class) +public class BasicAuthConfigurationIntegrationTest { + + @Test + public void givenCredentials_whenRequested_thenLogin() throws IllegalStateException, IOException, RestClientException, URISyntaxException { + TestRestTemplate restTemplate = new TestRestTemplate(); + URL base = new URL("http://192.168.1.101:8082/user"); + ResponseEntity response = restTemplate.withBasicAuth("user", "password").postForEntity(base.toURI(), null, String.class); + assertEquals(HttpStatus.OK, response.getStatusCode()); + } + +} From 92cc03c9a516e535d4c4b9bc590ec3bda2963771 Mon Sep 17 00:00:00 2001 From: TINO Date: Tue, 5 Feb 2019 00:14:06 +0300 Subject: [PATCH 12/28] BAEL-2226 --- spring-security-cors/pom.xml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/spring-security-cors/pom.xml b/spring-security-cors/pom.xml index 1f12c908c6..0dd41e66c7 100644 --- a/spring-security-cors/pom.xml +++ b/spring-security-cors/pom.xml @@ -28,10 +28,6 @@ - - - - org.springframework.boot spring-boot-starter-security From 1c5e742d3185f628cc047c32b3cf04331ccde8cc Mon Sep 17 00:00:00 2001 From: TINO Date: Tue, 5 Feb 2019 00:15:28 +0300 Subject: [PATCH 13/28] BAEL-2226 --- spring-security-cors/src/main/resources/logback.xml | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 spring-security-cors/src/main/resources/logback.xml diff --git a/spring-security-cors/src/main/resources/logback.xml b/spring-security-cors/src/main/resources/logback.xml deleted file mode 100644 index 7d900d8ea8..0000000000 --- a/spring-security-cors/src/main/resources/logback.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n - - - - - - - - \ No newline at end of file From 998e0a5b815245d4042614e864d669f22ec7499e Mon Sep 17 00:00:00 2001 From: Raghav Jha Date: Tue, 5 Feb 2019 17:45:51 +0530 Subject: [PATCH 14/28] BAEL-2456 Hibernate Query Plan Cache --- persistence-modules/hibernate5/pom.xml | 13 ++- .../QueryPlanCacheBenchmark.java | 106 ++++++++++++++++++ .../QueryPlanCacheUnitTest.java | 105 ----------------- 3 files changed, 115 insertions(+), 109 deletions(-) create mode 100644 persistence-modules/hibernate5/src/test/java/com/baeldung/hibernate/queryplancache/QueryPlanCacheBenchmark.java delete mode 100644 persistence-modules/hibernate5/src/test/java/com/baeldung/hibernate/queryplancache/QueryPlanCacheUnitTest.java diff --git a/persistence-modules/hibernate5/pom.xml b/persistence-modules/hibernate5/pom.xml index 6b9a9abbe5..a09669c8b5 100644 --- a/persistence-modules/hibernate5/pom.xml +++ b/persistence-modules/hibernate5/pom.xml @@ -74,9 +74,14 @@ ${hibernate.version} - io.dropwizard.metrics - metrics-core - ${dropwizard-metrics.version} + org.openjdk.jmh + jmh-core + ${openjdk-jmh.version} + + + org.openjdk.jmh + jmh-generator-annprocess + ${openjdk-jmh.version} @@ -97,7 +102,7 @@ 1.4.196 3.8.0 2.9.7 - 4.0.5 + 1.21 diff --git a/persistence-modules/hibernate5/src/test/java/com/baeldung/hibernate/queryplancache/QueryPlanCacheBenchmark.java b/persistence-modules/hibernate5/src/test/java/com/baeldung/hibernate/queryplancache/QueryPlanCacheBenchmark.java new file mode 100644 index 0000000000..13eae3d877 --- /dev/null +++ b/persistence-modules/hibernate5/src/test/java/com/baeldung/hibernate/queryplancache/QueryPlanCacheBenchmark.java @@ -0,0 +1,106 @@ +package com.baeldung.hibernate.queryplancache; + +import com.baeldung.hibernate.HibernateUtil; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.jpa.QueryHints; +import org.hibernate.query.Query; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.TearDown; +import org.openjdk.jmh.annotations.Warmup; +import org.openjdk.jmh.infra.Blackhole; +import org.openjdk.jmh.runner.RunnerException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.util.Properties; +import java.util.concurrent.TimeUnit; + +public class QueryPlanCacheBenchmark { + + private static final Logger LOGGER = LoggerFactory.getLogger(QueryPlanCacheBenchmark.class); + + @State(Scope.Thread) + public static class QueryPlanCacheBenchMarkState { + @Param({"1", "2", "3"}) + public int planCacheSize; + + public Session session; + + @Setup + public void stateSetup() throws IOException { + LOGGER.info("State - Setup"); + session = initSession(planCacheSize); + LOGGER.info("State - Setup Complete"); + } + + private Session initSession(int planCacheSize) throws IOException { + Properties properties = HibernateUtil.getProperties(); + properties.put("hibernate.query.plan_cache_max_size", planCacheSize); + properties.put("hibernate.query.plan_parameter_metadata_max_size", planCacheSize); + SessionFactory sessionFactory = HibernateUtil.getSessionFactoryByProperties(properties); + return sessionFactory.openSession(); + } + + @TearDown + public void tearDownState() { + LOGGER.info("State - Teardown"); + SessionFactory sessionFactory = session.getSessionFactory(); + session.close(); + sessionFactory.close(); + LOGGER.info("State - Teardown complete"); + } + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.MICROSECONDS) + @Fork(1) + @Warmup(iterations = 2) + @Measurement(iterations = 5) + public void givenQueryPlanCacheSize_thenCompileQueries(QueryPlanCacheBenchMarkState state, Blackhole blackhole) { + + Query query1 = findEmployeesByDepartmentNameQuery(state.session); + Query query2 = findEmployeesByDesignationQuery(state.session); + Query query3 = findDepartmentOfAnEmployeeQuery(state.session); + + blackhole.consume(query1); + blackhole.consume(query2); + blackhole.consume(query3); + + } + + private Query findEmployeesByDepartmentNameQuery(Session session) { + return session.createQuery("SELECT e FROM DeptEmployee e " + + "JOIN e.department WHERE e.department.name = :deptName") + .setMaxResults(30) + .setHint(QueryHints.HINT_FETCH_SIZE, 30); + } + + private Query findEmployeesByDesignationQuery(Session session) { + return session.createQuery("SELECT e FROM DeptEmployee e " + + "WHERE e.title = :designation") + .setHint(QueryHints.SPEC_HINT_TIMEOUT, 1000); + } + + private Query findDepartmentOfAnEmployeeQuery(Session session) { + return session.createQuery("SELECT e.department FROM DeptEmployee e " + + "JOIN e.department WHERE e.employeeNumber = :empId"); + + } + + public static void main(String... args) throws IOException, RunnerException { + //main-class to run the benchmark + org.openjdk.jmh.Main.main(args); + } +} diff --git a/persistence-modules/hibernate5/src/test/java/com/baeldung/hibernate/queryplancache/QueryPlanCacheUnitTest.java b/persistence-modules/hibernate5/src/test/java/com/baeldung/hibernate/queryplancache/QueryPlanCacheUnitTest.java deleted file mode 100644 index 68325c559f..0000000000 --- a/persistence-modules/hibernate5/src/test/java/com/baeldung/hibernate/queryplancache/QueryPlanCacheUnitTest.java +++ /dev/null @@ -1,105 +0,0 @@ -package com.baeldung.hibernate.queryplancache; - -import com.baeldung.hibernate.HibernateUtil; -import com.codahale.metrics.Timer; -import com.codahale.metrics.UniformReservoir; -import org.hibernate.Session; -import org.hibernate.SessionFactory; -import org.hibernate.jpa.QueryHints; -import org.hibernate.query.Query; -import org.junit.Ignore; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.Properties; -import java.util.concurrent.TimeUnit; - -@RunWith(Parameterized.class) -public class QueryPlanCacheUnitTest { - - private static final Logger LOGGER = LoggerFactory.getLogger(QueryPlanCacheUnitTest.class); - - @Parameterized.Parameters - public static List planCacheSize() { - List planCacheSizes = new ArrayList<>(); - - planCacheSizes.add(new Integer[]{1}); - planCacheSizes.add(new Integer[]{2}); - planCacheSizes.add(new Integer[]{3}); - - - return planCacheSizes; - } - - private Timer timer = new Timer(new UniformReservoir(9900)); - - private int planCacheSize; - - public QueryPlanCacheUnitTest(int planCacheSize) { - this.planCacheSize = planCacheSize; - } - - @Test - @Ignore - public void givenQueryPlanCacheSize_thenCompileQueries() throws IOException { - Session session = initSession(); - - //warm-up - for (int i = 0; i < 9900; i++) { - createFindEmployeesByDepartmentNameQuery(session); - createFindEmployeesByDesignationQuery(session); - createFindDepartmentOfAnEmployeeQuery(session); - } - - for (int i = 0; i < 3300; i++) { - long startTime = System.nanoTime(); - createFindEmployeesByDepartmentNameQuery(session); - timer.update(System.nanoTime() - startTime, TimeUnit.NANOSECONDS); - - startTime = System.nanoTime(); - createFindEmployeesByDesignationQuery(session); - timer.update(System.nanoTime() - startTime, TimeUnit.NANOSECONDS); - - startTime = System.nanoTime(); - createFindDepartmentOfAnEmployeeQuery(session); - timer.update(System.nanoTime() - startTime, TimeUnit.NANOSECONDS); - } - - LOGGER.info("Query Plan Cache Size - {}, Time(Nanoseconds) - {}", planCacheSize, timer.getSnapshot().get95thPercentile()); - - } - - private Session initSession() throws IOException { - Properties properties = HibernateUtil.getProperties(); - properties.put("hibernate.query.plan_cache_max_size", planCacheSize); - properties.put("hibernate.query.plan_parameter_metadata_max_size", planCacheSize); - SessionFactory sessionFactory = HibernateUtil.getSessionFactoryByProperties(properties); - return sessionFactory.openSession(); - } - - private Query createFindEmployeesByDepartmentNameQuery(Session session) { - return session.createQuery("SELECT e FROM DeptEmployee e " + - "JOIN e.department WHERE e.department.name = :deptName") - .setMaxResults(30) - .setHint(QueryHints.HINT_FETCH_SIZE, 30); - } - - private Query createFindEmployeesByDesignationQuery(Session session) { - return session.createQuery("SELECT e FROM DeptEmployee e " + - "WHERE e.title = :designation") - .setHint(QueryHints.SPEC_HINT_TIMEOUT, 1000); - } - - private Query createFindDepartmentOfAnEmployeeQuery(Session session) { - return session.createQuery("SELECT e.department FROM DeptEmployee e " + - "JOIN e.department WHERE e.employeeNumber = :empId"); - - } - -} From c49eaed0e5e2f38e8563143833c94d580ef13355 Mon Sep 17 00:00:00 2001 From: soufiane-cheouati <46105138+soufiane-cheouati@users.noreply.github.com> Date: Thu, 7 Feb 2019 19:51:04 +0000 Subject: [PATCH 15/28] Custom annotation files --- .../com/baeldung/customannotations/Init.java | 13 ++++ .../customannotations/JsonElement.java | 13 ++++ .../customannotations/JsonSerializable.java | 13 ++++ .../JsonSerializationException.java | 10 +++ .../ObjectToJsonConverter.java | 69 +++++++++++++++++++ .../baeldung/customannotations/Person.java | 66 ++++++++++++++++++ 6 files changed, 184 insertions(+) create mode 100644 core-java-8/src/main/java/com/baeldung/customannotations/Init.java create mode 100644 core-java-8/src/main/java/com/baeldung/customannotations/JsonElement.java create mode 100644 core-java-8/src/main/java/com/baeldung/customannotations/JsonSerializable.java create mode 100644 core-java-8/src/main/java/com/baeldung/customannotations/JsonSerializationException.java create mode 100644 core-java-8/src/main/java/com/baeldung/customannotations/ObjectToJsonConverter.java create mode 100644 core-java-8/src/main/java/com/baeldung/customannotations/Person.java diff --git a/core-java-8/src/main/java/com/baeldung/customannotations/Init.java b/core-java-8/src/main/java/com/baeldung/customannotations/Init.java new file mode 100644 index 0000000000..265e7ba1d6 --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/customannotations/Init.java @@ -0,0 +1,13 @@ +package com.baeldung.customannotations; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +@Retention(RUNTIME) +@Target(METHOD) +public @interface Init { + +} diff --git a/core-java-8/src/main/java/com/baeldung/customannotations/JsonElement.java b/core-java-8/src/main/java/com/baeldung/customannotations/JsonElement.java new file mode 100644 index 0000000000..e41a5b1e30 --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/customannotations/JsonElement.java @@ -0,0 +1,13 @@ +package com.baeldung.customannotations; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +@Retention(RUNTIME) +@Target({ FIELD }) +public @interface JsonElement { + public String key() default ""; +} diff --git a/core-java-8/src/main/java/com/baeldung/customannotations/JsonSerializable.java b/core-java-8/src/main/java/com/baeldung/customannotations/JsonSerializable.java new file mode 100644 index 0000000000..48eeb09a1b --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/customannotations/JsonSerializable.java @@ -0,0 +1,13 @@ +package com.baeldung.customannotations; + +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +@Retention(RUNTIME) +@Target(TYPE) +public @interface JsonSerializable { + +} diff --git a/core-java-8/src/main/java/com/baeldung/customannotations/JsonSerializationException.java b/core-java-8/src/main/java/com/baeldung/customannotations/JsonSerializationException.java new file mode 100644 index 0000000000..f2c29855ac --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/customannotations/JsonSerializationException.java @@ -0,0 +1,10 @@ +package com.baeldung.customannotations; + +public class JsonSerializationException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + public JsonSerializationException(String message) { + super(message); + } +} diff --git a/core-java-8/src/main/java/com/baeldung/customannotations/ObjectToJsonConverter.java b/core-java-8/src/main/java/com/baeldung/customannotations/ObjectToJsonConverter.java new file mode 100644 index 0000000000..bcde225a3b --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/customannotations/ObjectToJsonConverter.java @@ -0,0 +1,69 @@ +package com.baeldung.customannotations; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; + +import com.sun.istack.internal.NotNull; + +public class ObjectToJsonConverter { + public String convertToJson(@NotNull Object object) throws JsonSerializationException { + try { + + checkIfSerializable(object); + initializeObject(object); + return getJsonString(object); + + } catch (Exception e) { + throw new JsonSerializationException(e.getMessage()); + } + } + + private void checkIfSerializable(Object object) { + if (Objects.isNull(object)) { + throw new JsonSerializationException("Can't serialize a null object"); + } + + Class clazz = object.getClass(); + if (!clazz.isAnnotationPresent(JsonSerializable.class)) { + throw new JsonSerializationException("The class" + clazz.getSimpleName() + " is not annotated with JsonSerializable"); + } + } + + private void initializeObject(Object object) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException { + Class clazz = object.getClass(); + for (Method method : clazz.getDeclaredMethods()) { + if (method.isAnnotationPresent(Init.class)) { + method.setAccessible(true); + method.invoke(object); + } + } + } + + private String getJsonString(Object object) throws IllegalArgumentException, IllegalAccessException { + Class clazz = object.getClass(); + Map jsonElementsMap = new HashMap<>(); + for (Field field : clazz.getDeclaredFields()) { + field.setAccessible(true); + if (field.isAnnotationPresent(JsonElement.class)) { + jsonElementsMap.put(getKey(field), (String) field.get(object)); + } + } + + String jsonString = jsonElementsMap.entrySet() + .stream() + .map(entry -> "\"" + entry.getKey() + "\":\"" + entry.getValue() + "\"") + .collect(Collectors.joining(",")); + return "{" + jsonString + "}"; + } + + private String getKey(Field field) { + String value = field.getAnnotation(JsonElement.class) + .key(); + return value.isEmpty() ? field.getName() : value; + } +} diff --git a/core-java-8/src/main/java/com/baeldung/customannotations/Person.java b/core-java-8/src/main/java/com/baeldung/customannotations/Person.java new file mode 100644 index 0000000000..5db1a7f279 --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/customannotations/Person.java @@ -0,0 +1,66 @@ +package com.baeldung.customannotations; + +@JsonSerializable +public class Person { + @JsonElement + private String firstName; + @JsonElement + private String lastName; + @JsonElement(key = "personAge") + private String age; + + private String address; + + public Person(String firstName, String lastName) { + super(); + this.firstName = firstName; + this.lastName = lastName; + } + + public Person(String firstName, String lastName, String age) { + this.firstName = firstName; + this.lastName = lastName; + this.age = age; + } + + @Init + private void initNames() { + this.firstName = this.firstName.substring(0, 1) + .toUpperCase() + this.firstName.substring(1); + this.lastName = this.lastName.substring(0, 1) + .toUpperCase() + this.lastName.substring(1); + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getAge() { + return age; + } + + public void setAge(String age) { + this.age = age; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + +} From 0da1ab969ab689f28e8b83d4ea7494e11e245130 Mon Sep 17 00:00:00 2001 From: soufiane-cheouati <46105138+soufiane-cheouati@users.noreply.github.com> Date: Thu, 7 Feb 2019 19:53:42 +0000 Subject: [PATCH 16/28] Add files via upload --- .../JsonSerializerUnitTest.java | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 core-java-8/src/test/java/com/baeldung/customannotations/JsonSerializerUnitTest.java diff --git a/core-java-8/src/test/java/com/baeldung/customannotations/JsonSerializerUnitTest.java b/core-java-8/src/test/java/com/baeldung/customannotations/JsonSerializerUnitTest.java new file mode 100644 index 0000000000..a1f0f423e9 --- /dev/null +++ b/core-java-8/src/test/java/com/baeldung/customannotations/JsonSerializerUnitTest.java @@ -0,0 +1,27 @@ +package com.baeldung.customannotations; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.Test; + +public class JsonSerializerUnitTest { + + @Test + public void givenObjectNotSerializedThenExceptionThrown() throws JsonSerializationException { + Object object = new Object(); + ObjectToJsonConverter serializer = new ObjectToJsonConverter(); + serializer.convertToJson(object); + assertThrows(JsonSerializationException.class, () -> { + serializer.convertToJson(object); + }); + } + + @Test + public void givenObjectSerializedThenTrueReturned() throws JsonSerializationException { + Person person = new Person("soufiane", "cheouati", "34"); + ObjectToJsonConverter serializer = new ObjectToJsonConverter(); + String jsonString = serializer.convertToJson(person); + assertEquals("{\"personAge\":\"34\",\"firstName\":\"Soufiane\",\"lastName\":\"Cheouati\"}", jsonString); + } +} From a079636e79e16e47cd1c6d76333e4d6d4e626d65 Mon Sep 17 00:00:00 2001 From: Juan Vaccari Date: Sun, 10 Feb 2019 14:50:45 +0000 Subject: [PATCH 17/28] BAEL-2514 - Changed key pattern example to use same map as others --- .../com/baeldung/stream/StreamMapUnitTest.java | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/java-streams/src/test/java/com/baeldung/stream/StreamMapUnitTest.java b/java-streams/src/test/java/com/baeldung/stream/StreamMapUnitTest.java index 2d23f758e6..eda0b6be95 100644 --- a/java-streams/src/test/java/com/baeldung/stream/StreamMapUnitTest.java +++ b/java-streams/src/test/java/com/baeldung/stream/StreamMapUnitTest.java @@ -92,15 +92,14 @@ public class StreamMapUnitTest { } @Test - public void ValuesFromMapBasedOnPattern() { - Map authorToYearOfBirth = new HashMap<>(); - authorToYearOfBirth.put("Asimov, Isaac", 1920); - authorToYearOfBirth.put("Adams, Douglas", 1952); - authorToYearOfBirth.put("Bradbury, Ray", 1920); - authorToYearOfBirth.put("Clarke, Arthur", 1917); - - List yearOfBirthAuthorsStartingWithA = authorToYearOfBirth.entrySet().stream().filter(e -> e.getKey().startsWith("A")).map(Map.Entry::getValue).collect(Collectors.toList()); - assertEquals(2, yearOfBirthAuthorsStartingWithA.size()); + public void whenKeysFollowingPatternReturnsAllValuesForThoseKeys() { + List titlesForKeyPattern = books.entrySet().stream() + .filter(e -> e.getKey().startsWith("978-0")) + .map(Map.Entry::getValue) + .collect(Collectors.toList()); + assertEquals(2, titlesForKeyPattern.size()); + assertTrue(titlesForKeyPattern.contains("Design patterns : elements of reusable object-oriented software")); + assertTrue(titlesForKeyPattern.contains("Effective Java")); } From bed05a42895f5a9cea6641630d560ddcfb265dac Mon Sep 17 00:00:00 2001 From: Juan Vaccari Date: Mon, 11 Feb 2019 17:54:15 +0000 Subject: [PATCH 18/28] BAEL-2514 - Removed unit tests for orElse cases removed from tutorial --- .../baeldung/stream/StreamMapUnitTest.java | 26 +------------------ 1 file changed, 1 insertion(+), 25 deletions(-) diff --git a/java-streams/src/test/java/com/baeldung/stream/StreamMapUnitTest.java b/java-streams/src/test/java/com/baeldung/stream/StreamMapUnitTest.java index eda0b6be95..5cb2a274d1 100644 --- a/java-streams/src/test/java/com/baeldung/stream/StreamMapUnitTest.java +++ b/java-streams/src/test/java/com/baeldung/stream/StreamMapUnitTest.java @@ -46,28 +46,6 @@ public class StreamMapUnitTest { assertEquals(false, optionalIsbn.isPresent()); } - @Test - public void whenStringVersionCalledForExistingTitle_thenReturnISBN() { - String isbn = books.entrySet().stream() - .filter(e -> "Effective Java".equals(e.getValue())) - .map(Map.Entry::getKey) - .findFirst() - .orElse(null); - - assertEquals("978-0134685991", isbn); - } - - @Test - public void whenStringVersionCalledForNonExistingTitle_thenReturnNull() { - String isbn = books.entrySet().stream() - .filter(e -> "Non Existent Title".equals(e.getValue())) - .map(Map.Entry::getKey) - .findFirst() - .orElse(null); - - assertEquals(null, isbn); - } - @Test public void whenMultipleResultsVersionCalledForExistingTitle_aCollectionWithMultipleValuesIsReturned() { books.put("978-0321356680", "Effective Java: Second Edition"); @@ -100,8 +78,6 @@ public class StreamMapUnitTest { assertEquals(2, titlesForKeyPattern.size()); assertTrue(titlesForKeyPattern.contains("Design patterns : elements of reusable object-oriented software")); assertTrue(titlesForKeyPattern.contains("Effective Java")); - } - - + } From e1241e741f27e2dc0d96319a7af44082cdec0327 Mon Sep 17 00:00:00 2001 From: soufiane-cheouati <46105138+soufiane-cheouati@users.noreply.github.com> Date: Tue, 12 Feb 2019 19:22:40 +0000 Subject: [PATCH 19/28] Add files via upload --- .../com/baeldung/customannotations/JsonSerializerUnitTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/core-java-8/src/test/java/com/baeldung/customannotations/JsonSerializerUnitTest.java b/core-java-8/src/test/java/com/baeldung/customannotations/JsonSerializerUnitTest.java index a1f0f423e9..f24b37aef7 100644 --- a/core-java-8/src/test/java/com/baeldung/customannotations/JsonSerializerUnitTest.java +++ b/core-java-8/src/test/java/com/baeldung/customannotations/JsonSerializerUnitTest.java @@ -11,7 +11,6 @@ public class JsonSerializerUnitTest { public void givenObjectNotSerializedThenExceptionThrown() throws JsonSerializationException { Object object = new Object(); ObjectToJsonConverter serializer = new ObjectToJsonConverter(); - serializer.convertToJson(object); assertThrows(JsonSerializationException.class, () -> { serializer.convertToJson(object); }); From 669dc7804fe74c27c1db09631e45800952fb4ea7 Mon Sep 17 00:00:00 2001 From: soufiane-cheouati <46105138+soufiane-cheouati@users.noreply.github.com> Date: Tue, 12 Feb 2019 19:24:18 +0000 Subject: [PATCH 20/28] Add files via upload --- .../baeldung/customannotations/ObjectToJsonConverter.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/core-java-8/src/main/java/com/baeldung/customannotations/ObjectToJsonConverter.java b/core-java-8/src/main/java/com/baeldung/customannotations/ObjectToJsonConverter.java index bcde225a3b..dd126be8ed 100644 --- a/core-java-8/src/main/java/com/baeldung/customannotations/ObjectToJsonConverter.java +++ b/core-java-8/src/main/java/com/baeldung/customannotations/ObjectToJsonConverter.java @@ -8,10 +8,8 @@ import java.util.Map; import java.util.Objects; import java.util.stream.Collectors; -import com.sun.istack.internal.NotNull; - public class ObjectToJsonConverter { - public String convertToJson(@NotNull Object object) throws JsonSerializationException { + public String convertToJson(Object object) throws JsonSerializationException { try { checkIfSerializable(object); @@ -30,7 +28,7 @@ public class ObjectToJsonConverter { Class clazz = object.getClass(); if (!clazz.isAnnotationPresent(JsonSerializable.class)) { - throw new JsonSerializationException("The class" + clazz.getSimpleName() + " is not annotated with JsonSerializable"); + throw new JsonSerializationException("The class " + clazz.getSimpleName() + " is not annotated with JsonSerializable"); } } From 77775c67941179adecfd296f7236947a27b3cd15 Mon Sep 17 00:00:00 2001 From: TINO Date: Tue, 12 Feb 2019 23:50:53 +0300 Subject: [PATCH 21/28] BAEL - 2226 Review comments incorporated --- .../basicauth/config/WebSecurityConfig.java | 28 ++++------------ .../controller/ResourceController.java | 12 +++---- .../src/main/resources/application.properties | 3 -- ...BasicAuthConfigurationIntegrationTest.java | 33 ------------------- 4 files changed, 13 insertions(+), 63 deletions(-) delete mode 100644 spring-security-cors/src/main/resources/application.properties delete mode 100644 spring-security-cors/src/test/java/com/baeldung/springbootsecurityrest/BasicAuthConfigurationIntegrationTest.java diff --git a/spring-security-cors/src/main/java/com/baeldung/springbootsecuritycors/basicauth/config/WebSecurityConfig.java b/spring-security-cors/src/main/java/com/baeldung/springbootsecuritycors/basicauth/config/WebSecurityConfig.java index faa803cde9..684354bf26 100644 --- a/spring-security-cors/src/main/java/com/baeldung/springbootsecuritycors/basicauth/config/WebSecurityConfig.java +++ b/spring-security-cors/src/main/java/com/baeldung/springbootsecuritycors/basicauth/config/WebSecurityConfig.java @@ -1,33 +1,19 @@ package com.baeldung.springbootsecuritycors.basicauth.config; -import org.springframework.context.annotation.Configuration; -import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; -@Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override - protected void configure(AuthenticationManagerBuilder auth) throws Exception { - auth - .inMemoryAuthentication() - .withUser("user") - .password("{noop}password") - .roles("USER"); + protected void configure(HttpSecurity http) throws Exception { + http + .authorizeRequests() + .anyRequest().authenticated() + .and() + .httpBasic(); + http.cors(); //disable this line to reproduce the CORS 401 } - -@Override -protected void configure(HttpSecurity http) throws Exception { - http - .csrf().disable() - .cors().and() //disable this line to reproduce the CORS 401 - .authorizeRequests() - .anyRequest() - .authenticated() - .and() - .httpBasic(); -} } diff --git a/spring-security-cors/src/main/java/com/baeldung/springbootsecuritycors/controller/ResourceController.java b/spring-security-cors/src/main/java/com/baeldung/springbootsecuritycors/controller/ResourceController.java index d86c25e223..7292c7f4f4 100644 --- a/spring-security-cors/src/main/java/com/baeldung/springbootsecuritycors/controller/ResourceController.java +++ b/spring-security-cors/src/main/java/com/baeldung/springbootsecuritycors/controller/ResourceController.java @@ -1,17 +1,17 @@ package com.baeldung.springbootsecuritycors.controller; -import javax.servlet.http.HttpServletRequest; +import java.security.Principal; import org.springframework.web.bind.annotation.CrossOrigin; -import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController -@CrossOrigin +@CrossOrigin("http://localhost:4200") public class ResourceController { - @RequestMapping("/user") - public String user(HttpServletRequest request) { - return request.getUserPrincipal().getName(); + @GetMapping("/user") + public String user(Principal principal) { + return principal.getName(); } } diff --git a/spring-security-cors/src/main/resources/application.properties b/spring-security-cors/src/main/resources/application.properties deleted file mode 100644 index 4835515744..0000000000 --- a/spring-security-cors/src/main/resources/application.properties +++ /dev/null @@ -1,3 +0,0 @@ -server.port=8080 - - diff --git a/spring-security-cors/src/test/java/com/baeldung/springbootsecurityrest/BasicAuthConfigurationIntegrationTest.java b/spring-security-cors/src/test/java/com/baeldung/springbootsecurityrest/BasicAuthConfigurationIntegrationTest.java deleted file mode 100644 index 483e578ed4..0000000000 --- a/spring-security-cors/src/test/java/com/baeldung/springbootsecurityrest/BasicAuthConfigurationIntegrationTest.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.baeldung.springbootsecurityrest; - -import static org.junit.Assert.assertEquals; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -import java.io.IOException; -import java.net.URISyntaxException; -import java.net.URL; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.web.client.RestClientException; - -import com.baeldung.springbootsecuritycors.basicauth.SpringBootSecurityApplication; - -@RunWith(SpringRunner.class) -@SpringBootTest(webEnvironment = RANDOM_PORT, classes = SpringBootSecurityApplication.class) -public class BasicAuthConfigurationIntegrationTest { - - @Test - public void givenCredentials_whenRequested_thenLogin() throws IllegalStateException, IOException, RestClientException, URISyntaxException { - TestRestTemplate restTemplate = new TestRestTemplate(); - URL base = new URL("http://192.168.1.101:8082/user"); - ResponseEntity response = restTemplate.withBasicAuth("user", "password").postForEntity(base.toURI(), null, String.class); - assertEquals(HttpStatus.OK, response.getStatusCode()); - } - -} From 8dbe5d6ab7a08ef0e8794c07b0ba90bd504adca8 Mon Sep 17 00:00:00 2001 From: TINO Date: Wed, 13 Feb 2019 23:46:10 +0300 Subject: [PATCH 22/28] BAEL - 2226 Test added --- .../ResourceControllerTest.java | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 spring-security-cors/src/test/java/com/baeldung/springbootsecuritycors/ResourceControllerTest.java diff --git a/spring-security-cors/src/test/java/com/baeldung/springbootsecuritycors/ResourceControllerTest.java b/spring-security-cors/src/test/java/com/baeldung/springbootsecuritycors/ResourceControllerTest.java new file mode 100644 index 0000000000..b45529ca5f --- /dev/null +++ b/spring-security-cors/src/test/java/com/baeldung/springbootsecuritycors/ResourceControllerTest.java @@ -0,0 +1,42 @@ +package com.baeldung.springbootsecuritycors; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.options; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; + +import com.baeldung.springbootsecuritycors.basicauth.SpringBootSecurityApplication; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = { SpringBootSecurityApplication.class }) +public class ResourceControllerTest { + + private MockMvc mockMvc; + + @Autowired + private WebApplicationContext wac; + + @Before + public void setUp() { + this.mockMvc = MockMvcBuilders.webAppContextSetup(wac) + .apply(SecurityMockMvcConfigurers.springSecurity()) + .build(); + } + + @Test + public void givenPreFlightRequest_whenPerfomed_shouldReturnOK() throws Exception { + mockMvc.perform(options("/user") + .header("Access-Control-Request-Method", "GET") + .header("Origin", "http://localhost:4200")) + .andExpect(status().isOk()); + } +} From f8f78afe85084da5b937fceaabff24e3ce1b26dd Mon Sep 17 00:00:00 2001 From: Ger Roza Date: Thu, 14 Feb 2019 11:54:35 -0200 Subject: [PATCH 23/28] Moved al HATEOAS related code from spring-rest-full module to spring-boot-rest --- spring-boot-rest/README.md | 2 ++ .../web/AbstractDiscoverabilityLiveTest.java | 6 ++-- .../web/FooDiscoverabilityLiveTest.java | 8 ++--- .../baeldung/web/LiveTestSuiteLiveTest.java | 2 ++ spring-rest-full/README.md | 2 -- .../web/controller/FooController.java | 2 -- .../web/controller/RootController.java | 20 ----------- .../event/SingleResourceRetrievedEvent.java | 22 ------------ ...ourceRetrievedDiscoverabilityListener.java | 34 ------------------ .../baeldung/web/LiveTestSuiteLiveTest.java | 3 +- .../baeldung/web/util/HTTPLinkHeaderUtil.java | 36 ------------------- 11 files changed, 12 insertions(+), 125 deletions(-) rename {spring-rest-full/src/test/java/org => spring-boot-rest/src/test/java/com}/baeldung/common/web/AbstractDiscoverabilityLiveTest.java (95%) rename {spring-rest-full/src/test/java/org => spring-boot-rest/src/test/java/com}/baeldung/web/FooDiscoverabilityLiveTest.java (83%) delete mode 100644 spring-rest-full/src/main/java/org/baeldung/web/hateoas/event/SingleResourceRetrievedEvent.java delete mode 100644 spring-rest-full/src/main/java/org/baeldung/web/hateoas/listener/SingleResourceRetrievedDiscoverabilityListener.java delete mode 100644 spring-rest-full/src/test/java/org/baeldung/web/util/HTTPLinkHeaderUtil.java diff --git a/spring-boot-rest/README.md b/spring-boot-rest/README.md index 15e80ec515..3fbd21f24e 100644 --- a/spring-boot-rest/README.md +++ b/spring-boot-rest/README.md @@ -4,3 +4,5 @@ Module for the articles that are part of the Spring REST E-book: 2. [Error Handling for REST with Spring](http://www.baeldung.com/exception-handling-for-rest-with-spring) 3. [REST Pagination in Spring](http://www.baeldung.com/rest-api-pagination-in-spring) 4. [Build a REST API with Spring and Java Config](http://www.baeldung.com/building-a-restful-web-service-with-spring-and-java-based-configuration) +5. [HATEOAS for a Spring REST Service](http://www.baeldung.com/rest-api-discoverability-with-spring) +6. [REST API Discoverability and HATEOAS](http://www.baeldung.com/restful-web-service-discoverability) diff --git a/spring-rest-full/src/test/java/org/baeldung/common/web/AbstractDiscoverabilityLiveTest.java b/spring-boot-rest/src/test/java/com/baeldung/common/web/AbstractDiscoverabilityLiveTest.java similarity index 95% rename from spring-rest-full/src/test/java/org/baeldung/common/web/AbstractDiscoverabilityLiveTest.java rename to spring-boot-rest/src/test/java/com/baeldung/common/web/AbstractDiscoverabilityLiveTest.java index 96d796349a..fc581f2631 100644 --- a/spring-rest-full/src/test/java/org/baeldung/common/web/AbstractDiscoverabilityLiveTest.java +++ b/spring-boot-rest/src/test/java/com/baeldung/common/web/AbstractDiscoverabilityLiveTest.java @@ -1,4 +1,4 @@ -package org.baeldung.common.web; +package com.baeldung.common.web; import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic; import static org.hamcrest.Matchers.containsString; @@ -8,8 +8,8 @@ import static org.junit.Assert.assertThat; import java.io.Serializable; -import org.baeldung.persistence.model.Foo; -import org.baeldung.web.util.HTTPLinkHeaderUtil; +import com.baeldung.persistence.model.Foo; +import com.baeldung.web.util.HTTPLinkHeaderUtil; import org.hamcrest.core.AnyOf; import org.junit.Test; import org.springframework.http.MediaType; diff --git a/spring-rest-full/src/test/java/org/baeldung/web/FooDiscoverabilityLiveTest.java b/spring-boot-rest/src/test/java/com/baeldung/web/FooDiscoverabilityLiveTest.java similarity index 83% rename from spring-rest-full/src/test/java/org/baeldung/web/FooDiscoverabilityLiveTest.java rename to spring-boot-rest/src/test/java/com/baeldung/web/FooDiscoverabilityLiveTest.java index a6577e4de8..0b98edaf03 100644 --- a/spring-rest-full/src/test/java/org/baeldung/web/FooDiscoverabilityLiveTest.java +++ b/spring-boot-rest/src/test/java/com/baeldung/web/FooDiscoverabilityLiveTest.java @@ -1,10 +1,10 @@ -package org.baeldung.web; +package com.baeldung.web; import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic; -import org.baeldung.common.web.AbstractDiscoverabilityLiveTest; -import org.baeldung.persistence.model.Foo; -import org.baeldung.spring.ConfigIntegrationTest; +import com.baeldung.common.web.AbstractDiscoverabilityLiveTest; +import com.baeldung.persistence.model.Foo; +import com.baeldung.spring.ConfigIntegrationTest; import org.junit.runner.RunWith; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.ContextConfiguration; diff --git a/spring-boot-rest/src/test/java/com/baeldung/web/LiveTestSuiteLiveTest.java b/spring-boot-rest/src/test/java/com/baeldung/web/LiveTestSuiteLiveTest.java index 1e2ddd5ec5..b7cceb9008 100644 --- a/spring-boot-rest/src/test/java/com/baeldung/web/LiveTestSuiteLiveTest.java +++ b/spring-boot-rest/src/test/java/com/baeldung/web/LiveTestSuiteLiveTest.java @@ -1,11 +1,13 @@ package com.baeldung.web; +import com.baeldung.web.FooDiscoverabilityLiveTest; import org.junit.runner.RunWith; import org.junit.runners.Suite; @RunWith(Suite.class) @Suite.SuiteClasses({ // @formatter:off + FooDiscoverabilityLiveTest.class, FooLiveTest.class ,FooPageableLiveTest.class }) // diff --git a/spring-rest-full/README.md b/spring-rest-full/README.md index 5140c4b270..b8b9034a0b 100644 --- a/spring-rest-full/README.md +++ b/spring-rest-full/README.md @@ -8,8 +8,6 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring The "Learn Spring Security" Classes: http://github.learnspringsecurity.com ### Relevant Articles: -- [HATEOAS for a Spring REST Service](http://www.baeldung.com/rest-api-discoverability-with-spring) -- [REST API Discoverability and HATEOAS](http://www.baeldung.com/restful-web-service-discoverability) - [ETags for REST with Spring](http://www.baeldung.com/etags-for-rest-with-spring) - [Integration Testing with the Maven Cargo plugin](http://www.baeldung.com/integration-testing-with-the-maven-cargo-plugin) - [Introduction to Spring Data JPA](http://www.baeldung.com/the-persistence-layer-with-spring-data-jpa) diff --git a/spring-rest-full/src/main/java/org/baeldung/web/controller/FooController.java b/spring-rest-full/src/main/java/org/baeldung/web/controller/FooController.java index 2e4dbcacc9..9cb028bfdb 100644 --- a/spring-rest-full/src/main/java/org/baeldung/web/controller/FooController.java +++ b/spring-rest-full/src/main/java/org/baeldung/web/controller/FooController.java @@ -7,7 +7,6 @@ import javax.servlet.http.HttpServletResponse; import org.baeldung.persistence.model.Foo; import org.baeldung.persistence.service.IFooService; import org.baeldung.web.hateoas.event.ResourceCreatedEvent; -import org.baeldung.web.hateoas.event.SingleResourceRetrievedEvent; import org.baeldung.web.util.RestPreconditions; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationEventPublisher; @@ -53,7 +52,6 @@ public class FooController { public Foo findById(@PathVariable("id") final Long id, final HttpServletResponse response) { final Foo resourceById = RestPreconditions.checkFound(service.findOne(id)); - eventPublisher.publishEvent(new SingleResourceRetrievedEvent(this, response)); return resourceById; } diff --git a/spring-rest-full/src/main/java/org/baeldung/web/controller/RootController.java b/spring-rest-full/src/main/java/org/baeldung/web/controller/RootController.java index e23da6420d..a66f3d1893 100644 --- a/spring-rest-full/src/main/java/org/baeldung/web/controller/RootController.java +++ b/spring-rest-full/src/main/java/org/baeldung/web/controller/RootController.java @@ -1,22 +1,14 @@ package org.baeldung.web.controller; -import java.net.URI; import java.util.Map; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - import org.baeldung.web.metric.IActuatorMetricService; import org.baeldung.web.metric.IMetricService; -import org.baeldung.web.util.LinkUtil; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; -import org.springframework.web.bind.annotation.ResponseStatus; -import org.springframework.web.util.UriTemplate; @Controller @RequestMapping(value = "/auth/") @@ -34,18 +26,6 @@ public class RootController { // API - // discover - - @RequestMapping(value = "admin", method = RequestMethod.GET) - @ResponseStatus(value = HttpStatus.NO_CONTENT) - public void adminRoot(final HttpServletRequest request, final HttpServletResponse response) { - final String rootUri = request.getRequestURL().toString(); - - final URI fooUri = new UriTemplate("{rootUri}/{resource}").expand(rootUri, "foo"); - final String linkToFoo = LinkUtil.createLinkHeader(fooUri.toASCIIString(), "collection"); - response.addHeader("Link", linkToFoo); - } - @RequestMapping(value = "/metric", method = RequestMethod.GET) @ResponseBody public Map getMetric() { diff --git a/spring-rest-full/src/main/java/org/baeldung/web/hateoas/event/SingleResourceRetrievedEvent.java b/spring-rest-full/src/main/java/org/baeldung/web/hateoas/event/SingleResourceRetrievedEvent.java deleted file mode 100644 index 0c9eb889e6..0000000000 --- a/spring-rest-full/src/main/java/org/baeldung/web/hateoas/event/SingleResourceRetrievedEvent.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.baeldung.web.hateoas.event; - -import javax.servlet.http.HttpServletResponse; - -import org.springframework.context.ApplicationEvent; - -public class SingleResourceRetrievedEvent extends ApplicationEvent { - private final HttpServletResponse response; - - public SingleResourceRetrievedEvent(final Object source, final HttpServletResponse response) { - super(source); - - this.response = response; - } - - // API - - public HttpServletResponse getResponse() { - return response; - } - -} \ No newline at end of file diff --git a/spring-rest-full/src/main/java/org/baeldung/web/hateoas/listener/SingleResourceRetrievedDiscoverabilityListener.java b/spring-rest-full/src/main/java/org/baeldung/web/hateoas/listener/SingleResourceRetrievedDiscoverabilityListener.java deleted file mode 100644 index 32407e9f2b..0000000000 --- a/spring-rest-full/src/main/java/org/baeldung/web/hateoas/listener/SingleResourceRetrievedDiscoverabilityListener.java +++ /dev/null @@ -1,34 +0,0 @@ -package org.baeldung.web.hateoas.listener; - -import javax.servlet.http.HttpServletResponse; - -import org.baeldung.web.hateoas.event.SingleResourceRetrievedEvent; -import org.baeldung.web.util.LinkUtil; -import org.springframework.context.ApplicationListener; -import org.springframework.stereotype.Component; -import org.springframework.web.servlet.support.ServletUriComponentsBuilder; - -import com.google.common.base.Preconditions; -import com.google.common.net.HttpHeaders; - -@Component -class SingleResourceRetrievedDiscoverabilityListener implements ApplicationListener { - - @Override - public void onApplicationEvent(final SingleResourceRetrievedEvent resourceRetrievedEvent) { - Preconditions.checkNotNull(resourceRetrievedEvent); - - final HttpServletResponse response = resourceRetrievedEvent.getResponse(); - addLinkHeaderOnSingleResourceRetrieval(response); - } - - void addLinkHeaderOnSingleResourceRetrieval(final HttpServletResponse response) { - final String requestURL = ServletUriComponentsBuilder.fromCurrentRequestUri().build().toUri().toASCIIString(); - final int positionOfLastSlash = requestURL.lastIndexOf("/"); - final String uriForResourceCreation = requestURL.substring(0, positionOfLastSlash); - - final String linkHeaderValue = LinkUtil.createLinkHeader(uriForResourceCreation, "collection"); - response.addHeader(HttpHeaders.LINK, linkHeaderValue); - } - -} \ No newline at end of file diff --git a/spring-rest-full/src/test/java/org/baeldung/web/LiveTestSuiteLiveTest.java b/spring-rest-full/src/test/java/org/baeldung/web/LiveTestSuiteLiveTest.java index da736392c4..663935e72f 100644 --- a/spring-rest-full/src/test/java/org/baeldung/web/LiveTestSuiteLiveTest.java +++ b/spring-rest-full/src/test/java/org/baeldung/web/LiveTestSuiteLiveTest.java @@ -6,8 +6,7 @@ import org.junit.runners.Suite; @RunWith(Suite.class) @Suite.SuiteClasses({ // @formatter:off - FooDiscoverabilityLiveTest.class - ,FooLiveTest.class + FooLiveTest.class }) // public class LiveTestSuiteLiveTest { diff --git a/spring-rest-full/src/test/java/org/baeldung/web/util/HTTPLinkHeaderUtil.java b/spring-rest-full/src/test/java/org/baeldung/web/util/HTTPLinkHeaderUtil.java deleted file mode 100644 index 29f1c91ca3..0000000000 --- a/spring-rest-full/src/test/java/org/baeldung/web/util/HTTPLinkHeaderUtil.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.baeldung.web.util; - -public final class HTTPLinkHeaderUtil { - - private HTTPLinkHeaderUtil() { - throw new AssertionError(); - } - - // - - public static String extractURIByRel(final String linkHeader, final String rel) { - if (linkHeader == null) { - return null; - } - - String uriWithSpecifiedRel = null; - final String[] links = linkHeader.split(", "); - String linkRelation; - for (final String link : links) { - final int positionOfSeparator = link.indexOf(';'); - linkRelation = link.substring(positionOfSeparator + 1, link.length()).trim(); - if (extractTypeOfRelation(linkRelation).equals(rel)) { - uriWithSpecifiedRel = link.substring(1, positionOfSeparator - 1); - break; - } - } - - return uriWithSpecifiedRel; - } - - private static Object extractTypeOfRelation(final String linkRelation) { - final int positionOfEquals = linkRelation.indexOf('='); - return linkRelation.substring(positionOfEquals + 2, linkRelation.length() - 1).trim(); - } - -} From f29191df67115dc488d8bb6f5e40ac6d30e29f03 Mon Sep 17 00:00:00 2001 From: cror <37755757+cror@users.noreply.github.com> Date: Fri, 15 Feb 2019 15:12:32 +0100 Subject: [PATCH 24/28] BAEL-2548 updated the test with toMap and binary operator (#6303) --- .../baeldung/collectors/Java8CollectorsUnitTest.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/core-java-8/src/test/java/com/baeldung/collectors/Java8CollectorsUnitTest.java b/core-java-8/src/test/java/com/baeldung/collectors/Java8CollectorsUnitTest.java index 9ace27e38f..e742635758 100644 --- a/core-java-8/src/test/java/com/baeldung/collectors/Java8CollectorsUnitTest.java +++ b/core-java-8/src/test/java/com/baeldung/collectors/Java8CollectorsUnitTest.java @@ -85,10 +85,16 @@ public class Java8CollectorsUnitTest { } @Test - public void whenCollectingToMap_shouldCollectToMapMerging() throws Exception { - final Map result = givenList.stream().collect(toMap(Function.identity(), String::length, (i1, i2) -> i1)); + public void whenCollectingToMapwWithDuplicates_shouldCollectToMapMergingTheIdenticalItems() throws Exception { + final Map result = listWithDuplicates.stream().collect( + toMap( + Function.identity(), + String::length, + (item, identicalItem) -> item + ) + ); - assertThat(result).containsEntry("a", 1).containsEntry("bb", 2).containsEntry("ccc", 3).containsEntry("dd", 2); + assertThat(result).containsEntry("a", 1).containsEntry("bb", 2).containsEntry("c", 1).containsEntry("d", 1); } @Test From dec56b6d0ff2be0f7ff95b2de5bce913ec6b07dd Mon Sep 17 00:00:00 2001 From: Ekaterina Galkina Date: Thu, 14 Feb 2019 15:46:06 +0500 Subject: [PATCH 25/28] BAEL-2502 --- .../dao/repositories/user/UserRepository.java | 3 +++ .../repositories/UserRepositoryCommon.java | 21 +++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/user/UserRepository.java b/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/user/UserRepository.java index c291f93e2c..7d6b076517 100644 --- a/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/user/UserRepository.java +++ b/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/user/UserRepository.java @@ -70,4 +70,7 @@ public interface UserRepository extends JpaRepository , UserRepos @Modifying @Query(value = "UPDATE Users u SET status = ? WHERE u.name = ?", nativeQuery = true) int updateUserSetStatusForNameNativePostgres(Integer status, String name); + + @Query(value = "SELECT u FROM User u WHERE u.name IN :names") + List findUserByNameList(@Param("names") Collection names); } diff --git a/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/dao/repositories/UserRepositoryCommon.java b/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/dao/repositories/UserRepositoryCommon.java index 8c4e8073b7..55a453e48f 100644 --- a/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/dao/repositories/UserRepositoryCommon.java +++ b/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/dao/repositories/UserRepositoryCommon.java @@ -12,6 +12,7 @@ import org.springframework.data.jpa.domain.JpaSort; import org.springframework.data.mapping.PropertyReferenceException; import org.springframework.transaction.annotation.Transactional; +import java.util.Arrays; import java.util.Collection; import java.util.HashSet; import java.util.List; @@ -364,6 +365,26 @@ class UserRepositoryCommon { assertThat(usersWithEmails.size()).isEqualTo(2); } + @Test + public void givenUsersInDBWhenFindByNameListReturnCollection() { + + User user1 = new User(); + user1.setName(USER_NAME_ADAM); + user1.setEmail(USER_EMAIL); + userRepository.save(user1); + + User user2 = new User(); + user2.setName(USER_NAME_PETER); + user2.setEmail(USER_EMAIL2); + userRepository.save(user2); + + List names = Arrays.asList(USER_NAME_ADAM, USER_NAME_PETER); + + List usersWithNames = userRepository.findUserByNameList(names); + + assertThat(usersWithNames.size()).isEqualTo(2); + } + @After public void cleanUp() { userRepository.deleteAll(); From 8e60ff6b5de145368b8c3f8352d077be7b53acfb Mon Sep 17 00:00:00 2001 From: Eugen Date: Fri, 15 Feb 2019 23:15:28 +0200 Subject: [PATCH 26/28] Update README.md --- persistence-modules/spring-jpa/README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/persistence-modules/spring-jpa/README.md b/persistence-modules/spring-jpa/README.md index e6f91ac016..23c03d3bef 100644 --- a/persistence-modules/spring-jpa/README.md +++ b/persistence-modules/spring-jpa/README.md @@ -4,8 +4,8 @@ ### Relevant Articles: -- [Spring 3 and JPA with Hibernate](http://www.baeldung.com/2011/12/13/the-persistence-layer-with-spring-3-1-and-jpa/) -- [Transactions with Spring 3 and JPA](http://www.baeldung.com/2011/12/26/transaction-configuration-with-jpa-and-spring-3-1/) +- [A Guide to JPA with Spring](https://www.baeldung.com/the-persistence-layer-with-spring-and-jpa) +- [Transactions with Spring and JPA](https://www.baeldung.com/transaction-configuration-with-jpa-and-spring) - [The DAO with JPA and Spring](http://www.baeldung.com/spring-dao-jpa) - [JPA Pagination](http://www.baeldung.com/jpa-pagination) - [Sorting with JPA](http://www.baeldung.com/jpa-sort) @@ -21,6 +21,7 @@ - [Use Criteria Queries in a Spring Data Application](https://www.baeldung.com/spring-data-criteria-queries) - [Many-To-Many Relationship in JPA](https://www.baeldung.com/jpa-many-to-many) + ### Eclipse Config After importing the project into Eclipse, you may see the following error: "No persistence xml file found in project" From 91ac0588386b8f0ef730f636fa9eb07b56f93b15 Mon Sep 17 00:00:00 2001 From: Anshul Bansal Date: Sat, 16 Feb 2019 05:37:14 +0200 Subject: [PATCH 27/28] Bael 2726 introduction to traits in groovy (#6337) * BAEL-2726_Introduction_to_Traits_in_Groovy * BAEL-2726_Introduction_to_Traits_in_Groovy --- .../com/baeldung/traits/AnimalTrait.groovy | 8 ++ .../groovy/com/baeldung/traits/Dog.groovy | 9 ++ .../com/baeldung/traits/Employee.groovy | 12 ++ .../groovy/com/baeldung/traits/Human.groovy | 6 + .../com/baeldung/traits/SpeakingTrait.groovy | 13 ++ .../com/baeldung/traits/UserTrait.groovy | 36 ++++++ .../com/baeldung/traits/WalkingTrait.groovy | 13 ++ .../com/baeldung/traits/TraitsUnitTest.groovy | 114 ++++++++++++++++++ 8 files changed, 211 insertions(+) create mode 100644 core-groovy/src/main/groovy/com/baeldung/traits/AnimalTrait.groovy create mode 100644 core-groovy/src/main/groovy/com/baeldung/traits/Dog.groovy create mode 100644 core-groovy/src/main/groovy/com/baeldung/traits/Employee.groovy create mode 100644 core-groovy/src/main/groovy/com/baeldung/traits/Human.groovy create mode 100644 core-groovy/src/main/groovy/com/baeldung/traits/SpeakingTrait.groovy create mode 100644 core-groovy/src/main/groovy/com/baeldung/traits/UserTrait.groovy create mode 100644 core-groovy/src/main/groovy/com/baeldung/traits/WalkingTrait.groovy create mode 100644 core-groovy/src/test/groovy/com/baeldung/traits/TraitsUnitTest.groovy diff --git a/core-groovy/src/main/groovy/com/baeldung/traits/AnimalTrait.groovy b/core-groovy/src/main/groovy/com/baeldung/traits/AnimalTrait.groovy new file mode 100644 index 0000000000..6ec5cda571 --- /dev/null +++ b/core-groovy/src/main/groovy/com/baeldung/traits/AnimalTrait.groovy @@ -0,0 +1,8 @@ +package com.baeldung.traits + +trait AnimalTrait { + + String basicBehavior() { + return "Animalistic!!" + } +} \ No newline at end of file diff --git a/core-groovy/src/main/groovy/com/baeldung/traits/Dog.groovy b/core-groovy/src/main/groovy/com/baeldung/traits/Dog.groovy new file mode 100644 index 0000000000..3e0677ba18 --- /dev/null +++ b/core-groovy/src/main/groovy/com/baeldung/traits/Dog.groovy @@ -0,0 +1,9 @@ +package com.baeldung.traits + +class Dog implements WalkingTrait, SpeakingTrait { + + String speakAndWalk() { + WalkingTrait.super.speakAndWalk() + } + +} \ No newline at end of file diff --git a/core-groovy/src/main/groovy/com/baeldung/traits/Employee.groovy b/core-groovy/src/main/groovy/com/baeldung/traits/Employee.groovy new file mode 100644 index 0000000000..b3e4285476 --- /dev/null +++ b/core-groovy/src/main/groovy/com/baeldung/traits/Employee.groovy @@ -0,0 +1,12 @@ +package com.baeldung.traits + +class Employee implements UserTrait { + + String name() { + return 'Bob' + } + + String lastName() { + return "Marley" + } +} \ No newline at end of file diff --git a/core-groovy/src/main/groovy/com/baeldung/traits/Human.groovy b/core-groovy/src/main/groovy/com/baeldung/traits/Human.groovy new file mode 100644 index 0000000000..e78d59bbfd --- /dev/null +++ b/core-groovy/src/main/groovy/com/baeldung/traits/Human.groovy @@ -0,0 +1,6 @@ +package com.baeldung.traits + +interface Human { + + String lastName() +} \ No newline at end of file diff --git a/core-groovy/src/main/groovy/com/baeldung/traits/SpeakingTrait.groovy b/core-groovy/src/main/groovy/com/baeldung/traits/SpeakingTrait.groovy new file mode 100644 index 0000000000..f437a94bd9 --- /dev/null +++ b/core-groovy/src/main/groovy/com/baeldung/traits/SpeakingTrait.groovy @@ -0,0 +1,13 @@ +package com.baeldung.traits + +trait SpeakingTrait { + + String basicAbility() { + return "Speaking!!" + } + + String speakAndWalk() { + return "Speak and walk!!" + } + +} \ No newline at end of file diff --git a/core-groovy/src/main/groovy/com/baeldung/traits/UserTrait.groovy b/core-groovy/src/main/groovy/com/baeldung/traits/UserTrait.groovy new file mode 100644 index 0000000000..3f1e694f17 --- /dev/null +++ b/core-groovy/src/main/groovy/com/baeldung/traits/UserTrait.groovy @@ -0,0 +1,36 @@ +package com.baeldung.traits + +trait UserTrait implements Human { + + String sayHello() { + return "Hello!" + } + + abstract String name() + + String showName() { + return "Hello, ${name()}!" + } + + private String greetingMessage() { + return 'Hello, from a private method!' + } + + String greet() { + def msg = greetingMessage() + println msg + msg + } + + def whoAmI() { + return this + } + + String showLastName() { + return "Hello, ${lastName()}!" + } + + String email + String address +} + \ No newline at end of file diff --git a/core-groovy/src/main/groovy/com/baeldung/traits/WalkingTrait.groovy b/core-groovy/src/main/groovy/com/baeldung/traits/WalkingTrait.groovy new file mode 100644 index 0000000000..66cff8809f --- /dev/null +++ b/core-groovy/src/main/groovy/com/baeldung/traits/WalkingTrait.groovy @@ -0,0 +1,13 @@ +package com.baeldung.traits + +trait WalkingTrait { + + String basicAbility() { + return "Walking!!" + } + + String speakAndWalk() { + return "Walk and speak!!" + } + +} \ No newline at end of file diff --git a/core-groovy/src/test/groovy/com/baeldung/traits/TraitsUnitTest.groovy b/core-groovy/src/test/groovy/com/baeldung/traits/TraitsUnitTest.groovy new file mode 100644 index 0000000000..0c74a9be62 --- /dev/null +++ b/core-groovy/src/test/groovy/com/baeldung/traits/TraitsUnitTest.groovy @@ -0,0 +1,114 @@ +package com.baeldung.traits + +import spock.lang.Specification + +class TraitsUnitTest extends Specification { + + Employee employee + Dog dog + + void setup () { + employee = new Employee() + dog = new Dog() + } + + def 'Should return msg string when using Employee.sayHello method provided by UserTrait' () { + when: + def msg = employee.sayHello() + then: + msg + msg instanceof String + assert msg == "Hello!" + } + + def 'Should return displayMsg string when using Employee.showName method' () { + when: + def displayMsg = employee.showName() + then: + displayMsg + displayMsg instanceof String + assert displayMsg == "Hello, Bob!" + } + + def 'Should return greetMsg string when using Employee.greet method' () { + when: + def greetMsg = employee.greet() + then: + greetMsg + greetMsg instanceof String + assert greetMsg == "Hello, from a private method!" + } + + def 'Should return MissingMethodException when using Employee.greetingMessage method' () { + when: + def exception + try { + employee.greetingMessage() + }catch(Exception e) { + exception = e + } + + then: + exception + exception instanceof groovy.lang.MissingMethodException + assert exception.message == "No signature of method: com.baeldung.traits.Employee.greetingMessage()"+ + " is applicable for argument types: () values: []" + } + + def 'Should return employee instance when using Employee.whoAmI method' () { + when: + def emp = employee.whoAmI() + then: + emp + emp instanceof Employee + assert emp.is(employee) + } + + def 'Should display lastName when using Employee.showLastName method' () { + when: + def lastNameMsg = employee.showLastName() + then: + lastNameMsg + lastNameMsg instanceof String + assert lastNameMsg == "Hello, Marley!" + } + + def 'Should be able to define properties of UserTrait in Employee instance' () { + when: + employee = new Employee(email: "a@e.com", address: "baeldung.com") + then: + employee + employee instanceof Employee + assert employee.email == "a@e.com" + assert employee.address == "baeldung.com" + } + + def 'Should execute basicAbility method from SpeakingTrait and return msg string' () { + when: + def speakMsg = dog.basicAbility() + then: + speakMsg + speakMsg instanceof String + assert speakMsg == "Speaking!!" + } + + def 'Should verify multiple inheritance with traits and execute overridden traits method' () { + when: + def walkSpeakMsg = dog.speakAndWalk() + println walkSpeakMsg + then: + walkSpeakMsg + walkSpeakMsg instanceof String + assert walkSpeakMsg == "Walk and speak!!" + } + + def 'Should implement AnimalTrait at runtime and access basicBehavior method' () { + when: + def dogInstance = new Dog() as AnimalTrait + def basicBehaviorMsg = dogInstance.basicBehavior() + then: + basicBehaviorMsg + basicBehaviorMsg instanceof String + assert basicBehaviorMsg == "Animalistic!!" + } +} \ No newline at end of file From 033bc8bd5a9c094792e3a20a48af8d40fb81a730 Mon Sep 17 00:00:00 2001 From: Andrey Shcherbakov Date: Sat, 16 Feb 2019 23:23:08 +0100 Subject: [PATCH 28/28] Create snippets for BAEL-2574 (#6344) --- spring-boot-mvc/pom.xml | 161 +++++++++--------- .../java/com/baeldung/accessparamsjs/App.java | 1 - .../baeldung/accessparamsjs/Controller.java | 4 +- .../src/main/resources/application.properties | 3 +- .../resources/templates/thymeleaf/index.html | 29 ++++ .../src/main/webapp/WEB-INF/jsp/index.jsp | 27 --- .../accessparamsjs/ControllerUnitTest.java | 3 +- 7 files changed, 118 insertions(+), 110 deletions(-) create mode 100644 spring-boot-mvc/src/main/resources/templates/thymeleaf/index.html delete mode 100644 spring-boot-mvc/src/main/webapp/WEB-INF/jsp/index.jsp diff --git a/spring-boot-mvc/pom.xml b/spring-boot-mvc/pom.xml index 89fa6bb04d..e17c1d39b9 100644 --- a/spring-boot-mvc/pom.xml +++ b/spring-boot-mvc/pom.xml @@ -1,66 +1,77 @@ - - 4.0.0 - spring-boot-mvc - spring-boot-mvc - jar - Module For Spring Boot MVC + + 4.0.0 + spring-boot-mvc + spring-boot-mvc + jar + Module For Spring Boot MVC - - parent-boot-2 - com.baeldung - 0.0.1-SNAPSHOT - ../parent-boot-2 - + + parent-boot-2 + com.baeldung + 0.0.1-SNAPSHOT + ../parent-boot-2 + - + - - org.springframework.boot - spring-boot-starter-web - - - org.apache.tomcat.embed - tomcat-embed-jasper - + + org.springframework.boot + spring-boot-starter-web + + + org.apache.tomcat.embed + tomcat-embed-jasper + + + org.springframework.boot + spring-boot-starter-tomcat + provided + + + org.springframework.boot + spring-boot-starter-thymeleaf + - - - org.glassfish - javax.faces - 2.3.7 - - - - org.springframework.boot - spring-boot-starter-test - test - + + + org.glassfish + javax.faces + 2.3.7 + - - - com.rometools - rome - ${rome.version} - + + + org.springframework.boot + spring-boot-starter-test + test + - - - org.hibernate.validator - hibernate-validator - - - javax.validation - validation-api - - - org.springframework.boot - spring-boot-starter-validation - + + + com.rometools + rome + ${rome.version} + - + + + org.hibernate.validator + hibernate-validator + + + javax.validation + validation-api + + + org.springframework.boot + spring-boot-starter-validation + + + io.springfox springfox-swagger2 @@ -77,31 +88,27 @@ tomcat-embed-jasper provided - - javax.servlet - jstl - - + - - - - org.springframework.boot - spring-boot-maven-plugin - - com.baeldung.springbootmvc.SpringBootMvcApplication - JAR - - - - + + + + org.springframework.boot + spring-boot-maven-plugin + + com.baeldung.springbootmvc.SpringBootMvcApplication + JAR + + + + - - 2.9.2 - - 1.10.0 - com.baeldung.springbootmvc.SpringBootMvcApplication - + + 2.9.2 + + 1.10.0 + com.baeldung.springbootmvc.SpringBootMvcApplication + diff --git a/spring-boot-mvc/src/main/java/com/baeldung/accessparamsjs/App.java b/spring-boot-mvc/src/main/java/com/baeldung/accessparamsjs/App.java index 2ffbb354c3..c16e784dd2 100644 --- a/spring-boot-mvc/src/main/java/com/baeldung/accessparamsjs/App.java +++ b/spring-boot-mvc/src/main/java/com/baeldung/accessparamsjs/App.java @@ -9,5 +9,4 @@ public class App { public static void main(String[] args) { SpringApplication.run(App.class, args); } - } diff --git a/spring-boot-mvc/src/main/java/com/baeldung/accessparamsjs/Controller.java b/spring-boot-mvc/src/main/java/com/baeldung/accessparamsjs/Controller.java index cc838eb6a5..8759f1bcd6 100644 --- a/spring-boot-mvc/src/main/java/com/baeldung/accessparamsjs/Controller.java +++ b/spring-boot-mvc/src/main/java/com/baeldung/accessparamsjs/Controller.java @@ -23,10 +23,10 @@ public class Controller { * @return */ @RequestMapping("/index") - public ModelAndView index(Map model) { + public ModelAndView thymeleafView(Map model) { model.put("number", 1234); model.put("message", "Hello from Spring MVC"); - return new ModelAndView("/index"); + return new ModelAndView("thymeleaf/index"); } } diff --git a/spring-boot-mvc/src/main/resources/application.properties b/spring-boot-mvc/src/main/resources/application.properties index 00362e2588..6dab470c84 100644 --- a/spring-boot-mvc/src/main/resources/application.properties +++ b/spring-boot-mvc/src/main/resources/application.properties @@ -1,3 +1,2 @@ spring.main.allow-bean-definition-overriding=true -spring.mvc.view.prefix=/WEB-INF/jsp/ -spring.mvc.view.suffix=.jsp \ No newline at end of file +spring.thymeleaf.view-names=thymeleaf/* \ No newline at end of file diff --git a/spring-boot-mvc/src/main/resources/templates/thymeleaf/index.html b/spring-boot-mvc/src/main/resources/templates/thymeleaf/index.html new file mode 100644 index 0000000000..4939d0ea50 --- /dev/null +++ b/spring-boot-mvc/src/main/resources/templates/thymeleaf/index.html @@ -0,0 +1,29 @@ + + + +Access Spring MVC params + + + + + + + Number= + +
Message= + +

Data from the external JS file (due to loading order)

+
+
+

Asynchronous loading from external JS file (plain JS)

+
+
+

Asynchronous loading from external JS file (jQuery)

+
+
+ + + diff --git a/spring-boot-mvc/src/main/webapp/WEB-INF/jsp/index.jsp b/spring-boot-mvc/src/main/webapp/WEB-INF/jsp/index.jsp deleted file mode 100644 index d9f3966e82..0000000000 --- a/spring-boot-mvc/src/main/webapp/WEB-INF/jsp/index.jsp +++ /dev/null @@ -1,27 +0,0 @@ - -<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> - - -Access Spring MVC params - - - - - - -

Data from the external JS file (due to loading order)

-
-
-

Asynchronous loading from external JS file (plain JS)

-
-
-

Asynchronous loading from external JS file (jQuery)

-
-
- - - - \ No newline at end of file diff --git a/spring-boot-mvc/src/test/java/com/baeldung/accessparamsjs/ControllerUnitTest.java b/spring-boot-mvc/src/test/java/com/baeldung/accessparamsjs/ControllerUnitTest.java index 31f6c89ffe..2dc62a20f6 100644 --- a/spring-boot-mvc/src/test/java/com/baeldung/accessparamsjs/ControllerUnitTest.java +++ b/spring-boot-mvc/src/test/java/com/baeldung/accessparamsjs/ControllerUnitTest.java @@ -20,9 +20,10 @@ public class ControllerUnitTest { private MockMvc mvc; @Test - public void whenRequestIndex_thenStatusOk() throws Exception { + public void whenRequestThymeleaf_thenStatusOk() throws Exception { mvc.perform(MockMvcRequestBuilders.get("/index") .accept(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()); } + }