From ff3574933872d8577463dc604035c89ddf6d5160 Mon Sep 17 00:00:00 2001 From: felipe-gdr Date: Fri, 16 Dec 2016 05:26:52 -0200 Subject: [PATCH 01/10] BAEL-127: @PreFilter and @PostFilter annotations (#898) * BAEL-127: simple app with filters * removed data rest dependency, final adjustments * added first live test for the rest api * move filters code to new module * moved to root of module, create service layer, standard pom --- spring-security-core/.gitignore | 13 ++ spring-security-core/README.md | 7 + spring-security-core/pom.xml | 168 ++++++++++++++++++ .../src/main/java/org/baeldung/app/App.java | 17 ++ .../org/baeldung/config/DatabaseLoader.java | 23 +++ .../baeldung/config/WebSecurityConfig.java | 39 ++++ .../baeldung/controller/TaskController.java | 32 ++++ .../main/java/org/baeldung/entity/Task.java | 46 +++++ .../baeldung/repository/TaskRepository.java | 8 + .../org/baeldung/service/TaskService.java | 26 +++ .../test/java/org/baeldung/test/LiveTest.java | 75 ++++++++ .../src/test/resources/.gitignore | 13 ++ 12 files changed, 467 insertions(+) create mode 100644 spring-security-core/.gitignore create mode 100644 spring-security-core/README.md create mode 100644 spring-security-core/pom.xml create mode 100644 spring-security-core/src/main/java/org/baeldung/app/App.java create mode 100644 spring-security-core/src/main/java/org/baeldung/config/DatabaseLoader.java create mode 100644 spring-security-core/src/main/java/org/baeldung/config/WebSecurityConfig.java create mode 100644 spring-security-core/src/main/java/org/baeldung/controller/TaskController.java create mode 100644 spring-security-core/src/main/java/org/baeldung/entity/Task.java create mode 100644 spring-security-core/src/main/java/org/baeldung/repository/TaskRepository.java create mode 100644 spring-security-core/src/main/java/org/baeldung/service/TaskService.java create mode 100644 spring-security-core/src/test/java/org/baeldung/test/LiveTest.java create mode 100644 spring-security-core/src/test/resources/.gitignore diff --git a/spring-security-core/.gitignore b/spring-security-core/.gitignore new file mode 100644 index 0000000000..83c05e60c8 --- /dev/null +++ b/spring-security-core/.gitignore @@ -0,0 +1,13 @@ +*.class + +#folders# +/target +/neoDb* +/data +/src/main/webapp/WEB-INF/classes +*/META-INF/* + +# Packaged files # +*.jar +*.war +*.ear \ No newline at end of file diff --git a/spring-security-core/README.md b/spring-security-core/README.md new file mode 100644 index 0000000000..c7e0f645c7 --- /dev/null +++ b/spring-security-core/README.md @@ -0,0 +1,7 @@ +## @PreFilter and @PostFilter annotations + +### Build the Project ### + +``` +mvn clean install +``` diff --git a/spring-security-core/pom.xml b/spring-security-core/pom.xml new file mode 100644 index 0000000000..519ee73296 --- /dev/null +++ b/spring-security-core/pom.xml @@ -0,0 +1,168 @@ + + 4.0.0 + com.baeldung + spring-security-core + 0.1-SNAPSHOT + + spring-security-core + war + + + org.springframework.boot + spring-boot-starter-parent + 1.4.2.RELEASE + + + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.springframework.boot + spring-boot-devtools + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.boot + spring-boot-starter-thymeleaf + + + com.h2database + h2 + runtime + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.security + spring-security-test + + + + + + spring-security-core + + + src/main/resources + true + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + true + source + + + + + org.apache.maven.plugins + maven-war-plugin + + + + org.apache.maven.plugins + maven-surefire-plugin + + + **/*LiveTest.java + **/*ManualTest.java + + + + + + + + + + + + + + live + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + integration-test + + test + + + + none + + + **/*LiveTest.java + + + cargo + + + + + + + + + + + + + 4.3.4.RELEASE + 4.2.0.RELEASE + + + 4.4.5 + 4.5.2 + + + 1.7.21 + 1.1.7 + + + 5.3.3.Final + 1.2 + 3.1.0 + 2.8.5 + + + 19.0 + 3.5 + + + 1.3 + 4.12 + 1.10.19 + + 2.9.0 + + + 3.6.0 + 2.6 + 2.19.1 + 1.6.1 + + + diff --git a/spring-security-core/src/main/java/org/baeldung/app/App.java b/spring-security-core/src/main/java/org/baeldung/app/App.java new file mode 100644 index 0000000000..06c295fcd7 --- /dev/null +++ b/spring-security-core/src/main/java/org/baeldung/app/App.java @@ -0,0 +1,17 @@ +package org.baeldung.app; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; + +@SpringBootApplication +@EnableJpaRepositories("org.baeldung.repository") +@ComponentScan("org.baeldung") +@EntityScan("org.baeldung.entity") +public class App { + public static void main(String[] args) { + SpringApplication.run(App.class, args); + } +} diff --git a/spring-security-core/src/main/java/org/baeldung/config/DatabaseLoader.java b/spring-security-core/src/main/java/org/baeldung/config/DatabaseLoader.java new file mode 100644 index 0000000000..e311f62fff --- /dev/null +++ b/spring-security-core/src/main/java/org/baeldung/config/DatabaseLoader.java @@ -0,0 +1,23 @@ +package org.baeldung.config; + +import org.baeldung.entity.Task; +import org.baeldung.repository.TaskRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.stereotype.Component; + +@Component +public class DatabaseLoader implements CommandLineRunner { + + @Autowired + private TaskRepository taskRepository; + + @Override + public void run(String... strings) throws Exception { + this.taskRepository.save(new Task("Send a fax", "pam")); + this.taskRepository.save(new Task("Print a document", "pam")); + this.taskRepository.save(new Task("Answer the phone", "pam")); + this.taskRepository.save(new Task("Call a client", "jim")); + this.taskRepository.save(new Task("Organize a meeting", "michael")); + } +} \ No newline at end of file diff --git a/spring-security-core/src/main/java/org/baeldung/config/WebSecurityConfig.java b/spring-security-core/src/main/java/org/baeldung/config/WebSecurityConfig.java new file mode 100644 index 0000000000..02e60d29a2 --- /dev/null +++ b/spring-security-core/src/main/java/org/baeldung/config/WebSecurityConfig.java @@ -0,0 +1,39 @@ +package org.baeldung.config; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +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 +@EnableGlobalMethodSecurity(prePostEnabled = true) +public class WebSecurityConfig extends WebSecurityConfigurerAdapter { + + @Override + protected void configure(HttpSecurity http) throws Exception { + http + .authorizeRequests() + .antMatchers("/css/**", "/js/**", "/loggedout").permitAll() + .anyRequest().authenticated() + .and() + .httpBasic() + .and() + .logout().disable() + .csrf().disable(); + } + + @Autowired + public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { + auth + .inMemoryAuthentication() + .withUser("jim").password("jim").roles("USER") + .and() + .withUser("pam").password("pam").roles("USER") + .and() + .withUser("michael").password("michael").roles("MANAGER"); + } +} diff --git a/spring-security-core/src/main/java/org/baeldung/controller/TaskController.java b/spring-security-core/src/main/java/org/baeldung/controller/TaskController.java new file mode 100644 index 0000000000..d99109c543 --- /dev/null +++ b/spring-security-core/src/main/java/org/baeldung/controller/TaskController.java @@ -0,0 +1,32 @@ +package org.baeldung.controller; + +import org.baeldung.entity.Task; +import org.baeldung.service.TaskService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; + +@Controller +@RequestMapping("api/tasks") +public class TaskController { + + @Autowired + private TaskService taskService; + + @RequestMapping(method = RequestMethod.GET) + public ResponseEntity> findAllTasks() { + Iterable tasks = taskService.findAll(); + + return ResponseEntity.ok().body(tasks); + } + + @RequestMapping(method = RequestMethod.POST, consumes = "application/json") + public ResponseEntity> addTasks(@RequestBody Iterable newTasks) { + Iterable tasks = taskService.save(newTasks); + + return ResponseEntity.ok().body(tasks); + } +} diff --git a/spring-security-core/src/main/java/org/baeldung/entity/Task.java b/spring-security-core/src/main/java/org/baeldung/entity/Task.java new file mode 100644 index 0000000000..5d3321ef2e --- /dev/null +++ b/spring-security-core/src/main/java/org/baeldung/entity/Task.java @@ -0,0 +1,46 @@ +package org.baeldung.entity; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; + +@Entity +public class Task { + private @Id @GeneratedValue Long id; + private String description; + + private String assignee; + + public Task() { + } + + public Task(String description, String assignee) { + this.description = description; + this.assignee = assignee; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getAssignee() { + return assignee; + } + + public void setAssignee(String assignee) { + this.assignee = assignee; + } + +} diff --git a/spring-security-core/src/main/java/org/baeldung/repository/TaskRepository.java b/spring-security-core/src/main/java/org/baeldung/repository/TaskRepository.java new file mode 100644 index 0000000000..651b11684f --- /dev/null +++ b/spring-security-core/src/main/java/org/baeldung/repository/TaskRepository.java @@ -0,0 +1,8 @@ +package org.baeldung.repository; + +import org.baeldung.entity.Task; +import org.springframework.data.repository.CrudRepository; + +public interface TaskRepository extends CrudRepository { + +} diff --git a/spring-security-core/src/main/java/org/baeldung/service/TaskService.java b/spring-security-core/src/main/java/org/baeldung/service/TaskService.java new file mode 100644 index 0000000000..4a0dae3aac --- /dev/null +++ b/spring-security-core/src/main/java/org/baeldung/service/TaskService.java @@ -0,0 +1,26 @@ +package org.baeldung.service; + +import org.baeldung.entity.Task; +import org.baeldung.repository.TaskRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PostFilter; +import org.springframework.security.access.prepost.PreFilter; +import org.springframework.stereotype.Service; + +@Service +public class TaskService { + + @Autowired + private TaskRepository taskRepository; + + @PostFilter("hasRole('MANAGER') or filterObject.assignee == authentication.name") + public Iterable findAll() { + return taskRepository.findAll(); + } + + @PreFilter("hasRole('MANAGER') or filterObject.assignee == authentication.name") + public Iterable save(Iterable entities) { + return taskRepository.save(entities); + } + +} diff --git a/spring-security-core/src/test/java/org/baeldung/test/LiveTest.java b/spring-security-core/src/test/java/org/baeldung/test/LiveTest.java new file mode 100644 index 0000000000..596476d058 --- /dev/null +++ b/spring-security-core/src/test/java/org/baeldung/test/LiveTest.java @@ -0,0 +1,75 @@ +package org.baeldung.test; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import org.baeldung.app.App; +import org.junit.Before; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.MethodSorters; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; + +@RunWith(SpringJUnit4ClassRunner.class) +@SpringBootTest(classes = App.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class LiveTest { + + @Autowired + private WebApplicationContext context; + private MockMvc mockMvc; + + @Before + public void setUp() { + mockMvc = MockMvcBuilders.webAppContextSetup(context).dispatchOptions(true).build(); + } + + @Test + @WithMockUser(roles = "MANAGER") + public void givenUserIsManager_whenGetTasks_thenAllTasks() throws Exception { + String allTasks = "[{'id':1,'description':'Send a fax','assignee':'pam'}," + + "{'id':2,'description':'Print a document','assignee':'pam'}," + + "{'id':3,'description':'Answer the phone','assignee':'pam'}," + + "{'id':4,'description':'Call a client','assignee':'jim'}," + + "{'id':5,'description':'Organize a meeting','assignee':'michael'}]"; + + mockMvc.perform(get("/api/tasks")).andExpect(status().isOk()).andExpect(content().json(allTasks)); + } + + @Test + @WithMockUser(username = "jim") + public void givenUserNotManager_whenGetTasks_thenReturnAssignedToMe() throws Exception { + String myTasks = "[{'id':4,'description':'Call a client','assignee':'jim'}]"; + + mockMvc.perform(get("/api/tasks")).andExpect(status().isOk()).andExpect(content().json(myTasks)); + } + + @Test + @WithMockUser(roles = "MANAGER") + public void givenUserIsManager_whenPostTasks_thenIncludeAllTasks() throws Exception { + String newTasks = "[{\"description\":\"New to Michael\",\"assignee\":\"michael\"}," + + "{\"description\":\"New to Pam\",\"assignee\":\"pam\"}]"; + + mockMvc.perform(post("/api/tasks").contentType(MediaType.APPLICATION_JSON).content(newTasks)).andExpect(status().isOk()).andExpect(content().json("[{'id': 6,'description':'New to Michael','assignee':'michael'}, {'id': 7,'description':'New to Pam','assignee':'pam'}]")); + } + + @Test + @WithMockUser(username = "jim") + public void givenUserNotManager_whenPostTasks_thenIncludeOnlyAssignedToMe() throws Exception { + String newTasks = "[{\"description\":\"New to Jim\",\"assignee\":\"jim\"}," + + "{\"description\":\"New to Pam\",\"assignee\":\"pam\"}]"; + + mockMvc.perform(post("/api/tasks").contentType(MediaType.APPLICATION_JSON).content(newTasks)).andExpect(status().isOk()).andExpect(content().json("[{'id': 8,'description':'New to Jim','assignee':'jim'}]")); + } + +} diff --git a/spring-security-core/src/test/resources/.gitignore b/spring-security-core/src/test/resources/.gitignore new file mode 100644 index 0000000000..83c05e60c8 --- /dev/null +++ b/spring-security-core/src/test/resources/.gitignore @@ -0,0 +1,13 @@ +*.class + +#folders# +/target +/neoDb* +/data +/src/main/webapp/WEB-INF/classes +*/META-INF/* + +# Packaged files # +*.jar +*.war +*.ear \ No newline at end of file From e93714999e4343fefe9c599df6fc92f4c1ab615d Mon Sep 17 00:00:00 2001 From: Marek Lewandowski Date: Fri, 16 Dec 2016 09:58:13 +0100 Subject: [PATCH 02/10] Rename to spring-mvc-simple --- {spring-mvc-handlers => spring-mvc-simple}/pom.xml | 8 ++++---- .../controller/AnnotationMethodHandlerAdapterExample.java | 0 .../controller/RequestMappingHandlerAdapterExample.java | 0 .../controller/SimpleControllerHandlerAdapterExample.java | 0 .../spring-servlet_AnnotationMethodHandlerAdapter.xml | 0 .../spring-servlet_RequestMappingHandlerAdapter.xml | 0 .../spring-servlet_SimpleControllerHandlerAdapter.xml | 0 .../src/main/webapp/WEB-INF/Greeting.jsp | 0 .../src/main/webapp/WEB-INF/web.xml | 0 9 files changed, 4 insertions(+), 4 deletions(-) rename {spring-mvc-handlers => spring-mvc-simple}/pom.xml (92%) rename {spring-mvc-handlers => spring-mvc-simple}/src/main/java/com/baeldung/spring/controller/AnnotationMethodHandlerAdapterExample.java (100%) rename {spring-mvc-handlers => spring-mvc-simple}/src/main/java/com/baeldung/spring/controller/RequestMappingHandlerAdapterExample.java (100%) rename {spring-mvc-handlers => spring-mvc-simple}/src/main/java/com/baeldung/spring/controller/SimpleControllerHandlerAdapterExample.java (100%) rename {spring-mvc-handlers => spring-mvc-simple}/src/main/resources/spring-servlet_AnnotationMethodHandlerAdapter.xml (100%) rename {spring-mvc-handlers => spring-mvc-simple}/src/main/resources/spring-servlet_RequestMappingHandlerAdapter.xml (100%) rename {spring-mvc-handlers => spring-mvc-simple}/src/main/resources/spring-servlet_SimpleControllerHandlerAdapter.xml (100%) rename {spring-mvc-handlers => spring-mvc-simple}/src/main/webapp/WEB-INF/Greeting.jsp (100%) rename {spring-mvc-handlers => spring-mvc-simple}/src/main/webapp/WEB-INF/web.xml (100%) diff --git a/spring-mvc-handlers/pom.xml b/spring-mvc-simple/pom.xml similarity index 92% rename from spring-mvc-handlers/pom.xml rename to spring-mvc-simple/pom.xml index 0074898767..4ab5bd9d1e 100644 --- a/spring-mvc-handlers/pom.xml +++ b/spring-mvc-simple/pom.xml @@ -2,10 +2,10 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 com.baeldung - SpringMVCHandlers + spring-mvc-simple war 0.0.1-SNAPSHOT - SpringMVCHandlers Maven Webapp + Spring MVC simple Maven Webapp http://maven.apache.org @@ -59,12 +59,12 @@ ${maven-war-plugin.version} src/main/webapp - springMVCHandlers + springMvcSimple false - springMVCHandlers + springMvcSimple diff --git a/spring-mvc-handlers/src/main/java/com/baeldung/spring/controller/AnnotationMethodHandlerAdapterExample.java b/spring-mvc-simple/src/main/java/com/baeldung/spring/controller/AnnotationMethodHandlerAdapterExample.java similarity index 100% rename from spring-mvc-handlers/src/main/java/com/baeldung/spring/controller/AnnotationMethodHandlerAdapterExample.java rename to spring-mvc-simple/src/main/java/com/baeldung/spring/controller/AnnotationMethodHandlerAdapterExample.java diff --git a/spring-mvc-handlers/src/main/java/com/baeldung/spring/controller/RequestMappingHandlerAdapterExample.java b/spring-mvc-simple/src/main/java/com/baeldung/spring/controller/RequestMappingHandlerAdapterExample.java similarity index 100% rename from spring-mvc-handlers/src/main/java/com/baeldung/spring/controller/RequestMappingHandlerAdapterExample.java rename to spring-mvc-simple/src/main/java/com/baeldung/spring/controller/RequestMappingHandlerAdapterExample.java diff --git a/spring-mvc-handlers/src/main/java/com/baeldung/spring/controller/SimpleControllerHandlerAdapterExample.java b/spring-mvc-simple/src/main/java/com/baeldung/spring/controller/SimpleControllerHandlerAdapterExample.java similarity index 100% rename from spring-mvc-handlers/src/main/java/com/baeldung/spring/controller/SimpleControllerHandlerAdapterExample.java rename to spring-mvc-simple/src/main/java/com/baeldung/spring/controller/SimpleControllerHandlerAdapterExample.java diff --git a/spring-mvc-handlers/src/main/resources/spring-servlet_AnnotationMethodHandlerAdapter.xml b/spring-mvc-simple/src/main/resources/spring-servlet_AnnotationMethodHandlerAdapter.xml similarity index 100% rename from spring-mvc-handlers/src/main/resources/spring-servlet_AnnotationMethodHandlerAdapter.xml rename to spring-mvc-simple/src/main/resources/spring-servlet_AnnotationMethodHandlerAdapter.xml diff --git a/spring-mvc-handlers/src/main/resources/spring-servlet_RequestMappingHandlerAdapter.xml b/spring-mvc-simple/src/main/resources/spring-servlet_RequestMappingHandlerAdapter.xml similarity index 100% rename from spring-mvc-handlers/src/main/resources/spring-servlet_RequestMappingHandlerAdapter.xml rename to spring-mvc-simple/src/main/resources/spring-servlet_RequestMappingHandlerAdapter.xml diff --git a/spring-mvc-handlers/src/main/resources/spring-servlet_SimpleControllerHandlerAdapter.xml b/spring-mvc-simple/src/main/resources/spring-servlet_SimpleControllerHandlerAdapter.xml similarity index 100% rename from spring-mvc-handlers/src/main/resources/spring-servlet_SimpleControllerHandlerAdapter.xml rename to spring-mvc-simple/src/main/resources/spring-servlet_SimpleControllerHandlerAdapter.xml diff --git a/spring-mvc-handlers/src/main/webapp/WEB-INF/Greeting.jsp b/spring-mvc-simple/src/main/webapp/WEB-INF/Greeting.jsp similarity index 100% rename from spring-mvc-handlers/src/main/webapp/WEB-INF/Greeting.jsp rename to spring-mvc-simple/src/main/webapp/WEB-INF/Greeting.jsp diff --git a/spring-mvc-handlers/src/main/webapp/WEB-INF/web.xml b/spring-mvc-simple/src/main/webapp/WEB-INF/web.xml similarity index 100% rename from spring-mvc-handlers/src/main/webapp/WEB-INF/web.xml rename to spring-mvc-simple/src/main/webapp/WEB-INF/web.xml From 0087a4ab3b694d8f43686d926dd8bf9147c9bd2c Mon Sep 17 00:00:00 2001 From: Marek Lewandowski Date: Fri, 16 Dec 2016 09:58:23 +0100 Subject: [PATCH 03/10] Add spring-mvc-simple as a module --- pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/pom.xml b/pom.xml index 1dde581d13..211c3b2c4d 100644 --- a/pom.xml +++ b/pom.xml @@ -117,6 +117,7 @@ spring-mvc-velocity spring-mvc-web-vs-initializer spring-mvc-xml + spring-mvc-simple spring-openid spring-protobuf spring-quartz From 8844871e2bd38f035f05a1808c404f368ab02661 Mon Sep 17 00:00:00 2001 From: maibin Date: Fri, 16 Dec 2016 10:14:48 +0100 Subject: [PATCH 04/10] @Async and SecurityContext (#872) * @Async and Spring Security * @Async with SecurityContext propagated * Spring and @Async * Simulated Annealing algorithm * Rebase * Rebase --- .../algorithms/SimulatedAnnealingTest.java | 13 +++++ .../baeldung/spring/SecurityJavaConfig.java | 33 ++++++++---- .../web/controller/AsyncController.java | 13 +++++ .../baeldung/web/service/AsyncService.java | 11 ++++ .../web/service/AsyncServiceImpl.java | 36 +++++++++++++ .../src/main/resources/webSecurityConfig.xml | 51 +++++++++++-------- 6 files changed, 126 insertions(+), 31 deletions(-) create mode 100644 core-java/src/test/java/com/baeldung/algorithms/SimulatedAnnealingTest.java create mode 100644 spring-security-rest/src/main/java/org/baeldung/web/service/AsyncService.java create mode 100644 spring-security-rest/src/main/java/org/baeldung/web/service/AsyncServiceImpl.java diff --git a/core-java/src/test/java/com/baeldung/algorithms/SimulatedAnnealingTest.java b/core-java/src/test/java/com/baeldung/algorithms/SimulatedAnnealingTest.java new file mode 100644 index 0000000000..06b599dede --- /dev/null +++ b/core-java/src/test/java/com/baeldung/algorithms/SimulatedAnnealingTest.java @@ -0,0 +1,13 @@ +package com.baeldung.algorithms; + +import org.junit.Assert; +import org.junit.Test; + +public class SimulatedAnnealingTest { + + @Test + public void testSimulateAnnealing() { + Assert.assertTrue(SimulatedAnnealing.simulateAnnealing(10, 1000, 0.9) > 0); + } + +} diff --git a/spring-security-rest/src/main/java/org/baeldung/spring/SecurityJavaConfig.java b/spring-security-rest/src/main/java/org/baeldung/spring/SecurityJavaConfig.java index 3302482f48..448968a6c8 100644 --- a/spring-security-rest/src/main/java/org/baeldung/spring/SecurityJavaConfig.java +++ b/spring-security-rest/src/main/java/org/baeldung/spring/SecurityJavaConfig.java @@ -1,8 +1,7 @@ package org.baeldung.spring; import org.baeldung.security.MySavedRequestAwareAuthenticationSuccessHandler; -import org.baeldung.security.RestAuthenticationEntryPoint; -import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.MethodInvokingFactoryBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @@ -10,6 +9,7 @@ import org.springframework.security.config.annotation.authentication.builders.Au 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; +import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler; @Configuration @@ -17,11 +17,11 @@ import org.springframework.security.web.authentication.SimpleUrlAuthenticationFa @ComponentScan("org.baeldung.security") public class SecurityJavaConfig extends WebSecurityConfigurerAdapter { - @Autowired - private RestAuthenticationEntryPoint restAuthenticationEntryPoint; +// @Autowired +// private RestAuthenticationEntryPoint restAuthenticationEntryPoint; - @Autowired - private MySavedRequestAwareAuthenticationSuccessHandler authenticationSuccessHandler; +// @Autowired +// private MySavedRequestAwareAuthenticationSuccessHandler authenticationSuccessHandler; public SecurityJavaConfig() { super(); @@ -38,17 +38,21 @@ public class SecurityJavaConfig extends WebSecurityConfigurerAdapter { protected void configure(final HttpSecurity http) throws Exception {// @formatter:off http .csrf().disable() + .authorizeRequests() + .and() .exceptionHandling() - .authenticationEntryPoint(restAuthenticationEntryPoint) +// .authenticationEntryPoint(restAuthenticationEntryPoint) .and() .authorizeRequests() .antMatchers("/api/csrfAttacker*").permitAll() .antMatchers("/api/customer/**").permitAll() .antMatchers("/api/foos/**").authenticated() + .antMatchers("/api/async/**").authenticated() .and() - .formLogin() - .successHandler(authenticationSuccessHandler) - .failureHandler(new SimpleUrlAuthenticationFailureHandler()) + .httpBasic() +// .and() +// .successHandler(authenticationSuccessHandler) +// .failureHandler(new SimpleUrlAuthenticationFailureHandler()) .and() .logout(); } // @formatter:on @@ -62,5 +66,14 @@ public class SecurityJavaConfig extends WebSecurityConfigurerAdapter { public SimpleUrlAuthenticationFailureHandler myFailureHandler() { return new SimpleUrlAuthenticationFailureHandler(); } + + @Bean + public MethodInvokingFactoryBean methodInvokingFactoryBean() { + MethodInvokingFactoryBean methodInvokingFactoryBean = new MethodInvokingFactoryBean(); + methodInvokingFactoryBean.setTargetClass(SecurityContextHolder.class); + methodInvokingFactoryBean.setTargetMethod("setStrategyName"); + methodInvokingFactoryBean.setArguments(new String[]{SecurityContextHolder.MODE_INHERITABLETHREADLOCAL}); + return methodInvokingFactoryBean; + } } \ No newline at end of file diff --git a/spring-security-rest/src/main/java/org/baeldung/web/controller/AsyncController.java b/spring-security-rest/src/main/java/org/baeldung/web/controller/AsyncController.java index bc59b4226a..9e78a62eed 100644 --- a/spring-security-rest/src/main/java/org/baeldung/web/controller/AsyncController.java +++ b/spring-security-rest/src/main/java/org/baeldung/web/controller/AsyncController.java @@ -2,13 +2,20 @@ package org.baeldung.web.controller; import java.util.concurrent.Callable; +import org.baeldung.web.service.AsyncService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.context.SecurityContextHolder; 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.multipart.MultipartFile; @Controller public class AsyncController { + + @Autowired + private AsyncService asyncService; @RequestMapping(method = RequestMethod.POST, value = "/upload") public Callable processUpload(final MultipartFile file) { @@ -20,5 +27,11 @@ public class AsyncController { } }; } + + @RequestMapping(method = RequestMethod.GET, value = "/async") + @ResponseBody + public Boolean checkIfContextPropagated() throws Exception{ + return asyncService.checkIfPrincipalPropagated().call() && asyncService.checkIfContextPropagated(SecurityContextHolder.getContext()); + } } diff --git a/spring-security-rest/src/main/java/org/baeldung/web/service/AsyncService.java b/spring-security-rest/src/main/java/org/baeldung/web/service/AsyncService.java new file mode 100644 index 0000000000..b7cf2b9f0c --- /dev/null +++ b/spring-security-rest/src/main/java/org/baeldung/web/service/AsyncService.java @@ -0,0 +1,11 @@ +package org.baeldung.web.service; + +import java.util.concurrent.Callable; + +public interface AsyncService { + + Callable checkIfPrincipalPropagated(); + + Boolean checkIfContextPropagated(Object context); + +} diff --git a/spring-security-rest/src/main/java/org/baeldung/web/service/AsyncServiceImpl.java b/spring-security-rest/src/main/java/org/baeldung/web/service/AsyncServiceImpl.java new file mode 100644 index 0000000000..51f8c5157b --- /dev/null +++ b/spring-security-rest/src/main/java/org/baeldung/web/service/AsyncServiceImpl.java @@ -0,0 +1,36 @@ +package org.baeldung.web.service; + +import java.util.concurrent.Callable; + +import org.apache.log4j.Logger; +import org.springframework.scheduling.annotation.Async; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.stereotype.Service; + +@Service +public class AsyncServiceImpl implements AsyncService { + + private static final Logger log = Logger.getLogger(AsyncService.class); + + @Override + public Callable checkIfPrincipalPropagated() { + Object before = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); + log.info("Before new thread: " + before); + return new Callable() { + public Boolean call() throws Exception { + Object after = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); + log.info("New thread: " + after); + return before == after; + } + }; + } + + @Async + @Override + public Boolean checkIfContextPropagated(Object context) { + log.info("Before @Async: " + context); + log.info("Inside @Async: " + SecurityContextHolder.getContext()); + return context == SecurityContextHolder.getContext(); + } + +} diff --git a/spring-security-rest/src/main/resources/webSecurityConfig.xml b/spring-security-rest/src/main/resources/webSecurityConfig.xml index cf8357633c..4172fe036f 100644 --- a/spring-security-rest/src/main/resources/webSecurityConfig.xml +++ b/spring-security-rest/src/main/resources/webSecurityConfig.xml @@ -1,33 +1,42 @@ - + http://www.springframework.org/schema/beans/spring-beans-4.2.xsd"> - - + + - + - + - - + + - - + + - - - - - - - - + + + + + + + + + + \ No newline at end of file From 2fe2e2a971a1e545f3e881f64a4b33e9e831464b Mon Sep 17 00:00:00 2001 From: Sunil Mogadati Date: Fri, 16 Dec 2016 11:29:32 -0700 Subject: [PATCH 05/10] BAEL-40: Add NDC and JBoss Logging to the demo application (#880) * Add NDC and JBoss Logging to the demo application * NDC for Log4j, Log4j2 and JBoss Logging * Simplify NDC example by making it a single operation instead of two * Make NDC example as RestController, Use JBoss Logging only as a logging bridge * Fix merge conflicts in pull request - log-mdc pom.xml updated --- log-mdc/pom.xml | 90 +++++++++++++++---- .../com/baeldung/config/AppConfiguration.java | 19 ++++ .../com/baeldung/config/AppInitializer.java | 29 ++++++ .../java/com/baeldung/ndc/Investment.java | 41 +++++++++ .../controller/JBossLoggingController.java | 42 +++++++++ .../ndc/controller/Log4J2Controller.java | 41 +++++++++ .../ndc/controller/Log4JController.java | 41 +++++++++ .../ndc/service/InvestmentService.java | 31 +++++++ .../JBossLoggingInvestmentService.java | 21 +++++ .../ndc/service/Log4J2InvestmentService.java | 22 +++++ .../ndc/service/Log4JInvestmentService.java | 21 +++++ log-mdc/src/main/resources/log4j.properties | 6 +- log-mdc/src/main/resources/log4j2.xml | 9 +- .../java/com/baeldung/ndc/NDCLogTest.java | 61 +++++++++++++ 14 files changed, 457 insertions(+), 17 deletions(-) create mode 100644 log-mdc/src/main/java/com/baeldung/config/AppConfiguration.java create mode 100644 log-mdc/src/main/java/com/baeldung/config/AppInitializer.java create mode 100644 log-mdc/src/main/java/com/baeldung/ndc/Investment.java create mode 100644 log-mdc/src/main/java/com/baeldung/ndc/controller/JBossLoggingController.java create mode 100644 log-mdc/src/main/java/com/baeldung/ndc/controller/Log4J2Controller.java create mode 100644 log-mdc/src/main/java/com/baeldung/ndc/controller/Log4JController.java create mode 100644 log-mdc/src/main/java/com/baeldung/ndc/service/InvestmentService.java create mode 100644 log-mdc/src/main/java/com/baeldung/ndc/service/JBossLoggingInvestmentService.java create mode 100644 log-mdc/src/main/java/com/baeldung/ndc/service/Log4J2InvestmentService.java create mode 100644 log-mdc/src/main/java/com/baeldung/ndc/service/Log4JInvestmentService.java create mode 100644 log-mdc/src/test/java/com/baeldung/ndc/NDCLogTest.java diff --git a/log-mdc/pom.xml b/log-mdc/pom.xml index 4cabce502e..28c8bb820e 100644 --- a/log-mdc/pom.xml +++ b/log-mdc/pom.xml @@ -5,20 +5,37 @@ logmdc 0.0.1-SNAPSHOT logmdc - tutorial on logging with MDC + war + tutorial on logging with MDC and NDC - - org.springframework - spring-context - ${springframework.version} - - - org.springframework - spring-webmvc - ${springframework.version} - + + org.springframework + spring-core + ${springframework.version} + + + org.springframework + spring-web + ${springframework.version} + + + org.springframework + spring-webmvc + ${springframework.version} + + + javax.servlet + javax.servlet-api + ${javax.servlet.version} + provided + + + com.fasterxml.jackson.core + jackson-databind + ${jackson.library} + @@ -31,12 +48,12 @@ org.apache.logging.log4j log4j-api - 2.7 + ${log4j2.version} org.apache.logging.log4j log4j-core - ${log4j-api.version} + ${log4j2.version} @@ -52,6 +69,13 @@ logback-classic ${logback.version} + + + + org.jboss.logging + jboss-logging + ${jbosslogging.version} + junit @@ -59,15 +83,51 @@ ${junit.version} test + + org.springframework + spring-test + ${springframework.version} + test + 4.3.4.RELEASE 1.2.17 - 2.7 + 2.7 3.3.6 1.1.7 + 3.3.0.Final + 3.1.0 + 2.8.5 4.12 - \ No newline at end of file + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.2 + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-war-plugin + 2.4 + + src/main/webapp + logging-service + false + + + + + logging-service + + diff --git a/log-mdc/src/main/java/com/baeldung/config/AppConfiguration.java b/log-mdc/src/main/java/com/baeldung/config/AppConfiguration.java new file mode 100644 index 0000000000..5e52c5f25e --- /dev/null +++ b/log-mdc/src/main/java/com/baeldung/config/AppConfiguration.java @@ -0,0 +1,19 @@ +package com.baeldung.config; + +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; + +@Configuration +@EnableWebMvc +@ComponentScan(basePackages = "com.baeldung") +public class AppConfiguration extends WebMvcConfigurerAdapter { + + @Override + public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { + configurer.enable(); + } + +} diff --git a/log-mdc/src/main/java/com/baeldung/config/AppInitializer.java b/log-mdc/src/main/java/com/baeldung/config/AppInitializer.java new file mode 100644 index 0000000000..828c2b2efa --- /dev/null +++ b/log-mdc/src/main/java/com/baeldung/config/AppInitializer.java @@ -0,0 +1,29 @@ +package com.baeldung.config; + +import javax.servlet.ServletContext; +import javax.servlet.ServletException; + +import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; + +public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { + + @Override + public void onStartup(ServletContext servletContext) throws ServletException { + super.onStartup(servletContext); + } + + @Override + protected Class[] getRootConfigClasses() { + return new Class[] { AppConfiguration.class }; + } + + @Override + protected Class[] getServletConfigClasses() { + return null; + } + + @Override + protected String[] getServletMappings() { + return new String[] { "/" }; + } +} diff --git a/log-mdc/src/main/java/com/baeldung/ndc/Investment.java b/log-mdc/src/main/java/com/baeldung/ndc/Investment.java new file mode 100644 index 0000000000..4275c6ef21 --- /dev/null +++ b/log-mdc/src/main/java/com/baeldung/ndc/Investment.java @@ -0,0 +1,41 @@ +package com.baeldung.ndc; + +public class Investment { + private String transactionId; + private String owner; + private Long amount; + + public Investment() { + } + + public Investment(String transactionId, String owner, Long amount) { + this.transactionId = transactionId; + this.owner = owner; + this.amount = amount; + } + + public String getTransactionId() { + return transactionId; + } + + public void setTransactionId(String transactionId) { + this.transactionId = transactionId; + } + + public String getOwner() { + return owner; + } + + public void setOwner(String owner) { + this.owner = owner; + } + + public Long getAmount() { + return amount; + } + + public void setAmount(Long amount) { + this.amount = amount; + } + +} diff --git a/log-mdc/src/main/java/com/baeldung/ndc/controller/JBossLoggingController.java b/log-mdc/src/main/java/com/baeldung/ndc/controller/JBossLoggingController.java new file mode 100644 index 0000000000..b024f3ec81 --- /dev/null +++ b/log-mdc/src/main/java/com/baeldung/ndc/controller/JBossLoggingController.java @@ -0,0 +1,42 @@ +package com.baeldung.ndc.controller; + +import org.jboss.logging.NDC; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; + +import com.baeldung.ndc.Investment; +import com.baeldung.ndc.service.InvestmentService; + + +@RestController +public class JBossLoggingController { + @Autowired + @Qualifier("JBossLoggingInvestmentService") + private InvestmentService jbossLoggingBusinessService; + + @RequestMapping(value = "/ndc/jboss-logging", method = RequestMethod.POST) + public ResponseEntity postPayment(@RequestBody Investment investment) { + // Add transactionId and owner to NDC + NDC.push("tx.id=" + investment.getTransactionId()); + NDC.push("tx.owner=" + investment.getOwner()); + + try { + jbossLoggingBusinessService.transfer(investment.getAmount()); + } finally { + // take out owner from the NDC stack + NDC.pop(); + + // take out transactionId from the NDC stack + NDC.pop(); + + NDC.clear(); + } + return new ResponseEntity(investment, HttpStatus.OK); + } +} \ No newline at end of file diff --git a/log-mdc/src/main/java/com/baeldung/ndc/controller/Log4J2Controller.java b/log-mdc/src/main/java/com/baeldung/ndc/controller/Log4J2Controller.java new file mode 100644 index 0000000000..9cc57d9fa7 --- /dev/null +++ b/log-mdc/src/main/java/com/baeldung/ndc/controller/Log4J2Controller.java @@ -0,0 +1,41 @@ +package com.baeldung.ndc.controller; + +import org.apache.logging.log4j.ThreadContext; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; + +import com.baeldung.ndc.Investment; +import com.baeldung.ndc.service.InvestmentService; + +@RestController +public class Log4J2Controller { + @Autowired + @Qualifier("log4j2InvestmentService") + private InvestmentService log4j2BusinessService; + + @RequestMapping(value = "/ndc/log4j2", method = RequestMethod.POST) + public ResponseEntity postPayment(@RequestBody Investment investment) { + // Add transactionId and owner to NDC + ThreadContext.push("tx.id=" + investment.getTransactionId()); + ThreadContext.push("tx.owner=" + investment.getOwner()); + + try { + log4j2BusinessService.transfer(investment.getAmount()); + } finally { + // take out owner from the NDC stack + ThreadContext.pop(); + + // take out transactionId from the NDC stack + ThreadContext.pop(); + + ThreadContext.clearAll(); + } + return new ResponseEntity(investment, HttpStatus.OK); + } +} \ No newline at end of file diff --git a/log-mdc/src/main/java/com/baeldung/ndc/controller/Log4JController.java b/log-mdc/src/main/java/com/baeldung/ndc/controller/Log4JController.java new file mode 100644 index 0000000000..daf7994a88 --- /dev/null +++ b/log-mdc/src/main/java/com/baeldung/ndc/controller/Log4JController.java @@ -0,0 +1,41 @@ +package com.baeldung.ndc.controller; + +import org.apache.log4j.NDC; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; + +import com.baeldung.ndc.Investment; +import com.baeldung.ndc.service.InvestmentService; + +@RestController +public class Log4JController { + @Autowired + @Qualifier("log4jInvestmentService") + private InvestmentService log4jBusinessService; + + @RequestMapping(value = "/ndc/log4j", method = RequestMethod.POST) + public ResponseEntity postPayment(@RequestBody Investment investment) { + // Add transactionId and owner to NDC + NDC.push("tx.id=" + investment.getTransactionId()); + NDC.push("tx.owner=" + investment.getOwner()); + + try { + log4jBusinessService.transfer(investment.getAmount()); + } finally { + // take out owner from the NDC stack + NDC.pop(); + + // take out transactionId from the NDC stack + NDC.pop(); + + NDC.remove(); + } + return new ResponseEntity(investment, HttpStatus.OK); + } +} \ No newline at end of file diff --git a/log-mdc/src/main/java/com/baeldung/ndc/service/InvestmentService.java b/log-mdc/src/main/java/com/baeldung/ndc/service/InvestmentService.java new file mode 100644 index 0000000000..13d8e6a71b --- /dev/null +++ b/log-mdc/src/main/java/com/baeldung/ndc/service/InvestmentService.java @@ -0,0 +1,31 @@ +package com.baeldung.ndc.service; + +/** + * A fake investment service. + */ +public interface InvestmentService { + + /** + * Sample service transferring a given amount of money. + * @param amount + * @return {@code true} when the transfer complete successfully, {@code false} otherwise. + */ + default public boolean transfer(long amount) { + beforeTransfer(amount); + // exchange messages with a remote system to transfer the money + try { + // let's pause randomly to properly simulate an actual system. + Thread.sleep((long) (500 + Math.random() * 500)); + } catch (InterruptedException e) { + // should never happen + } + // let's simulate both failing and successful transfers + boolean outcome = Math.random() >= 0.25; + afterTransfer(amount, outcome); + return outcome; + } + + void beforeTransfer(long amount); + + void afterTransfer(long amount, boolean outcome); +} diff --git a/log-mdc/src/main/java/com/baeldung/ndc/service/JBossLoggingInvestmentService.java b/log-mdc/src/main/java/com/baeldung/ndc/service/JBossLoggingInvestmentService.java new file mode 100644 index 0000000000..e1e5e0a083 --- /dev/null +++ b/log-mdc/src/main/java/com/baeldung/ndc/service/JBossLoggingInvestmentService.java @@ -0,0 +1,21 @@ +package com.baeldung.ndc.service; + +import org.jboss.logging.Logger; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Service; + +@Service +@Qualifier("JBossLoggingInvestmentService") +public class JBossLoggingInvestmentService implements InvestmentService { + private static final Logger logger = Logger.getLogger(JBossLoggingInvestmentService.class); + + @Override + public void beforeTransfer(long amount) { + logger.infov("Preparing to transfer {0}$.", amount); + } + + @Override + public void afterTransfer(long amount, boolean outcome) { + logger.infov("Has transfer of {0}$ completed successfully ? {1}.", amount, outcome); + } +} \ No newline at end of file diff --git a/log-mdc/src/main/java/com/baeldung/ndc/service/Log4J2InvestmentService.java b/log-mdc/src/main/java/com/baeldung/ndc/service/Log4J2InvestmentService.java new file mode 100644 index 0000000000..6e55796574 --- /dev/null +++ b/log-mdc/src/main/java/com/baeldung/ndc/service/Log4J2InvestmentService.java @@ -0,0 +1,22 @@ +package com.baeldung.ndc.service; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Service; + +@Service +@Qualifier("log4j2InvestmentService") +public class Log4J2InvestmentService implements InvestmentService { + private static final Logger logger = LogManager.getLogger(); + + @Override + public void beforeTransfer(long amount) { + logger.info("Preparing to transfer {}$.", amount); + } + + @Override + public void afterTransfer(long amount, boolean outcome) { + logger.info("Has transfer of {}$ completed successfully ? {}.", amount, outcome); + } +} \ No newline at end of file diff --git a/log-mdc/src/main/java/com/baeldung/ndc/service/Log4JInvestmentService.java b/log-mdc/src/main/java/com/baeldung/ndc/service/Log4JInvestmentService.java new file mode 100644 index 0000000000..1f581554e5 --- /dev/null +++ b/log-mdc/src/main/java/com/baeldung/ndc/service/Log4JInvestmentService.java @@ -0,0 +1,21 @@ +package com.baeldung.ndc.service; + +import org.apache.log4j.Logger; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Service; + +@Service +@Qualifier("log4jInvestmentService") +public class Log4JInvestmentService implements InvestmentService { + private Logger logger = Logger.getLogger(Log4JInvestmentService.class); + + @Override + public void beforeTransfer(long amount) { + logger.info("Preparing to transfer " + amount + "$."); + } + + @Override + public void afterTransfer(long amount, boolean outcome) { + logger.info("Has transfer of " + amount + "$ completed successfully ? " + outcome + "."); + } +} \ No newline at end of file diff --git a/log-mdc/src/main/resources/log4j.properties b/log-mdc/src/main/resources/log4j.properties index 39be027f3f..575ebcca8d 100644 --- a/log-mdc/src/main/resources/log4j.properties +++ b/log-mdc/src/main/resources/log4j.properties @@ -3,6 +3,10 @@ log4j.appender.consoleAppender.layout=org.apache.log4j.PatternLayout #note the %X{userName} - this is how you fetch data from Mapped Diagnostic Context (MDC) #log4j.appender.consoleAppender.layout.ConversionPattern=%-4r [%t] %5p %c{1} %x - %m%n +# %x is used to fetch data from NDC. So below setting uses both MDC and NDC log4j.appender.consoleAppender.layout.ConversionPattern=%-4r [%t] %5p %c{1} %x - %m - tx.id=%X{transaction.id} tx.owner=%X{transaction.owner}%n -log4j.rootLogger = TRACE, consoleAppender \ No newline at end of file +# NDC only setting - %x is used to fetch data from NDC +#log4j.appender.consoleAppender.layout.ConversionPattern=%-4r [%t] %5p %c{1} - %m - [%x]%n + +log4j.rootLogger = INFO, consoleAppender \ No newline at end of file diff --git a/log-mdc/src/main/resources/log4j2.xml b/log-mdc/src/main/resources/log4j2.xml index 800cfacafe..cbdf02fc51 100644 --- a/log-mdc/src/main/resources/log4j2.xml +++ b/log-mdc/src/main/resources/log4j2.xml @@ -2,8 +2,15 @@ + + pattern="%-4r [%t] %5p %c{1} - %m - %x - tx.id=%X{transaction.id} tx.owner=%X{transaction.owner}%n" /> + + + + diff --git a/log-mdc/src/test/java/com/baeldung/ndc/NDCLogTest.java b/log-mdc/src/test/java/com/baeldung/ndc/NDCLogTest.java new file mode 100644 index 0000000000..8cba176f7e --- /dev/null +++ b/log-mdc/src/test/java/com/baeldung/ndc/NDCLogTest.java @@ -0,0 +1,61 @@ +package com.baeldung.ndc; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +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.http.MediaType; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +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 com.baeldung.config.AppConfiguration; +import com.fasterxml.jackson.databind.ObjectMapper; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = AppConfiguration.class) +@WebAppConfiguration +public class NDCLogTest { + + private MockMvc mockMvc; + + @Autowired + private WebApplicationContext webApplicationContext; + + private Investment investment; + + @Before + public void setUp() { + mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build(); + + investment = new Investment(); + investment.setTransactionId("123"); + investment.setOwner("Mark"); + investment.setAmount(1000L); + } + + @Test + public void givenLog4jLogger_whenNDCAdded_thenResponseOkAndNDCInLog() throws Exception { + mockMvc.perform(post("/ndc/log4j", investment).contentType(MediaType.APPLICATION_JSON).content(new ObjectMapper().writeValueAsString(investment))).andExpect(status().is2xxSuccessful()); + + } + + @Test + public void givenLog4j2Logger_whenNDCAdded_thenResponseOkAndNDCInLog() throws Exception { + mockMvc.perform(post("/ndc/log4j2", investment).contentType(MediaType.APPLICATION_JSON).content(new ObjectMapper().writeValueAsString(investment))).andExpect(status().is2xxSuccessful()); + + } + + @Test + public void givenJBossLoggerBridge_whenNDCAdded_thenResponseOkAndNDCInLog() throws Exception { + mockMvc.perform(post("/ndc/jboss-logging", investment).contentType(MediaType.APPLICATION_JSON).content(new ObjectMapper().writeValueAsString(investment))).andExpect(status().is2xxSuccessful()); + + } + +} From 7f45d8f9c97949264852c68f7ebaac86a3aae4e0 Mon Sep 17 00:00:00 2001 From: maibin Date: Fri, 16 Dec 2016 21:10:54 +0100 Subject: [PATCH 06/10] Simulated Annealing algorithm (#900) * @Async and Spring Security * @Async with SecurityContext propagated * Spring and @Async * Simulated Annealing algorithm * Simulated Annealing algorithm * Rebase * Rebase --- core-java/pom.xml | 6 ++ .../java/com/baeldung/algorithms/City.java | 22 +++++++ .../algorithms/SimulatedAnnealing.java | 41 +++++++++++++ .../java/com/baeldung/algorithms/Travel.java | 60 +++++++++++++++++++ 4 files changed, 129 insertions(+) create mode 100644 core-java/src/main/java/com/baeldung/algorithms/City.java create mode 100644 core-java/src/main/java/com/baeldung/algorithms/SimulatedAnnealing.java create mode 100644 core-java/src/main/java/com/baeldung/algorithms/Travel.java diff --git a/core-java/pom.xml b/core-java/pom.xml index 0c14da2245..f5a800d508 100644 --- a/core-java/pom.xml +++ b/core-java/pom.xml @@ -85,6 +85,12 @@ log4j-over-slf4j ${org.slf4j.version} + + org.projectlombok + lombok + 1.16.12 + provided + diff --git a/core-java/src/main/java/com/baeldung/algorithms/City.java b/core-java/src/main/java/com/baeldung/algorithms/City.java new file mode 100644 index 0000000000..1a96dc759d --- /dev/null +++ b/core-java/src/main/java/com/baeldung/algorithms/City.java @@ -0,0 +1,22 @@ +package com.baeldung.algorithms; + +import lombok.Data; + +@Data +public class City { + + private int x; + private int y; + + public City() { + this.x = (int) (Math.random() * 500); + this.y = (int) (Math.random() * 500); + } + + public double distanceToCity(City city) { + int x = Math.abs(getX() - city.getX()); + int y = Math.abs(getY() - city.getY()); + return Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)); + } + +} diff --git a/core-java/src/main/java/com/baeldung/algorithms/SimulatedAnnealing.java b/core-java/src/main/java/com/baeldung/algorithms/SimulatedAnnealing.java new file mode 100644 index 0000000000..b62e861399 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/algorithms/SimulatedAnnealing.java @@ -0,0 +1,41 @@ +package com.baeldung.algorithms; + +public class SimulatedAnnealing { + + private static Travel travel = new Travel(10); + + public static double simulateAnnealing(double startingTemperature, int numberOfIterations, double coolingRate) { + System.out.println("Starting SA with temperature: " + startingTemperature + ", # of iterations: " + + numberOfIterations + " and colling rate: " + coolingRate); + double t = startingTemperature; + travel.generateInitialTravel(); + double bestDistance = travel.getDistance(); + System.out.println("Initial distance of travel: " + bestDistance); + Travel bestSolution = travel; + Travel currentSolution = bestSolution; + + for (int i = 0; i < numberOfIterations; i++) { + if (t > 0.1) { + currentSolution.swapCities(); + double currentDistance = currentSolution.getDistance(); + if (currentDistance == 0) + continue; + if (currentDistance < bestDistance) { + bestDistance = currentDistance; + } else if (Math.exp((currentDistance - bestDistance) / t) < Math.random()) { + currentSolution.revertSwap(); + } + t *= coolingRate; + } + if (i % 100 == 0) { + System.out.println("Iteration #" + i); + } + } + return bestDistance; + } + + public static void main(String[] args) { + System.out.println("Optimized distance for travel: " + simulateAnnealing(10, 10000, 0.9)); + } + +} diff --git a/core-java/src/main/java/com/baeldung/algorithms/Travel.java b/core-java/src/main/java/com/baeldung/algorithms/Travel.java new file mode 100644 index 0000000000..9921b2516e --- /dev/null +++ b/core-java/src/main/java/com/baeldung/algorithms/Travel.java @@ -0,0 +1,60 @@ +package com.baeldung.algorithms; + +import java.util.ArrayList; +import java.util.Collections; + +import lombok.Data; + +@Data +public class Travel { + + private ArrayList travel = new ArrayList<>(); + private ArrayList previousTravel = new ArrayList<>(); + + public Travel(int numberOfCities) { + for (int i = 0; i < numberOfCities; i++) { + travel.add(new City()); + } + } + + public void generateInitialTravel() { + if (travel.isEmpty()) + new Travel(10); + Collections.shuffle(travel); + } + + public void swapCities() { + int a = generateRandomIndex(); + int b = generateRandomIndex(); + previousTravel = travel; + travel.set(a, travel.get(b)); + } + + public void revertSwap() { + travel = previousTravel; + } + + private int generateRandomIndex() { + return (int) (Math.random() * travel.size()); + } + + public City getCity(int index) { + return travel.get(index); + } + + public int getDistance() { + int distance = 0; + for (int index = 0; index < travel.size(); index++) { + City starting = getCity(index); + City destination; + if (index + 1 < travel.size()) { + destination = getCity(index + 1); + } else { + destination = getCity(0); + } + distance += starting.distanceToCity(destination); + } + return distance; + } + +} From a2c022f4dd415a03841f5964f37214ddd8f40fb7 Mon Sep 17 00:00:00 2001 From: DOHA Date: Fri, 16 Dec 2016 23:01:10 +0200 Subject: [PATCH 07/10] create intelliJ formatter --- intelliJ/intelliJ-formatter.xml | 40 +++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 intelliJ/intelliJ-formatter.xml diff --git a/intelliJ/intelliJ-formatter.xml b/intelliJ/intelliJ-formatter.xml new file mode 100644 index 0000000000..c9aa35122b --- /dev/null +++ b/intelliJ/intelliJ-formatter.xml @@ -0,0 +1,40 @@ + + \ No newline at end of file From 5faf49eae2535df4c8560f98d64b3d487cc615a0 Mon Sep 17 00:00:00 2001 From: DOHA Date: Sat, 17 Dec 2016 01:42:47 +0200 Subject: [PATCH 08/10] fix intelliJ formatter --- intelliJ/intelliJ-formatter.xml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/intelliJ/intelliJ-formatter.xml b/intelliJ/intelliJ-formatter.xml index c9aa35122b..8c072cd161 100644 --- a/intelliJ/intelliJ-formatter.xml +++ b/intelliJ/intelliJ-formatter.xml @@ -4,6 +4,7 @@ + - - org.apache.maven.plugins - maven-dependency-plugin - - - copy-dependencies - prepare-package - - copy-dependencies - - - ${project.build.directory}/libs - - - - + + org.apache.maven.plugins + maven-dependency-plugin + + + copy-dependencies + prepare-package + + copy-dependencies + + + ${project.build.directory}/libs + + + + - - org.apache.maven.plugins - maven-jar-plugin - - - - true - libs/ - org.baeldung.executable.ExecutableMavenJar - - - - + + org.apache.maven.plugins + maven-jar-plugin + + + + true + libs/ + org.baeldung.executable.ExecutableMavenJar + + + + - - org.apache.maven.plugins - maven-assembly-plugin - - - package - - single - - - - - org.baeldung.executable.ExecutableMavenJar - - - - jar-with-dependencies - - - - - + + org.apache.maven.plugins + maven-assembly-plugin + + + package + + single + + + + + org.baeldung.executable.ExecutableMavenJar + + + + jar-with-dependencies + + + + + - - org.apache.maven.plugins - maven-shade-plugin - - - - shade - - - true - - - org.baeldung.executable.ExecutableMavenJar - - - - - - + + org.apache.maven.plugins + maven-shade-plugin + + + + shade + + + true + + + org.baeldung.executable.ExecutableMavenJar + + + + + + - - com.jolira - onejar-maven-plugin - - - - org.baeldung.executable.ExecutableMavenJar - true - ${project.build.finalName}-onejar.${project.packaging} - - - one-jar - - - - + + com.jolira + onejar-maven-plugin + + + + org.baeldung.executable.ExecutableMavenJar + true + ${project.build.finalName}-onejar.${project.packaging} + + + one-jar + + + + - - org.springframework.boot - spring-boot-maven-plugin - - - - repackage - - - spring-boot - org.baeldung.executable.ExecutableMavenJar - - - - - - + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + spring-boot + org.baeldung.executable.ExecutableMavenJar + + + + - - - + + + + + integration @@ -336,35 +342,35 @@ - - - 2.8.5 + + + 2.8.5 - - 1.7.21 - 1.1.7 + + 1.7.21 + 1.1.7 - - 19.0 - 3.5 - 1.55 - 1.10 - 3.6.1 - 2.5 - 4.1 - 4.01 + + 19.0 + 3.5 + 1.55 + 1.10 + 3.6.1 + 2.5 + 4.1 + 4.01 - - 1.3 - 4.12 - 1.10.19 - 6.10 - 3.6.1 + + 1.3 + 4.12 + 1.10.19 + 6.10 + 3.6.1 - - 3.6.0 - 2.19.1 + + 3.6.0 + 2.19.1 - + \ No newline at end of file diff --git a/core-java/src/main/java/com/baeldung/algorithms/City.java b/core-java/src/main/java/com/baeldung/algorithms/City.java index 1a96dc759d..32335cda80 100644 --- a/core-java/src/main/java/com/baeldung/algorithms/City.java +++ b/core-java/src/main/java/com/baeldung/algorithms/City.java @@ -5,18 +5,18 @@ import lombok.Data; @Data public class City { - private int x; - private int y; + private int x; + private int y; - public City() { - this.x = (int) (Math.random() * 500); - this.y = (int) (Math.random() * 500); - } + public City() { + this.x = (int) (Math.random() * 500); + this.y = (int) (Math.random() * 500); + } - public double distanceToCity(City city) { - int x = Math.abs(getX() - city.getX()); - int y = Math.abs(getY() - city.getY()); - return Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)); - } + public double distanceToCity(City city) { + int x = Math.abs(getX() - city.getX()); + int y = Math.abs(getY() - city.getY()); + return Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)); + } } diff --git a/core-java/src/main/java/com/baeldung/algorithms/SimulatedAnnealing.java b/core-java/src/main/java/com/baeldung/algorithms/SimulatedAnnealing.java index b62e861399..3ccba9b3e9 100644 --- a/core-java/src/main/java/com/baeldung/algorithms/SimulatedAnnealing.java +++ b/core-java/src/main/java/com/baeldung/algorithms/SimulatedAnnealing.java @@ -2,40 +2,39 @@ package com.baeldung.algorithms; public class SimulatedAnnealing { - private static Travel travel = new Travel(10); - - public static double simulateAnnealing(double startingTemperature, int numberOfIterations, double coolingRate) { - System.out.println("Starting SA with temperature: " + startingTemperature + ", # of iterations: " - + numberOfIterations + " and colling rate: " + coolingRate); - double t = startingTemperature; - travel.generateInitialTravel(); - double bestDistance = travel.getDistance(); - System.out.println("Initial distance of travel: " + bestDistance); - Travel bestSolution = travel; - Travel currentSolution = bestSolution; + private static Travel travel = new Travel(10); - for (int i = 0; i < numberOfIterations; i++) { - if (t > 0.1) { - currentSolution.swapCities(); - double currentDistance = currentSolution.getDistance(); - if (currentDistance == 0) - continue; - if (currentDistance < bestDistance) { - bestDistance = currentDistance; - } else if (Math.exp((currentDistance - bestDistance) / t) < Math.random()) { - currentSolution.revertSwap(); - } - t *= coolingRate; - } - if (i % 100 == 0) { - System.out.println("Iteration #" + i); - } - } - return bestDistance; - } + public static double simulateAnnealing(double startingTemperature, int numberOfIterations, double coolingRate) { + System.out.println("Starting SA with temperature: " + startingTemperature + ", # of iterations: " + numberOfIterations + " and colling rate: " + coolingRate); + double t = startingTemperature; + travel.generateInitialTravel(); + double bestDistance = travel.getDistance(); + System.out.println("Initial distance of travel: " + bestDistance); + Travel bestSolution = travel; + Travel currentSolution = bestSolution; - public static void main(String[] args) { - System.out.println("Optimized distance for travel: " + simulateAnnealing(10, 10000, 0.9)); - } + for (int i = 0; i < numberOfIterations; i++) { + if (t > 0.1) { + currentSolution.swapCities(); + double currentDistance = currentSolution.getDistance(); + if (currentDistance == 0) + continue; + if (currentDistance < bestDistance) { + bestDistance = currentDistance; + } else if (Math.exp((currentDistance - bestDistance) / t) < Math.random()) { + currentSolution.revertSwap(); + } + t *= coolingRate; + } + if (i % 100 == 0) { + System.out.println("Iteration #" + i); + } + } + return bestDistance; + } + + public static void main(String[] args) { + System.out.println("Optimized distance for travel: " + simulateAnnealing(10, 10000, 0.9)); + } } diff --git a/core-java/src/main/java/com/baeldung/algorithms/Travel.java b/core-java/src/main/java/com/baeldung/algorithms/Travel.java index 9921b2516e..6e6059b3eb 100644 --- a/core-java/src/main/java/com/baeldung/algorithms/Travel.java +++ b/core-java/src/main/java/com/baeldung/algorithms/Travel.java @@ -8,53 +8,53 @@ import lombok.Data; @Data public class Travel { - private ArrayList travel = new ArrayList<>(); - private ArrayList previousTravel = new ArrayList<>(); + private ArrayList travel = new ArrayList<>(); + private ArrayList previousTravel = new ArrayList<>(); - public Travel(int numberOfCities) { - for (int i = 0; i < numberOfCities; i++) { - travel.add(new City()); - } - } + public Travel(int numberOfCities) { + for (int i = 0; i < numberOfCities; i++) { + travel.add(new City()); + } + } - public void generateInitialTravel() { - if (travel.isEmpty()) - new Travel(10); - Collections.shuffle(travel); - } + public void generateInitialTravel() { + if (travel.isEmpty()) + new Travel(10); + Collections.shuffle(travel); + } - public void swapCities() { - int a = generateRandomIndex(); - int b = generateRandomIndex(); - previousTravel = travel; - travel.set(a, travel.get(b)); - } + public void swapCities() { + int a = generateRandomIndex(); + int b = generateRandomIndex(); + previousTravel = travel; + travel.set(a, travel.get(b)); + } - public void revertSwap() { - travel = previousTravel; - } + public void revertSwap() { + travel = previousTravel; + } - private int generateRandomIndex() { - return (int) (Math.random() * travel.size()); - } + private int generateRandomIndex() { + return (int) (Math.random() * travel.size()); + } - public City getCity(int index) { - return travel.get(index); - } + public City getCity(int index) { + return travel.get(index); + } - public int getDistance() { - int distance = 0; - for (int index = 0; index < travel.size(); index++) { - City starting = getCity(index); - City destination; - if (index + 1 < travel.size()) { - destination = getCity(index + 1); - } else { - destination = getCity(0); - } - distance += starting.distanceToCity(destination); - } - return distance; - } + public int getDistance() { + int distance = 0; + for (int index = 0; index < travel.size(); index++) { + City starting = getCity(index); + City destination; + if (index + 1 < travel.size()) { + destination = getCity(index + 1); + } else { + destination = getCity(0); + } + distance += starting.distanceToCity(destination); + } + return distance; + } } diff --git a/core-java/src/test/java/com/baeldung/algorithms/SimulatedAnnealingTest.java b/core-java/src/test/java/com/baeldung/algorithms/SimulatedAnnealingTest.java index 06b599dede..3fe3650041 100644 --- a/core-java/src/test/java/com/baeldung/algorithms/SimulatedAnnealingTest.java +++ b/core-java/src/test/java/com/baeldung/algorithms/SimulatedAnnealingTest.java @@ -5,9 +5,9 @@ import org.junit.Test; public class SimulatedAnnealingTest { - @Test - public void testSimulateAnnealing() { - Assert.assertTrue(SimulatedAnnealing.simulateAnnealing(10, 1000, 0.9) > 0); - } + @Test + public void testSimulateAnnealing() { + Assert.assertTrue(SimulatedAnnealing.simulateAnnealing(10, 1000, 0.9) > 0); + } } diff --git a/core-java/src/test/java/com/baeldung/encoderdecoder/EncoderDecoderUnitTest.java b/core-java/src/test/java/com/baeldung/encoderdecoder/EncoderDecoderUnitTest.java index 08f4e0b4bd..da615eef6f 100644 --- a/core-java/src/test/java/com/baeldung/encoderdecoder/EncoderDecoderUnitTest.java +++ b/core-java/src/test/java/com/baeldung/encoderdecoder/EncoderDecoderUnitTest.java @@ -22,7 +22,6 @@ public class EncoderDecoderUnitTest { private static final String testUrl = "http://www.baeldung.com?key1=value+1&key2=value%40%21%242&key3=value%253"; private static final String testUrlWithPath = "http://www.baeldung.com/path+1?key1=value+1&key2=value%40%21%242&key3=value%253"; - private String encodeValue(String value) { String encoded = null; try { @@ -59,9 +58,7 @@ public class EncoderDecoderUnitTest { requestParams.put("key2", "value@!$2"); requestParams.put("key3", "value%3"); - String encodedURL = requestParams.keySet().stream() - .map(key -> key + "=" + encodeValue(requestParams.get(key))) - .collect(joining("&", "http://www.baeldung.com?", "")); + String encodedURL = requestParams.keySet().stream().map(key -> key + "=" + encodeValue(requestParams.get(key))).collect(joining("&", "http://www.baeldung.com?", "")); Assert.assertThat(testUrl, is(encodedURL)); } @@ -103,12 +100,9 @@ public class EncoderDecoderUnitTest { String path = "path+1"; - String encodedURL = requestParams.keySet().stream() - .map(key -> key + "=" + encodeValue(requestParams.get(key))) - .collect(joining("&", "http://www.baeldung.com/" + encodePath(path) + "?", "")); + String encodedURL = requestParams.keySet().stream().map(key -> key + "=" + encodeValue(requestParams.get(key))).collect(joining("&", "http://www.baeldung.com/" + encodePath(path) + "?", "")); Assert.assertThat(testUrlWithPath, is(encodedURL)); } - } diff --git a/core-java/src/test/java/com/baeldung/java8/Java8CollectionCleanupUnitTest.java b/core-java/src/test/java/com/baeldung/java8/Java8CollectionCleanupUnitTest.java index 4b900c31a7..ef7b642f89 100644 --- a/core-java/src/test/java/com/baeldung/java8/Java8CollectionCleanupUnitTest.java +++ b/core-java/src/test/java/com/baeldung/java8/Java8CollectionCleanupUnitTest.java @@ -17,9 +17,7 @@ public class Java8CollectionCleanupUnitTest { @Test public void givenListContainsNulls_whenFilteringParallel_thenCorrect() { final List list = Lists.newArrayList(null, 1, 2, null, 3, null); - final List listWithoutNulls = list.parallelStream() - .filter(Objects::nonNull) - .collect(Collectors.toList()); + final List listWithoutNulls = list.parallelStream().filter(Objects::nonNull).collect(Collectors.toList()); assertThat(listWithoutNulls, hasSize(3)); } @@ -27,9 +25,7 @@ public class Java8CollectionCleanupUnitTest { @Test public void givenListContainsNulls_whenFilteringSerial_thenCorrect() { final List list = Lists.newArrayList(null, 1, 2, null, 3, null); - final List listWithoutNulls = list.stream() - .filter(Objects::nonNull) - .collect(Collectors.toList()); + final List listWithoutNulls = list.stream().filter(Objects::nonNull).collect(Collectors.toList()); assertThat(listWithoutNulls, hasSize(3)); } @@ -45,9 +41,7 @@ public class Java8CollectionCleanupUnitTest { @Test public void givenListContainsDuplicates_whenRemovingDuplicatesWithJava8_thenCorrect() { final List listWithDuplicates = Lists.newArrayList(1, 1, 2, 2, 3, 3); - final List listWithoutDuplicates = listWithDuplicates.parallelStream() - .distinct() - .collect(Collectors.toList()); + final List listWithoutDuplicates = listWithDuplicates.parallelStream().distinct().collect(Collectors.toList()); assertThat(listWithoutDuplicates, hasSize(3)); } diff --git a/core-java/src/test/java/com/baeldung/java8/JavaFileSizeUnitTest.java b/core-java/src/test/java/com/baeldung/java8/JavaFileSizeUnitTest.java index c4920c51f6..c640932d6f 100644 --- a/core-java/src/test/java/com/baeldung/java8/JavaFileSizeUnitTest.java +++ b/core-java/src/test/java/com/baeldung/java8/JavaFileSizeUnitTest.java @@ -18,13 +18,13 @@ public class JavaFileSizeUnitTest { @Before public void init() { final String separator = File.separator; - filePath = String.join(separator, new String[] {"src", "test", "resources", "testFolder", "sample_file_1.in"}); + filePath = String.join(separator, new String[] { "src", "test", "resources", "testFolder", "sample_file_1.in" }); } @Test public void whenGetFileSize_thenCorrect() { final File file = new File(filePath); - + final long size = getFileSize(file); assertEquals(EXPECTED_FILE_SIZE_IN_BYTES, size); @@ -34,16 +34,16 @@ public class JavaFileSizeUnitTest { public void whenGetFileSizeUsingNioApi_thenCorrect() throws IOException { final Path path = Paths.get(this.filePath); final FileChannel fileChannel = FileChannel.open(path); - + final long fileSize = fileChannel.size(); - + assertEquals(EXPECTED_FILE_SIZE_IN_BYTES, fileSize); } @Test public void whenGetFileSizeUsingApacheCommonsIO_thenCorrect() { final File file = new File(filePath); - + final long size = FileUtils.sizeOf(file); assertEquals(EXPECTED_FILE_SIZE_IN_BYTES, size); @@ -52,9 +52,9 @@ public class JavaFileSizeUnitTest { @Test public void whenGetReadableFileSize_thenCorrect() { final File file = new File(filePath); - + final long size = getFileSize(file); - + assertEquals(EXPECTED_FILE_SIZE_IN_BYTES + " bytes", FileUtils.byteCountToDisplaySize(size)); } diff --git a/core-java/src/test/java/com/baeldung/java8/optional/OptionalTest.java b/core-java/src/test/java/com/baeldung/java8/optional/OptionalTest.java index c0538931b0..bf2078186c 100644 --- a/core-java/src/test/java/com/baeldung/java8/optional/OptionalTest.java +++ b/core-java/src/test/java/com/baeldung/java8/optional/OptionalTest.java @@ -93,6 +93,7 @@ public class OptionalTest { boolean is2017 = yearOptional.filter(y -> y == 2017).isPresent(); assertFalse(is2017); } + @Test public void whenFiltersWithoutOptional_thenCorrect() { assertTrue(priceIsInRange1(new Modem(10.0))); @@ -121,12 +122,9 @@ public class OptionalTest { } public boolean priceIsInRange2(Modem modem2) { - return Optional.ofNullable(modem2) - .map(Modem::getPrice) - .filter(p -> p >= 10) - .filter(p -> p <= 15) - .isPresent(); + return Optional.ofNullable(modem2).map(Modem::getPrice).filter(p -> p >= 10).filter(p -> p <= 15).isPresent(); } + // Transforming Value With map() @Test public void givenOptional_whenMapWorks_thenCorrect() { diff --git a/core-java/src/test/java/com/baeldung/java8/unix/grep/GrepWithUnix4JTest.java b/core-java/src/test/java/com/baeldung/java8/unix/grep/GrepWithUnix4JTest.java index d6efdfdf5c..79ba2e0b17 100644 --- a/core-java/src/test/java/com/baeldung/java8/unix/grep/GrepWithUnix4JTest.java +++ b/core-java/src/test/java/com/baeldung/java8/unix/grep/GrepWithUnix4JTest.java @@ -13,46 +13,43 @@ import static org.unix4j.unix.Grep.*; import static org.unix4j.unix.cut.CutOption.*; public class GrepWithUnix4JTest { - - private File fileToGrep; + + private File fileToGrep; @Before public void init() { final String separator = File.separator; - final String filePath = String.join(separator, new String[] {"src", "test", "resources", "dictionary.in"}); + final String filePath = String.join(separator, new String[] { "src", "test", "resources", "dictionary.in" }); fileToGrep = new File(filePath); } - - @Test - public void whenGrepWithSimpleString_thenCorrect() { - int expectedLineCount = 4; - - //grep "NINETEEN" dictionary.txt - List lines = Unix4j.grep("NINETEEN", fileToGrep).toLineList(); - - assertEquals(expectedLineCount, lines.size()); - } - @Test - public void whenInverseGrepWithSimpleString_thenCorrect() { - int expectedLineCount = 178687; - - //grep -v "NINETEEN" dictionary.txt - List lines = grep(Options.v, "NINETEEN", fileToGrep). - toLineList(); - - assertEquals(expectedLineCount, lines.size()); - } + @Test + public void whenGrepWithSimpleString_thenCorrect() { + int expectedLineCount = 4; + // grep "NINETEEN" dictionary.txt + List lines = Unix4j.grep("NINETEEN", fileToGrep).toLineList(); - @Test - public void whenGrepWithRegex_thenCorrect() { - int expectedLineCount = 151; - - //grep -c ".*?NINE.*?" dictionary.txt - String patternCount = grep(Options.c, ".*?NINE.*?", fileToGrep). - cut(fields, ":", 1).toStringResult(); - - assertEquals(expectedLineCount, Integer.parseInt(patternCount)); - } + assertEquals(expectedLineCount, lines.size()); + } + + @Test + public void whenInverseGrepWithSimpleString_thenCorrect() { + int expectedLineCount = 178687; + + // grep -v "NINETEEN" dictionary.txt + List lines = grep(Options.v, "NINETEEN", fileToGrep).toLineList(); + + assertEquals(expectedLineCount, lines.size()); + } + + @Test + public void whenGrepWithRegex_thenCorrect() { + int expectedLineCount = 151; + + // grep -c ".*?NINE.*?" dictionary.txt + String patternCount = grep(Options.c, ".*?NINE.*?", fileToGrep).cut(fields, ":", 1).toStringResult(); + + assertEquals(expectedLineCount, Integer.parseInt(patternCount)); + } } diff --git a/core-java/src/test/java/org/baeldung/java/collections/JoinSplitCollectionsUnitTest.java b/core-java/src/test/java/org/baeldung/java/collections/JoinSplitCollectionsUnitTest.java index 16b3509925..c594529f41 100644 --- a/core-java/src/test/java/org/baeldung/java/collections/JoinSplitCollectionsUnitTest.java +++ b/core-java/src/test/java/org/baeldung/java/collections/JoinSplitCollectionsUnitTest.java @@ -15,8 +15,7 @@ public class JoinSplitCollectionsUnitTest { public void whenJoiningTwoArrays_thenJoined() { String[] animals1 = new String[] { "Dog", "Cat" }; String[] animals2 = new String[] { "Bird", "Cow" }; - String[] result = Stream.concat( - Arrays.stream(animals1), Arrays.stream(animals2)).toArray(String[]::new); + String[] result = Stream.concat(Arrays.stream(animals1), Arrays.stream(animals2)).toArray(String[]::new); assertArrayEquals(result, new String[] { "Dog", "Cat", "Bird", "Cow" }); } @@ -25,9 +24,7 @@ public class JoinSplitCollectionsUnitTest { public void whenJoiningTwoCollections_thenJoined() { Collection collection1 = Arrays.asList("Dog", "Cat"); Collection collection2 = Arrays.asList("Bird", "Cow", "Moose"); - Collection result = Stream.concat( - collection1.stream(), collection2.stream()) - .collect(Collectors.toList()); + Collection result = Stream.concat(collection1.stream(), collection2.stream()).collect(Collectors.toList()); assertTrue(result.equals(Arrays.asList("Dog", "Cat", "Bird", "Cow", "Moose"))); } @@ -36,10 +33,7 @@ public class JoinSplitCollectionsUnitTest { public void whenJoiningTwoCollectionsWithFilter_thenJoined() { Collection collection1 = Arrays.asList("Dog", "Cat"); Collection collection2 = Arrays.asList("Bird", "Cow", "Moose"); - Collection result = Stream.concat( - collection1.stream(), collection2.stream()) - .filter(e -> e.length() == 3) - .collect(Collectors.toList()); + Collection result = Stream.concat(collection1.stream(), collection2.stream()).filter(e -> e.length() == 3).collect(Collectors.toList()); assertTrue(result.equals(Arrays.asList("Dog", "Cat", "Cow"))); } @@ -67,9 +61,7 @@ public class JoinSplitCollectionsUnitTest { animals.put(2, "Cat"); animals.put(3, "Cow"); - String result = animals.entrySet().stream() - .map(entry -> entry.getKey() + " = " + entry.getValue()) - .collect(Collectors.joining(", ")); + String result = animals.entrySet().stream().map(entry -> entry.getKey() + " = " + entry.getValue()).collect(Collectors.joining(", ")); assertEquals(result, "1 = Dog, 2 = Cat, 3 = Cow"); } @@ -80,10 +72,7 @@ public class JoinSplitCollectionsUnitTest { nested.add(Arrays.asList("Dog", "Cat")); nested.add(Arrays.asList("Cow", "Pig")); - String result = nested.stream().map( - nextList -> nextList.stream() - .collect(Collectors.joining("-"))) - .collect(Collectors.joining("; ")); + String result = nested.stream().map(nextList -> nextList.stream().collect(Collectors.joining("-"))).collect(Collectors.joining("; ")); assertEquals(result, "Dog-Cat; Cow-Pig"); } @@ -91,17 +80,14 @@ public class JoinSplitCollectionsUnitTest { @Test public void whenConvertCollectionToStringAndSkipNull_thenConverted() { Collection animals = Arrays.asList("Dog", "Cat", null, "Moose"); - String result = animals.stream() - .filter(Objects::nonNull) - .collect(Collectors.joining(", ")); + String result = animals.stream().filter(Objects::nonNull).collect(Collectors.joining(", ")); assertEquals(result, "Dog, Cat, Moose"); } @Test public void whenSplitCollectionHalf_thenConverted() { - Collection animals = Arrays.asList( - "Dog", "Cat", "Cow", "Bird", "Moose", "Pig"); + Collection animals = Arrays.asList("Dog", "Cat", "Cow", "Bird", "Moose", "Pig"); Collection result1 = new ArrayList<>(); Collection result2 = new ArrayList<>(); AtomicInteger count = new AtomicInteger(); @@ -122,9 +108,8 @@ public class JoinSplitCollectionsUnitTest { @Test public void whenSplitArrayByWordLength_thenConverted() { - String[] animals = new String[] { "Dog", "Cat", "Bird", "Cow", "Pig", "Moose"}; - Map> result = Arrays.stream(animals) - .collect(Collectors.groupingBy(String::length)); + String[] animals = new String[] { "Dog", "Cat", "Bird", "Cow", "Pig", "Moose" }; + Map> result = Arrays.stream(animals).collect(Collectors.groupingBy(String::length)); assertTrue(result.get(3).equals(Arrays.asList("Dog", "Cat", "Cow", "Pig"))); assertTrue(result.get(4).equals(Arrays.asList("Bird"))); @@ -151,9 +136,7 @@ public class JoinSplitCollectionsUnitTest { public void whenConvertStringToMap_thenConverted() { String animals = "1 = Dog, 2 = Cat, 3 = Bird"; - Map result = Arrays.stream( - animals.split(", ")).map(next -> next.split(" = ")) - .collect(Collectors.toMap(entry -> Integer.parseInt(entry[0]), entry -> entry[1])); + Map result = Arrays.stream(animals.split(", ")).map(next -> next.split(" = ")).collect(Collectors.toMap(entry -> Integer.parseInt(entry[0]), entry -> entry[1])); assertEquals(result.get(1), "Dog"); assertEquals(result.get(2), "Cat"); @@ -164,10 +147,7 @@ public class JoinSplitCollectionsUnitTest { public void whenConvertCollectionToStringMultipleSeparators_thenConverted() { String animals = "Dog. , Cat, Bird. Cow"; - Collection result = Arrays.stream(animals.split("[,|.]")) - .map(String::trim) - .filter(next -> !next.isEmpty()) - .collect(Collectors.toList()); + Collection result = Arrays.stream(animals.split("[,|.]")).map(String::trim).filter(next -> !next.isEmpty()).collect(Collectors.toList()); assertTrue(result.equals(Arrays.asList("Dog", "Cat", "Bird", "Cow"))); }