From 4331871e09966b5521600c9076617c7ad465b4b9 Mon Sep 17 00:00:00 2001 From: Markus Gulden Date: Tue, 2 Jan 2018 15:21:09 +0100 Subject: [PATCH 01/58] BAEL-592 Guide to Hibernate 5 with Spring --- .../hibernate/bootstrap/BarHibernateDAO.java | 39 ++++++++++++ .../hibernate/bootstrap/HibernateConf.java | 61 +++++++++++++++++++ .../hibernate/bootstrap/HibernateXMLConf.java | 24 ++++++++ .../hibernate/bootstrap/model/TestEntity.java | 29 +++++++++ .../resources/hibernate5Configuration.xml | 30 +++++++++ .../main/resources/persistence-h2.properties | 1 + .../HibernateBootstrapIntegrationTest.java | 38 ++++++++++++ .../HibernateXMLBootstrapIntegrationTest.java | 36 +++++++++++ 8 files changed, 258 insertions(+) create mode 100644 persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/bootstrap/BarHibernateDAO.java create mode 100644 persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/bootstrap/HibernateConf.java create mode 100644 persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/bootstrap/HibernateXMLConf.java create mode 100644 persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/bootstrap/model/TestEntity.java create mode 100644 persistence-modules/spring-hibernate-5/src/main/resources/hibernate5Configuration.xml create mode 100644 persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/bootstrap/HibernateBootstrapIntegrationTest.java create mode 100644 persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/bootstrap/HibernateXMLBootstrapIntegrationTest.java diff --git a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/bootstrap/BarHibernateDAO.java b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/bootstrap/BarHibernateDAO.java new file mode 100644 index 0000000000..5fc932b256 --- /dev/null +++ b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/bootstrap/BarHibernateDAO.java @@ -0,0 +1,39 @@ +package com.baeldung.hibernate.bootstrap; + +import com.baeldung.hibernate.bootstrap.model.TestEntity; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.springframework.beans.factory.annotation.Autowired; + +public abstract class BarHibernateDAO { + + @Autowired + private SessionFactory sessionFactory; + + public TestEntity findEntity(int id) { + + return getCurrentSession().find(TestEntity.class, 1); + } + + public void createEntity(TestEntity entity) { + + getCurrentSession().save(entity); + } + + public void createEntity(int id, String newDescription) { + + TestEntity entity = findEntity(id); + entity.setDescription(newDescription); + getCurrentSession().save(entity); + } + + public void deleteEntity(int id) { + + TestEntity entity = findEntity(id); + getCurrentSession().delete(entity); + } + + protected Session getCurrentSession() { + return sessionFactory.getCurrentSession(); + } +} diff --git a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/bootstrap/HibernateConf.java b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/bootstrap/HibernateConf.java new file mode 100644 index 0000000000..150e3778af --- /dev/null +++ b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/bootstrap/HibernateConf.java @@ -0,0 +1,61 @@ +package com.baeldung.hibernate.bootstrap; + +import com.google.common.base.Preconditions; +import org.apache.tomcat.dbcp.dbcp2.BasicDataSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; +import org.springframework.core.env.Environment; +import org.springframework.orm.hibernate5.HibernateTransactionManager; +import org.springframework.orm.hibernate5.LocalSessionFactoryBean; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +import javax.sql.DataSource; +import java.util.Properties; + +@Configuration +@EnableTransactionManagement +@PropertySource({ "classpath:persistence-h2.properties" }) +public class HibernateConf { + + @Autowired + private Environment env; + + @Bean + public LocalSessionFactoryBean sessionFactory() { + final LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean(); + sessionFactory.setDataSource(dataSource()); + sessionFactory.setPackagesToScan(new String[] { "com.baeldung.hibernate.bootstrap.model" }); + sessionFactory.setHibernateProperties(hibernateProperties()); + + return sessionFactory; + } + + @Bean + public DataSource dataSource() { + final BasicDataSource dataSource = new BasicDataSource(); + dataSource.setDriverClassName(Preconditions.checkNotNull(env.getProperty("jdbc.driverClassName"))); + dataSource.setUrl(Preconditions.checkNotNull(env.getProperty("jdbc.url"))); + dataSource.setUsername(Preconditions.checkNotNull(env.getProperty("jdbc.user"))); + dataSource.setPassword(Preconditions.checkNotNull(env.getProperty("jdbc.pass"))); + + return dataSource; + } + + @Bean + public PlatformTransactionManager hibernateTransactionManager() { + final HibernateTransactionManager transactionManager = new HibernateTransactionManager(); + transactionManager.setSessionFactory(sessionFactory().getObject()); + return transactionManager; + } + + private final Properties hibernateProperties() { + final Properties hibernateProperties = new Properties(); + hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto")); + hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect")); + + return hibernateProperties; + } +} diff --git a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/bootstrap/HibernateXMLConf.java b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/bootstrap/HibernateXMLConf.java new file mode 100644 index 0000000000..b3e979478f --- /dev/null +++ b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/bootstrap/HibernateXMLConf.java @@ -0,0 +1,24 @@ +package com.baeldung.hibernate.bootstrap; + +import com.google.common.base.Preconditions; +import org.apache.tomcat.dbcp.dbcp2.BasicDataSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.ImportResource; +import org.springframework.context.annotation.PropertySource; +import org.springframework.core.env.Environment; +import org.springframework.orm.hibernate5.HibernateTransactionManager; +import org.springframework.orm.hibernate5.LocalSessionFactoryBean; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +import javax.sql.DataSource; +import java.util.Properties; + +@Configuration +@EnableTransactionManagement +@ImportResource({ "classpath:hibernate5Configuration.xml" }) +public class HibernateXMLConf { + +} diff --git a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/bootstrap/model/TestEntity.java b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/bootstrap/model/TestEntity.java new file mode 100644 index 0000000000..cae41db831 --- /dev/null +++ b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/bootstrap/model/TestEntity.java @@ -0,0 +1,29 @@ +package com.baeldung.hibernate.bootstrap.model; + +import javax.persistence.Entity; +import javax.persistence.Id; + +@Entity +public class TestEntity { + + private int id; + + private String description; + + @Id + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } +} diff --git a/persistence-modules/spring-hibernate-5/src/main/resources/hibernate5Configuration.xml b/persistence-modules/spring-hibernate-5/src/main/resources/hibernate5Configuration.xml new file mode 100644 index 0000000000..cb6cf0aa5c --- /dev/null +++ b/persistence-modules/spring-hibernate-5/src/main/resources/hibernate5Configuration.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + ${hibernate.hbm2ddl.auto} + ${hibernate.dialect} + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/persistence-modules/spring-hibernate-5/src/main/resources/persistence-h2.properties b/persistence-modules/spring-hibernate-5/src/main/resources/persistence-h2.properties index 915bc4317b..0325174b67 100644 --- a/persistence-modules/spring-hibernate-5/src/main/resources/persistence-h2.properties +++ b/persistence-modules/spring-hibernate-5/src/main/resources/persistence-h2.properties @@ -2,6 +2,7 @@ jdbc.driverClassName=org.h2.Driver jdbc.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1 jdbc.eventGeneratedId=sa +jdbc.user=sa jdbc.pass=sa # hibernate.X diff --git a/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/bootstrap/HibernateBootstrapIntegrationTest.java b/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/bootstrap/HibernateBootstrapIntegrationTest.java new file mode 100644 index 0000000000..ffe82b7ced --- /dev/null +++ b/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/bootstrap/HibernateBootstrapIntegrationTest.java @@ -0,0 +1,38 @@ +package com.baeldung.hibernate.bootstrap; + +import com.baeldung.hibernate.bootstrap.model.TestEntity; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.support.AnnotationConfigContextLoader; +import org.springframework.transaction.annotation.Transactional; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = { HibernateConf.class }) +@Transactional +public class HibernateBootstrapIntegrationTest { + + @Autowired + private SessionFactory sessionFactory; + + @Test + public void whenBootstrapHibernateSession_thenNoException() { + + Session session = sessionFactory.getCurrentSession(); + + TestEntity newEntity = new TestEntity(); + newEntity.setId(1); + session.save(newEntity); + + TestEntity searchEntity = session.find(TestEntity.class, 1); + + Assert.assertNotNull(searchEntity); + } + +} diff --git a/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/bootstrap/HibernateXMLBootstrapIntegrationTest.java b/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/bootstrap/HibernateXMLBootstrapIntegrationTest.java new file mode 100644 index 0000000000..5b811ad576 --- /dev/null +++ b/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/bootstrap/HibernateXMLBootstrapIntegrationTest.java @@ -0,0 +1,36 @@ +package com.baeldung.hibernate.bootstrap; + +import com.baeldung.hibernate.bootstrap.model.TestEntity; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.transaction.annotation.Transactional; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = { HibernateXMLConf.class }) +@Transactional +public class HibernateXMLBootstrapIntegrationTest { + + @Autowired + private SessionFactory sessionFactory; + + @Test + public void whenBootstrapHibernateSession_thenNoException() { + + Session session = sessionFactory.getCurrentSession(); + + TestEntity newEntity = new TestEntity(); + newEntity.setId(1); + session.save(newEntity); + + TestEntity searchEntity = session.find(TestEntity.class, 1); + + Assert.assertNotNull(searchEntity); + } + +} From 02b0c1d2933ee636241ae1446773af770f68dd13 Mon Sep 17 00:00:00 2001 From: Markus Gulden Date: Thu, 4 Jan 2018 10:26:48 +0100 Subject: [PATCH 02/58] BAEL-592: Upgrade to Spring 5 --- persistence-modules/spring-hibernate-5/pom.xml | 2 +- .../com/baeldung/manytomany/spring/PersistenceConfig.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/persistence-modules/spring-hibernate-5/pom.xml b/persistence-modules/spring-hibernate-5/pom.xml index 88db38b2fc..86e952c0e4 100644 --- a/persistence-modules/spring-hibernate-5/pom.xml +++ b/persistence-modules/spring-hibernate-5/pom.xml @@ -179,7 +179,7 @@ - 4.3.10.RELEASE + 5.0.2.RELEASE 1.10.6.RELEASE diff --git a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/manytomany/spring/PersistenceConfig.java b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/manytomany/spring/PersistenceConfig.java index 6f359054b6..5dace1f742 100644 --- a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/manytomany/spring/PersistenceConfig.java +++ b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/manytomany/spring/PersistenceConfig.java @@ -10,8 +10,8 @@ import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; import org.springframework.core.env.Environment; import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor; -import org.springframework.orm.hibernate4.HibernateTransactionManager; -import org.springframework.orm.hibernate4.LocalSessionFactoryBean; +import org.springframework.orm.hibernate5.HibernateTransactionManager; +import org.springframework.orm.hibernate5.LocalSessionFactoryBean; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; From 81e8da29a402f0cb8fd1c362ce249271b1e94f5d Mon Sep 17 00:00:00 2001 From: Markus Gulden Date: Sat, 27 Jan 2018 11:14:14 +0100 Subject: [PATCH 03/58] BAEL-1335 --- javaxval/pom.xml | 15 +- .../MethodValidationConfig.java | 38 ++++ .../ConsistentDateParameterValidator.java | 32 +++ .../constraints/ConsistentDateParameters.java | 23 ++ .../constraints/ValidReservation.java | 24 +++ .../ValidReservationValidator.java | 40 ++++ .../methodvalidation/model/Customer.java | 41 ++++ .../methodvalidation/model/Reservation.java | 60 ++++++ .../model/ReservationManagement.java | 50 +++++ .../ContainerValidationIntegrationTest.java | 86 ++++++++ .../ValidationIntegrationTest.java | 199 ++++++++++++++++++ 11 files changed, 606 insertions(+), 2 deletions(-) create mode 100644 javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/MethodValidationConfig.java create mode 100644 javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/constraints/ConsistentDateParameterValidator.java create mode 100644 javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/constraints/ConsistentDateParameters.java create mode 100644 javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/constraints/ValidReservation.java create mode 100644 javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/constraints/ValidReservationValidator.java create mode 100644 javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/model/Customer.java create mode 100644 javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/model/Reservation.java create mode 100644 javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/model/ReservationManagement.java create mode 100644 javaxval/src/test/java/org/baeldung/javaxval/methodvalidation/ContainerValidationIntegrationTest.java create mode 100644 javaxval/src/test/java/org/baeldung/javaxval/methodvalidation/ValidationIntegrationTest.java diff --git a/javaxval/pom.xml b/javaxval/pom.xml index 6a83a25f01..0891fe6959 100644 --- a/javaxval/pom.xml +++ b/javaxval/pom.xml @@ -6,10 +6,11 @@ 0.1-SNAPSHOT - 2.0.0.Final - 6.0.2.Final + 2.0.1.Final + 6.0.7.Final 3.0.0 2.2.6 + 5.0.2.RELEASE @@ -50,6 +51,16 @@ javax.el ${javax.el.version} + + org.springframework + spring-context + ${org.springframework.version} + + + org.springframework + spring-test + ${org.springframework.version} + diff --git a/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/MethodValidationConfig.java b/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/MethodValidationConfig.java new file mode 100644 index 0000000000..206a145337 --- /dev/null +++ b/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/MethodValidationConfig.java @@ -0,0 +1,38 @@ +package org.baeldung.javaxval.methodvalidation; + +import org.baeldung.javaxval.methodvalidation.model.Customer; +import org.baeldung.javaxval.methodvalidation.model.Reservation; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Scope; +import org.springframework.validation.beanvalidation.MethodValidationPostProcessor; + +import java.time.LocalDate; + +@Configuration +@ComponentScan({ "org.baeldung.javaxval.methodvalidation.model" }) +public class MethodValidationConfig { + + @Bean + public MethodValidationPostProcessor methodValidationPostProcessor() { + return new MethodValidationPostProcessor(); + } + + @Bean("customer") + @Scope(BeanDefinition.SCOPE_PROTOTYPE) + public Customer customer(String firstName, String lastName) { + + Customer customer = new Customer(firstName, lastName); + return customer; + } + + @Bean("reservation") + @Scope(BeanDefinition.SCOPE_PROTOTYPE) + public Reservation reservation(LocalDate begin, LocalDate end, Customer customer, int room) { + + Reservation reservation = new Reservation(begin, end, customer, room); + return reservation; + } +} diff --git a/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/constraints/ConsistentDateParameterValidator.java b/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/constraints/ConsistentDateParameterValidator.java new file mode 100644 index 0000000000..b28abcba45 --- /dev/null +++ b/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/constraints/ConsistentDateParameterValidator.java @@ -0,0 +1,32 @@ +package org.baeldung.javaxval.methodvalidation.constraints; + +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; +import javax.validation.constraintvalidation.SupportedValidationTarget; +import javax.validation.constraintvalidation.ValidationTarget; +import java.time.LocalDate; + +@SupportedValidationTarget(ValidationTarget.PARAMETERS) +public class ConsistentDateParameterValidator implements ConstraintValidator { + + @Override + public void initialize(ConsistentDateParameters constraintAnnotation) { + } + + @Override + public boolean isValid(Object[] value, ConstraintValidatorContext context) { + if (value.length != 4 && value.length != 3) { + throw new IllegalArgumentException("Illegal method signature"); + } + + if (value[0] == null || value[1] == null) { + return false; + } + + if (!(value[0] instanceof LocalDate) || !(value[1] instanceof LocalDate)) { + throw new IllegalArgumentException("Illegal method signature, expected two parameters of type LocalDate."); + } + + return ((LocalDate) value[0]).isBefore((LocalDate) value[1]); + } +} diff --git a/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/constraints/ConsistentDateParameters.java b/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/constraints/ConsistentDateParameters.java new file mode 100644 index 0000000000..6b321f545c --- /dev/null +++ b/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/constraints/ConsistentDateParameters.java @@ -0,0 +1,23 @@ +package org.baeldung.javaxval.methodvalidation.constraints; + +import javax.validation.Constraint; +import javax.validation.Payload; +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.*; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +@Constraint(validatedBy = ConsistentDateParameterValidator.class) +@Target({ METHOD, CONSTRUCTOR }) +@Retention(RUNTIME) +@Documented +public @interface ConsistentDateParameters { + + String message() default "End date must be after begin date and both must be in the future"; + + Class[] groups() default {}; + + Class[] payload() default {}; +} diff --git a/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/constraints/ValidReservation.java b/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/constraints/ValidReservation.java new file mode 100644 index 0000000000..f9cdea1483 --- /dev/null +++ b/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/constraints/ValidReservation.java @@ -0,0 +1,24 @@ +package org.baeldung.javaxval.methodvalidation.constraints; + +import javax.validation.Constraint; +import javax.validation.Payload; +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.CONSTRUCTOR; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +@Constraint(validatedBy = ValidReservationValidator.class) +@Target({ METHOD, CONSTRUCTOR }) +@Retention(RUNTIME) +@Documented +public @interface ValidReservation { + + String message() default "End date must be after begin date and both must be in the future, room number must be bigger than 0"; + + Class[] groups() default {}; + + Class[] payload() default {}; +} diff --git a/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/constraints/ValidReservationValidator.java b/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/constraints/ValidReservationValidator.java new file mode 100644 index 0000000000..1da257044b --- /dev/null +++ b/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/constraints/ValidReservationValidator.java @@ -0,0 +1,40 @@ +package org.baeldung.javaxval.methodvalidation.constraints; + +import org.baeldung.javaxval.methodvalidation.model.Reservation; + +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; +import java.time.LocalDate; + +public class ValidReservationValidator implements ConstraintValidator { + + @Override + public void initialize(ValidReservation constraintAnnotation) { + } + + @Override + public boolean isValid(Reservation reservation, ConstraintValidatorContext context) { + + if (reservation == null) { + return true; + } + + if (!(reservation instanceof Reservation)) { + throw new IllegalArgumentException("Illegal method signature, expected parameter of type Reservation."); + } + + if (reservation.getBegin() == null || reservation.getEnd() == null || reservation.getCustomer() == null) { + return false; + } + + if (reservation.getBegin() + .isAfter(LocalDate.now()) + && reservation.getBegin() + .isBefore(reservation.getEnd()) + && reservation.getRoom() > 0) { + + return true; + } + return false; + } +} diff --git a/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/model/Customer.java b/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/model/Customer.java new file mode 100644 index 0000000000..529cf436da --- /dev/null +++ b/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/model/Customer.java @@ -0,0 +1,41 @@ +package org.baeldung.javaxval.methodvalidation.model; + +import org.springframework.validation.annotation.Validated; + +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; + +@Validated +public class Customer { + + @Size(min = 5, max = 200) + private String firstName; + + @Size(min = 5, max = 200) + private String lastName; + + public Customer(@Size(min = 5, max = 200) @NotNull String firstName, @Size(min = 5, max = 200) String lastName) { + this.firstName = firstName; + this.lastName = lastName; + } + + public Customer() { + + } + + 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; + } +} diff --git a/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/model/Reservation.java b/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/model/Reservation.java new file mode 100644 index 0000000000..89f13e9e37 --- /dev/null +++ b/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/model/Reservation.java @@ -0,0 +1,60 @@ +package org.baeldung.javaxval.methodvalidation.model; + +import org.baeldung.javaxval.methodvalidation.constraints.ConsistentDateParameters; +import org.baeldung.javaxval.methodvalidation.constraints.ValidReservation; +import org.springframework.validation.annotation.Validated; + +import java.time.LocalDate; + +@Validated +public class Reservation { + + private LocalDate begin; + + private LocalDate end; + + private Customer customer; + + private int room; + + @ConsistentDateParameters + @ValidReservation + public Reservation(LocalDate begin, LocalDate end, Customer customer, int room) { + this.begin = begin; + this.end = end; + this.customer = customer; + this.room = room; + } + + public LocalDate getBegin() { + return begin; + } + + public void setBegin(LocalDate begin) { + this.begin = begin; + } + + public LocalDate getEnd() { + return end; + } + + public void setEnd(LocalDate end) { + this.end = end; + } + + public Customer getCustomer() { + return customer; + } + + public void setCustomer(Customer customer) { + this.customer = customer; + } + + public int getRoom() { + return room; + } + + public void setRoom(int room) { + this.room = room; + } +} diff --git a/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/model/ReservationManagement.java b/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/model/ReservationManagement.java new file mode 100644 index 0000000000..0aeeb52e1f --- /dev/null +++ b/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/model/ReservationManagement.java @@ -0,0 +1,50 @@ +package org.baeldung.javaxval.methodvalidation.model; + +import org.baeldung.javaxval.methodvalidation.constraints.ConsistentDateParameters; +import org.baeldung.javaxval.methodvalidation.constraints.ValidReservation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.stereotype.Controller; +import org.springframework.validation.annotation.Validated; + +import javax.validation.Valid; +import javax.validation.constraints.*; +import java.time.LocalDate; +import java.util.List; + +@Controller +@Validated +public class ReservationManagement { + + @Autowired + private ApplicationContext applicationContext; + + @ConsistentDateParameters + public void createReservation(LocalDate begin, LocalDate end, @NotNull Customer customer) { + + // ... + } + + public void createReservation(@NotNull @Future LocalDate begin, @Min(1) int duration, @NotNull Customer customer) { + + // ... + } + + @NotNull + @Size(min = 1) + public List<@NotNull Customer> getAllCustomers() { + + return null; + } + + public void createNewCustomer(@Valid Customer customer) { + + // ... + } + + @Valid + public Customer getCustomerById() { + + return null; + } +} diff --git a/javaxval/src/test/java/org/baeldung/javaxval/methodvalidation/ContainerValidationIntegrationTest.java b/javaxval/src/test/java/org/baeldung/javaxval/methodvalidation/ContainerValidationIntegrationTest.java new file mode 100644 index 0000000000..53133edd48 --- /dev/null +++ b/javaxval/src/test/java/org/baeldung/javaxval/methodvalidation/ContainerValidationIntegrationTest.java @@ -0,0 +1,86 @@ +package org.baeldung.javaxval.methodvalidation; + +import org.baeldung.javaxval.methodvalidation.model.Customer; +import org.baeldung.javaxval.methodvalidation.model.ReservationManagement; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.support.AnnotationConfigContextLoader; + +import javax.validation.ConstraintViolationException; +import java.time.LocalDate; +import java.util.List; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = { MethodValidationConfig.class }, loader = AnnotationConfigContextLoader.class) +public class ContainerValidationIntegrationTest { + + @Autowired + ReservationManagement reservationManagement; + + @Rule + public final ExpectedException exception = ExpectedException.none(); + + @Test + public void whenValidationWithInvalidMethodParameters_thenConstraintViolationException() { + + exception.expect(ConstraintViolationException.class); + reservationManagement.createReservation(LocalDate.now(), 0, null); + } + + @Test + public void whenValidationWithValidMethodParameters_thenNoException() { + + reservationManagement.createReservation(LocalDate.now() + .plusDays(1), 1, new Customer("William", "Smith")); + } + + @Test + public void whenCrossParameterValidationWithInvalidParameters_thenConstraintViolationException() { + + exception.expect(ConstraintViolationException.class); + reservationManagement.createReservation(LocalDate.now(), LocalDate.now(), null); + } + + @Test + public void whenCrossParameterValidationWithValidParameters_thenNoException() { + + reservationManagement.createReservation(LocalDate.now() + .plusDays(1), + LocalDate.now() + .plusDays(2), + new Customer("William", "Smith")); + } + + @Test + public void whenValidationWithInvalidReturnValue_thenConstraintViolationException() { + + exception.expect(ConstraintViolationException.class); + List list = reservationManagement.getAllCustomers(); + } + + @Test + public void whenValidationWithInvalidCascadedValue_thenConstraintViolationException() { + + Customer customer = new Customer(); + customer.setFirstName("John"); + customer.setLastName("Doe"); + + exception.expect(ConstraintViolationException.class); + reservationManagement.createNewCustomer(customer); + } + + @Test + public void whenValidationWithValidCascadedValue_thenCNoException() { + + Customer customer = new Customer(); + customer.setFirstName("William"); + customer.setLastName("Smith"); + + reservationManagement.createNewCustomer(customer); + } +} diff --git a/javaxval/src/test/java/org/baeldung/javaxval/methodvalidation/ValidationIntegrationTest.java b/javaxval/src/test/java/org/baeldung/javaxval/methodvalidation/ValidationIntegrationTest.java new file mode 100644 index 0000000000..6a750698c6 --- /dev/null +++ b/javaxval/src/test/java/org/baeldung/javaxval/methodvalidation/ValidationIntegrationTest.java @@ -0,0 +1,199 @@ +package org.baeldung.javaxval.methodvalidation; + +import org.baeldung.javaxval.methodvalidation.model.Customer; +import org.baeldung.javaxval.methodvalidation.model.Reservation; +import org.baeldung.javaxval.methodvalidation.model.ReservationManagement; +import org.junit.Before; +import org.junit.Test; +import static org.junit.Assert.*; + +import javax.validation.ConstraintViolation; +import javax.validation.Validation; +import javax.validation.ValidatorFactory; +import javax.validation.executable.ExecutableValidator; +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import java.time.LocalDate; +import java.util.Collections; +import java.util.Set; + +public class ValidationIntegrationTest { + + private ExecutableValidator executableValidator; + + @Before + public void getExecutableValidator() { + + ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); + this.executableValidator = factory.getValidator() + .forExecutables(); + } + + @Test + public void whenValidationWithInvalidMethodParameters_thenCorrectNumberOfVoilations() throws NoSuchMethodException { + + ReservationManagement object = new ReservationManagement(); + Method method = ReservationManagement.class.getMethod("createReservation", LocalDate.class, int.class, Customer.class); + Object[] parameterValues = { LocalDate.now(), 0, null }; + Set> violations = executableValidator.validateParameters(object, method, parameterValues); + + assertEquals(3, violations.size()); + } + + @Test + public void whenValidationWithValidMethodParameters_thenZeroVoilations() throws NoSuchMethodException { + + ReservationManagement object = new ReservationManagement(); + Method method = ReservationManagement.class.getMethod("createReservation", LocalDate.class, int.class, Customer.class); + Object[] parameterValues = { LocalDate.now() + .plusDays(1), 1, new Customer("John", "Doe") }; + Set> violations = executableValidator.validateParameters(object, method, parameterValues); + + assertEquals(0, violations.size()); + } + + @Test + public void whenCrossParameterValidationWithInvalidParameters_thenCorrectNumberOfVoilations() throws NoSuchMethodException { + + ReservationManagement object = new ReservationManagement(); + Method method = ReservationManagement.class.getMethod("createReservation", LocalDate.class, LocalDate.class, Customer.class); + Object[] parameterValues = { LocalDate.now(), LocalDate.now(), new Customer("John", "Doe") }; + Set> violations = executableValidator.validateParameters(object, method, parameterValues); + + assertEquals(1, violations.size()); + } + + @Test + public void whenCrossParameterValidationWithValidParameters_thenZeroVoilations() throws NoSuchMethodException { + + ReservationManagement object = new ReservationManagement(); + Method method = ReservationManagement.class.getMethod("createReservation", LocalDate.class, LocalDate.class, Customer.class); + Object[] parameterValues = { LocalDate.now() + .plusDays(1), + LocalDate.now() + .plusDays(2), + new Customer("John", "Doe") }; + Set> violations = executableValidator.validateParameters(object, method, parameterValues); + + assertEquals(0, violations.size()); + } + + @Test + public void whenValidationWithInvalidConstructorParameters_thenCorrectNumberOfVoilations() throws NoSuchMethodException { + + Constructor constructor = Customer.class.getConstructor(String.class, String.class); + Object[] parameterValues = { "John", "Doe" }; + Set> violations = executableValidator.validateConstructorParameters(constructor, parameterValues); + + assertEquals(2, violations.size()); + } + + @Test + public void whenValidationWithValidConstructorParameters_thenZeroVoilations() throws NoSuchMethodException { + + Constructor constructor = Customer.class.getConstructor(String.class, String.class); + Object[] parameterValues = { "William", "Smith" }; + Set> violations = executableValidator.validateConstructorParameters(constructor, parameterValues); + + assertEquals(0, violations.size()); + } + + @Test + public void whenCrossParameterValidationWithInvalidConstructorParameters_thenCorrectNumberOfVoilations() throws NoSuchMethodException { + + Constructor constructor = Reservation.class.getConstructor(LocalDate.class, LocalDate.class, Customer.class, int.class); + Object[] parameterValues = { LocalDate.now(), LocalDate.now(), new Customer("William", "Smith"), 1 }; + Set> violations = executableValidator.validateConstructorParameters(constructor, parameterValues); + + assertEquals(1, violations.size()); + } + + @Test + public void whenCrossParameterValidationWithValidConstructorParameters_thenZeroVoilations() throws NoSuchMethodException { + + Constructor constructor = Reservation.class.getConstructor(LocalDate.class, LocalDate.class, Customer.class, int.class); + Object[] parameterValues = { LocalDate.now() + .plusDays(1), + LocalDate.now() + .plusDays(2), + new Customer("William", "Smith"), 1 }; + Set> violations = executableValidator.validateConstructorParameters(constructor, parameterValues); + + assertEquals(0, violations.size()); + } + + @Test + public void whenValidationWithInvalidReturnValue_thenCorrectNumberOfVoilations() throws NoSuchMethodException { + + ReservationManagement object = new ReservationManagement(); + Method method = ReservationManagement.class.getMethod("getAllCustomers"); + Object returnValue = Collections. emptyList(); + Set> violations = executableValidator.validateReturnValue(object, method, returnValue); + + assertEquals(1, violations.size()); + } + + @Test + public void whenValidationWithValidReturnValue_thenZeroVoilations() throws NoSuchMethodException { + + ReservationManagement object = new ReservationManagement(); + Method method = ReservationManagement.class.getMethod("getAllCustomers"); + Object returnValue = Collections.singletonList(new Customer("William", "Smith")); + Set> violations = executableValidator.validateReturnValue(object, method, returnValue); + + assertEquals(0, violations.size()); + } + + @Test + public void whenValidationWithInvalidConstructorReturnValue_thenCorrectNumberOfVoilations() throws NoSuchMethodException { + + Constructor constructor = Reservation.class.getConstructor(LocalDate.class, LocalDate.class, Customer.class, int.class); + Reservation createdObject = new Reservation(LocalDate.now(), LocalDate.now(), new Customer("William", "Smith"), 0); + Set> violations = executableValidator.validateConstructorReturnValue(constructor, createdObject); + + assertEquals(1, violations.size()); + } + + @Test + public void whenValidationWithValidConstructorReturnValue_thenZeroVoilations() throws NoSuchMethodException { + + Constructor constructor = Reservation.class.getConstructor(LocalDate.class, LocalDate.class, Customer.class, int.class); + Reservation createdObject = new Reservation(LocalDate.now() + .plusDays(1), + LocalDate.now() + .plusDays(2), + new Customer("William", "Smith"), 1); + Set> violations = executableValidator.validateConstructorReturnValue(constructor, createdObject); + + assertEquals(0, violations.size()); + } + + @Test + public void whenValidationWithInvalidCascadedValue_thenCorrectNumberOfVoilations() throws NoSuchMethodException { + + ReservationManagement object = new ReservationManagement(); + Method method = ReservationManagement.class.getMethod("createNewCustomer", Customer.class); + Customer customer = new Customer(); + customer.setFirstName("John"); + customer.setLastName("Doe"); + Object[] parameterValues = { customer }; + Set> violations = executableValidator.validateParameters(object, method, parameterValues); + + assertEquals(2, violations.size()); + } + + @Test + public void whenValidationWithValidCascadedValue_thenCorrectNumberOfVoilations() throws NoSuchMethodException { + + ReservationManagement object = new ReservationManagement(); + Method method = ReservationManagement.class.getMethod("createNewCustomer", Customer.class); + Customer customer = new Customer(); + customer.setFirstName("William"); + customer.setLastName("Smith"); + Object[] parameterValues = { customer }; + Set> violations = executableValidator.validateParameters(object, method, parameterValues); + + assertEquals(0, violations.size()); + } + +} From b9ac0dc78b8e51e0bda526b420746227ab53eff3 Mon Sep 17 00:00:00 2001 From: Markus Gulden Date: Sat, 3 Feb 2018 12:51:59 +0100 Subject: [PATCH 04/58] Updates after editor feedback --- .../ConsistentDateParameterValidator.java | 5 +---- .../constraints/ValidReservationValidator.java | 2 +- .../methodvalidation/model/Reservation.java | 4 ++++ .../model/ReservationManagement.java | 12 ++++++------ .../ContainerValidationIntegrationTest.java | 15 +++++++++++++-- .../ValidationIntegrationTest.java | 18 ++++++++++++++---- 6 files changed, 39 insertions(+), 17 deletions(-) diff --git a/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/constraints/ConsistentDateParameterValidator.java b/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/constraints/ConsistentDateParameterValidator.java index b28abcba45..0ee1b6eda1 100644 --- a/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/constraints/ConsistentDateParameterValidator.java +++ b/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/constraints/ConsistentDateParameterValidator.java @@ -15,9 +15,6 @@ public class ConsistentDateParameterValidator implements ConstraintValidator getAllCustomers() { @@ -37,13 +42,8 @@ public class ReservationManagement { return null; } - public void createNewCustomer(@Valid Customer customer) { - - // ... - } - @Valid - public Customer getCustomerById() { + public Reservation getReservationById(int id) { return null; } diff --git a/javaxval/src/test/java/org/baeldung/javaxval/methodvalidation/ContainerValidationIntegrationTest.java b/javaxval/src/test/java/org/baeldung/javaxval/methodvalidation/ContainerValidationIntegrationTest.java index 53133edd48..2363bf8f5d 100644 --- a/javaxval/src/test/java/org/baeldung/javaxval/methodvalidation/ContainerValidationIntegrationTest.java +++ b/javaxval/src/test/java/org/baeldung/javaxval/methodvalidation/ContainerValidationIntegrationTest.java @@ -1,6 +1,7 @@ package org.baeldung.javaxval.methodvalidation; import org.baeldung.javaxval.methodvalidation.model.Customer; +import org.baeldung.javaxval.methodvalidation.model.Reservation; import org.baeldung.javaxval.methodvalidation.model.ReservationManagement; import org.junit.Rule; import org.junit.Test; @@ -69,9 +70,14 @@ public class ContainerValidationIntegrationTest { Customer customer = new Customer(); customer.setFirstName("John"); customer.setLastName("Doe"); + Reservation reservation = new Reservation(LocalDate.now() + .plusDays(1), + LocalDate.now() + .plusDays(2), + customer, 1); exception.expect(ConstraintViolationException.class); - reservationManagement.createNewCustomer(customer); + reservationManagement.createReservation(reservation); } @Test @@ -80,7 +86,12 @@ public class ContainerValidationIntegrationTest { Customer customer = new Customer(); customer.setFirstName("William"); customer.setLastName("Smith"); + Reservation reservation = new Reservation(LocalDate.now() + .plusDays(1), + LocalDate.now() + .plusDays(2), + customer, 1); - reservationManagement.createNewCustomer(customer); + reservationManagement.createReservation(reservation); } } diff --git a/javaxval/src/test/java/org/baeldung/javaxval/methodvalidation/ValidationIntegrationTest.java b/javaxval/src/test/java/org/baeldung/javaxval/methodvalidation/ValidationIntegrationTest.java index 6a750698c6..6b53d3a107 100644 --- a/javaxval/src/test/java/org/baeldung/javaxval/methodvalidation/ValidationIntegrationTest.java +++ b/javaxval/src/test/java/org/baeldung/javaxval/methodvalidation/ValidationIntegrationTest.java @@ -172,11 +172,16 @@ public class ValidationIntegrationTest { public void whenValidationWithInvalidCascadedValue_thenCorrectNumberOfVoilations() throws NoSuchMethodException { ReservationManagement object = new ReservationManagement(); - Method method = ReservationManagement.class.getMethod("createNewCustomer", Customer.class); + Method method = ReservationManagement.class.getMethod("createReservation", Reservation.class); Customer customer = new Customer(); customer.setFirstName("John"); customer.setLastName("Doe"); - Object[] parameterValues = { customer }; + Reservation reservation = new Reservation(LocalDate.now() + .plusDays(1), + LocalDate.now() + .plusDays(2), + customer, 1); + Object[] parameterValues = { reservation }; Set> violations = executableValidator.validateParameters(object, method, parameterValues); assertEquals(2, violations.size()); @@ -186,11 +191,16 @@ public class ValidationIntegrationTest { public void whenValidationWithValidCascadedValue_thenCorrectNumberOfVoilations() throws NoSuchMethodException { ReservationManagement object = new ReservationManagement(); - Method method = ReservationManagement.class.getMethod("createNewCustomer", Customer.class); + Method method = ReservationManagement.class.getMethod("createReservation", Reservation.class); Customer customer = new Customer(); customer.setFirstName("William"); customer.setLastName("Smith"); - Object[] parameterValues = { customer }; + Reservation reservation = new Reservation(LocalDate.now() + .plusDays(1), + LocalDate.now() + .plusDays(2), + customer, 1); + Object[] parameterValues = { reservation }; Set> violations = executableValidator.validateParameters(object, method, parameterValues); assertEquals(0, violations.size()); From e15f2fc7dd347b42dbf414747cac8aa11e3c0b86 Mon Sep 17 00:00:00 2001 From: Markus Gulden Date: Sat, 3 Feb 2018 13:10:31 +0100 Subject: [PATCH 05/58] Updates after editor feedback --- .../constraints/ValidReservationValidator.java | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/constraints/ValidReservationValidator.java b/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/constraints/ValidReservationValidator.java index a1cba9a5f6..fc225999be 100644 --- a/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/constraints/ValidReservationValidator.java +++ b/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/constraints/ValidReservationValidator.java @@ -27,14 +27,10 @@ public class ValidReservationValidator implements ConstraintValidator 0) { - - return true; - } - return false; + && reservation.getRoom() > 0); } } From 5a31640528ac3e7fce5314b06e194077b0cccd4b Mon Sep 17 00:00:00 2001 From: Markus Gulden Date: Sat, 3 Feb 2018 13:30:52 +0100 Subject: [PATCH 06/58] Updates after editor feedback --- .../org/baeldung/javaxval/methodvalidation/model/Customer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/model/Customer.java b/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/model/Customer.java index 529cf436da..fe9ad7080e 100644 --- a/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/model/Customer.java +++ b/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/model/Customer.java @@ -14,7 +14,7 @@ public class Customer { @Size(min = 5, max = 200) private String lastName; - public Customer(@Size(min = 5, max = 200) @NotNull String firstName, @Size(min = 5, max = 200) String lastName) { + public Customer(@Size(min = 5, max = 200) @NotNull String firstName, @Size(min = 5, max = 200) @NotNull String lastName) { this.firstName = firstName; this.lastName = lastName; } From 581e8592ae52591525054054e906f8d9df7cf9a3 Mon Sep 17 00:00:00 2001 From: shouvikbhattacharya Date: Sun, 4 Feb 2018 18:22:17 +0530 Subject: [PATCH 07/58] BAEL-1525: Article code completed. --- .../java/com/baeldung/string/Palindrome.java | 14 +++++++ .../string/WhenCheckingPalindrome.java | 37 +++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 core-java/src/main/java/com/baeldung/string/Palindrome.java create mode 100644 core-java/src/test/java/com/baeldung/string/WhenCheckingPalindrome.java diff --git a/core-java/src/main/java/com/baeldung/string/Palindrome.java b/core-java/src/main/java/com/baeldung/string/Palindrome.java new file mode 100644 index 0000000000..e339d92447 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/string/Palindrome.java @@ -0,0 +1,14 @@ +package com.baeldung.string; + +public class Palindrome { + + public boolean isPalindrome(String text) { + text = text.replaceAll("\\s+", "").toLowerCase(); + int length = text.length(); + int forward = 0; + int backward = length - 1; + boolean palindrome = true; + while ((backward > forward)?(palindrome=(text.charAt(forward++) == text.charAt(backward--))):false); + return palindrome; + } +} diff --git a/core-java/src/test/java/com/baeldung/string/WhenCheckingPalindrome.java b/core-java/src/test/java/com/baeldung/string/WhenCheckingPalindrome.java new file mode 100644 index 0000000000..691d74c751 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/string/WhenCheckingPalindrome.java @@ -0,0 +1,37 @@ +package com.baeldung.string; + +import org.junit.Assert; +import org.junit.Test; + +public class WhenCheckingPalindrome { + + private String[] words = { + "Anna", + "Civic", + "Kayak", + "Level", + "Madam", + }; + + private String[] sentences = { + "Sore was I ere I saw Eros", + "Euston saw I was not Sue", + "Too hot to hoot", + "No mists or frost Simon", + "Stella won no wallets" + }; + + private Palindrome palindrome = new Palindrome(); + + @Test + public void whenWord_shouldBePalindrome() { + for(String word:words) + Assert.assertTrue(palindrome.isPalindrome(word)); + } + + @Test + public void whenSentence_shouldBePalindrome() { + for(String sentence:sentences) + Assert.assertTrue(palindrome.isPalindrome(sentence)); + } +} From c03e0919e1195bdc06139a930220568dfefa72b1 Mon Sep 17 00:00:00 2001 From: Markus Gulden Date: Mon, 5 Feb 2018 10:21:36 +0100 Subject: [PATCH 08/58] Updates after editor feedback --- javaxval/pom.xml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/javaxval/pom.xml b/javaxval/pom.xml index 0891fe6959..a05ee43aaf 100644 --- a/javaxval/pom.xml +++ b/javaxval/pom.xml @@ -22,12 +22,6 @@ - - javax.validation - validation-api - ${validation-api.version} - - org.hibernate hibernate-validator From 7ecceaf5e25ba9d1b549bf2bfad60f592a8677c2 Mon Sep 17 00:00:00 2001 From: Markus Gulden Date: Mon, 5 Feb 2018 11:17:37 +0100 Subject: [PATCH 09/58] Updates after editor feedback --- .../constraints/ConsistentDateParameterValidator.java | 6 +----- .../constraints/ValidReservationValidator.java | 6 +----- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/constraints/ConsistentDateParameterValidator.java b/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/constraints/ConsistentDateParameterValidator.java index 0ee1b6eda1..f1c97760d7 100644 --- a/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/constraints/ConsistentDateParameterValidator.java +++ b/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/constraints/ConsistentDateParameterValidator.java @@ -9,15 +9,11 @@ import java.time.LocalDate; @SupportedValidationTarget(ValidationTarget.PARAMETERS) public class ConsistentDateParameterValidator implements ConstraintValidator { - @Override - public void initialize(ConsistentDateParameters constraintAnnotation) { - } - @Override public boolean isValid(Object[] value, ConstraintValidatorContext context) { if (value[0] == null || value[1] == null) { - return false; + return true; } if (!(value[0] instanceof LocalDate) || !(value[1] instanceof LocalDate)) { diff --git a/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/constraints/ValidReservationValidator.java b/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/constraints/ValidReservationValidator.java index fc225999be..7b730480ed 100644 --- a/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/constraints/ValidReservationValidator.java +++ b/javaxval/src/main/java/org/baeldung/javaxval/methodvalidation/constraints/ValidReservationValidator.java @@ -8,15 +8,11 @@ import java.time.LocalDate; public class ValidReservationValidator implements ConstraintValidator { - @Override - public void initialize(ValidReservation constraintAnnotation) { - } - @Override public boolean isValid(Reservation reservation, ConstraintValidatorContext context) { if (reservation == null) { - return false; + return true; } if (!(reservation instanceof Reservation)) { From 56316fd029ff941e39e5bdf7dc3f5cca170946b0 Mon Sep 17 00:00:00 2001 From: linhvovn Date: Wed, 7 Feb 2018 03:43:44 +0800 Subject: [PATCH 10/58] [tlinh2110-BAEL1382] Add Security in SI (#3593) * [tlinh2110-BAEL1382] Add Security in SI * [tlinh2110-BAEL1382] Upgrade to Spring 5 & add Logger --- spring-integration/pom.xml | 41 ++++++++-- .../baeldung/si/security/MessageConsumer.java | 45 ++++++++++ .../si/security/SecuredDirectChannel.java | 50 +++++++++++ .../baeldung/si/security/SecurityConfig.java | 46 +++++++++++ .../si/security/SecurityPubSubChannel.java | 82 +++++++++++++++++++ .../security/UsernameAccessDecisionVoter.java | 45 ++++++++++ .../si/TestSpringIntegrationSecurity.java | 81 ++++++++++++++++++ ...TestSpringIntegrationSecurityExecutor.java | 68 +++++++++++++++ 8 files changed, 452 insertions(+), 6 deletions(-) create mode 100644 spring-integration/src/main/java/com/baeldung/si/security/MessageConsumer.java create mode 100644 spring-integration/src/main/java/com/baeldung/si/security/SecuredDirectChannel.java create mode 100644 spring-integration/src/main/java/com/baeldung/si/security/SecurityConfig.java create mode 100644 spring-integration/src/main/java/com/baeldung/si/security/SecurityPubSubChannel.java create mode 100644 spring-integration/src/main/java/com/baeldung/si/security/UsernameAccessDecisionVoter.java create mode 100644 spring-integration/src/test/java/com/baeldung/si/TestSpringIntegrationSecurity.java create mode 100644 spring-integration/src/test/java/com/baeldung/si/TestSpringIntegrationSecurityExecutor.java diff --git a/spring-integration/pom.xml b/spring-integration/pom.xml index 4e210122b0..27cc7381e3 100644 --- a/spring-integration/pom.xml +++ b/spring-integration/pom.xml @@ -18,7 +18,7 @@ UTF-8 - 4.3.5.RELEASE + 5.0.1.RELEASE 1.1.4.RELEASE 1.4.7 1.1.1 @@ -68,7 +68,7 @@ org.springframework.integration spring-integration-core - ${spring.integration.version} + ${spring.version} javax.activation @@ -84,17 +84,17 @@ org.springframework.integration spring-integration-twitter - ${spring.integration.version} + ${spring.version} org.springframework.integration spring-integration-mail - ${spring.integration.version} + ${spring.version} org.springframework.integration spring-integration-ftp - ${spring.integration.version} + ${spring.version} org.springframework.social @@ -104,7 +104,36 @@ org.springframework.integration spring-integration-file - ${spring.integration.version} + ${spring.version} + + + + org.springframework.security + spring-security-core + ${spring.version} + + + org.springframework.security + spring-security-config + ${spring.version} + + + org.springframework.integration + spring-integration-security + ${spring.version} + + + + org.springframework.security + spring-security-test + ${spring.version} + test + + + org.springframework + spring-test + ${spring.version} + test junit diff --git a/spring-integration/src/main/java/com/baeldung/si/security/MessageConsumer.java b/spring-integration/src/main/java/com/baeldung/si/security/MessageConsumer.java new file mode 100644 index 0000000000..af925c63a7 --- /dev/null +++ b/spring-integration/src/main/java/com/baeldung/si/security/MessageConsumer.java @@ -0,0 +1,45 @@ +package com.baeldung.si.security; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.logging.Logger; + +import org.springframework.integration.annotation.ServiceActivator; +import org.springframework.messaging.Message; +import org.springframework.stereotype.Service; + +@Service +public class MessageConsumer { + + private String messageContent; + + private Map messagePSContent = new ConcurrentHashMap<>(); + + public String getMessageContent() { + return messageContent; + } + + public void setMessageContent(String messageContent) { + this.messageContent = messageContent; + } + + public Map getMessagePSContent() { + return messagePSContent; + } + + public void setMessagePSContent(Map messagePSContent) { + this.messagePSContent = messagePSContent; + } + + @ServiceActivator(inputChannel = "endDirectChannel") + public void endDirectFlow(Message message) { + setMessageContent(message.getPayload().toString()); + } + + @ServiceActivator(inputChannel = "finalPSResult") + public void endPSFlow(Message message) { + Logger.getAnonymousLogger().info(Thread.currentThread().getName() + " has completed ---------------------------"); + messagePSContent.put(Thread.currentThread().getName(), (String) message.getPayload()); + } + +} diff --git a/spring-integration/src/main/java/com/baeldung/si/security/SecuredDirectChannel.java b/spring-integration/src/main/java/com/baeldung/si/security/SecuredDirectChannel.java new file mode 100644 index 0000000000..964a07d7d7 --- /dev/null +++ b/spring-integration/src/main/java/com/baeldung/si/security/SecuredDirectChannel.java @@ -0,0 +1,50 @@ +package com.baeldung.si.security; + +import java.util.logging.Logger; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.integration.annotation.ServiceActivator; +import org.springframework.integration.channel.DirectChannel; +import org.springframework.integration.config.EnableIntegration; +import org.springframework.integration.security.channel.ChannelSecurityInterceptor; +import org.springframework.integration.security.channel.SecuredChannel; +import org.springframework.messaging.Message; +import org.springframework.security.access.AccessDecisionManager; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.security.authentication.AuthenticationManager; + +@Configuration +@EnableIntegration +public class SecuredDirectChannel { + + @Bean(name = "startDirectChannel") + @SecuredChannel(interceptor = "channelSecurityInterceptor", sendAccess = { "ROLE_VIEWER", "jane" }) + public DirectChannel startDirectChannel() { + return new DirectChannel(); + } + + @ServiceActivator(inputChannel = "startDirectChannel", outputChannel = "endDirectChannel") + @PreAuthorize("hasRole('ROLE_LOGGER')") + public Message logMessage(Message message) { + Logger.getAnonymousLogger().info(message.toString()); + return message; + } + + @Bean(name = "endDirectChannel") + @SecuredChannel(interceptor = "channelSecurityInterceptor", sendAccess = { "ROLE_EDITOR" }) + public DirectChannel endDirectChannel() { + return new DirectChannel(); + } + + @Autowired + @Bean + public ChannelSecurityInterceptor channelSecurityInterceptor(AuthenticationManager authenticationManager, AccessDecisionManager customAccessDecisionManager) { + ChannelSecurityInterceptor channelSecurityInterceptor = new ChannelSecurityInterceptor(); + channelSecurityInterceptor.setAuthenticationManager(authenticationManager); + channelSecurityInterceptor.setAccessDecisionManager(customAccessDecisionManager); + return channelSecurityInterceptor; + } + +} diff --git a/spring-integration/src/main/java/com/baeldung/si/security/SecurityConfig.java b/spring-integration/src/main/java/com/baeldung/si/security/SecurityConfig.java new file mode 100644 index 0000000000..9c5b38b909 --- /dev/null +++ b/spring-integration/src/main/java/com/baeldung/si/security/SecurityConfig.java @@ -0,0 +1,46 @@ +package com.baeldung.si.security; + +import java.util.ArrayList; +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.integration.security.channel.ChannelSecurityInterceptor; +import org.springframework.security.access.AccessDecisionManager; +import org.springframework.security.access.AccessDecisionVoter; +import org.springframework.security.access.vote.AffirmativeBased; +import org.springframework.security.access.vote.RoleVoter; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration; + +@Configuration +@EnableGlobalMethodSecurity(prePostEnabled = true) +public class SecurityConfig extends GlobalMethodSecurityConfiguration { + + @Override + @Bean + public AuthenticationManager authenticationManager() throws Exception { + return super.authenticationManager(); + } + + @Bean + public AccessDecisionManager customAccessDecisionManager() { + List> decisionVoters = new ArrayList<>(); + decisionVoters.add(new RoleVoter()); + decisionVoters.add(new UsernameAccessDecisionVoter()); + AccessDecisionManager accessDecisionManager = new AffirmativeBased(decisionVoters); + return accessDecisionManager; + } + + @Autowired + @Bean + public ChannelSecurityInterceptor channelSecurityInterceptor(AuthenticationManager authenticationManager, AccessDecisionManager customAccessDecisionManager) { + ChannelSecurityInterceptor channelSecurityInterceptor = new ChannelSecurityInterceptor(); + channelSecurityInterceptor.setAuthenticationManager(authenticationManager); + channelSecurityInterceptor.setAccessDecisionManager(customAccessDecisionManager); + return channelSecurityInterceptor; + } + +} diff --git a/spring-integration/src/main/java/com/baeldung/si/security/SecurityPubSubChannel.java b/spring-integration/src/main/java/com/baeldung/si/security/SecurityPubSubChannel.java new file mode 100644 index 0000000000..11409bb89b --- /dev/null +++ b/spring-integration/src/main/java/com/baeldung/si/security/SecurityPubSubChannel.java @@ -0,0 +1,82 @@ +package com.baeldung.si.security; + +import java.util.stream.Collectors; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.integration.annotation.ServiceActivator; +import org.springframework.integration.channel.DirectChannel; +import org.springframework.integration.channel.PublishSubscribeChannel; +import org.springframework.integration.config.EnableIntegration; +import org.springframework.integration.config.GlobalChannelInterceptor; +import org.springframework.integration.security.channel.SecuredChannel; +import org.springframework.integration.security.channel.SecurityContextPropagationChannelInterceptor; +import org.springframework.integration.support.DefaultMessageBuilderFactory; +import org.springframework.integration.support.MessageBuilder; +import org.springframework.messaging.Message; +import org.springframework.messaging.support.ChannelInterceptor; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.security.core.context.SecurityContext; +import org.springframework.security.core.context.SecurityContextHolder; + +@Configuration +@EnableIntegration +public class SecurityPubSubChannel { + + @Bean(name = "startPSChannel") + @SecuredChannel(interceptor = "channelSecurityInterceptor", sendAccess = "ROLE_VIEWER") + public PublishSubscribeChannel startChannel() { + return new PublishSubscribeChannel(executor()); + } + + @ServiceActivator(inputChannel = "startPSChannel", outputChannel = "finalPSResult") + @PreAuthorize("hasRole('ROLE_LOGGER')") + public Message changeMessageToRole(Message message) { + return buildNewMessage(getRoles(), message); + } + + @ServiceActivator(inputChannel = "startPSChannel", outputChannel = "finalPSResult") + @PreAuthorize("hasRole('ROLE_VIEWER')") + public Message changeMessageToUserName(Message message) { + return buildNewMessage(getUsername(), message); + } + + @Bean(name = "finalPSResult") + public DirectChannel finalPSResult() { + return new DirectChannel(); + } + + @Bean + @GlobalChannelInterceptor(patterns = { "startPSChannel", "endDirectChannel" }) + public ChannelInterceptor securityContextPropagationInterceptor() { + return new SecurityContextPropagationChannelInterceptor(); + } + + @Bean + public ThreadPoolTaskExecutor executor() { + ThreadPoolTaskExecutor pool = new ThreadPoolTaskExecutor(); + pool.setCorePoolSize(10); + pool.setMaxPoolSize(10); + pool.setWaitForTasksToCompleteOnShutdown(true); + return pool; + } + + public String getRoles() { + SecurityContext securityContext = SecurityContextHolder.getContext(); + return securityContext.getAuthentication().getAuthorities().stream().map(auth -> auth.getAuthority()).collect(Collectors.joining(",")); + } + + public String getUsername() { + SecurityContext securityContext = SecurityContextHolder.getContext(); + return securityContext.getAuthentication().getName(); + } + + public Message buildNewMessage(String content, Message message) { + DefaultMessageBuilderFactory builderFactory = new DefaultMessageBuilderFactory(); + MessageBuilder messageBuilder = builderFactory.withPayload(content); + messageBuilder.copyHeaders(message.getHeaders()); + return messageBuilder.build(); + } + +} diff --git a/spring-integration/src/main/java/com/baeldung/si/security/UsernameAccessDecisionVoter.java b/spring-integration/src/main/java/com/baeldung/si/security/UsernameAccessDecisionVoter.java new file mode 100644 index 0000000000..052f79ddf7 --- /dev/null +++ b/spring-integration/src/main/java/com/baeldung/si/security/UsernameAccessDecisionVoter.java @@ -0,0 +1,45 @@ +package com.baeldung.si.security; + +import java.util.Collection; + +import org.springframework.security.access.AccessDecisionVoter; +import org.springframework.security.access.ConfigAttribute; +import org.springframework.security.core.Authentication; + +public class UsernameAccessDecisionVoter implements AccessDecisionVoter { + private String rolePrefix = "ROLE_"; + + @Override + public boolean supports(ConfigAttribute attribute) { + if ((attribute.getAttribute() != null) + && !attribute.getAttribute().startsWith(rolePrefix)) { + return true; + }else { + return false; + } + } + + @Override + public boolean supports(Class clazz) { + return true; + } + + @Override + public int vote(Authentication authentication, Object object, Collection attributes) { + if (authentication == null) { + return ACCESS_DENIED; + } + String name = authentication.getName(); + int result = ACCESS_ABSTAIN; + for (ConfigAttribute attribute : attributes) { + if (this.supports(attribute)) { + result = ACCESS_DENIED; + if (attribute.getAttribute().equals(name)) { + return ACCESS_GRANTED; + } + } + } + return result; + } + +} diff --git a/spring-integration/src/test/java/com/baeldung/si/TestSpringIntegrationSecurity.java b/spring-integration/src/test/java/com/baeldung/si/TestSpringIntegrationSecurity.java new file mode 100644 index 0000000000..45dcb1e836 --- /dev/null +++ b/spring-integration/src/test/java/com/baeldung/si/TestSpringIntegrationSecurity.java @@ -0,0 +1,81 @@ +package com.baeldung.si; + +import static org.junit.Assert.*; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.messaging.SubscribableChannel; +import org.springframework.messaging.support.GenericMessage; +import org.springframework.security.access.AccessDeniedException; +import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.baeldung.si.security.MessageConsumer; +import com.baeldung.si.security.SecuredDirectChannel; +import com.baeldung.si.security.SecurityConfig; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = { SecurityConfig.class, SecuredDirectChannel.class, MessageConsumer.class }) +public class TestSpringIntegrationSecurity { + + @Autowired + SubscribableChannel startDirectChannel; + + @Autowired + MessageConsumer messageConsumer; + + final String DIRECT_CHANNEL_MESSAGE = "Direct channel message"; + + @Test(expected = AuthenticationCredentialsNotFoundException.class) + public void givenNoUser_whenSendToDirectChannel_thenCredentialNotFound() { + startDirectChannel.send(new GenericMessage(DIRECT_CHANNEL_MESSAGE)); + } + + @Test(expected = AccessDeniedException.class) + @WithMockUser(username = "jane", roles = { "LOGGER" }) + public void givenRoleLogger_whenSendMessageToDirectChannel_thenAccessDenied() throws Throwable { + try { + startDirectChannel.send(new GenericMessage(DIRECT_CHANNEL_MESSAGE)); + } catch (Exception e) { + throw e.getCause(); + } + } + + @Test(expected = AccessDeniedException.class) + @WithMockUser(username = "jane") + public void givenJane_whenSendMessageToDirectChannel_thenAccessDenied() throws Throwable { + try { + startDirectChannel.send(new GenericMessage(DIRECT_CHANNEL_MESSAGE)); + } catch (Exception e) { + throw e.getCause(); + } + } + + @Test(expected = AccessDeniedException.class) + @WithMockUser(roles = { "VIEWER" }) + public void givenRoleViewer_whenSendToDirectChannel_thenAccessDenied() throws Throwable { + try { + startDirectChannel.send(new GenericMessage(DIRECT_CHANNEL_MESSAGE)); + } catch (Exception e) { + throw e.getCause(); + } + } + + @Test + @WithMockUser(roles = { "LOGGER", "VIEWER", "EDITOR" }) + public void givenRoleLoggerAndUser_whenSendMessageToDirectChannel_thenFlowCompletedSuccessfully() { + startDirectChannel.send(new GenericMessage(DIRECT_CHANNEL_MESSAGE)); + assertEquals(DIRECT_CHANNEL_MESSAGE, messageConsumer.getMessageContent()); + } + + @Test + @WithMockUser(username = "jane", roles = { "LOGGER", "EDITOR" }) + public void givenJaneLoggerEditor_whenSendToDirectChannel_thenFlowCompleted() { + startDirectChannel.send(new GenericMessage(DIRECT_CHANNEL_MESSAGE)); + assertEquals(DIRECT_CHANNEL_MESSAGE, messageConsumer.getMessageContent()); + } + +} diff --git a/spring-integration/src/test/java/com/baeldung/si/TestSpringIntegrationSecurityExecutor.java b/spring-integration/src/test/java/com/baeldung/si/TestSpringIntegrationSecurityExecutor.java new file mode 100644 index 0000000000..b06136a7ca --- /dev/null +++ b/spring-integration/src/test/java/com/baeldung/si/TestSpringIntegrationSecurityExecutor.java @@ -0,0 +1,68 @@ +package com.baeldung.si; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.messaging.SubscribableChannel; +import org.springframework.messaging.support.GenericMessage; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.baeldung.si.security.MessageConsumer; +import com.baeldung.si.security.SecurityConfig; +import com.baeldung.si.security.SecurityPubSubChannel; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = { SecurityPubSubChannel.class, MessageConsumer.class, SecurityConfig.class }) +public class TestSpringIntegrationSecurityExecutor { + + @Autowired + SubscribableChannel startPSChannel; + + @Autowired + MessageConsumer messageConsumer; + + @Autowired + ThreadPoolTaskExecutor executor; + + final String DIRECT_CHANNEL_MESSAGE = "Direct channel message"; + + @Before + public void clearData() { + messageConsumer.setMessagePSContent(new ConcurrentHashMap<>()); + executor.setWaitForTasksToCompleteOnShutdown(true); + } + + @Test + @WithMockUser(username = "user", roles = { "VIEWER" }) + public void givenRoleUser_whenSendMessageToPSChannel_thenNoMessageArrived() throws IllegalStateException, InterruptedException { + startPSChannel.send(new GenericMessage(DIRECT_CHANNEL_MESSAGE)); + + executor.getThreadPoolExecutor().awaitTermination(2, TimeUnit.SECONDS); + + assertEquals(1, messageConsumer.getMessagePSContent().size()); + assertTrue(messageConsumer.getMessagePSContent().values().contains("user")); + } + + @Test + @WithMockUser(username = "user", roles = { "LOGGER", "VIEWER" }) + public void givenRoleUserAndLogger_whenSendMessageToPSChannel_then2GetMessages() throws IllegalStateException, InterruptedException { + startPSChannel.send(new GenericMessage(DIRECT_CHANNEL_MESSAGE)); + + executor.getThreadPoolExecutor().awaitTermination(2, TimeUnit.SECONDS); + + assertEquals(2, messageConsumer.getMessagePSContent().size()); + assertTrue(messageConsumer.getMessagePSContent().values().contains("user")); + assertTrue(messageConsumer.getMessagePSContent().values().contains("ROLE_LOGGER,ROLE_VIEWER")); + } + +} From 5a34de448edd30514b3454dddcb30f9ce5ea749e Mon Sep 17 00:00:00 2001 From: Orry Date: Tue, 6 Feb 2018 21:47:26 +0200 Subject: [PATCH 11/58] AssertJ Exception Assertions (#3600) * Add XML, JavaConfig and Autowired examples. * BAEL-1517: Added Java7 style assertions * BAEL-1517: Upgrade AssertJ to 3.9.0; add Java 8 style assertion tests * Revert "Add XML, JavaConfig and Autowired examples." This reverts commit 8f4df6b903866dac1725832d06ee7382fc89d0ce. --- testing-modules/testing/pom.xml | 2 +- .../exceptions/Java7StyleAssertions.java | 24 +++++++++++ .../exceptions/Java8StyleAssertions.java | 42 +++++++++++++++++++ 3 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 testing-modules/testing/src/test/java/com/baeldung/testing/assertj/exceptions/Java7StyleAssertions.java create mode 100644 testing-modules/testing/src/test/java/com/baeldung/testing/assertj/exceptions/Java8StyleAssertions.java diff --git a/testing-modules/testing/pom.xml b/testing-modules/testing/pom.xml index c76045380b..91792a4681 100644 --- a/testing-modules/testing/pom.xml +++ b/testing-modules/testing/pom.xml @@ -173,7 +173,7 @@ 0.7.7.201606060606 21.0 3.1.0 - 3.6.1 + 3.9.0 2.1.0 0.32 1.1.0 diff --git a/testing-modules/testing/src/test/java/com/baeldung/testing/assertj/exceptions/Java7StyleAssertions.java b/testing-modules/testing/src/test/java/com/baeldung/testing/assertj/exceptions/Java7StyleAssertions.java new file mode 100644 index 0000000000..07a5be1118 --- /dev/null +++ b/testing-modules/testing/src/test/java/com/baeldung/testing/assertj/exceptions/Java7StyleAssertions.java @@ -0,0 +1,24 @@ +package com.baeldung.testing.assertj.exceptions; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.fail; +import static org.assertj.core.api.Assertions.failBecauseExceptionWasNotThrown; + +import org.junit.Test; + +public class Java7StyleAssertions { + + @Test + public void whenDividingByZero_thenArithmeticException() { + try { + int numerator = 10; + int denominator = 0; + int quotient = numerator / denominator; + fail("ArithmeticException expected because dividing by zero yields an ArithmeticException."); + failBecauseExceptionWasNotThrown(ArithmeticException.class); + } catch (Exception e) { + assertThat(e).hasMessage("/ by zero"); + assertThat(e).isInstanceOf(ArithmeticException.class); + } + } +} diff --git a/testing-modules/testing/src/test/java/com/baeldung/testing/assertj/exceptions/Java8StyleAssertions.java b/testing-modules/testing/src/test/java/com/baeldung/testing/assertj/exceptions/Java8StyleAssertions.java new file mode 100644 index 0000000000..53f192bb2f --- /dev/null +++ b/testing-modules/testing/src/test/java/com/baeldung/testing/assertj/exceptions/Java8StyleAssertions.java @@ -0,0 +1,42 @@ +package com.baeldung.testing.assertj.exceptions; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.assertj.core.api.Assertions.catchThrowable; + +import org.junit.Test; + +public class Java8StyleAssertions { + + @Test + public void whenDividingByZero_thenArithmeticException() { + assertThatThrownBy(() -> { + int numerator = 10; + int denominator = 0; + int quotient = numerator / denominator; + }).isInstanceOf(ArithmeticException.class) + .hasMessageContaining("/ by zero"); + + assertThatExceptionOfType(ArithmeticException.class).isThrownBy(() -> { + int numerator = 10; + int denominator = 0; + int quotient = numerator / denominator; + }) + .withMessageContaining("/ by zero"); + + // BDD style: + + // when + Throwable thrown = catchThrowable(() -> { + int numerator = 10; + int denominator = 0; + int quotient = numerator / denominator; + }); + + // then + assertThat(thrown).isInstanceOf(ArithmeticException.class) + .hasMessageContaining("/ by zero"); + + } +} From efb66e300108383c5c72b304dc81429dba1a7acf Mon Sep 17 00:00:00 2001 From: deep20jain Date: Wed, 7 Feb 2018 01:37:38 +0530 Subject: [PATCH 12/58] Bael 1299 - Maze Solver - deep20jain@gmail.com (#3537) * Maze solver using DFS * Adding BFS maze solver * Fixing formatting --- .../algorithms/maze/solver/BFSMazeSolver.java | 52 +++++++ .../algorithms/maze/solver/Coordinate.java | 31 ++++ .../algorithms/maze/solver/DFSMazeSolver.java | 48 ++++++ .../baeldung/algorithms/maze/solver/Maze.java | 141 ++++++++++++++++++ .../algorithms/maze/solver/MazeDriver.java | 34 +++++ algorithms/src/main/resources/maze/maze1.txt | 12 ++ algorithms/src/main/resources/maze/maze2.txt | 22 +++ 7 files changed, 340 insertions(+) create mode 100644 algorithms/src/main/java/com/baeldung/algorithms/maze/solver/BFSMazeSolver.java create mode 100644 algorithms/src/main/java/com/baeldung/algorithms/maze/solver/Coordinate.java create mode 100644 algorithms/src/main/java/com/baeldung/algorithms/maze/solver/DFSMazeSolver.java create mode 100644 algorithms/src/main/java/com/baeldung/algorithms/maze/solver/Maze.java create mode 100644 algorithms/src/main/java/com/baeldung/algorithms/maze/solver/MazeDriver.java create mode 100644 algorithms/src/main/resources/maze/maze1.txt create mode 100644 algorithms/src/main/resources/maze/maze2.txt diff --git a/algorithms/src/main/java/com/baeldung/algorithms/maze/solver/BFSMazeSolver.java b/algorithms/src/main/java/com/baeldung/algorithms/maze/solver/BFSMazeSolver.java new file mode 100644 index 0000000000..08972251b8 --- /dev/null +++ b/algorithms/src/main/java/com/baeldung/algorithms/maze/solver/BFSMazeSolver.java @@ -0,0 +1,52 @@ +package com.baeldung.algorithms.maze.solver; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; + +public class BFSMazeSolver { + private static final int[][] DIRECTIONS = { { 0, 1 }, { 1, 0 }, { 0, -1 }, { -1, 0 } }; + + public List solve(Maze maze) { + LinkedList nextToVisit = new LinkedList<>(); + Coordinate start = maze.getEntry(); + nextToVisit.add(start); + + while (!nextToVisit.isEmpty()) { + Coordinate cur = nextToVisit.remove(); + + if (!maze.isValidLocation(cur.getX(), cur.getY()) || maze.isExplored(cur.getX(), cur.getY())) { + continue; + } + + if (maze.isWall(cur.getX(), cur.getY())) { + maze.setVisited(cur.getX(), cur.getY(), true); + continue; + } + + if (maze.isExit(cur.getX(), cur.getY())) { + return backtrackPath(cur); + } + + for (int[] direction : DIRECTIONS) { + Coordinate coordinate = new Coordinate(cur.getX() + direction[0], cur.getY() + direction[1], cur); + nextToVisit.add(coordinate); + maze.setVisited(cur.getX(), cur.getY(), true); + } + } + return Collections.emptyList(); + } + + private List backtrackPath(Coordinate cur) { + List path = new ArrayList<>(); + Coordinate iter = cur; + + while (iter != null) { + path.add(iter); + iter = iter.parent; + } + + return path; + } +} diff --git a/algorithms/src/main/java/com/baeldung/algorithms/maze/solver/Coordinate.java b/algorithms/src/main/java/com/baeldung/algorithms/maze/solver/Coordinate.java new file mode 100644 index 0000000000..09b2ced5e6 --- /dev/null +++ b/algorithms/src/main/java/com/baeldung/algorithms/maze/solver/Coordinate.java @@ -0,0 +1,31 @@ +package com.baeldung.algorithms.maze.solver; + +public class Coordinate { + int x; + int y; + Coordinate parent; + + public Coordinate(int x, int y) { + this.x = x; + this.y = y; + this.parent = null; + } + + public Coordinate(int x, int y, Coordinate parent) { + this.x = x; + this.y = y; + this.parent = parent; + } + + int getX() { + return x; + } + + int getY() { + return y; + } + + Coordinate getParent() { + return parent; + } +} diff --git a/algorithms/src/main/java/com/baeldung/algorithms/maze/solver/DFSMazeSolver.java b/algorithms/src/main/java/com/baeldung/algorithms/maze/solver/DFSMazeSolver.java new file mode 100644 index 0000000000..f9640066b9 --- /dev/null +++ b/algorithms/src/main/java/com/baeldung/algorithms/maze/solver/DFSMazeSolver.java @@ -0,0 +1,48 @@ +package com.baeldung.algorithms.maze.solver; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class DFSMazeSolver { + private static final int[][] DIRECTIONS = { { 0, 1 }, { 1, 0 }, { 0, -1 }, { -1, 0 } }; + + public List solve(Maze maze) { + List path = new ArrayList<>(); + if (explore(maze, maze.getEntry() + .getX(), + maze.getEntry() + .getY(), + path)) { + return path; + } + return Collections.emptyList(); + } + + private boolean explore(Maze maze, int row, int col, List path) { + if (!maze.isValidLocation(row, col) || maze.isWall(row, col) || maze.isExplored(row, col)) { + return false; + } + + path.add(new Coordinate(row, col)); + maze.setVisited(row, col, true); + + if (maze.isExit(row, col)) { + return true; + } + + for (int[] direction : DIRECTIONS) { + Coordinate coordinate = getNextCoordinate(row, col, direction[0], direction[1]); + if (explore(maze, coordinate.getX(), coordinate.getY(), path)) { + return true; + } + } + + path.remove(path.size() - 1); + return false; + } + + private Coordinate getNextCoordinate(int row, int col, int i, int j) { + return new Coordinate(row + i, col + j); + } +} diff --git a/algorithms/src/main/java/com/baeldung/algorithms/maze/solver/Maze.java b/algorithms/src/main/java/com/baeldung/algorithms/maze/solver/Maze.java new file mode 100644 index 0000000000..8aaa44d9b1 --- /dev/null +++ b/algorithms/src/main/java/com/baeldung/algorithms/maze/solver/Maze.java @@ -0,0 +1,141 @@ +package com.baeldung.algorithms.maze.solver; + +import java.io.File; +import java.io.FileNotFoundException; +import java.util.Arrays; +import java.util.List; +import java.util.Scanner; + +public class Maze { + private static final int ROAD = 0; + private static final int WALL = 1; + private static final int START = 2; + private static final int EXIT = 3; + private static final int PATH = 4; + + private int[][] maze; + private boolean[][] visited; + private Coordinate start; + private Coordinate end; + + public Maze(File maze) throws FileNotFoundException { + String fileText = ""; + try (Scanner input = new Scanner(maze)) { + while (input.hasNextLine()) { + fileText += input.nextLine() + "\n"; + } + } + initializeMaze(fileText); + } + + private void initializeMaze(String text) { + if (text == null || (text = text.trim()).length() == 0) { + throw new IllegalArgumentException("empty lines data"); + } + + String[] lines = text.split("[\r]?\n"); + maze = new int[lines.length][lines[0].length()]; + visited = new boolean[lines.length][lines[0].length()]; + + for (int row = 0; row < getHeight(); row++) { + if (lines[row].length() != getWidth()) { + throw new IllegalArgumentException("line " + (row + 1) + " wrong length (was " + lines[row].length() + " but should be " + getWidth() + ")"); + } + + for (int col = 0; col < getWidth(); col++) { + if (lines[row].charAt(col) == '#') + maze[row][col] = WALL; + else if (lines[row].charAt(col) == 'S') { + maze[row][col] = START; + start = new Coordinate(row, col); + } else if (lines[row].charAt(col) == 'E') { + maze[row][col] = EXIT; + end = new Coordinate(row, col); + } else + maze[row][col] = ROAD; + } + } + } + + public int getHeight() { + return maze.length; + } + + public int getWidth() { + return maze[0].length; + } + + public Coordinate getEntry() { + return start; + } + + public Coordinate getExit() { + return end; + } + + public boolean isExit(int x, int y) { + return x == end.getX() && y == end.getY(); + } + + public boolean isStart(int x, int y) { + return x == start.getX() && y == start.getY(); + } + + public boolean isExplored(int row, int col) { + return visited[row][col]; + } + + public boolean isWall(int row, int col) { + return maze[row][col] == WALL; + } + + public void setVisited(int row, int col, boolean value) { + visited[row][col] = value; + } + + public boolean isValidLocation(int row, int col) { + if (row < 0 || row >= getHeight() || col < 0 || col >= getWidth()) { + return false; + } + return true; + } + + public void printPath(List path) { + int[][] tempMaze = Arrays.stream(maze) + .map(int[]::clone) + .toArray(int[][]::new); + for (Coordinate coordinate : path) { + if (isStart(coordinate.getX(), coordinate.getY()) || isExit(coordinate.getX(), coordinate.getY())) { + continue; + } + tempMaze[coordinate.getX()][coordinate.getY()] = PATH; + } + System.out.println(toString(tempMaze)); + } + + public String toString(int[][] maze) { + StringBuilder result = new StringBuilder(getWidth() * (getHeight() + 1)); + for (int row = 0; row < getHeight(); row++) { + for (int col = 0; col < getWidth(); col++) { + if (maze[row][col] == ROAD) { + result.append(' '); + } else if (maze[row][col] == WALL) { + result.append('#'); + } else if (maze[row][col] == START) { + result.append('S'); + } else if (maze[row][col] == EXIT) { + result.append('E'); + } else { + result.append('.'); + } + } + result.append('\n'); + } + return result.toString(); + } + + public void reset() { + for (int i = 0; i < visited.length; i++) + Arrays.fill(visited[i], false); + } +} diff --git a/algorithms/src/main/java/com/baeldung/algorithms/maze/solver/MazeDriver.java b/algorithms/src/main/java/com/baeldung/algorithms/maze/solver/MazeDriver.java new file mode 100644 index 0000000000..60263deba3 --- /dev/null +++ b/algorithms/src/main/java/com/baeldung/algorithms/maze/solver/MazeDriver.java @@ -0,0 +1,34 @@ +package com.baeldung.algorithms.maze.solver; + +import java.io.File; +import java.util.List; + +public class MazeDriver { + public static void main(String[] args) throws Exception { + File maze1 = new File("src/main/resources/maze/maze1.txt"); + File maze2 = new File("src/main/resources/maze/maze2.txt"); + + execute(maze1); + execute(maze2); + } + + private static void execute(File file) throws Exception { + Maze maze = new Maze(file); + dfs(maze); + bfs(maze); + } + + private static void bfs(Maze maze) { + BFSMazeSolver bfs = new BFSMazeSolver(); + List path = bfs.solve(maze); + maze.printPath(path); + maze.reset(); + } + + private static void dfs(Maze maze) { + DFSMazeSolver dfs = new DFSMazeSolver(); + List path = dfs.solve(maze); + maze.printPath(path); + maze.reset(); + } +} diff --git a/algorithms/src/main/resources/maze/maze1.txt b/algorithms/src/main/resources/maze/maze1.txt new file mode 100644 index 0000000000..0a6309d25b --- /dev/null +++ b/algorithms/src/main/resources/maze/maze1.txt @@ -0,0 +1,12 @@ +S ######## +# # +# ### ## # +# # # # +# # # # # +# ## ##### +# # # +# # # # # +##### #### +# # E +# # # # +########## \ No newline at end of file diff --git a/algorithms/src/main/resources/maze/maze2.txt b/algorithms/src/main/resources/maze/maze2.txt new file mode 100644 index 0000000000..22e6d0382a --- /dev/null +++ b/algorithms/src/main/resources/maze/maze2.txt @@ -0,0 +1,22 @@ +S ########################## +# # # # +# # #### ############### # +# # # # # # +# # #### # # ############### +# # # # # # # +# # # #### ### ########### # +# # # # # # +# ################## # +######### # # # # # +# # #### # ####### # # +# # ### ### # # # # # +# # ## # ##### # # +##### ####### # # # # # +# # ## ## #### # # +# ##### ####### # # +# # ############ +####### ######### # # +# # ######## # +# ####### ###### ## # E +# # # ## # +############################ \ No newline at end of file From 596efe3042c68eb91cc048356ab71a9ae95ce1d7 Mon Sep 17 00:00:00 2001 From: Nikhil Khatwani Date: Wed, 7 Feb 2018 19:45:04 +0530 Subject: [PATCH 13/58] Changes for BAEL-1472 --- persistence-modules/spring-data-redis/pom.xml | 12 ++++- .../spring/data/redis/config/RedisConfig.java | 9 ++-- .../spring/data/redis/model/Student.java | 3 ++ .../data/redis/repo/StudentRepository.java | 19 ++----- .../redis/repo/StudentRepositoryImpl.java | 49 ------------------- .../StudentRepositoryIntegrationTest.java | 40 ++++++++------- 6 files changed, 46 insertions(+), 86 deletions(-) delete mode 100644 persistence-modules/spring-data-redis/src/main/java/com/baeldung/spring/data/redis/repo/StudentRepositoryImpl.java diff --git a/persistence-modules/spring-data-redis/pom.xml b/persistence-modules/spring-data-redis/pom.xml index 6cb49f11cf..0dc51e790e 100644 --- a/persistence-modules/spring-data-redis/pom.xml +++ b/persistence-modules/spring-data-redis/pom.xml @@ -16,11 +16,13 @@ UTF-8 - 4.3.7.RELEASE - 1.8.1.RELEASE + 5.0.3.RELEASE + 2.0.3.RELEASE 3.2.4 2.9.0 0.10.0 + 2.0.3.RELEASE + @@ -73,6 +75,12 @@ nosqlunit-redis ${nosqlunit.version} + + + org.springframework.data + spring-data-commons + 2.0.3.RELEASE + diff --git a/persistence-modules/spring-data-redis/src/main/java/com/baeldung/spring/data/redis/config/RedisConfig.java b/persistence-modules/spring-data-redis/src/main/java/com/baeldung/spring/data/redis/config/RedisConfig.java index 4fd83a2bb6..4ea8bb4bc0 100644 --- a/persistence-modules/spring-data-redis/src/main/java/com/baeldung/spring/data/redis/config/RedisConfig.java +++ b/persistence-modules/spring-data-redis/src/main/java/com/baeldung/spring/data/redis/config/RedisConfig.java @@ -1,8 +1,5 @@ package com.baeldung.spring.data.redis.config; -import com.baeldung.spring.data.redis.queue.MessagePublisher; -import com.baeldung.spring.data.redis.queue.RedisMessagePublisher; -import com.baeldung.spring.data.redis.queue.RedisMessageSubscriber; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @@ -11,10 +8,16 @@ import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.listener.ChannelTopic; import org.springframework.data.redis.listener.RedisMessageListenerContainer; import org.springframework.data.redis.listener.adapter.MessageListenerAdapter; +import org.springframework.data.redis.repository.configuration.EnableRedisRepositories; import org.springframework.data.redis.serializer.GenericToStringSerializer; +import com.baeldung.spring.data.redis.queue.MessagePublisher; +import com.baeldung.spring.data.redis.queue.RedisMessagePublisher; +import com.baeldung.spring.data.redis.queue.RedisMessageSubscriber; + @Configuration @ComponentScan("com.baeldung.spring.data.redis") +@EnableRedisRepositories(basePackages = "com.baeldung.spring.data.redis.repo") public class RedisConfig { @Bean diff --git a/persistence-modules/spring-data-redis/src/main/java/com/baeldung/spring/data/redis/model/Student.java b/persistence-modules/spring-data-redis/src/main/java/com/baeldung/spring/data/redis/model/Student.java index 10ba0f5ef4..b97ed23387 100644 --- a/persistence-modules/spring-data-redis/src/main/java/com/baeldung/spring/data/redis/model/Student.java +++ b/persistence-modules/spring-data-redis/src/main/java/com/baeldung/spring/data/redis/model/Student.java @@ -2,6 +2,9 @@ package com.baeldung.spring.data.redis.model; import java.io.Serializable; +import org.springframework.data.redis.core.RedisHash; + +@RedisHash("Student") public class Student implements Serializable { public enum Gender { diff --git a/persistence-modules/spring-data-redis/src/main/java/com/baeldung/spring/data/redis/repo/StudentRepository.java b/persistence-modules/spring-data-redis/src/main/java/com/baeldung/spring/data/redis/repo/StudentRepository.java index 250c227f00..39f13bb6a7 100644 --- a/persistence-modules/spring-data-redis/src/main/java/com/baeldung/spring/data/redis/repo/StudentRepository.java +++ b/persistence-modules/spring-data-redis/src/main/java/com/baeldung/spring/data/redis/repo/StudentRepository.java @@ -1,18 +1,9 @@ package com.baeldung.spring.data.redis.repo; +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Repository; + import com.baeldung.spring.data.redis.model.Student; -import java.util.Map; - -public interface StudentRepository { - - void saveStudent(Student person); - - void updateStudent(Student student); - - Student findStudent(String id); - - Map findAllStudents(); - - void deleteStudent(String id); -} +@Repository +public interface StudentRepository extends CrudRepository {} diff --git a/persistence-modules/spring-data-redis/src/main/java/com/baeldung/spring/data/redis/repo/StudentRepositoryImpl.java b/persistence-modules/spring-data-redis/src/main/java/com/baeldung/spring/data/redis/repo/StudentRepositoryImpl.java deleted file mode 100644 index f13bef0f54..0000000000 --- a/persistence-modules/spring-data-redis/src/main/java/com/baeldung/spring/data/redis/repo/StudentRepositoryImpl.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.baeldung.spring.data.redis.repo; - -import com.baeldung.spring.data.redis.model.Student; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.redis.core.HashOperations; -import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.stereotype.Repository; - -import javax.annotation.PostConstruct; -import java.util.Map; - -@Repository -public class StudentRepositoryImpl implements StudentRepository { - - private static final String KEY = "Student"; - - private RedisTemplate redisTemplate; - private HashOperations hashOperations; - - @Autowired - public StudentRepositoryImpl(RedisTemplate redisTemplate) { - this.redisTemplate = redisTemplate; - } - - @PostConstruct - private void init() { - hashOperations = redisTemplate.opsForHash(); - } - - public void saveStudent(final Student student) { - hashOperations.put(KEY, student.getId(), student); - } - - public void updateStudent(final Student student) { - hashOperations.put(KEY, student.getId(), student); - } - - public Student findStudent(final String id) { - return (Student) hashOperations.get(KEY, id); - } - - public Map findAllStudents() { - return hashOperations.entries(KEY); - } - - public void deleteStudent(final String id) { - hashOperations.delete(KEY, id); - } -} diff --git a/persistence-modules/spring-data-redis/src/test/java/com/baeldung/spring/data/redis/repo/StudentRepositoryIntegrationTest.java b/persistence-modules/spring-data-redis/src/test/java/com/baeldung/spring/data/redis/repo/StudentRepositoryIntegrationTest.java index 1028c0bc24..66ef3c21b2 100644 --- a/persistence-modules/spring-data-redis/src/test/java/com/baeldung/spring/data/redis/repo/StudentRepositoryIntegrationTest.java +++ b/persistence-modules/spring-data-redis/src/test/java/com/baeldung/spring/data/redis/repo/StudentRepositoryIntegrationTest.java @@ -1,17 +1,20 @@ package com.baeldung.spring.data.redis.repo; -import com.baeldung.spring.data.redis.config.RedisConfig; -import com.baeldung.spring.data.redis.model.Student; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import java.util.Map; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; +import com.baeldung.spring.data.redis.config.RedisConfig; +import com.baeldung.spring.data.redis.model.Student; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = RedisConfig.class) @@ -23,18 +26,18 @@ public class StudentRepositoryIntegrationTest { @Test public void whenSavingStudent_thenAvailableOnRetrieval() throws Exception { final Student student = new Student("Eng2015001", "John Doe", Student.Gender.MALE, 1); - studentRepository.saveStudent(student); - final Student retrievedStudent = studentRepository.findStudent(student.getId()); + studentRepository.save(student); + final Student retrievedStudent = studentRepository.findById(student.getId()).get(); assertEquals(student.getId(), retrievedStudent.getId()); } @Test public void whenUpdatingStudent_thenAvailableOnRetrieval() throws Exception { final Student student = new Student("Eng2015001", "John Doe", Student.Gender.MALE, 1); - studentRepository.saveStudent(student); + studentRepository.save(student); student.setName("Richard Watson"); - studentRepository.saveStudent(student); - final Student retrievedStudent = studentRepository.findStudent(student.getId()); + studentRepository.save(student); + final Student retrievedStudent = studentRepository.findById(student.getId()).get(); assertEquals(student.getName(), retrievedStudent.getName()); } @@ -42,18 +45,19 @@ public class StudentRepositoryIntegrationTest { public void whenSavingStudents_thenAllShouldAvailableOnRetrieval() throws Exception { final Student engStudent = new Student("Eng2015001", "John Doe", Student.Gender.MALE, 1); final Student medStudent = new Student("Med2015001", "Gareth Houston", Student.Gender.MALE, 2); - studentRepository.saveStudent(engStudent); - studentRepository.saveStudent(medStudent); - final Map retrievedStudent = studentRepository.findAllStudents(); - assertEquals(retrievedStudent.size(), 2); + studentRepository.save(engStudent); + studentRepository.save(medStudent); + List students = new ArrayList<>(); + studentRepository.findAll().forEach(students::add); + assertEquals(students.size(), 2); } @Test public void whenDeletingStudent_thenNotAvailableOnRetrieval() throws Exception { final Student student = new Student("Eng2015001", "John Doe", Student.Gender.MALE, 1); - studentRepository.saveStudent(student); - studentRepository.deleteStudent(student.getId()); - final Student retrievedStudent = studentRepository.findStudent(student.getId()); + studentRepository.save(student); + studentRepository.deleteById(student.getId()); + final Student retrievedStudent = studentRepository.findById(student.getId()).orElse(null); assertNull(retrievedStudent); } } \ No newline at end of file From b2372b50061766aa27e203d6a1f84a2e04fb4198 Mon Sep 17 00:00:00 2001 From: Nikhil Khatwani Date: Wed, 7 Feb 2018 19:46:42 +0530 Subject: [PATCH 14/58] Changes for BAEL-1472 --- persistence-modules/spring-data-redis/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/persistence-modules/spring-data-redis/pom.xml b/persistence-modules/spring-data-redis/pom.xml index 0dc51e790e..0b9075147d 100644 --- a/persistence-modules/spring-data-redis/pom.xml +++ b/persistence-modules/spring-data-redis/pom.xml @@ -79,7 +79,7 @@ org.springframework.data spring-data-commons - 2.0.3.RELEASE + ${spring-data-commons.version} From 6887bc10d1a3aa1d8b5778917c77c9047ef97dee Mon Sep 17 00:00:00 2001 From: shouvikbhattacharya Date: Wed, 7 Feb 2018 20:29:35 +0530 Subject: [PATCH 15/58] BAEL-1525: More changes. --- .../java/com/baeldung/string/Palindrome.java | 28 ++++++++++++++- .../string/WhenCheckingPalindrome.java | 36 +++++++++++++++++++ 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/core-java/src/main/java/com/baeldung/string/Palindrome.java b/core-java/src/main/java/com/baeldung/string/Palindrome.java index e339d92447..37284a5424 100644 --- a/core-java/src/main/java/com/baeldung/string/Palindrome.java +++ b/core-java/src/main/java/com/baeldung/string/Palindrome.java @@ -8,7 +8,33 @@ public class Palindrome { int forward = 0; int backward = length - 1; boolean palindrome = true; - while ((backward > forward)?(palindrome=(text.charAt(forward++) == text.charAt(backward--))):false); + while (backward > forward) { + char forwardChar = text.charAt(forward++); + char backwardChar = text.charAt(backward--); + if (forwardChar != backwardChar) + return false; + } return palindrome; } + + public boolean isPalindromeReverseTheString(String text) { + String reverse = ""; + text = text.toLowerCase(); + char[] plain = text.toCharArray(); + for (int i = plain.length - 1; i >= 0; i--) + reverse += plain[i]; + return reverse.equals(text); + } + + public boolean isPalindromeUsingStringBuilder(String text) { + StringBuilder plain = new StringBuilder(text); + StringBuilder reverse = plain.reverse(); + return reverse.equals(plain); + } + + public boolean isPalindromeUsingStringBuffer(String text) { + StringBuffer plain = new StringBuffer(text); + StringBuffer reverse = plain.reverse(); + return reverse.equals(plain); + } } diff --git a/core-java/src/test/java/com/baeldung/string/WhenCheckingPalindrome.java b/core-java/src/test/java/com/baeldung/string/WhenCheckingPalindrome.java index 691d74c751..eeaed09fff 100644 --- a/core-java/src/test/java/com/baeldung/string/WhenCheckingPalindrome.java +++ b/core-java/src/test/java/com/baeldung/string/WhenCheckingPalindrome.java @@ -34,4 +34,40 @@ public class WhenCheckingPalindrome { for(String sentence:sentences) Assert.assertTrue(palindrome.isPalindrome(sentence)); } + + @Test + public void whenReverseWord_shouldBePalindrome() { + for(String word:words) + Assert.assertTrue(palindrome.isPalindromeReverseTheString(word)); + } + + @Test + public void whenReverseSentence_shouldBePalindrome() { + for(String sentence:sentences) + Assert.assertTrue(palindrome.isPalindromeReverseTheString(sentence)); + } + + @Test + public void whenStringBuilderWord_shouldBePalindrome() { + for(String word:words) + Assert.assertTrue(palindrome.isPalindromeUsingStringBuilder(word)); + } + + @Test + public void whenStringBuilderSentence_shouldBePalindrome() { + for(String sentence:sentences) + Assert.assertTrue(palindrome.isPalindromeUsingStringBuilder(sentence)); + } + + @Test + public void whenStringBufferWord_shouldBePalindrome() { + for(String word:words) + Assert.assertTrue(palindrome.isPalindromeUsingStringBuffer(word)); + } + + @Test + public void whenStringBufferSentence_shouldBePalindrome() { + for(String sentence:sentences) + Assert.assertTrue(palindrome.isPalindromeUsingStringBuffer(sentence)); + } } From 0743dec07c59c0fecb8ac3ad0052457d5e6feaf6 Mon Sep 17 00:00:00 2001 From: iaforek Date: Thu, 8 Feb 2018 06:26:42 +0000 Subject: [PATCH 16/58] Extracted 'constraints' methods and renamed variables (#3580) * Code for Dependency Injection Article. * Added Java based configuration. Downloaded formatter.xml and reformatted all changed files. Manually changed tab into 4 spaces in XML configuration files. * BAEL-434 - Spring Roo project files generated by Spring Roo. No formatting applied. Added POM, java and resources folders. * Moved project from roo to spring-roo folder. * BAEL-838 Initial code showing how to remove last char - helper class and tests. * BAEL-838 Corrected Helper class and associated empty string test case. Added StringUtils.substing tests. * BAEL-838 Refromatted code using formatter.xml. Added Assert.assertEquals import. Renamed test to follow convention. Reordered tests. * BAEL-838 - Added regex method and updated tests. * BAEL-838 Added new line examples. * BAEL-838 Renamed RemoveLastChar class to StringHelper and added Java8 examples. Refactord code. * BAEL-838 Changed method names * BAEL-838 Tiny change to keep code consistant. Return null or empty. * BAEL-838 Removed unresolved conflict. * BAEL-821 New class that shows different rounding techniques. Updated POM. * BAEL-821 - Added unit test for different round methods. * BAEL-821 Changed test method name to follow the convention * BAEL-821 Added more test and updated round methods. * BAEL-837 - initial commit. A few examples of adding doubles. * BAEL-837 - Couple of smaller changes * BAEL-837 - Added jUnit test. * BAEL-579 Updated Spring Cloud Version I was getting error: java.lang.NoSuchMethodError: org.springframework.cloud.config.environment.Environment After version update, all is okay. * BAEL-579 Added actuator to Cloud Config Client. * BAEL-579 Enabled cloud bus and updated dependencies. * BAEL-579 Config Client using Spring Cloud Bus. * BAEL-579 Recreated Basic Config Server. * BAEL-579 Recreated Config Client. * BAEL-579 Removed test Git URL. * BAEL-579 Added Actuator to Config Client * BAEL-579 Added Spring Cloud Bus to Client. * BAEL-579 Server changes for Spring Cloud Bus Added dependencies and removed git.clone-on-start as this was causing server to throw errors after git properties change. * BAEL-579 Removed Git URL. * Revert "BAEL-579 Updated Spring Cloud Version" This reverts commit f775bf91e53a1ecfb9b70596688d7c8202bf495f. * Revert "BAEL-579 Config Client using Spring Cloud Bus." This reverts commit 1d96bc5761994a33af9a7a9aa5ab68604a5b44dc. * Revert "BAEL-579 Enabled cloud bus and updated dependencies." This reverts commit 7845da922d89d53506dd0fff387ea13694c50bc1. * Revert "BAEL-579 Added actuator to Cloud Config Client." This reverts commit 076657a26a57e0aa676989a4d97966a3b9d53e1c. * BAEL-579 Added missing dependency versions. * BAEL-579 Added missing dependency versions. * Updated gitignore * BAEL-1065 Simple performance check StringBuffer vs StringBuilder. * BAEL-1065 Added JMH benchmarks * BAEL-1298 Sudoku - Backtracking Algorithm * BAEL-1298 Sudoku - Backtracking Algorithm * BAEL-1298 Dancing Links Algorithm. Smaller changes to Backtracking * BAEL-1298 Resolve conflict - use most up-to-date POM * Updated code - mostly with CONSTANTS. Extracted methods. * Removed pointless Java8 code. Renamed constant * Extracted 'constraints' methods and renamed coverBoard variable * Extracted 'constraints' methods and renamed coverBoard variable --- .../sudoku/BacktrackingAlgorithm.java | 2 +- .../algorithms/sudoku/DancingLinks.java | 4 +- .../sudoku/DancingLinksAlgorithm.java | 87 +++++++++++-------- 3 files changed, 53 insertions(+), 40 deletions(-) diff --git a/algorithms/src/main/java/com/baeldung/algorithms/sudoku/BacktrackingAlgorithm.java b/algorithms/src/main/java/com/baeldung/algorithms/sudoku/BacktrackingAlgorithm.java index dc2a324c12..ff426cbe68 100644 --- a/algorithms/src/main/java/com/baeldung/algorithms/sudoku/BacktrackingAlgorithm.java +++ b/algorithms/src/main/java/com/baeldung/algorithms/sudoku/BacktrackingAlgorithm.java @@ -101,4 +101,4 @@ public class BacktrackingAlgorithm { } return true; } -} \ No newline at end of file +} diff --git a/algorithms/src/main/java/com/baeldung/algorithms/sudoku/DancingLinks.java b/algorithms/src/main/java/com/baeldung/algorithms/sudoku/DancingLinks.java index e5a02b7c91..d3cbb2bd02 100644 --- a/algorithms/src/main/java/com/baeldung/algorithms/sudoku/DancingLinks.java +++ b/algorithms/src/main/java/com/baeldung/algorithms/sudoku/DancingLinks.java @@ -120,10 +120,10 @@ public class DancingLinks { } private static void printSolution(int[][] result) { - int N = result.length; + int size = result.length; for (int[] aResult : result) { StringBuilder ret = new StringBuilder(); - for (int j = 0; j < N; j++) { + for (int j = 0; j < size; j++) { ret.append(aResult[j]).append(" "); } System.out.println(ret); diff --git a/algorithms/src/main/java/com/baeldung/algorithms/sudoku/DancingLinksAlgorithm.java b/algorithms/src/main/java/com/baeldung/algorithms/sudoku/DancingLinksAlgorithm.java index 6b0f57a075..76b686afa6 100644 --- a/algorithms/src/main/java/com/baeldung/algorithms/sudoku/DancingLinksAlgorithm.java +++ b/algorithms/src/main/java/com/baeldung/algorithms/sudoku/DancingLinksAlgorithm.java @@ -39,70 +39,83 @@ public class DancingLinksAlgorithm { } private boolean[][] createExactCoverBoard() { - boolean[][] R = new boolean[BOARD_SIZE * BOARD_SIZE * MAX_VALUE][BOARD_SIZE * BOARD_SIZE * CONSTRAINTS]; + boolean[][] coverBoard = new boolean[BOARD_SIZE * BOARD_SIZE * MAX_VALUE][BOARD_SIZE * BOARD_SIZE * CONSTRAINTS]; int hBase = 0; + hBase = checkCellConstraint(coverBoard, hBase); + hBase = checkRowConstraint(coverBoard, hBase); + hBase = checkColumnConstraint(coverBoard, hBase); + checkSubsectionConstraint(coverBoard, hBase); + + return coverBoard; + } - // Cell constraint. - for (int r = COVER_START_INDEX; r <= BOARD_SIZE; r++) { - for (int c = COVER_START_INDEX; c <= BOARD_SIZE; c++, hBase++) { - for (int n = COVER_START_INDEX; n <= BOARD_SIZE; n++) { - int index = getIndex(r, c, n); - R[index][hBase] = true; - } - } - } - - // Row constrain. - for (int r = COVER_START_INDEX; r <= BOARD_SIZE; r++) { - for (int n = COVER_START_INDEX; n <= BOARD_SIZE; n++, hBase++) { - for (int c1 = COVER_START_INDEX; c1 <= BOARD_SIZE; c1++) { - int index = getIndex(r, c1, n); - R[index][hBase] = true; - } - } - } - - // Column constraint. - for (int c = COVER_START_INDEX; c <= BOARD_SIZE; c++) { - for (int n = COVER_START_INDEX; n <= BOARD_SIZE; n++, hBase++) { - for (int r1 = COVER_START_INDEX; r1 <= BOARD_SIZE; r1++) { - int index = getIndex(r1, c, n); - R[index][hBase] = true; - } - } - } - - // Subsection constraint + private int checkSubsectionConstraint(boolean[][] coverBoard, int hBase) { for (int br = COVER_START_INDEX; br <= BOARD_SIZE; br += SUBSECTION_SIZE) { for (int bc = COVER_START_INDEX; bc <= BOARD_SIZE; bc += SUBSECTION_SIZE) { for (int n = COVER_START_INDEX; n <= BOARD_SIZE; n++, hBase++) { for (int rDelta = 0; rDelta < SUBSECTION_SIZE; rDelta++) { for (int cDelta = 0; cDelta < SUBSECTION_SIZE; cDelta++) { int index = getIndex(br + rDelta, bc + cDelta, n); - R[index][hBase] = true; + coverBoard[index][hBase] = true; } } } } } - return R; + return hBase; + } + + private int checkColumnConstraint(boolean[][] coverBoard, int hBase) { + for (int c = COVER_START_INDEX; c <= BOARD_SIZE; c++) { + for (int n = COVER_START_INDEX; n <= BOARD_SIZE; n++, hBase++) { + for (int r1 = COVER_START_INDEX; r1 <= BOARD_SIZE; r1++) { + int index = getIndex(r1, c, n); + coverBoard[index][hBase] = true; + } + } + } + return hBase; + } + + private int checkRowConstraint(boolean[][] coverBoard, int hBase) { + for (int r = COVER_START_INDEX; r <= BOARD_SIZE; r++) { + for (int n = COVER_START_INDEX; n <= BOARD_SIZE; n++, hBase++) { + for (int c1 = COVER_START_INDEX; c1 <= BOARD_SIZE; c1++) { + int index = getIndex(r, c1, n); + coverBoard[index][hBase] = true; + } + } + } + return hBase; + } + + private int checkCellConstraint(boolean[][] coverBoard, int hBase) { + for (int r = COVER_START_INDEX; r <= BOARD_SIZE; r++) { + for (int c = COVER_START_INDEX; c <= BOARD_SIZE; c++, hBase++) { + for (int n = COVER_START_INDEX; n <= BOARD_SIZE; n++) { + int index = getIndex(r, c, n); + coverBoard[index][hBase] = true; + } + } + } + return hBase; } private boolean[][] initializeExactCoverBoard(int[][] board) { - boolean[][] R = createExactCoverBoard(); + boolean[][] coverBoard = createExactCoverBoard(); for (int i = COVER_START_INDEX; i <= BOARD_SIZE; i++) { for (int j = COVER_START_INDEX; j <= BOARD_SIZE; j++) { int n = board[i - 1][j - 1]; if (n != NO_VALUE) { for (int num = MIN_VALUE; num <= MAX_VALUE; num++) { if (num != n) { - Arrays.fill(R[getIndex(i, j, num)], false); + Arrays.fill(coverBoard[getIndex(i, j, num)], false); } } } } } - return R; + return coverBoard; } } \ No newline at end of file From 2b2b78cbf28072ed643c1b37cfd5929bada148b3 Mon Sep 17 00:00:00 2001 From: felipeazv Date: Thu, 8 Feb 2018 10:24:21 +0100 Subject: [PATCH 17/58] [BAEL-1449]-Combining Publishers (Project Reactor) --- .../reactor/core/CombiningPublishersTest.java | 107 ++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 reactor-core/src/test/java/com/baeldung/reactor/core/CombiningPublishersTest.java diff --git a/reactor-core/src/test/java/com/baeldung/reactor/core/CombiningPublishersTest.java b/reactor-core/src/test/java/com/baeldung/reactor/core/CombiningPublishersTest.java new file mode 100644 index 0000000000..f33f911274 --- /dev/null +++ b/reactor-core/src/test/java/com/baeldung/reactor/core/CombiningPublishersTest.java @@ -0,0 +1,107 @@ +package com.baeldung.reactor.core; + +import java.time.Duration; + +import org.junit.Test; + +import reactor.core.publisher.Flux; +import reactor.test.StepVerifier; + +public class CombiningPublishersTest { + + private static Integer min = 1; + private static Integer max = 5; + + private static Flux evenNumbers = Flux.range(min, max).filter(x -> x % 2 == 0); + private static Flux oddNumbers = Flux.range(min, max).filter(x -> x % 2 > 0); + + + @Test + public void testMerge() { + Flux fluxOfIntegers = Flux.merge( + evenNumbers, + oddNumbers); + + StepVerifier.create(fluxOfIntegers) + .expectNext(2) + .expectNext(4) + .expectNext(1) + .expectNext(3) + .expectNext(5) + .expectComplete() + .verify(); + } + + @Test + public void testMergeWithDelayedElements() { + Flux fluxOfIntegers = Flux.merge( + evenNumbers.delayElements(Duration.ofMillis(500L)), + oddNumbers.delayElements(Duration.ofMillis(300L))); + + StepVerifier.create(fluxOfIntegers) + .expectNext(1) + .expectNext(2) + .expectNext(3) + .expectNext(5) + .expectNext(4) + .expectComplete() + .verify(); + } + + @Test + public void testConcat() { + Flux fluxOfIntegers = Flux.concat( + evenNumbers.delayElements(Duration.ofMillis(500L)), + oddNumbers.delayElements(Duration.ofMillis(300L))); + + StepVerifier.create(fluxOfIntegers) + .expectNext(2) + .expectNext(4) + .expectNext(1) + .expectNext(3) + .expectNext(5) + .expectComplete() + .verify(); + } + + @Test + public void testConcatWith() { + Flux fluxOfIntegers = evenNumbers + .concatWith(oddNumbers); + + StepVerifier.create(fluxOfIntegers) + .expectNext(2) + .expectNext(4) + .expectNext(1) + .expectNext(3) + .expectNext(5) + .expectComplete() + .verify(); + } + + @Test + public void testCombineLatest() { + Flux fluxOfIntegers = Flux.combineLatest( + evenNumbers, + oddNumbers, + (a, b) -> a + b); + + StepVerifier.create(fluxOfIntegers) + .expectNext(5) + .expectNext(7) + .expectNext(9) + .expectComplete() + .verify(); + + } + + @Test + public void testCombineLatest1() { + StepVerifier.create(Flux.combineLatest(obj -> (int) obj[1], evenNumbers, oddNumbers)) + .expectNext(1) + .expectNext(3) + .expectNext(5) + .verifyComplete(); + } + +} From 19ef04d07cb25d48f7c6b8ab6e8f0ea24556d46d Mon Sep 17 00:00:00 2001 From: felipeazv Date: Thu, 8 Feb 2018 10:30:46 +0100 Subject: [PATCH 18/58] [BAEL-1449]-Combining Publishers (Project Reactor) --- reactor-core/pom.xml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/reactor-core/pom.xml b/reactor-core/pom.xml index 12f481c96f..d387471d56 100644 --- a/reactor-core/pom.xml +++ b/reactor-core/pom.xml @@ -26,11 +26,17 @@ ${assertj.version} test - + + + io.projectreactor + reactor-test + ${reactor-core.version} + test + - 3.0.5.RELEASE + 3.1.3.RELEASE 3.6.1 From 5ce6ad7d8f42af90c131f2efe107be303b143f2c Mon Sep 17 00:00:00 2001 From: felipeazv Date: Thu, 8 Feb 2018 11:39:09 +0100 Subject: [PATCH 19/58] [BAEL-1449]-Combining Publishers (Project Reactor) --- .../reactor/core/CombiningPublishersTest.java | 77 ++++++++++++++++++- 1 file changed, 76 insertions(+), 1 deletion(-) diff --git a/reactor-core/src/test/java/com/baeldung/reactor/core/CombiningPublishersTest.java b/reactor-core/src/test/java/com/baeldung/reactor/core/CombiningPublishersTest.java index f33f911274..9d5d094875 100644 --- a/reactor-core/src/test/java/com/baeldung/reactor/core/CombiningPublishersTest.java +++ b/reactor-core/src/test/java/com/baeldung/reactor/core/CombiningPublishersTest.java @@ -103,5 +103,80 @@ public class CombiningPublishersTest { .expectNext(5) .verifyComplete(); } - + + @Test + public void testMergeSequential() { + Flux fluxOfIntegers = Flux.mergeSequential( + evenNumbers, + oddNumbers); + + StepVerifier.create(fluxOfIntegers) + .expectNext(2) + .expectNext(4) + .expectNext(1) + .expectNext(3) + .expectNext(5) + .expectComplete() + .verify(); + } + + + @Test + public void testMergeDelayError() { + Flux fluxOfIntegers = Flux.mergeDelayError(1, + evenNumbers.delayElements(Duration.ofMillis(500L)), + oddNumbers.delayElements(Duration.ofMillis(300L))); + + StepVerifier.create(fluxOfIntegers) + .expectNext(1) + .expectNext(2) + .expectNext(3) + .expectNext(5) + .expectNext(4) + .expectComplete() + .verify(); + } + + @Test + public void testMergeWith() { + Flux fluxOfIntegers = evenNumbers.mergeWith(oddNumbers); + + StepVerifier.create(fluxOfIntegers) + .expectNext(2) + .expectNext(4) + .expectNext(1) + .expectNext(3) + .expectNext(5) + .expectComplete() + .verify(); + } + + @Test + public void testZip() { + Flux fluxOfIntegers = Flux.zip( + evenNumbers, + oddNumbers, + (a, b) -> a + b); + + StepVerifier.create(fluxOfIntegers) + .expectNext(3) + .expectNext(7) + .expectComplete() + .verify(); + } + + @Test + public void testZipWith() { + Flux fluxOfIntegers = evenNumbers + .zipWith(oddNumbers, + (a, b) -> a * b); + + StepVerifier.create(fluxOfIntegers) + .expectNext(2) + .expectNext(12) + .expectComplete() + .verify(); + } + + } From 9d9045f130e647ccc48f78c11a3b7980880c2a72 Mon Sep 17 00:00:00 2001 From: shouvikbhattacharya Date: Thu, 8 Feb 2018 21:04:46 +0530 Subject: [PATCH 20/58] BAEL-1525: New changes added. --- .../java/com/baeldung/string/Palindrome.java | 17 +++++++- .../string/WhenCheckingPalindrome.java | 41 +++++++++++++++++++ 2 files changed, 56 insertions(+), 2 deletions(-) diff --git a/core-java/src/main/java/com/baeldung/string/Palindrome.java b/core-java/src/main/java/com/baeldung/string/Palindrome.java index 37284a5424..03b65d1a84 100644 --- a/core-java/src/main/java/com/baeldung/string/Palindrome.java +++ b/core-java/src/main/java/com/baeldung/string/Palindrome.java @@ -3,7 +3,8 @@ package com.baeldung.string; public class Palindrome { public boolean isPalindrome(String text) { - text = text.replaceAll("\\s+", "").toLowerCase(); + text = text.replaceAll("\\s+", "") + .toLowerCase(); int length = text.length(); int forward = 0; int backward = length - 1; @@ -19,7 +20,7 @@ public class Palindrome { public boolean isPalindromeReverseTheString(String text) { String reverse = ""; - text = text.toLowerCase(); + text = text.replaceAll("\\s+", "").toLowerCase(); char[] plain = text.toCharArray(); for (int i = plain.length - 1; i >= 0; i--) reverse += plain[i]; @@ -37,4 +38,16 @@ public class Palindrome { StringBuffer reverse = plain.reverse(); return reverse.equals(plain); } + + public boolean isPalindromeRecursive(String text, int forward, int backward) { + if (forward == backward) + return true; + if ((text.charAt(forward)) != (text.charAt(backward))) + return false; + if (forward < backward + 1) { + return isPalindromeRecursive(text, forward + 1, backward - 1); + } + + return true; + } } diff --git a/core-java/src/test/java/com/baeldung/string/WhenCheckingPalindrome.java b/core-java/src/test/java/com/baeldung/string/WhenCheckingPalindrome.java index eeaed09fff..e3655a3140 100644 --- a/core-java/src/test/java/com/baeldung/string/WhenCheckingPalindrome.java +++ b/core-java/src/test/java/com/baeldung/string/WhenCheckingPalindrome.java @@ -1,5 +1,7 @@ package com.baeldung.string; +import java.util.Arrays; + import org.junit.Assert; import org.junit.Test; @@ -68,6 +70,45 @@ public class WhenCheckingPalindrome { @Test public void whenStringBufferSentence_shouldBePalindrome() { for(String sentence:sentences) + Assert.assertTrue(palindrome.isPalindromeUsingStringBuffer(sentence)); } + + @Test + public void whenPalindromeRecursive_wordShouldBePalindrome() { + for(String word:words) { + word = word.replaceAll("\\s+", "").toLowerCase(); + int backward = word.length()-1; + + Assert.assertTrue(palindrome.isPalindromeRecursive(word,0,backward)); + } + } + + @Test + public void whenPalindromeRecursive_sentenceShouldBePalindrome() { + for(String sentence:sentences) { + sentence = sentence.replaceAll("\\s+", "").toLowerCase(); + int backward = sentence.length()-1; + + Assert.assertTrue(palindrome.isPalindromeRecursive(sentence,0,backward)); + } + } + + @Test + public void whenPalindromeStreams_wordShouldBePalindrome() { + String[] expected = Arrays.stream(words) + .filter(palindrome::isPalindrome) + .toArray(String[]::new); + + Assert.assertArrayEquals(expected, words); + } + + @Test + public void whenPalindromeStreams_sentenceShouldBePalindrome() { + String[] expected = Arrays.stream(sentences) + .filter(palindrome::isPalindrome) + .toArray(String[]::new); + + Assert.assertArrayEquals(expected, sentences); + } } From 8b279673c493f43ea821c90ab9fe3f4995276b49 Mon Sep 17 00:00:00 2001 From: Alessio Stalla Date: Thu, 8 Feb 2018 23:05:13 +0100 Subject: [PATCH 21/58] Code for BAEL-894 - regular expressions in Kotlin (#3618) --- .../com/baeldung/kotlin/stdlib/RegexTest.kt | 128 ++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 core-kotlin/src/test/kotlin/com/baeldung/kotlin/stdlib/RegexTest.kt diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/stdlib/RegexTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/stdlib/RegexTest.kt new file mode 100644 index 0000000000..eeb587ee22 --- /dev/null +++ b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/stdlib/RegexTest.kt @@ -0,0 +1,128 @@ +package com.baeldung.kotlin.stdlib + +import org.junit.Test +import java.beans.ExceptionListener +import java.beans.XMLEncoder +import java.io.* +import java.lang.Exception +import kotlin.test.* +import kotlin.text.RegexOption.* + +class RegexTest { + + @Test + fun whenRegexIsInstantiated_thenIsEqualToToRegexMethod() { + val pattern = """a([bc]+)d?\\""" + + assertEquals(Regex.fromLiteral(pattern).pattern, pattern) + assertEquals(pattern, Regex(pattern).pattern) + assertEquals(pattern, pattern.toRegex().pattern) + } + + @Test + fun whenRegexMatches_thenResultIsTrue() { + val regex = """a([bc]+)d?""".toRegex() + + assertTrue(regex.containsMatchIn("xabcdy")) + assertTrue(regex.matches("abcd")) + assertFalse(regex matches "xabcdy") + } + + @Test + fun givenCompletelyMatchingRegex_whenMatchResult_thenDestructuring() { + val regex = """a([bc]+)d?""".toRegex() + + assertNull(regex.matchEntire("xabcdy")) + + val matchResult = regex.matchEntire("abbccbbd") + + assertNotNull(matchResult) + assertEquals(matchResult!!.value, matchResult.groupValues[0]) + assertEquals(matchResult.destructured.toList(), matchResult.groupValues.drop(1)) + assertEquals("bbccbb", matchResult.destructured.component1()) + assertNull(matchResult.next()) + } + + @Test + fun givenPartiallyMatchingRegex_whenMatchResult_thenGroups() { + val regex = """a([bc]+)d?""".toRegex() + var matchResult = regex.find("abcb abbd") + + assertNotNull(matchResult) + assertEquals(matchResult!!.value, matchResult.groupValues[0]) + assertEquals("abcb", matchResult.value) + assertEquals(IntRange(0, 3), matchResult.range) + assertEquals(listOf("abcb", "bcb"), matchResult.groupValues) + assertEquals(matchResult.destructured.toList(), matchResult.groupValues.drop(1)) + + matchResult = matchResult.next() + + assertNotNull(matchResult) + assertEquals("abbd", matchResult!!.value) + assertEquals("bb", matchResult.groupValues[1]) + + matchResult = matchResult.next() + + assertNull(matchResult) + } + + @Test + fun givenPartiallyMatchingRegex_whenMatchResult_thenDestructuring() { + val regex = """([\w\s]+) is (\d+) years old""".toRegex() + val matchResult = regex.find("Mickey Mouse is 95 years old") + val (name, age) = matchResult!!.destructured + + assertEquals("Mickey Mouse", name) + assertEquals("95", age) + } + + @Test + fun givenNonMatchingRegex_whenFindCalled_thenNull() { + val regex = """a([bc]+)d?""".toRegex() + val matchResult = regex.find("foo") + + assertNull(matchResult) + } + + @Test + fun givenNonMatchingRegex_whenFindAllCalled_thenEmptySet() { + val regex = """a([bc]+)d?""".toRegex() + val matchResults = regex.findAll("foo") + + assertNotNull(matchResults) + assertTrue(matchResults.none()) + } + + @Test + fun whenReplace_thenReplacement() { + val regex = """(red|green|blue)""".toRegex() + val beautiful = "Roses are red, Violets are blue" + val grim = regex.replace(beautiful, "dark") + val shiny = regex.replaceFirst(beautiful, "rainbow") + + assertEquals("Roses are dark, Violets are dark", grim) + assertEquals("Roses are rainbow, Violets are blue", shiny) + } + + @Test + fun whenComplexReplace_thenReplacement() { + val regex = """(red|green|blue)""".toRegex() + val beautiful = "Roses are red, Violets are blue" + val reallyBeautiful = regex.replace(beautiful) { + matchResult -> matchResult.value.toUpperCase() + "!" + } + + assertEquals("Roses are RED!, Violets are BLUE!", reallyBeautiful) + } + + @Test + fun whenSplit_thenList() { + val regex = """\W+""".toRegex() + val beautiful = "Roses are red, Violets are blue" + + assertEquals(listOf("Roses", "are", "red", "Violets", "are", "blue"), regex.split(beautiful)) + assertEquals(listOf("Roses", "are", "red", "Violets are blue"), regex.split(beautiful, 4)) + assertEquals(regex.toPattern().split(beautiful).asList(), regex.split(beautiful)) + } + +} \ No newline at end of file From 65267041c31b198960404408a45d872f9476656c Mon Sep 17 00:00:00 2001 From: Graham Cox Date: Fri, 9 Feb 2018 12:11:19 +0000 Subject: [PATCH 22/58] Examples for Infix Functions article (#3606) --- .../com/baeldung/kotlin/InfixFunctionsTest.kt | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 core-kotlin/src/test/kotlin/com/baeldung/kotlin/InfixFunctionsTest.kt diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/InfixFunctionsTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/InfixFunctionsTest.kt new file mode 100644 index 0000000000..fc4286460a --- /dev/null +++ b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/InfixFunctionsTest.kt @@ -0,0 +1,51 @@ +package com.baeldung.kotlin + +import org.junit.Assert +import org.junit.Test + +class InfixFunctionsTest { + @Test + fun testColours() { + val color = 0x123456 + val red = (color and 0xff0000) shr 16 + val green = (color and 0x00ff00) shr 8 + val blue = (color and 0x0000ff) shr 0 + + Assert.assertEquals(0x12, red) + Assert.assertEquals(0x34, green) + Assert.assertEquals(0x56, blue) + } + + @Test + fun testNewAssertions() { + class Assertion(private val target: T) { + infix fun isEqualTo(other: T) { + Assert.assertEquals(other, target) + } + + infix fun isDifferentFrom(other: T) { + Assert.assertNotEquals(other, target) + } + } + + val result = Assertion(5) + + result isEqualTo 5 + + // The following two lines are expected to fail + // result isEqualTo 6 + // result isDifferentFrom 5 + } + + @Test + fun testNewStringMethod() { + infix fun String.substringMatches(r: Regex) : List { + return r.findAll(this) + .map { it.value } + .toList() + } + + val matches = "a bc def" substringMatches ".*? ".toRegex() + Assert.assertEquals(listOf("a ", "bc "), matches) + } +} From d4522c7c16acc1c0f0c0e4eddd4e4e6165857b5c Mon Sep 17 00:00:00 2001 From: Dassi orleando Date: Fri, 9 Feb 2018 22:25:13 +0100 Subject: [PATCH 23/58] BAEL-1285: Update Jackson articles (#3623) * BAEL-1216: improve tests * BAEL-1448: Update Spring 5 articles to use the release version * Setting up the Maven Wrapper on a maven project * Add Maven Wrapper on spring-boot module * simple add * BAEL-976: Update spring version * BAEL-1273: Display RSS feed with spring mvc (AbstractRssFeedView) * Move RSS feed with Spring MVC from spring-boot to spring-mvc-simple * BAEL-1285: Update Jackson articles * BAEL-1273: implement both MVC and Rest approach to serve RSS content --- .gitignore | 1 + jackson/pom.xml | 2 +- spring-mvc-java/pom.xml | 2 +- .../ApplicationConfiguration.java | 25 ++++++++-- .../controller/rss/ArticleRssController.java | 49 ++++++++++++++++++- .../rss/ArticleRssFeedViewResolver.java | 15 ++++++ 6 files changed, 85 insertions(+), 9 deletions(-) create mode 100644 spring-mvc-simple/src/main/java/com/baeldung/spring/controller/rss/ArticleRssFeedViewResolver.java diff --git a/.gitignore b/.gitignore index 08f570ad06..693a35c176 100644 --- a/.gitignore +++ b/.gitignore @@ -43,3 +43,4 @@ spring-call-getters-using-reflection/.mvn/wrapper/maven-wrapper.properties spring-check-if-a-property-is-null/.mvn/wrapper/maven-wrapper.properties *.springBeans +20171220-JMeter.csv diff --git a/jackson/pom.xml b/jackson/pom.xml index 001fde5021..2587e61ac1 100644 --- a/jackson/pom.xml +++ b/jackson/pom.xml @@ -129,7 +129,7 @@ - 2.9.2 + 2.9.4 19.0 diff --git a/spring-mvc-java/pom.xml b/spring-mvc-java/pom.xml index b939f0496d..9d90ba2dbf 100644 --- a/spring-mvc-java/pom.xml +++ b/spring-mvc-java/pom.xml @@ -297,7 +297,7 @@ 4.3.4.RELEASE 4.2.0.RELEASE 2.1.5.RELEASE - 2.8.5 + 2.9.4 5.2.5.Final diff --git a/spring-mvc-simple/src/main/java/com/baeldung/spring/configuration/ApplicationConfiguration.java b/spring-mvc-simple/src/main/java/com/baeldung/spring/configuration/ApplicationConfiguration.java index b9a8336bf2..69c45d90b3 100644 --- a/spring-mvc-simple/src/main/java/com/baeldung/spring/configuration/ApplicationConfiguration.java +++ b/spring-mvc-simple/src/main/java/com/baeldung/spring/configuration/ApplicationConfiguration.java @@ -1,14 +1,21 @@ package com.baeldung.spring.configuration; +import com.baeldung.spring.controller.rss.ArticleRssFeedViewResolver; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.web.multipart.MultipartResolver; import org.springframework.web.multipart.commons.CommonsMultipartResolver; +import org.springframework.web.servlet.ViewResolver; import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import org.springframework.web.servlet.view.ContentNegotiatingViewResolver; import org.springframework.web.servlet.view.InternalResourceViewResolver; +import org.springframework.web.accept.ContentNegotiationManager; + +import java.util.List; +import java.util.ArrayList; @Configuration @EnableWebMvc @@ -21,11 +28,19 @@ class ApplicationConfiguration implements WebMvcConfigurer { } @Bean - public InternalResourceViewResolver jspViewResolver() { - InternalResourceViewResolver bean = new InternalResourceViewResolver(); - bean.setPrefix("/WEB-INF/views/"); - bean.setSuffix(".jsp"); - return bean; + public ContentNegotiatingViewResolver viewResolver(ContentNegotiationManager cnManager) { + ContentNegotiatingViewResolver cnvResolver = new ContentNegotiatingViewResolver(); + cnvResolver.setContentNegotiationManager(cnManager); + List resolvers = new ArrayList<>(); + + InternalResourceViewResolver bean = new InternalResourceViewResolver("/WEB-INF/views/",".jsp"); + ArticleRssFeedViewResolver articleRssFeedViewResolver = new ArticleRssFeedViewResolver(); + + resolvers.add(bean); + resolvers.add(articleRssFeedViewResolver); + + cnvResolver.setViewResolvers(resolvers); + return cnvResolver; } @Bean diff --git a/spring-mvc-simple/src/main/java/com/baeldung/spring/controller/rss/ArticleRssController.java b/spring-mvc-simple/src/main/java/com/baeldung/spring/controller/rss/ArticleRssController.java index 1f51b238ac..8f23076e8e 100644 --- a/spring-mvc-simple/src/main/java/com/baeldung/spring/controller/rss/ArticleRssController.java +++ b/spring-mvc-simple/src/main/java/com/baeldung/spring/controller/rss/ArticleRssController.java @@ -1,14 +1,59 @@ package com.baeldung.spring.controller.rss; +import com.rometools.rome.feed.synd.*; +import com.rometools.rome.io.FeedException; +import com.rometools.rome.io.SyndFeedOutput; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; @Controller public class ArticleRssController { - @GetMapping(value = "/rss", produces = "application/*") - public String articleFeed() { + @GetMapping(value = "/rssMvc") + public String articleMvcFeed() { return "articleFeedView"; } + @GetMapping(value = "/rssRest", produces = "application/rss+xml") + @ResponseBody + public String articleRestFeed() throws FeedException { + SyndFeed feed = new SyndFeedImpl(); + feed.setFeedType("rss_2.0"); + feed.setLink("http://localhost:8080/spring-mvc-simple/rss"); + feed.setTitle("Article Feed"); + feed.setDescription("Article Feed Description"); + feed.setPublishedDate(new Date()); + + List list = new ArrayList(); + + SyndEntry item1 = new SyndEntryImpl(); + item1.setLink("http://www.baeldung.com/netty-exception-handling"); + item1.setTitle("Exceptions in Netty"); + SyndContent description1 = new SyndContentImpl(); + description1.setValue("In this quick article, we’ll be looking at exception handling in Netty."); + item1.setDescription(description1); + item1.setPublishedDate(new Date()); + item1.setAuthor("Carlos"); + + SyndEntry item2 = new SyndEntryImpl(); + item2.setLink("http://www.baeldung.com/cockroachdb-java"); + item2.setTitle("Guide to CockroachDB in Java"); + SyndContent description2 = new SyndContentImpl(); + description2.setValue("This tutorial is an introductory guide to using CockroachDB with Java."); + item2.setDescription(description2); + item2.setPublishedDate(new Date()); + item2.setAuthor("Baeldung"); + + list.add(item1); + list.add(item2); + feed.setEntries(list); + + return new SyndFeedOutput().outputString(feed); + } + } diff --git a/spring-mvc-simple/src/main/java/com/baeldung/spring/controller/rss/ArticleRssFeedViewResolver.java b/spring-mvc-simple/src/main/java/com/baeldung/spring/controller/rss/ArticleRssFeedViewResolver.java new file mode 100644 index 0000000000..6be06c4812 --- /dev/null +++ b/spring-mvc-simple/src/main/java/com/baeldung/spring/controller/rss/ArticleRssFeedViewResolver.java @@ -0,0 +1,15 @@ +package com.baeldung.spring.controller.rss; + +import org.springframework.web.servlet.View; +import org.springframework.web.servlet.ViewResolver; + +import java.util.Locale; + +public class ArticleRssFeedViewResolver implements ViewResolver { + + @Override + public View resolveViewName(String s, Locale locale) throws Exception { + ArticleFeedView articleFeedView = new ArticleFeedView(); + return articleFeedView; + } +} From c67eca5faa952fa1aaa33fc92ac4a1915efc36bc Mon Sep 17 00:00:00 2001 From: Adam InTae Gerard Date: Fri, 9 Feb 2018 22:55:34 -0800 Subject: [PATCH 24/58] Issue #3628 - Closed unclosed input stream --- .../controller/MultipartController.java | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/spring-dispatcher-servlet/src/main/java/com/baeldung/springdispatcherservlet/controller/MultipartController.java b/spring-dispatcher-servlet/src/main/java/com/baeldung/springdispatcherservlet/controller/MultipartController.java index 1cc8261f7c..a693bf039f 100644 --- a/spring-dispatcher-servlet/src/main/java/com/baeldung/springdispatcherservlet/controller/MultipartController.java +++ b/spring-dispatcher-servlet/src/main/java/com/baeldung/springdispatcherservlet/controller/MultipartController.java @@ -25,14 +25,20 @@ public class MultipartController { try { InputStream in = file.getInputStream(); String path = new File(".").getAbsolutePath(); - FileOutputStream f = new FileOutputStream(path.substring(0, path.length()-1)+ "/uploads/" + file.getOriginalFilename()); - int ch; - while ((ch = in.read()) != -1) { - f.write(ch); + FileOutputStream f = new FileOutputStream(path.substring(0, path.length() - 1) + "/uploads/" + file.getOriginalFilename()); + try { + int ch; + while ((ch = in.read()) != -1) { + f.write(ch); + } + modelAndView.getModel().put("message", "File uploaded successfully!"); + } catch (Exception e) { + System.out.println("Exception uploading multipart: " + e); + } finally { + f.flush(); + f.close(); + in.close(); } - f.flush(); - f.close(); - modelAndView.getModel().put("message", "File uploaded successfully!"); } catch (Exception e) { System.out.println("Exception uploading multipart: " + e); } From 50deec5b5cb8c1ae7d732ffd5726933c1e98f956 Mon Sep 17 00:00:00 2001 From: Loredana Crusoveanu Date: Sat, 10 Feb 2018 17:42:52 +0200 Subject: [PATCH 25/58] refactor streams ex --- .../java/com/baeldung/string/Palindrome.java | 8 ++++ ...ingPalindrome.java => PalindromeTest.java} | 40 +++++++++---------- 2 files changed, 26 insertions(+), 22 deletions(-) rename core-java/src/test/java/com/baeldung/string/{WhenCheckingPalindrome.java => PalindromeTest.java} (63%) diff --git a/core-java/src/main/java/com/baeldung/string/Palindrome.java b/core-java/src/main/java/com/baeldung/string/Palindrome.java index 03b65d1a84..d70a89525a 100644 --- a/core-java/src/main/java/com/baeldung/string/Palindrome.java +++ b/core-java/src/main/java/com/baeldung/string/Palindrome.java @@ -1,5 +1,7 @@ package com.baeldung.string; +import java.util.stream.IntStream; + public class Palindrome { public boolean isPalindrome(String text) { @@ -50,4 +52,10 @@ public class Palindrome { return true; } + + public boolean isPalindromeUsingIntStream(String text) { + String temp = text.replaceAll("\\s+", "").toLowerCase(); + return IntStream.range(0, temp.length() / 2) + .noneMatch(i -> temp.charAt(i) != temp.charAt(temp.length() - i - 1)); + } } diff --git a/core-java/src/test/java/com/baeldung/string/WhenCheckingPalindrome.java b/core-java/src/test/java/com/baeldung/string/PalindromeTest.java similarity index 63% rename from core-java/src/test/java/com/baeldung/string/WhenCheckingPalindrome.java rename to core-java/src/test/java/com/baeldung/string/PalindromeTest.java index e3655a3140..ef78a2d840 100644 --- a/core-java/src/test/java/com/baeldung/string/WhenCheckingPalindrome.java +++ b/core-java/src/test/java/com/baeldung/string/PalindromeTest.java @@ -2,10 +2,10 @@ package com.baeldung.string; import java.util.Arrays; -import org.junit.Assert; +import static org.junit.Assert.*; import org.junit.Test; -public class WhenCheckingPalindrome { +public class PalindromeTest { private String[] words = { "Anna", @@ -28,50 +28,50 @@ public class WhenCheckingPalindrome { @Test public void whenWord_shouldBePalindrome() { for(String word:words) - Assert.assertTrue(palindrome.isPalindrome(word)); + assertTrue(palindrome.isPalindrome(word)); } @Test public void whenSentence_shouldBePalindrome() { for(String sentence:sentences) - Assert.assertTrue(palindrome.isPalindrome(sentence)); + assertTrue(palindrome.isPalindrome(sentence)); } @Test public void whenReverseWord_shouldBePalindrome() { for(String word:words) - Assert.assertTrue(palindrome.isPalindromeReverseTheString(word)); + assertTrue(palindrome.isPalindromeReverseTheString(word)); } @Test public void whenReverseSentence_shouldBePalindrome() { for(String sentence:sentences) - Assert.assertTrue(palindrome.isPalindromeReverseTheString(sentence)); + assertTrue(palindrome.isPalindromeReverseTheString(sentence)); } @Test public void whenStringBuilderWord_shouldBePalindrome() { for(String word:words) - Assert.assertTrue(palindrome.isPalindromeUsingStringBuilder(word)); + assertTrue(palindrome.isPalindromeUsingStringBuilder(word)); } @Test public void whenStringBuilderSentence_shouldBePalindrome() { for(String sentence:sentences) - Assert.assertTrue(palindrome.isPalindromeUsingStringBuilder(sentence)); + assertTrue(palindrome.isPalindromeUsingStringBuilder(sentence)); } @Test public void whenStringBufferWord_shouldBePalindrome() { for(String word:words) - Assert.assertTrue(palindrome.isPalindromeUsingStringBuffer(word)); + assertTrue(palindrome.isPalindromeUsingStringBuffer(word)); } @Test public void whenStringBufferSentence_shouldBePalindrome() { for(String sentence:sentences) - Assert.assertTrue(palindrome.isPalindromeUsingStringBuffer(sentence)); + assertTrue(palindrome.isPalindromeUsingStringBuffer(sentence)); } @Test @@ -80,7 +80,7 @@ public class WhenCheckingPalindrome { word = word.replaceAll("\\s+", "").toLowerCase(); int backward = word.length()-1; - Assert.assertTrue(palindrome.isPalindromeRecursive(word,0,backward)); + assertTrue(palindrome.isPalindromeRecursive(word,0,backward)); } } @@ -90,25 +90,21 @@ public class WhenCheckingPalindrome { sentence = sentence.replaceAll("\\s+", "").toLowerCase(); int backward = sentence.length()-1; - Assert.assertTrue(palindrome.isPalindromeRecursive(sentence,0,backward)); + assertTrue(palindrome.isPalindromeRecursive(sentence,0,backward)); } } @Test public void whenPalindromeStreams_wordShouldBePalindrome() { - String[] expected = Arrays.stream(words) - .filter(palindrome::isPalindrome) - .toArray(String[]::new); - - Assert.assertArrayEquals(expected, words); + for(String word:words) { + assertTrue(palindrome.isPalindromeUsingIntStream(word)); + } } @Test public void whenPalindromeStreams_sentenceShouldBePalindrome() { - String[] expected = Arrays.stream(sentences) - .filter(palindrome::isPalindrome) - .toArray(String[]::new); - - Assert.assertArrayEquals(expected, sentences); + for(String sentence:sentences) { + assertTrue(palindrome.isPalindromeUsingIntStream(sentence)); + } } } From 4c044fcaeec33a3b68637f751672a8f48de74c83 Mon Sep 17 00:00:00 2001 From: Loredana Crusoveanu Date: Sat, 10 Feb 2018 17:45:01 +0200 Subject: [PATCH 26/58] remove imports --- core-java/src/test/java/com/baeldung/string/PalindromeTest.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/core-java/src/test/java/com/baeldung/string/PalindromeTest.java b/core-java/src/test/java/com/baeldung/string/PalindromeTest.java index ef78a2d840..d1a05b6617 100644 --- a/core-java/src/test/java/com/baeldung/string/PalindromeTest.java +++ b/core-java/src/test/java/com/baeldung/string/PalindromeTest.java @@ -1,7 +1,5 @@ package com.baeldung.string; -import java.util.Arrays; - import static org.junit.Assert.*; import org.junit.Test; From 7c6a4b0b4dc5250faf6b17cac8a69fece05f58d1 Mon Sep 17 00:00:00 2001 From: Loredana Crusoveanu Date: Sat, 10 Feb 2018 18:48:41 +0200 Subject: [PATCH 27/58] Update Palindrome.java --- core-java/src/main/java/com/baeldung/string/Palindrome.java | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java/src/main/java/com/baeldung/string/Palindrome.java b/core-java/src/main/java/com/baeldung/string/Palindrome.java index d70a89525a..0759787249 100644 --- a/core-java/src/main/java/com/baeldung/string/Palindrome.java +++ b/core-java/src/main/java/com/baeldung/string/Palindrome.java @@ -58,4 +58,5 @@ public class Palindrome { return IntStream.range(0, temp.length() / 2) .noneMatch(i -> temp.charAt(i) != temp.charAt(temp.length() - i - 1)); } + } From 3c371bea4587ed754e2e28b42873fead3af75695 Mon Sep 17 00:00:00 2001 From: Loredana Crusoveanu Date: Sat, 10 Feb 2018 19:04:31 +0200 Subject: [PATCH 28/58] rename projects (#3604) --- .../{oauth2client => auth-client}/pom.xml | 4 ++-- .../src/main/java/com/baeldung/CloudSite.java | 0 .../com/baeldung/config/SiteSecurityConfigurer.java | 0 .../baeldung/controller/CloudSiteController.java | 0 .../java/com/baeldung/filters/SimpleFilter.java | 0 .../src/main/resources/application.properties | 0 .../src/main/resources/application.yml | 0 .../src/main/resources/templates/personinfo.html | 0 .../springoath2/Springoath2ApplicationTests.java | 0 .../{personresource => auth-resource}/pom.xml | 4 ++-- .../src/main/java/com/baeldung/Application.java | 0 .../com/baeldung/config/ResourceConfigurer.java | 0 .../baeldung/controller/PersonInfoController.java | 0 .../src/main/java/com/baeldung/model/Person.java | 0 .../src/main/resources/application.yml | 0 .../PersonserviceApplicationTests.java | 0 .../{authserver => auth-server}/pom.xml | 2 +- .../src/main/java/com/baeldung/AuthServer.java | 0 .../com/baeldung/config/AuthServerConfigurer.java | 0 .../baeldung/config/ResourceServerConfigurer.java | 0 .../java/com/baeldung/config/WebMvcConfigurer.java | 0 .../com/baeldung/config/WebSecurityConfigurer.java | 0 .../com/baeldung/controller/ResourceController.java | 0 .../src/main/resources/application.yml | 0 .../src/main/resources/certificate/mykeystore.jks | Bin .../src/main/resources/templates/login.html | 0 26 files changed, 5 insertions(+), 5 deletions(-) rename spring-cloud/spring-cloud-security/{oauth2client => auth-client}/pom.xml (97%) rename spring-cloud/spring-cloud-security/{oauth2client => auth-client}/src/main/java/com/baeldung/CloudSite.java (100%) rename spring-cloud/spring-cloud-security/{oauth2client => auth-client}/src/main/java/com/baeldung/config/SiteSecurityConfigurer.java (100%) rename spring-cloud/spring-cloud-security/{oauth2client => auth-client}/src/main/java/com/baeldung/controller/CloudSiteController.java (100%) rename spring-cloud/spring-cloud-security/{oauth2client => auth-client}/src/main/java/com/baeldung/filters/SimpleFilter.java (100%) rename spring-cloud/spring-cloud-security/{oauth2client => auth-client}/src/main/resources/application.properties (100%) rename spring-cloud/spring-cloud-security/{oauth2client => auth-client}/src/main/resources/application.yml (100%) rename spring-cloud/spring-cloud-security/{oauth2client => auth-client}/src/main/resources/templates/personinfo.html (100%) rename spring-cloud/spring-cloud-security/{oauth2client => auth-client}/src/test/java/com/example/springoath2/Springoath2ApplicationTests.java (100%) rename spring-cloud/spring-cloud-security/{personresource => auth-resource}/pom.xml (96%) rename spring-cloud/spring-cloud-security/{personresource => auth-resource}/src/main/java/com/baeldung/Application.java (100%) rename spring-cloud/spring-cloud-security/{personresource => auth-resource}/src/main/java/com/baeldung/config/ResourceConfigurer.java (100%) rename spring-cloud/spring-cloud-security/{personresource => auth-resource}/src/main/java/com/baeldung/controller/PersonInfoController.java (100%) rename spring-cloud/spring-cloud-security/{personresource => auth-resource}/src/main/java/com/baeldung/model/Person.java (100%) rename spring-cloud/spring-cloud-security/{personresource => auth-resource}/src/main/resources/application.yml (100%) rename spring-cloud/spring-cloud-security/{personresource => auth-resource}/src/test/java/com/baeldung/service/personservice/PersonserviceApplicationTests.java (100%) rename spring-cloud/spring-cloud-security/{authserver => auth-server}/pom.xml (96%) rename spring-cloud/spring-cloud-security/{authserver => auth-server}/src/main/java/com/baeldung/AuthServer.java (100%) rename spring-cloud/spring-cloud-security/{authserver => auth-server}/src/main/java/com/baeldung/config/AuthServerConfigurer.java (100%) rename spring-cloud/spring-cloud-security/{authserver => auth-server}/src/main/java/com/baeldung/config/ResourceServerConfigurer.java (100%) rename spring-cloud/spring-cloud-security/{authserver => auth-server}/src/main/java/com/baeldung/config/WebMvcConfigurer.java (100%) rename spring-cloud/spring-cloud-security/{authserver => auth-server}/src/main/java/com/baeldung/config/WebSecurityConfigurer.java (100%) rename spring-cloud/spring-cloud-security/{authserver => auth-server}/src/main/java/com/baeldung/controller/ResourceController.java (100%) rename spring-cloud/spring-cloud-security/{authserver => auth-server}/src/main/resources/application.yml (100%) rename spring-cloud/spring-cloud-security/{authserver => auth-server}/src/main/resources/certificate/mykeystore.jks (100%) rename spring-cloud/spring-cloud-security/{authserver => auth-server}/src/main/resources/templates/login.html (100%) diff --git a/spring-cloud/spring-cloud-security/oauth2client/pom.xml b/spring-cloud/spring-cloud-security/auth-client/pom.xml similarity index 97% rename from spring-cloud/spring-cloud-security/oauth2client/pom.xml rename to spring-cloud/spring-cloud-security/auth-client/pom.xml index fd1c6964e1..5213b93f9a 100644 --- a/spring-cloud/spring-cloud-security/oauth2client/pom.xml +++ b/spring-cloud/spring-cloud-security/auth-client/pom.xml @@ -3,11 +3,11 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.baeldung - oauth2client + auth-client 0.0.1-SNAPSHOT jar - oauth2client + auth-client Demo project for Spring Boot diff --git a/spring-cloud/spring-cloud-security/oauth2client/src/main/java/com/baeldung/CloudSite.java b/spring-cloud/spring-cloud-security/auth-client/src/main/java/com/baeldung/CloudSite.java similarity index 100% rename from spring-cloud/spring-cloud-security/oauth2client/src/main/java/com/baeldung/CloudSite.java rename to spring-cloud/spring-cloud-security/auth-client/src/main/java/com/baeldung/CloudSite.java diff --git a/spring-cloud/spring-cloud-security/oauth2client/src/main/java/com/baeldung/config/SiteSecurityConfigurer.java b/spring-cloud/spring-cloud-security/auth-client/src/main/java/com/baeldung/config/SiteSecurityConfigurer.java similarity index 100% rename from spring-cloud/spring-cloud-security/oauth2client/src/main/java/com/baeldung/config/SiteSecurityConfigurer.java rename to spring-cloud/spring-cloud-security/auth-client/src/main/java/com/baeldung/config/SiteSecurityConfigurer.java diff --git a/spring-cloud/spring-cloud-security/oauth2client/src/main/java/com/baeldung/controller/CloudSiteController.java b/spring-cloud/spring-cloud-security/auth-client/src/main/java/com/baeldung/controller/CloudSiteController.java similarity index 100% rename from spring-cloud/spring-cloud-security/oauth2client/src/main/java/com/baeldung/controller/CloudSiteController.java rename to spring-cloud/spring-cloud-security/auth-client/src/main/java/com/baeldung/controller/CloudSiteController.java diff --git a/spring-cloud/spring-cloud-security/oauth2client/src/main/java/com/baeldung/filters/SimpleFilter.java b/spring-cloud/spring-cloud-security/auth-client/src/main/java/com/baeldung/filters/SimpleFilter.java similarity index 100% rename from spring-cloud/spring-cloud-security/oauth2client/src/main/java/com/baeldung/filters/SimpleFilter.java rename to spring-cloud/spring-cloud-security/auth-client/src/main/java/com/baeldung/filters/SimpleFilter.java diff --git a/spring-cloud/spring-cloud-security/oauth2client/src/main/resources/application.properties b/spring-cloud/spring-cloud-security/auth-client/src/main/resources/application.properties similarity index 100% rename from spring-cloud/spring-cloud-security/oauth2client/src/main/resources/application.properties rename to spring-cloud/spring-cloud-security/auth-client/src/main/resources/application.properties diff --git a/spring-cloud/spring-cloud-security/oauth2client/src/main/resources/application.yml b/spring-cloud/spring-cloud-security/auth-client/src/main/resources/application.yml similarity index 100% rename from spring-cloud/spring-cloud-security/oauth2client/src/main/resources/application.yml rename to spring-cloud/spring-cloud-security/auth-client/src/main/resources/application.yml diff --git a/spring-cloud/spring-cloud-security/oauth2client/src/main/resources/templates/personinfo.html b/spring-cloud/spring-cloud-security/auth-client/src/main/resources/templates/personinfo.html similarity index 100% rename from spring-cloud/spring-cloud-security/oauth2client/src/main/resources/templates/personinfo.html rename to spring-cloud/spring-cloud-security/auth-client/src/main/resources/templates/personinfo.html diff --git a/spring-cloud/spring-cloud-security/oauth2client/src/test/java/com/example/springoath2/Springoath2ApplicationTests.java b/spring-cloud/spring-cloud-security/auth-client/src/test/java/com/example/springoath2/Springoath2ApplicationTests.java similarity index 100% rename from spring-cloud/spring-cloud-security/oauth2client/src/test/java/com/example/springoath2/Springoath2ApplicationTests.java rename to spring-cloud/spring-cloud-security/auth-client/src/test/java/com/example/springoath2/Springoath2ApplicationTests.java diff --git a/spring-cloud/spring-cloud-security/personresource/pom.xml b/spring-cloud/spring-cloud-security/auth-resource/pom.xml similarity index 96% rename from spring-cloud/spring-cloud-security/personresource/pom.xml rename to spring-cloud/spring-cloud-security/auth-resource/pom.xml index ca1ff82515..2c54d24e7d 100644 --- a/spring-cloud/spring-cloud-security/personresource/pom.xml +++ b/spring-cloud/spring-cloud-security/auth-resource/pom.xml @@ -4,11 +4,11 @@ 4.0.0 com.baeldung - personresource + auth-resource 0.0.1-SNAPSHOT jar - personresource + auth-resource Demo project for Spring Boot diff --git a/spring-cloud/spring-cloud-security/personresource/src/main/java/com/baeldung/Application.java b/spring-cloud/spring-cloud-security/auth-resource/src/main/java/com/baeldung/Application.java similarity index 100% rename from spring-cloud/spring-cloud-security/personresource/src/main/java/com/baeldung/Application.java rename to spring-cloud/spring-cloud-security/auth-resource/src/main/java/com/baeldung/Application.java diff --git a/spring-cloud/spring-cloud-security/personresource/src/main/java/com/baeldung/config/ResourceConfigurer.java b/spring-cloud/spring-cloud-security/auth-resource/src/main/java/com/baeldung/config/ResourceConfigurer.java similarity index 100% rename from spring-cloud/spring-cloud-security/personresource/src/main/java/com/baeldung/config/ResourceConfigurer.java rename to spring-cloud/spring-cloud-security/auth-resource/src/main/java/com/baeldung/config/ResourceConfigurer.java diff --git a/spring-cloud/spring-cloud-security/personresource/src/main/java/com/baeldung/controller/PersonInfoController.java b/spring-cloud/spring-cloud-security/auth-resource/src/main/java/com/baeldung/controller/PersonInfoController.java similarity index 100% rename from spring-cloud/spring-cloud-security/personresource/src/main/java/com/baeldung/controller/PersonInfoController.java rename to spring-cloud/spring-cloud-security/auth-resource/src/main/java/com/baeldung/controller/PersonInfoController.java diff --git a/spring-cloud/spring-cloud-security/personresource/src/main/java/com/baeldung/model/Person.java b/spring-cloud/spring-cloud-security/auth-resource/src/main/java/com/baeldung/model/Person.java similarity index 100% rename from spring-cloud/spring-cloud-security/personresource/src/main/java/com/baeldung/model/Person.java rename to spring-cloud/spring-cloud-security/auth-resource/src/main/java/com/baeldung/model/Person.java diff --git a/spring-cloud/spring-cloud-security/personresource/src/main/resources/application.yml b/spring-cloud/spring-cloud-security/auth-resource/src/main/resources/application.yml similarity index 100% rename from spring-cloud/spring-cloud-security/personresource/src/main/resources/application.yml rename to spring-cloud/spring-cloud-security/auth-resource/src/main/resources/application.yml diff --git a/spring-cloud/spring-cloud-security/personresource/src/test/java/com/baeldung/service/personservice/PersonserviceApplicationTests.java b/spring-cloud/spring-cloud-security/auth-resource/src/test/java/com/baeldung/service/personservice/PersonserviceApplicationTests.java similarity index 100% rename from spring-cloud/spring-cloud-security/personresource/src/test/java/com/baeldung/service/personservice/PersonserviceApplicationTests.java rename to spring-cloud/spring-cloud-security/auth-resource/src/test/java/com/baeldung/service/personservice/PersonserviceApplicationTests.java diff --git a/spring-cloud/spring-cloud-security/authserver/pom.xml b/spring-cloud/spring-cloud-security/auth-server/pom.xml similarity index 96% rename from spring-cloud/spring-cloud-security/authserver/pom.xml rename to spring-cloud/spring-cloud-security/auth-server/pom.xml index ed88ac046b..ab30f3f2ec 100644 --- a/spring-cloud/spring-cloud-security/authserver/pom.xml +++ b/spring-cloud/spring-cloud-security/auth-server/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.baeldung - authserver + auth-server 0.0.1-SNAPSHOT diff --git a/spring-cloud/spring-cloud-security/authserver/src/main/java/com/baeldung/AuthServer.java b/spring-cloud/spring-cloud-security/auth-server/src/main/java/com/baeldung/AuthServer.java similarity index 100% rename from spring-cloud/spring-cloud-security/authserver/src/main/java/com/baeldung/AuthServer.java rename to spring-cloud/spring-cloud-security/auth-server/src/main/java/com/baeldung/AuthServer.java diff --git a/spring-cloud/spring-cloud-security/authserver/src/main/java/com/baeldung/config/AuthServerConfigurer.java b/spring-cloud/spring-cloud-security/auth-server/src/main/java/com/baeldung/config/AuthServerConfigurer.java similarity index 100% rename from spring-cloud/spring-cloud-security/authserver/src/main/java/com/baeldung/config/AuthServerConfigurer.java rename to spring-cloud/spring-cloud-security/auth-server/src/main/java/com/baeldung/config/AuthServerConfigurer.java diff --git a/spring-cloud/spring-cloud-security/authserver/src/main/java/com/baeldung/config/ResourceServerConfigurer.java b/spring-cloud/spring-cloud-security/auth-server/src/main/java/com/baeldung/config/ResourceServerConfigurer.java similarity index 100% rename from spring-cloud/spring-cloud-security/authserver/src/main/java/com/baeldung/config/ResourceServerConfigurer.java rename to spring-cloud/spring-cloud-security/auth-server/src/main/java/com/baeldung/config/ResourceServerConfigurer.java diff --git a/spring-cloud/spring-cloud-security/authserver/src/main/java/com/baeldung/config/WebMvcConfigurer.java b/spring-cloud/spring-cloud-security/auth-server/src/main/java/com/baeldung/config/WebMvcConfigurer.java similarity index 100% rename from spring-cloud/spring-cloud-security/authserver/src/main/java/com/baeldung/config/WebMvcConfigurer.java rename to spring-cloud/spring-cloud-security/auth-server/src/main/java/com/baeldung/config/WebMvcConfigurer.java diff --git a/spring-cloud/spring-cloud-security/authserver/src/main/java/com/baeldung/config/WebSecurityConfigurer.java b/spring-cloud/spring-cloud-security/auth-server/src/main/java/com/baeldung/config/WebSecurityConfigurer.java similarity index 100% rename from spring-cloud/spring-cloud-security/authserver/src/main/java/com/baeldung/config/WebSecurityConfigurer.java rename to spring-cloud/spring-cloud-security/auth-server/src/main/java/com/baeldung/config/WebSecurityConfigurer.java diff --git a/spring-cloud/spring-cloud-security/authserver/src/main/java/com/baeldung/controller/ResourceController.java b/spring-cloud/spring-cloud-security/auth-server/src/main/java/com/baeldung/controller/ResourceController.java similarity index 100% rename from spring-cloud/spring-cloud-security/authserver/src/main/java/com/baeldung/controller/ResourceController.java rename to spring-cloud/spring-cloud-security/auth-server/src/main/java/com/baeldung/controller/ResourceController.java diff --git a/spring-cloud/spring-cloud-security/authserver/src/main/resources/application.yml b/spring-cloud/spring-cloud-security/auth-server/src/main/resources/application.yml similarity index 100% rename from spring-cloud/spring-cloud-security/authserver/src/main/resources/application.yml rename to spring-cloud/spring-cloud-security/auth-server/src/main/resources/application.yml diff --git a/spring-cloud/spring-cloud-security/authserver/src/main/resources/certificate/mykeystore.jks b/spring-cloud/spring-cloud-security/auth-server/src/main/resources/certificate/mykeystore.jks similarity index 100% rename from spring-cloud/spring-cloud-security/authserver/src/main/resources/certificate/mykeystore.jks rename to spring-cloud/spring-cloud-security/auth-server/src/main/resources/certificate/mykeystore.jks diff --git a/spring-cloud/spring-cloud-security/authserver/src/main/resources/templates/login.html b/spring-cloud/spring-cloud-security/auth-server/src/main/resources/templates/login.html similarity index 100% rename from spring-cloud/spring-cloud-security/authserver/src/main/resources/templates/login.html rename to spring-cloud/spring-cloud-security/auth-server/src/main/resources/templates/login.html From ef8276dd1a62e528a35696f6e334285ed0c3c5e8 Mon Sep 17 00:00:00 2001 From: Loredana Crusoveanu Date: Sat, 10 Feb 2018 19:11:06 +0200 Subject: [PATCH 29/58] remove project from build --- pom.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pom.xml b/pom.xml index ca6d4afe82..fc0c8f8ba7 100644 --- a/pom.xml +++ b/pom.xml @@ -49,7 +49,9 @@ core-java core-java-io core-java-8 + couchbase deltaspike From d488e693017a7eba978c5cf9ce4cf81e12122f39 Mon Sep 17 00:00:00 2001 From: linhvovn Date: Sun, 11 Feb 2018 01:28:00 +0800 Subject: [PATCH 30/58] [BAEL 1382] Update Unit Test (#3630) * [tlinh2110-BAEL1382] Add Security in SI * [tlinh2110-BAEL1382] Upgrade to Spring 5 & add Logger * [tlinh2110-BAEL-1382] Update Unit Test --- .../si/TestSpringIntegrationSecurity.java | 46 +++++++++---------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/spring-integration/src/test/java/com/baeldung/si/TestSpringIntegrationSecurity.java b/spring-integration/src/test/java/com/baeldung/si/TestSpringIntegrationSecurity.java index 45dcb1e836..9ae82af2dc 100644 --- a/spring-integration/src/test/java/com/baeldung/si/TestSpringIntegrationSecurity.java +++ b/spring-integration/src/test/java/com/baeldung/si/TestSpringIntegrationSecurity.java @@ -1,8 +1,11 @@ package com.baeldung.si; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import org.hamcrest.core.IsInstanceOf; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.messaging.SubscribableChannel; @@ -21,6 +24,9 @@ import com.baeldung.si.security.SecurityConfig; @ContextConfiguration(classes = { SecurityConfig.class, SecuredDirectChannel.class, MessageConsumer.class }) public class TestSpringIntegrationSecurity { + @Rule + public ExpectedException expectedException = ExpectedException.none(); + @Autowired SubscribableChannel startDirectChannel; @@ -34,34 +40,28 @@ public class TestSpringIntegrationSecurity { startDirectChannel.send(new GenericMessage(DIRECT_CHANNEL_MESSAGE)); } - @Test(expected = AccessDeniedException.class) + @Test @WithMockUser(username = "jane", roles = { "LOGGER" }) - public void givenRoleLogger_whenSendMessageToDirectChannel_thenAccessDenied() throws Throwable { - try { - startDirectChannel.send(new GenericMessage(DIRECT_CHANNEL_MESSAGE)); - } catch (Exception e) { - throw e.getCause(); - } + public void givenRoleLogger_whenSendMessageToDirectChannel_thenAccessDenied() { + expectedException.expectCause(IsInstanceOf. instanceOf(AccessDeniedException.class)); + + startDirectChannel.send(new GenericMessage(DIRECT_CHANNEL_MESSAGE)); } - @Test(expected = AccessDeniedException.class) + @Test @WithMockUser(username = "jane") - public void givenJane_whenSendMessageToDirectChannel_thenAccessDenied() throws Throwable { - try { - startDirectChannel.send(new GenericMessage(DIRECT_CHANNEL_MESSAGE)); - } catch (Exception e) { - throw e.getCause(); - } + public void givenJane_whenSendMessageToDirectChannel_thenAccessDenied() { + expectedException.expectCause(IsInstanceOf. instanceOf(AccessDeniedException.class)); + + startDirectChannel.send(new GenericMessage(DIRECT_CHANNEL_MESSAGE)); } - @Test(expected = AccessDeniedException.class) + @Test @WithMockUser(roles = { "VIEWER" }) - public void givenRoleViewer_whenSendToDirectChannel_thenAccessDenied() throws Throwable { - try { - startDirectChannel.send(new GenericMessage(DIRECT_CHANNEL_MESSAGE)); - } catch (Exception e) { - throw e.getCause(); - } + public void givenRoleViewer_whenSendToDirectChannel_thenAccessDenied() { + expectedException.expectCause(IsInstanceOf. instanceOf(AccessDeniedException.class)); + + startDirectChannel.send(new GenericMessage(DIRECT_CHANNEL_MESSAGE)); } @Test @@ -78,4 +78,4 @@ public class TestSpringIntegrationSecurity { assertEquals(DIRECT_CHANNEL_MESSAGE, messageConsumer.getMessageContent()); } -} +} \ No newline at end of file From d935985ec1b541558864f146c4dd530571f09df4 Mon Sep 17 00:00:00 2001 From: Ganesh Date: Sun, 11 Feb 2018 13:29:30 +0530 Subject: [PATCH 31/58] Priorityjobscheduler (#3583) * priority based job execution in java * minor fixes * updated to use java 8 features * fix need for type inference * handle exception * indentation * handling exception generated during terminal of normal flow * handling exception generated during terminal of normal flow * added comment --- .../concurrent/prioritytaskexecution/Job.java | 3 ++- .../prioritytaskexecution/PriorityJobScheduler.java | 12 ++++++------ .../PriorityJobSchedulerUnitTest.java | 4 +++- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/core-java-concurrency/src/main/java/com/baeldung/concurrent/prioritytaskexecution/Job.java b/core-java-concurrency/src/main/java/com/baeldung/concurrent/prioritytaskexecution/Job.java index a70041ed7d..9900d1c63d 100644 --- a/core-java-concurrency/src/main/java/com/baeldung/concurrent/prioritytaskexecution/Job.java +++ b/core-java-concurrency/src/main/java/com/baeldung/concurrent/prioritytaskexecution/Job.java @@ -16,7 +16,8 @@ public class Job implements Runnable { @Override public void run() { try { - System.out.println("Job:" + jobName + " Priority:" + jobPriority); + System.out.println("Job:" + jobName + + " Priority:" + jobPriority); Thread.sleep(1000); } catch (InterruptedException ignored) { } diff --git a/core-java-concurrency/src/main/java/com/baeldung/concurrent/prioritytaskexecution/PriorityJobScheduler.java b/core-java-concurrency/src/main/java/com/baeldung/concurrent/prioritytaskexecution/PriorityJobScheduler.java index 70fd1710c0..ba55696d5a 100644 --- a/core-java-concurrency/src/main/java/com/baeldung/concurrent/prioritytaskexecution/PriorityJobScheduler.java +++ b/core-java-concurrency/src/main/java/com/baeldung/concurrent/prioritytaskexecution/PriorityJobScheduler.java @@ -9,21 +9,21 @@ import java.util.concurrent.TimeUnit; public class PriorityJobScheduler { private ExecutorService priorityJobPoolExecutor; - private ExecutorService priorityJobScheduler; - private PriorityBlockingQueue priorityQueue; + private ExecutorService priorityJobScheduler = + Executors.newSingleThreadExecutor(); + private PriorityBlockingQueue priorityQueue; public PriorityJobScheduler(Integer poolSize, Integer queueSize) { priorityJobPoolExecutor = Executors.newFixedThreadPool(poolSize); - Comparator jobComparator = Comparator.comparing(Job::getJobPriority); - priorityQueue = new PriorityBlockingQueue(queueSize, - (Comparator) jobComparator); + priorityQueue = new PriorityBlockingQueue(queueSize, + Comparator.comparing(Job::getJobPriority)); - priorityJobScheduler = Executors.newSingleThreadExecutor(); priorityJobScheduler.execute(()->{ while (true) { try { priorityJobPoolExecutor.execute(priorityQueue.take()); } catch (InterruptedException e) { + // exception needs special handling break; } } diff --git a/core-java-concurrency/src/test/java/com/baeldung/concurrent/prioritytaskexecution/PriorityJobSchedulerUnitTest.java b/core-java-concurrency/src/test/java/com/baeldung/concurrent/prioritytaskexecution/PriorityJobSchedulerUnitTest.java index 902bada3a2..1e67fe45c1 100644 --- a/core-java-concurrency/src/test/java/com/baeldung/concurrent/prioritytaskexecution/PriorityJobSchedulerUnitTest.java +++ b/core-java-concurrency/src/test/java/com/baeldung/concurrent/prioritytaskexecution/PriorityJobSchedulerUnitTest.java @@ -30,7 +30,9 @@ public class PriorityJobSchedulerUnitTest { // delay to avoid job sleep (added for demo) being interrupted try { Thread.sleep(2000); - } catch (InterruptedException ignored) { + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new RuntimeException(e); } pjs.closeScheduler(); From 1c043dc20287524d91562e81aab5a64bcbb3d2f5 Mon Sep 17 00:00:00 2001 From: Loredana Crusoveanu Date: Sun, 11 Feb 2018 12:34:49 +0200 Subject: [PATCH 32/58] custom dsl ex (#3577) * custom dsl ex * Update application.properties --- .../baeldung/dsl/ClientErrorLoggingDsl.java | 32 +++++++++++ .../dsl/ClientErrorLoggingFilter.java | 54 +++++++++++++++++++ .../baeldung/dsl/CustomDslApplication.java | 13 +++++ .../java/com/baeldung/dsl/MyController.java | 14 +++++ .../java/com/baeldung/dsl/SecurityConfig.java | 50 +++++++++++++++++ .../src/main/resources/application.properties | 4 +- 6 files changed, 166 insertions(+), 1 deletion(-) create mode 100644 spring-5-security/src/main/java/com/baeldung/dsl/ClientErrorLoggingDsl.java create mode 100644 spring-5-security/src/main/java/com/baeldung/dsl/ClientErrorLoggingFilter.java create mode 100644 spring-5-security/src/main/java/com/baeldung/dsl/CustomDslApplication.java create mode 100644 spring-5-security/src/main/java/com/baeldung/dsl/MyController.java create mode 100644 spring-5-security/src/main/java/com/baeldung/dsl/SecurityConfig.java diff --git a/spring-5-security/src/main/java/com/baeldung/dsl/ClientErrorLoggingDsl.java b/spring-5-security/src/main/java/com/baeldung/dsl/ClientErrorLoggingDsl.java new file mode 100644 index 0000000000..6c7c0d2717 --- /dev/null +++ b/spring-5-security/src/main/java/com/baeldung/dsl/ClientErrorLoggingDsl.java @@ -0,0 +1,32 @@ +package com.baeldung.dsl; + +import java.util.List; + +import org.springframework.http.HttpStatus; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; +import org.springframework.security.web.access.intercept.FilterSecurityInterceptor; + +public class ClientErrorLoggingDsl extends AbstractHttpConfigurer { + + private List errorCodes; + + public ClientErrorLoggingDsl(List errorCodes) { + this.errorCodes = errorCodes; + } + + public ClientErrorLoggingDsl() { + + } + + @Override + public void init(HttpSecurity http) throws Exception { + // initialization code + } + + @Override + public void configure(HttpSecurity http) throws Exception { + http.addFilterAfter(new ClientErrorLoggingFilter(errorCodes), FilterSecurityInterceptor.class); + } + +} diff --git a/spring-5-security/src/main/java/com/baeldung/dsl/ClientErrorLoggingFilter.java b/spring-5-security/src/main/java/com/baeldung/dsl/ClientErrorLoggingFilter.java new file mode 100644 index 0000000000..56f7cea3b8 --- /dev/null +++ b/spring-5-security/src/main/java/com/baeldung/dsl/ClientErrorLoggingFilter.java @@ -0,0 +1,54 @@ +package com.baeldung.dsl; + +import java.io.IOException; +import java.util.List; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletResponse; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.springframework.http.HttpStatus; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.web.filter.GenericFilterBean; + +public class ClientErrorLoggingFilter extends GenericFilterBean { + + private static final Logger logger = LogManager.getLogger(ClientErrorLoggingFilter.class); + + private List errorCodes; + + public ClientErrorLoggingFilter(List errorCodes) { + this.errorCodes = errorCodes; + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + + Authentication auth = SecurityContextHolder.getContext() + .getAuthentication(); + + if (auth != null) { + int status = ((HttpServletResponse) response).getStatus(); + if (status >= 400 && status < 500) { + if (errorCodes == null) { + logger.debug("User " + auth.getName() + " encountered error " + status); + } else { + if (errorCodes.stream() + .filter(s -> s.value() == status) + .findFirst() + .isPresent()) { + logger.debug("User " + auth.getName() + " encountered error " + status); + } + } + } + } + + chain.doFilter(request, response); + } + +} diff --git a/spring-5-security/src/main/java/com/baeldung/dsl/CustomDslApplication.java b/spring-5-security/src/main/java/com/baeldung/dsl/CustomDslApplication.java new file mode 100644 index 0000000000..3e58bccaf4 --- /dev/null +++ b/spring-5-security/src/main/java/com/baeldung/dsl/CustomDslApplication.java @@ -0,0 +1,13 @@ +package com.baeldung.dsl; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class CustomDslApplication { + + public static void main(String[] args) { + SpringApplication.run(CustomDslApplication.class, args); + } + +} diff --git a/spring-5-security/src/main/java/com/baeldung/dsl/MyController.java b/spring-5-security/src/main/java/com/baeldung/dsl/MyController.java new file mode 100644 index 0000000000..c69046afb5 --- /dev/null +++ b/spring-5-security/src/main/java/com/baeldung/dsl/MyController.java @@ -0,0 +1,14 @@ +package com.baeldung.dsl; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class MyController { + + @GetMapping("/admin") + public String getAdminPage() { + return "Hello Admin"; + } + +} diff --git a/spring-5-security/src/main/java/com/baeldung/dsl/SecurityConfig.java b/spring-5-security/src/main/java/com/baeldung/dsl/SecurityConfig.java new file mode 100644 index 0000000000..4494aaa131 --- /dev/null +++ b/spring-5-security/src/main/java/com/baeldung/dsl/SecurityConfig.java @@ -0,0 +1,50 @@ +package com.baeldung.dsl; + +import org.springframework.context.annotation.Bean; +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.WebSecurityConfigurerAdapter; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; + +@Configuration +public class SecurityConfig extends WebSecurityConfigurerAdapter { + + @Override + protected void configure(HttpSecurity http) throws Exception { + http.authorizeRequests() + .antMatchers("/admin*") + .hasAnyRole("ADMIN") + .anyRequest() + .authenticated() + .and() + .formLogin() + .and() + .apply(clientErrorLogging()); + } + + @Bean + public ClientErrorLoggingDsl clientErrorLogging() { + return new ClientErrorLoggingDsl(); + } + + @Override + protected void configure(AuthenticationManagerBuilder auth) throws Exception { + auth.inMemoryAuthentication() + .passwordEncoder(passwordEncoder()) + .withUser("user1") + .password(passwordEncoder().encode("user")) + .roles("USER") + .and() + .withUser("admin") + .password(passwordEncoder().encode("admin")) + .roles("ADMIN"); + } + + @Bean + public PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } + +} diff --git a/spring-5-security/src/main/resources/application.properties b/spring-5-security/src/main/resources/application.properties index ccec014c2b..781ee76826 100644 --- a/spring-5-security/src/main/resources/application.properties +++ b/spring-5-security/src/main/resources/application.properties @@ -1,3 +1,5 @@ server.port=8081 -logging.level.root=INFO \ No newline at end of file +logging.level.root=INFO + +logging.level.com.baeldung.dsl.ClientErrorLoggingFilter=DEBUG From 6eeff13c459a3661c9151086ce2cf70e0faf31f1 Mon Sep 17 00:00:00 2001 From: Allan Vital Date: Sun, 11 Feb 2018 11:36:33 -0200 Subject: [PATCH 33/58] BAEL-1368: infinispan article (#3633) --- libraries/pom.xml | 8 +- .../infinispan/CacheConfiguration.java | 85 ++++++++++++++ .../infinispan/listener/CacheListener.java | 55 +++++++++ .../repository/HelloWorldRepository.java | 15 +++ .../infinispan/service/HelloWorldService.java | 90 +++++++++++++++ .../service/TransactionalService.java | 57 ++++++++++ .../infinispan/ConfigurationTest.java | 56 ++++++++++ .../service/HelloWorldServiceUnitTest.java | 105 ++++++++++++++++++ .../service/TransactionalServiceUnitTest.java | 24 ++++ 9 files changed, 494 insertions(+), 1 deletion(-) create mode 100644 libraries/src/main/java/com/baeldung/infinispan/CacheConfiguration.java create mode 100644 libraries/src/main/java/com/baeldung/infinispan/listener/CacheListener.java create mode 100644 libraries/src/main/java/com/baeldung/infinispan/repository/HelloWorldRepository.java create mode 100644 libraries/src/main/java/com/baeldung/infinispan/service/HelloWorldService.java create mode 100644 libraries/src/main/java/com/baeldung/infinispan/service/TransactionalService.java create mode 100644 libraries/src/test/java/com/baeldung/infinispan/ConfigurationTest.java create mode 100644 libraries/src/test/java/com/baeldung/infinispan/service/HelloWorldServiceUnitTest.java create mode 100644 libraries/src/test/java/com/baeldung/infinispan/service/TransactionalServiceUnitTest.java diff --git a/libraries/pom.xml b/libraries/pom.xml index fa1839010c..64cc9c6a84 100644 --- a/libraries/pom.xml +++ b/libraries/pom.xml @@ -649,6 +649,11 @@ google-http-client-gson ${googleclient.version} + + org.infinispan + infinispan-core + ${infinispan.version} + @@ -811,5 +816,6 @@ 3.0.14 8.5.24 2.2.0 + 9.1.5.Final - \ No newline at end of file + diff --git a/libraries/src/main/java/com/baeldung/infinispan/CacheConfiguration.java b/libraries/src/main/java/com/baeldung/infinispan/CacheConfiguration.java new file mode 100644 index 0000000000..bf214458f3 --- /dev/null +++ b/libraries/src/main/java/com/baeldung/infinispan/CacheConfiguration.java @@ -0,0 +1,85 @@ +package com.baeldung.infinispan; + +import com.baeldung.infinispan.listener.CacheListener; +import org.infinispan.Cache; +import org.infinispan.configuration.cache.Configuration; +import org.infinispan.configuration.cache.ConfigurationBuilder; +import org.infinispan.eviction.EvictionType; +import org.infinispan.manager.DefaultCacheManager; +import org.infinispan.transaction.LockingMode; +import org.infinispan.transaction.TransactionMode; + +import java.util.concurrent.TimeUnit; + +public class CacheConfiguration { + + public static final String SIMPLE_HELLO_WORLD_CACHE = "simple-hello-world-cache"; + public static final String EXPIRING_HELLO_WORLD_CACHE = "expiring-hello-world-cache"; + public static final String EVICTING_HELLO_WORLD_CACHE = "evicting-hello-world-cache"; + public static final String PASSIVATING_HELLO_WORLD_CACHE = "passivating-hello-world-cache"; + public static final String TRANSACTIONAL_CACHE = "transactional-cache"; + + public DefaultCacheManager cacheManager() { + DefaultCacheManager cacheManager = new DefaultCacheManager(); + return cacheManager; + } + + public Cache transactionalCache(DefaultCacheManager cacheManager, CacheListener listener) { + return this.buildCache(TRANSACTIONAL_CACHE, cacheManager, listener, transactionalConfiguration()); + } + + public Cache simpleHelloWorldCache(DefaultCacheManager cacheManager, CacheListener listener) { + return this.buildCache(SIMPLE_HELLO_WORLD_CACHE, cacheManager, listener, new ConfigurationBuilder().build()); + } + + public Cache expiringHelloWorldCache(DefaultCacheManager cacheManager, CacheListener listener) { + return this.buildCache(EXPIRING_HELLO_WORLD_CACHE, cacheManager, listener, expiringConfiguration()); + } + + public Cache evictingHelloWorldCache(DefaultCacheManager cacheManager, CacheListener listener) { + return this.buildCache(EVICTING_HELLO_WORLD_CACHE, cacheManager, listener, evictingConfiguration()); + } + + public Cache passivatingHelloWorldCache(DefaultCacheManager cacheManager, CacheListener listener) { + return this.buildCache(PASSIVATING_HELLO_WORLD_CACHE, cacheManager, listener, passivatingConfiguration()); + } + + private Cache buildCache(String cacheName, DefaultCacheManager cacheManager, + CacheListener listener, Configuration configuration) { + + cacheManager.defineConfiguration(cacheName, configuration); + Cache cache = cacheManager.getCache(cacheName); + cache.addListener(listener); + return cache; + } + + private Configuration expiringConfiguration() { + return new ConfigurationBuilder().expiration().lifespan(1, TimeUnit.SECONDS) + .build(); + } + + private Configuration evictingConfiguration() { + return new ConfigurationBuilder() + .memory().evictionType(EvictionType.COUNT).size(1) + .build(); + } + + private Configuration passivatingConfiguration() { + return new ConfigurationBuilder() + .memory().evictionType(EvictionType.COUNT).size(1) + .persistence() + .passivation(true) + .addSingleFileStore() + .purgeOnStartup(true) + .location(System.getProperty("java.io.tmpdir")) + .build(); + } + + private Configuration transactionalConfiguration() { + return new ConfigurationBuilder() + .transaction().transactionMode(TransactionMode.TRANSACTIONAL) + .lockingMode(LockingMode.PESSIMISTIC) + .build(); + } + +} diff --git a/libraries/src/main/java/com/baeldung/infinispan/listener/CacheListener.java b/libraries/src/main/java/com/baeldung/infinispan/listener/CacheListener.java new file mode 100644 index 0000000000..2f6536ad87 --- /dev/null +++ b/libraries/src/main/java/com/baeldung/infinispan/listener/CacheListener.java @@ -0,0 +1,55 @@ +package com.baeldung.infinispan.listener; + +import org.infinispan.notifications.Listener; +import org.infinispan.notifications.cachelistener.annotation.*; +import org.infinispan.notifications.cachelistener.event.*; + +@Listener +public class CacheListener { + + @CacheEntryCreated + public void entryCreated(CacheEntryCreatedEvent event) { + this.printLog("Adding key '" + event.getKey() + "' to cache", event); + } + + @CacheEntryExpired + public void entryExpired(CacheEntryExpiredEvent event) { + this.printLog("Expiring key '" + event.getKey() + "' from cache", event); + } + + @CacheEntryVisited + public void entryVisited(CacheEntryVisitedEvent event) { + this.printLog("Key '" + event.getKey() + "' was visited", event); + } + + @CacheEntryActivated + public void entryActivated(CacheEntryActivatedEvent event) { + this.printLog("Activating key '" + event.getKey() + "' on cache", event); + } + + @CacheEntryPassivated + public void entryPassivated(CacheEntryPassivatedEvent event) { + this.printLog("Passivating key '" + event.getKey() + "' from cache", event); + } + + @CacheEntryLoaded + public void entryLoaded(CacheEntryLoadedEvent event) { + this.printLog("Loading key '" + event.getKey() + "' to cache", event); + } + + @CacheEntriesEvicted + public void entriesEvicted(CacheEntriesEvictedEvent event) { + final StringBuilder builder = new StringBuilder(); + event.getEntries().entrySet().forEach((e) -> + builder.append(e.getKey() + ", ") + ); + System.out.println("Evicting following entries from cache: " + builder.toString()); + } + + private void printLog(String log, CacheEntryEvent event) { + if (!event.isPre()) { + System.out.println(log); + } + } + +} diff --git a/libraries/src/main/java/com/baeldung/infinispan/repository/HelloWorldRepository.java b/libraries/src/main/java/com/baeldung/infinispan/repository/HelloWorldRepository.java new file mode 100644 index 0000000000..85c0d539a3 --- /dev/null +++ b/libraries/src/main/java/com/baeldung/infinispan/repository/HelloWorldRepository.java @@ -0,0 +1,15 @@ +package com.baeldung.infinispan.repository; + +public class HelloWorldRepository { + + public String getHelloWorld() { + try { + System.out.println("Executing some heavy query"); + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + return "Hello World!"; + } + +} diff --git a/libraries/src/main/java/com/baeldung/infinispan/service/HelloWorldService.java b/libraries/src/main/java/com/baeldung/infinispan/service/HelloWorldService.java new file mode 100644 index 0000000000..0d1ffb4168 --- /dev/null +++ b/libraries/src/main/java/com/baeldung/infinispan/service/HelloWorldService.java @@ -0,0 +1,90 @@ +package com.baeldung.infinispan.service; + +import com.baeldung.infinispan.listener.CacheListener; +import com.baeldung.infinispan.repository.HelloWorldRepository; +import org.infinispan.Cache; + +import java.util.concurrent.TimeUnit; + +public class HelloWorldService { + + private final HelloWorldRepository repository; + + private final Cache simpleHelloWorldCache; + private final Cache expiringHelloWorldCache; + private final Cache evictingHelloWorldCache; + private final Cache passivatingHelloWorldCache; + + public HelloWorldService(HelloWorldRepository repository, CacheListener listener, + Cache simpleHelloWorldCache, + Cache expiringHelloWorldCache, + Cache evictingHelloWorldCache, + Cache passivatingHelloWorldCache) { + + this.repository = repository; + + this.simpleHelloWorldCache = simpleHelloWorldCache; + this.expiringHelloWorldCache = expiringHelloWorldCache; + this.evictingHelloWorldCache = evictingHelloWorldCache; + this.passivatingHelloWorldCache = passivatingHelloWorldCache; + } + + public String findSimpleHelloWorld() { + String cacheKey = "simple-hello"; + String helloWorld = simpleHelloWorldCache.get(cacheKey); + if (helloWorld == null) { + helloWorld = repository.getHelloWorld(); + simpleHelloWorldCache.put(cacheKey, helloWorld); + } + return helloWorld; + } + + public String findExpiringHelloWorld() { + String cacheKey = "expiring-hello"; + String helloWorld = simpleHelloWorldCache.get(cacheKey); + if (helloWorld == null) { + helloWorld = repository.getHelloWorld(); + simpleHelloWorldCache.put(cacheKey, helloWorld, 1, TimeUnit.SECONDS); + } + return helloWorld; + } + + public String findIdleHelloWorld() { + String cacheKey = "idle-hello"; + String helloWorld = simpleHelloWorldCache.get(cacheKey); + if (helloWorld == null) { + helloWorld = repository.getHelloWorld(); + simpleHelloWorldCache.put(cacheKey, helloWorld, -1, TimeUnit.SECONDS, 10, TimeUnit.SECONDS); + } + return helloWorld; + } + + public String findSimpleHelloWorldInExpiringCache() { + String cacheKey = "simple-hello"; + String helloWorld = expiringHelloWorldCache.get(cacheKey); + if (helloWorld == null) { + helloWorld = repository.getHelloWorld(); + expiringHelloWorldCache.put(cacheKey, helloWorld); + } + return helloWorld; + } + + public String findEvictingHelloWorld(String key) { + String value = evictingHelloWorldCache.get(key); + if(value == null) { + value = repository.getHelloWorld(); + evictingHelloWorldCache.put(key, value); + } + return value; + } + + public String findPassivatingHelloWorld(String key) { + String value = passivatingHelloWorldCache.get(key); + if(value == null) { + value = repository.getHelloWorld(); + passivatingHelloWorldCache.put(key, value); + } + return value; + } + +} diff --git a/libraries/src/main/java/com/baeldung/infinispan/service/TransactionalService.java b/libraries/src/main/java/com/baeldung/infinispan/service/TransactionalService.java new file mode 100644 index 0000000000..b0dbf5475f --- /dev/null +++ b/libraries/src/main/java/com/baeldung/infinispan/service/TransactionalService.java @@ -0,0 +1,57 @@ +package com.baeldung.infinispan.service; + +import org.infinispan.Cache; +import org.springframework.util.StopWatch; + +import javax.transaction.TransactionManager; + +public class TransactionalService { + + private final Cache transactionalCache; + + private static final String KEY = "key"; + + public TransactionalService(Cache transactionalCache) { + this.transactionalCache = transactionalCache; + + transactionalCache.put(KEY, 0); + } + + public Integer getQuickHowManyVisits() { + try { + TransactionManager tm = transactionalCache.getAdvancedCache().getTransactionManager(); + tm.begin(); + Integer howManyVisits = transactionalCache.get(KEY); + howManyVisits++; + System.out.println("Ill try to set HowManyVisits to " + howManyVisits); + StopWatch watch = new StopWatch(); + watch.start(); + transactionalCache.put(KEY, howManyVisits); + watch.stop(); + System.out.println("I was able to set HowManyVisits to " + howManyVisits + + " after waiting " + watch.getTotalTimeSeconds() + " seconds"); + + tm.commit(); + return howManyVisits; + } catch (Exception e) { + e.printStackTrace(); + return 0; + } + } + + public void startBackgroundBatch() { + try { + TransactionManager tm = transactionalCache.getAdvancedCache().getTransactionManager(); + tm.begin(); + transactionalCache.put(KEY, 1000); + System.out.println("HowManyVisits should now be 1000, " + + "but we are holding the transaction"); + Thread.sleep(1000L); + tm.rollback(); + System.out.println("The slow batch suffered a rollback"); + } catch (Exception e) { + e.printStackTrace(); + } + } + +} diff --git a/libraries/src/test/java/com/baeldung/infinispan/ConfigurationTest.java b/libraries/src/test/java/com/baeldung/infinispan/ConfigurationTest.java new file mode 100644 index 0000000000..b05314491b --- /dev/null +++ b/libraries/src/test/java/com/baeldung/infinispan/ConfigurationTest.java @@ -0,0 +1,56 @@ +package com.baeldung.infinispan; + +import com.baeldung.infinispan.listener.CacheListener; +import com.baeldung.infinispan.repository.HelloWorldRepository; +import com.baeldung.infinispan.service.HelloWorldService; +import com.baeldung.infinispan.service.TransactionalService; +import org.infinispan.Cache; +import org.infinispan.manager.DefaultCacheManager; +import org.junit.After; +import org.junit.Before; + +public class ConfigurationTest { + + private DefaultCacheManager cacheManager; + + private HelloWorldRepository repository = new HelloWorldRepository(); + + protected HelloWorldService helloWorldService; + protected TransactionalService transactionalService; + + @Before + public void setup() { + CacheConfiguration configuration = new CacheConfiguration(); + CacheListener listener = new CacheListener(); + + cacheManager = configuration.cacheManager(); + + Cache transactionalCache = + configuration.transactionalCache(cacheManager, listener); + + Cache simpleHelloWorldCache = + configuration.simpleHelloWorldCache(cacheManager, listener); + + Cache expiringHelloWorldCache = + configuration.expiringHelloWorldCache(cacheManager, listener); + + Cache evictingHelloWorldCache = + configuration.evictingHelloWorldCache(cacheManager, listener); + + Cache passivatingHelloWorldCache = + configuration.passivatingHelloWorldCache(cacheManager, listener); + + this.helloWorldService = new HelloWorldService(repository, + listener, simpleHelloWorldCache, expiringHelloWorldCache, evictingHelloWorldCache, + passivatingHelloWorldCache); + + this.transactionalService = new TransactionalService(transactionalCache); + + } + + @After + public void tearDown() { + cacheManager.stop(); + } + +} diff --git a/libraries/src/test/java/com/baeldung/infinispan/service/HelloWorldServiceUnitTest.java b/libraries/src/test/java/com/baeldung/infinispan/service/HelloWorldServiceUnitTest.java new file mode 100644 index 0000000000..bda2e6886b --- /dev/null +++ b/libraries/src/test/java/com/baeldung/infinispan/service/HelloWorldServiceUnitTest.java @@ -0,0 +1,105 @@ +package com.baeldung.infinispan.service; + +import com.baeldung.infinispan.ConfigurationTest; +import org.junit.Test; + +import static org.assertj.core.api.Java6Assertions.assertThat; + +public class HelloWorldServiceUnitTest extends ConfigurationTest { + + @Test + public void whenGetIsCalledTwoTimes_thenTheSecondShouldHitTheCache() { + long milis = System.currentTimeMillis(); + helloWorldService.findSimpleHelloWorld(); + long executionTime = System.currentTimeMillis() - milis; + + assertThat(executionTime).isGreaterThanOrEqualTo(1000); + + milis = System.currentTimeMillis(); + helloWorldService.findSimpleHelloWorld(); + executionTime = System.currentTimeMillis() - milis; + + assertThat(executionTime).isLessThan(100); + } + + @Test + public void whenGetIsCalledTwoTimesQuickly_thenTheSecondShouldHitTheCache() { + long milis = System.currentTimeMillis(); + helloWorldService.findExpiringHelloWorld(); + long executionTime = System.currentTimeMillis() - milis; + + assertThat(executionTime).isGreaterThanOrEqualTo(1000); + + milis = System.currentTimeMillis(); + helloWorldService.findExpiringHelloWorld(); + executionTime = System.currentTimeMillis() - milis; + + assertThat(executionTime).isLessThan(100); + } + + @Test + public void whenGetIsCalledTwoTimesSparsely_thenNeitherShouldHitTheCache() + throws InterruptedException { + + long milis = System.currentTimeMillis(); + helloWorldService.findSimpleHelloWorldInExpiringCache(); + long executionTime = System.currentTimeMillis() - milis; + + assertThat(executionTime).isGreaterThanOrEqualTo(1000); + + Thread.sleep(1100); + + milis = System.currentTimeMillis(); + helloWorldService.findSimpleHelloWorldInExpiringCache(); + executionTime = System.currentTimeMillis() - milis; + + assertThat(executionTime).isGreaterThanOrEqualTo(1000); + } + + @Test + public void givenOneEntryIsConfigured_whenTwoAreAdded_thenFirstShouldntBeAvailable() + throws InterruptedException { + + long milis = System.currentTimeMillis(); + helloWorldService.findEvictingHelloWorld("key 1"); + long executionTime = System.currentTimeMillis() - milis; + + assertThat(executionTime).isGreaterThanOrEqualTo(1000); + + milis = System.currentTimeMillis(); + helloWorldService.findEvictingHelloWorld("key 2"); + executionTime = System.currentTimeMillis() - milis; + + assertThat(executionTime).isGreaterThanOrEqualTo(1000); + + milis = System.currentTimeMillis(); + helloWorldService.findEvictingHelloWorld("key 1"); + executionTime = System.currentTimeMillis() - milis; + + assertThat(executionTime).isGreaterThanOrEqualTo(1000); + } + + @Test + public void givenOneEntryIsConfigured_whenTwoAreAdded_thenTheFirstShouldBeAvailable() + throws InterruptedException { + + long milis = System.currentTimeMillis(); + helloWorldService.findPassivatingHelloWorld("key 1"); + long executionTime = System.currentTimeMillis() - milis; + + assertThat(executionTime).isGreaterThanOrEqualTo(1000); + + milis = System.currentTimeMillis(); + helloWorldService.findPassivatingHelloWorld("key 2"); + executionTime = System.currentTimeMillis() - milis; + + assertThat(executionTime).isGreaterThanOrEqualTo(1000); + + milis = System.currentTimeMillis(); + helloWorldService.findPassivatingHelloWorld("key 1"); + executionTime = System.currentTimeMillis() - milis; + + assertThat(executionTime).isLessThan(100); + } + +} diff --git a/libraries/src/test/java/com/baeldung/infinispan/service/TransactionalServiceUnitTest.java b/libraries/src/test/java/com/baeldung/infinispan/service/TransactionalServiceUnitTest.java new file mode 100644 index 0000000000..f529222079 --- /dev/null +++ b/libraries/src/test/java/com/baeldung/infinispan/service/TransactionalServiceUnitTest.java @@ -0,0 +1,24 @@ +package com.baeldung.infinispan.service; + +import com.baeldung.infinispan.ConfigurationTest; +import org.junit.Test; + +import static org.assertj.core.api.Java6Assertions.assertThat; + +public class TransactionalServiceUnitTest extends ConfigurationTest { + + @Test + public void whenLockingAnEntry_thenItShouldBeInaccessible() throws InterruptedException { + Runnable backGroundJob = () -> transactionalService.startBackgroundBatch(); + Thread backgroundThread = new Thread(backGroundJob); + transactionalService.getQuickHowManyVisits(); + backgroundThread.start(); + Thread.sleep(100); //lets wait our thread warm up + long milis = System.currentTimeMillis(); + transactionalService.getQuickHowManyVisits(); + long executionTime = System.currentTimeMillis() - milis; + + assertThat(executionTime).isGreaterThan(500).isLessThan(1000); + } + +} From 5a3e15a6e9599d955b8cb12afd2c9e15c5b12c43 Mon Sep 17 00:00:00 2001 From: Loredana Crusoveanu Date: Sun, 11 Feb 2018 17:10:07 +0200 Subject: [PATCH 34/58] update http client incubator package --- .../java9/httpclient/SimpleHttpRequestsUnitTest.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core-java-9/src/test/java/com/baeldung/java9/httpclient/SimpleHttpRequestsUnitTest.java b/core-java-9/src/test/java/com/baeldung/java9/httpclient/SimpleHttpRequestsUnitTest.java index 4a704139a1..aea9945e2b 100644 --- a/core-java-9/src/test/java/com/baeldung/java9/httpclient/SimpleHttpRequestsUnitTest.java +++ b/core-java-9/src/test/java/com/baeldung/java9/httpclient/SimpleHttpRequestsUnitTest.java @@ -8,10 +8,10 @@ import java.net.CookieManager; import java.net.CookiePolicy; import java.net.URI; import java.net.URISyntaxException; -import java.net.http.HttpClient; -import java.net.http.HttpHeaders; -import java.net.http.HttpRequest; -import java.net.http.HttpResponse; +import jdk.incubator.http.HttpClient; +import jdk.incubator.http.HttpHeaders; +import jdk.incubator.http.HttpRequest; +import jdk.incubator.http.HttpResponse; import java.security.NoSuchAlgorithmException; import java.util.List; import java.util.Map; From 0b5a301c7c356a89fe36bd4cdd5c821f22029e51 Mon Sep 17 00:00:00 2001 From: Loredana Crusoveanu Date: Sun, 11 Feb 2018 18:29:27 +0200 Subject: [PATCH 35/58] remove old http client api --- .../SimpleHttpRequestsUnitTest.java | 126 ------------------ 1 file changed, 126 deletions(-) delete mode 100644 core-java-9/src/test/java/com/baeldung/java9/httpclient/SimpleHttpRequestsUnitTest.java diff --git a/core-java-9/src/test/java/com/baeldung/java9/httpclient/SimpleHttpRequestsUnitTest.java b/core-java-9/src/test/java/com/baeldung/java9/httpclient/SimpleHttpRequestsUnitTest.java deleted file mode 100644 index aea9945e2b..0000000000 --- a/core-java-9/src/test/java/com/baeldung/java9/httpclient/SimpleHttpRequestsUnitTest.java +++ /dev/null @@ -1,126 +0,0 @@ -package com.baeldung.java9.httpclient; - -import static java.net.HttpURLConnection.HTTP_OK; -import static org.junit.Assert.assertTrue; - -import java.io.IOException; -import java.net.CookieManager; -import java.net.CookiePolicy; -import java.net.URI; -import java.net.URISyntaxException; -import jdk.incubator.http.HttpClient; -import jdk.incubator.http.HttpHeaders; -import jdk.incubator.http.HttpRequest; -import jdk.incubator.http.HttpResponse; -import java.security.NoSuchAlgorithmException; -import java.util.List; -import java.util.Map; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; - -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLParameters; - -import org.junit.Before; -import org.junit.Test; - -public class SimpleHttpRequestsUnitTest { - - private URI httpURI; - - @Before - public void init() throws URISyntaxException { - httpURI = new URI("http://www.baeldung.com/"); - } - - @Test - public void quickGet() throws IOException, InterruptedException, URISyntaxException { - HttpRequest request = HttpRequest.create(httpURI).GET(); - HttpResponse response = request.response(); - int responseStatusCode = response.statusCode(); - String responseBody = response.body(HttpResponse.asString()); - assertTrue("Get response status code is bigger then 400", responseStatusCode < 400); - } - - @Test - public void asynchronousGet() throws URISyntaxException, IOException, InterruptedException, ExecutionException { - HttpRequest request = HttpRequest.create(httpURI).GET(); - long before = System.currentTimeMillis(); - CompletableFuture futureResponse = request.responseAsync(); - futureResponse.thenAccept(response -> { - String responseBody = response.body(HttpResponse.asString()); - }); - HttpResponse resp = futureResponse.get(); - HttpHeaders hs = resp.headers(); - assertTrue("There should be more then 1 header.", hs.map().size() > 1); - } - - @Test - public void postMehtod() throws URISyntaxException, IOException, InterruptedException { - HttpRequest.Builder requestBuilder = HttpRequest.create(httpURI); - requestBuilder.body(HttpRequest.fromString("param1=foo,param2=bar")).followRedirects(HttpClient.Redirect.SECURE); - HttpRequest request = requestBuilder.POST(); - HttpResponse response = request.response(); - int statusCode = response.statusCode(); - assertTrue("HTTP return code", statusCode == HTTP_OK); - } - - @Test - public void configureHttpClient() throws NoSuchAlgorithmException, URISyntaxException, IOException, InterruptedException { - CookieManager cManager = new CookieManager(); - cManager.setCookiePolicy(CookiePolicy.ACCEPT_ORIGINAL_SERVER); - - SSLParameters sslParam = new SSLParameters(new String[] { "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256" }, new String[] { "TLSv1.2" }); - - HttpClient.Builder hcBuilder = HttpClient.create(); - hcBuilder.cookieManager(cManager).sslContext(SSLContext.getDefault()).sslParameters(sslParam); - HttpClient httpClient = hcBuilder.build(); - HttpRequest.Builder reqBuilder = httpClient.request(new URI("https://www.facebook.com")); - - HttpRequest request = reqBuilder.followRedirects(HttpClient.Redirect.ALWAYS).GET(); - HttpResponse response = request.response(); - int statusCode = response.statusCode(); - assertTrue("HTTP return code", statusCode == HTTP_OK); - } - - SSLParameters getDefaultSSLParameters() throws NoSuchAlgorithmException { - SSLParameters sslP1 = SSLContext.getDefault().getSupportedSSLParameters(); - String[] proto = sslP1.getApplicationProtocols(); - String[] cifers = sslP1.getCipherSuites(); - System.out.println(printStringArr(proto)); - System.out.println(printStringArr(cifers)); - return sslP1; - } - - String printStringArr(String... args) { - if (args == null) { - return null; - } - StringBuilder sb = new StringBuilder(); - for (String s : args) { - sb.append(s); - sb.append("\n"); - } - return sb.toString(); - } - - String printHeaders(HttpHeaders h) { - if (h == null) { - return null; - } - - StringBuilder sb = new StringBuilder(); - Map> hMap = h.map(); - for (String k : hMap.keySet()) { - sb.append(k).append(":"); - List l = hMap.get(k); - if (l != null) { - l.forEach(s -> { - sb.append(s).append(","); - }); - } - sb.append("\n"); - } - return sb.toString(); - } -} From 9cc582e66a26df4359f0d527d740c9392f54a29b Mon Sep 17 00:00:00 2001 From: Orry Date: Sun, 11 Feb 2018 18:40:56 +0200 Subject: [PATCH 36/58] BAEL-1517: Editor Review Changes (#3635) * Add XML, JavaConfig and Autowired examples. * BAEL-1517: Added Java7 style assertions * BAEL-1517: Upgrade AssertJ to 3.9.0; add Java 8 style assertion tests * Revert "Add XML, JavaConfig and Autowired examples." This reverts commit 8f4df6b903866dac1725832d06ee7382fc89d0ce. * BAEL-1517: Editor Review changes * BAEL-1517: Formatting... --- .../exceptions/Java8StyleAssertions.java | 38 +++++++++++++++---- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/testing-modules/testing/src/test/java/com/baeldung/testing/assertj/exceptions/Java8StyleAssertions.java b/testing-modules/testing/src/test/java/com/baeldung/testing/assertj/exceptions/Java8StyleAssertions.java index 53f192bb2f..973b921654 100644 --- a/testing-modules/testing/src/test/java/com/baeldung/testing/assertj/exceptions/Java8StyleAssertions.java +++ b/testing-modules/testing/src/test/java/com/baeldung/testing/assertj/exceptions/Java8StyleAssertions.java @@ -5,19 +5,43 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.assertj.core.api.Assertions.catchThrowable; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; import org.junit.Test; public class Java8StyleAssertions { @Test - public void whenDividingByZero_thenArithmeticException() { + public void whenGettingOutOfBoundsItem_thenIndexOutOfBoundsException() { assertThatThrownBy(() -> { - int numerator = 10; - int denominator = 0; - int quotient = numerator / denominator; - }).isInstanceOf(ArithmeticException.class) - .hasMessageContaining("/ by zero"); + ArrayList myStringList = new ArrayList(Arrays.asList("Strine one", "String two")); + myStringList.get(2); + }).isInstanceOf(IndexOutOfBoundsException.class) + .hasMessageStartingWith("Index: 2") + .hasMessageContaining("2") + .hasMessageEndingWith("Size: 2") + .hasMessageContaining("Index: 2, Size: 2") + .hasMessage("Index: %s, Size: %s", 2, 2) + .hasMessageMatching("Index: \\d+, Size: \\d+") + .hasNoCause(); + } + @Test + public void whenWrappingException_thenCauseInstanceOfWrappedExceptionType() { + assertThatThrownBy(() -> { + try { + throw new IOException(); + } catch (IOException e) { + throw new RuntimeException(e); + } + }).isInstanceOf(RuntimeException.class) + .hasCauseInstanceOf(IOException.class) + .hasStackTraceContaining("IOException"); + } + + @Test + public void whenDividingByZero_thenArithmeticException() { assertThatExceptionOfType(ArithmeticException.class).isThrownBy(() -> { int numerator = 10; int denominator = 0; @@ -25,7 +49,7 @@ public class Java8StyleAssertions { }) .withMessageContaining("/ by zero"); - // BDD style: + // Alternatively: // when Throwable thrown = catchThrowable(() -> { From 4d64a122710d4c6de532c7afc4d4f3e849862684 Mon Sep 17 00:00:00 2001 From: Shouvik Bhattacharya <33756821+shouvikbhattacharya@users.noreply.github.com> Date: Mon, 12 Feb 2018 10:28:07 +0530 Subject: [PATCH 37/58] BAEL-1525: Review comments incorporated. (#3639) --- .../java/com/baeldung/string/Palindrome.java | 46 ++++++++------- .../com/baeldung/string/PalindromeTest.java | 59 ++++++++----------- 2 files changed, 49 insertions(+), 56 deletions(-) diff --git a/core-java/src/main/java/com/baeldung/string/Palindrome.java b/core-java/src/main/java/com/baeldung/string/Palindrome.java index 0759787249..97d4d36d07 100644 --- a/core-java/src/main/java/com/baeldung/string/Palindrome.java +++ b/core-java/src/main/java/com/baeldung/string/Palindrome.java @@ -5,58 +5,62 @@ import java.util.stream.IntStream; public class Palindrome { public boolean isPalindrome(String text) { - text = text.replaceAll("\\s+", "") - .toLowerCase(); - int length = text.length(); + String clean = text.replaceAll("\\s+", "").toLowerCase(); + int length = clean.length(); int forward = 0; int backward = length - 1; - boolean palindrome = true; while (backward > forward) { - char forwardChar = text.charAt(forward++); - char backwardChar = text.charAt(backward--); + char forwardChar = clean.charAt(forward++); + char backwardChar = clean.charAt(backward--); if (forwardChar != backwardChar) return false; } - return palindrome; + return true; } public boolean isPalindromeReverseTheString(String text) { - String reverse = ""; - text = text.replaceAll("\\s+", "").toLowerCase(); - char[] plain = text.toCharArray(); + StringBuilder reverse = new StringBuilder(); + String clean = text.replaceAll("\\s+", "").toLowerCase(); + char[] plain = clean.toCharArray(); for (int i = plain.length - 1; i >= 0; i--) - reverse += plain[i]; - return reverse.equals(text); + reverse.append(plain[i]); + return (reverse.toString()).equals(clean); } public boolean isPalindromeUsingStringBuilder(String text) { - StringBuilder plain = new StringBuilder(text); + String clean = text.replaceAll("\\s+", "").toLowerCase(); + StringBuilder plain = new StringBuilder(clean); StringBuilder reverse = plain.reverse(); - return reverse.equals(plain); + return (reverse.toString()).equals(clean); } public boolean isPalindromeUsingStringBuffer(String text) { - StringBuffer plain = new StringBuffer(text); + String clean = text.replaceAll("\\s+", "").toLowerCase(); + StringBuffer plain = new StringBuffer(clean); StringBuffer reverse = plain.reverse(); - return reverse.equals(plain); + return (reverse.toString()).equals(clean); } - public boolean isPalindromeRecursive(String text, int forward, int backward) { + public boolean isPalindromeRecursive(String text) { + String clean = text.replaceAll("\\s+", "").toLowerCase(); + return recursivePalindrome(clean, 0, clean.length() - 1); + } + + private boolean recursivePalindrome(String text, int forward, int backward) { if (forward == backward) return true; if ((text.charAt(forward)) != (text.charAt(backward))) return false; if (forward < backward + 1) { - return isPalindromeRecursive(text, forward + 1, backward - 1); + return recursivePalindrome(text, forward + 1, backward - 1); } return true; } - + public boolean isPalindromeUsingIntStream(String text) { - String temp = text.replaceAll("\\s+", "").toLowerCase(); + String temp = text.replaceAll("\\s+", "").toLowerCase(); return IntStream.range(0, temp.length() / 2) .noneMatch(i -> temp.charAt(i) != temp.charAt(temp.length() - i - 1)); } - } diff --git a/core-java/src/test/java/com/baeldung/string/PalindromeTest.java b/core-java/src/test/java/com/baeldung/string/PalindromeTest.java index d1a05b6617..bc6fee2cd9 100644 --- a/core-java/src/test/java/com/baeldung/string/PalindromeTest.java +++ b/core-java/src/test/java/com/baeldung/string/PalindromeTest.java @@ -25,84 +25,73 @@ public class PalindromeTest { @Test public void whenWord_shouldBePalindrome() { - for(String word:words) + for (String word : words) assertTrue(palindrome.isPalindrome(word)); } @Test public void whenSentence_shouldBePalindrome() { - for(String sentence:sentences) + for (String sentence : sentences) assertTrue(palindrome.isPalindrome(sentence)); } - + @Test public void whenReverseWord_shouldBePalindrome() { - for(String word:words) + for (String word : words) assertTrue(palindrome.isPalindromeReverseTheString(word)); } - + @Test public void whenReverseSentence_shouldBePalindrome() { - for(String sentence:sentences) + for (String sentence : sentences) assertTrue(palindrome.isPalindromeReverseTheString(sentence)); } - + @Test public void whenStringBuilderWord_shouldBePalindrome() { - for(String word:words) + for (String word : words) assertTrue(palindrome.isPalindromeUsingStringBuilder(word)); } - + @Test public void whenStringBuilderSentence_shouldBePalindrome() { - for(String sentence:sentences) + for (String sentence : sentences) assertTrue(palindrome.isPalindromeUsingStringBuilder(sentence)); } - + @Test public void whenStringBufferWord_shouldBePalindrome() { - for(String word:words) + for (String word : words) assertTrue(palindrome.isPalindromeUsingStringBuffer(word)); } - + @Test public void whenStringBufferSentence_shouldBePalindrome() { - for(String sentence:sentences) - + for (String sentence : sentences) assertTrue(palindrome.isPalindromeUsingStringBuffer(sentence)); } - + @Test public void whenPalindromeRecursive_wordShouldBePalindrome() { - for(String word:words) { - word = word.replaceAll("\\s+", "").toLowerCase(); - int backward = word.length()-1; - - assertTrue(palindrome.isPalindromeRecursive(word,0,backward)); - } + for (String word : words) + assertTrue(palindrome.isPalindromeRecursive(word)); } - + @Test public void whenPalindromeRecursive_sentenceShouldBePalindrome() { - for(String sentence:sentences) { - sentence = sentence.replaceAll("\\s+", "").toLowerCase(); - int backward = sentence.length()-1; - - assertTrue(palindrome.isPalindromeRecursive(sentence,0,backward)); - } + for (String sentence : sentences) + assertTrue(palindrome.isPalindromeRecursive(sentence)); } - + @Test public void whenPalindromeStreams_wordShouldBePalindrome() { - for(String word:words) { + for (String word : words) assertTrue(palindrome.isPalindromeUsingIntStream(word)); - } } - + @Test public void whenPalindromeStreams_sentenceShouldBePalindrome() { - for(String sentence:sentences) { + for (String sentence : sentences) assertTrue(palindrome.isPalindromeUsingIntStream(sentence)); - } } } From 97f56f33f69c95d25d1d57d64087e62a7a6afe71 Mon Sep 17 00:00:00 2001 From: Rakesh Kumar Date: Mon, 12 Feb 2018 11:20:01 -0500 Subject: [PATCH 38/58] BAEL-1149 - Spring ResponseStatusException (#3648) --- .../baeldung/execption/ActorController.java | 41 +++++++++++++++++++ .../execption/ActorNotFoundException.java | 13 ++++++ .../com/baeldung/execption/ActorService.java | 35 ++++++++++++++++ .../execption/SpringExceptionApplication.java | 14 +++++++ 4 files changed, 103 insertions(+) create mode 100644 spring-5/src/main/java/com/baeldung/execption/ActorController.java create mode 100644 spring-5/src/main/java/com/baeldung/execption/ActorNotFoundException.java create mode 100644 spring-5/src/main/java/com/baeldung/execption/ActorService.java create mode 100644 spring-5/src/main/java/com/baeldung/execption/SpringExceptionApplication.java diff --git a/spring-5/src/main/java/com/baeldung/execption/ActorController.java b/spring-5/src/main/java/com/baeldung/execption/ActorController.java new file mode 100644 index 0000000000..6c9c46253a --- /dev/null +++ b/spring-5/src/main/java/com/baeldung/execption/ActorController.java @@ -0,0 +1,41 @@ +package com.baeldung.execption; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.server.ResponseStatusException; + +@RestController +public class ActorController { + + @Autowired + ActorService actorService; + + @GetMapping("/actor/{id}") + public String getActorName(@PathVariable("id") int id) { + try { + return actorService.getActor(id); + } catch (ActorNotFoundException ex) { + throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Actor Not Found", ex); + } + } + + @DeleteMapping("/actor/{id}") + public String getActor(@PathVariable("id") int id) { + return actorService.removeActor(id); + } + + @PutMapping("/actor/{id}/{name}") + public String updateActorName(@PathVariable("id") int id, @PathVariable("name") String name) { + try { + return actorService.updateActor(id, name); + } catch (ActorNotFoundException ex) { + throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Provide correct Actor Id", ex); + } + } + +} diff --git a/spring-5/src/main/java/com/baeldung/execption/ActorNotFoundException.java b/spring-5/src/main/java/com/baeldung/execption/ActorNotFoundException.java new file mode 100644 index 0000000000..642c075b5d --- /dev/null +++ b/spring-5/src/main/java/com/baeldung/execption/ActorNotFoundException.java @@ -0,0 +1,13 @@ +package com.baeldung.execption; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; + +@ResponseStatus(code = HttpStatus.NOT_FOUND, reason = "Actor Not Found") +public class ActorNotFoundException extends Exception { + private static final long serialVersionUID = 1L; + + public ActorNotFoundException(String errorMessage) { + super(errorMessage); + } +} diff --git a/spring-5/src/main/java/com/baeldung/execption/ActorService.java b/spring-5/src/main/java/com/baeldung/execption/ActorService.java new file mode 100644 index 0000000000..956fa92015 --- /dev/null +++ b/spring-5/src/main/java/com/baeldung/execption/ActorService.java @@ -0,0 +1,35 @@ +package com.baeldung.execption; + +import java.util.Arrays; +import java.util.List; + +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Service; +import org.springframework.web.server.ResponseStatusException; + +@Service +public class ActorService { + List actors = Arrays.asList("Jack Nicholson", "Marlon Brando", "Robert De Niro", "Al Pacino", "Tom Hanks"); + + public String getActor(int index) throws ActorNotFoundException { + if (index >= actors.size()) { + throw new ActorNotFoundException("Actor Not Found in Repsoitory"); + } + return actors.get(index); + } + + public String updateActor(int index, String actorName) throws ActorNotFoundException { + if (index >= actors.size()) { + throw new ActorNotFoundException("Actor Not Found in Repsoitory"); + } + actors.set(index, actorName); + return actorName; + } + + public String removeActor(int index) { + if (index >= actors.size()) { + throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Actor Not Found in Repsoitory"); + } + return actors.remove(index); + } +} diff --git a/spring-5/src/main/java/com/baeldung/execption/SpringExceptionApplication.java b/spring-5/src/main/java/com/baeldung/execption/SpringExceptionApplication.java new file mode 100644 index 0000000000..287356256c --- /dev/null +++ b/spring-5/src/main/java/com/baeldung/execption/SpringExceptionApplication.java @@ -0,0 +1,14 @@ +package com.baeldung.execption; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration; +import org.springframework.context.annotation.ComponentScan; + +@SpringBootApplication(exclude = SecurityAutoConfiguration.class) +@ComponentScan(basePackages = { "com.baeldung.execption" }) +public class SpringExceptionApplication { + public static void main(String[] args) { + SpringApplication.run(SpringExceptionApplication.class, args); + } +} \ No newline at end of file From a18ce8a3803dd4d5a384a5018f67c8e909acf59f Mon Sep 17 00:00:00 2001 From: ramansahasi Date: Mon, 12 Feb 2018 23:09:31 +0530 Subject: [PATCH 39/58] Bael 1427 Life cycle of thread (#3637) * Interrupted thread before logging * abbrevated word thread and interrupted main thread --- .../threadlifecycle/BlockedState.java | 31 ++++++++++++++++ .../concurrent/threadlifecycle/NewState.java | 14 ++++++++ .../threadlifecycle/RunnableState.java | 15 ++++++++ .../threadlifecycle/TerminatedState.java | 15 ++++++++ .../threadlifecycle/TimedWaitingState.java | 25 +++++++++++++ .../threadlifecycle/WaitingState.java | 35 +++++++++++++++++++ 6 files changed, 135 insertions(+) create mode 100644 core-java-concurrency/src/main/java/com/baeldung/concurrent/threadlifecycle/BlockedState.java create mode 100644 core-java-concurrency/src/main/java/com/baeldung/concurrent/threadlifecycle/NewState.java create mode 100644 core-java-concurrency/src/main/java/com/baeldung/concurrent/threadlifecycle/RunnableState.java create mode 100644 core-java-concurrency/src/main/java/com/baeldung/concurrent/threadlifecycle/TerminatedState.java create mode 100644 core-java-concurrency/src/main/java/com/baeldung/concurrent/threadlifecycle/TimedWaitingState.java create mode 100644 core-java-concurrency/src/main/java/com/baeldung/concurrent/threadlifecycle/WaitingState.java diff --git a/core-java-concurrency/src/main/java/com/baeldung/concurrent/threadlifecycle/BlockedState.java b/core-java-concurrency/src/main/java/com/baeldung/concurrent/threadlifecycle/BlockedState.java new file mode 100644 index 0000000000..19c6d08c2d --- /dev/null +++ b/core-java-concurrency/src/main/java/com/baeldung/concurrent/threadlifecycle/BlockedState.java @@ -0,0 +1,31 @@ +package com.baeldung.concurrent.threadlifecycle; + +public class BlockedState { + public static void main(String[] args) throws InterruptedException { + Thread t1 = new Thread(new DemoThreadB()); + Thread t2 = new Thread(new DemoThreadB()); + + t1.start(); + t2.start(); + + Thread.sleep(1000); + + System.out.println(t2.getState()); + System.exit(0); + } +} + +class DemoThreadB implements Runnable { + @Override + public void run() { + commonResource(); + } + + public static synchronized void commonResource() { + while(true) { + // Infinite loop to mimic heavy processing + // Thread 't1' won't leave this method + // when Thread 't2' enters this + } + } +} \ No newline at end of file diff --git a/core-java-concurrency/src/main/java/com/baeldung/concurrent/threadlifecycle/NewState.java b/core-java-concurrency/src/main/java/com/baeldung/concurrent/threadlifecycle/NewState.java new file mode 100644 index 0000000000..b524cc5ec7 --- /dev/null +++ b/core-java-concurrency/src/main/java/com/baeldung/concurrent/threadlifecycle/NewState.java @@ -0,0 +1,14 @@ +package com.baeldung.concurrent.threadlifecycle; + +public class NewState implements Runnable { + public static void main(String[] args) { + Runnable runnable = new NewState(); + Thread t = new Thread(runnable); + System.out.println(t.getState()); + } + + @Override + public void run() { + + } +} \ No newline at end of file diff --git a/core-java-concurrency/src/main/java/com/baeldung/concurrent/threadlifecycle/RunnableState.java b/core-java-concurrency/src/main/java/com/baeldung/concurrent/threadlifecycle/RunnableState.java new file mode 100644 index 0000000000..4aa8b36a76 --- /dev/null +++ b/core-java-concurrency/src/main/java/com/baeldung/concurrent/threadlifecycle/RunnableState.java @@ -0,0 +1,15 @@ +package com.baeldung.concurrent.threadlifecycle; + +public class RunnableState implements Runnable { + public static void main(String[] args) { + Runnable runnable = new NewState(); + Thread t = new Thread(runnable); + t.start(); + System.out.println(t.getState()); + } + + @Override + public void run() { + + } +} \ No newline at end of file diff --git a/core-java-concurrency/src/main/java/com/baeldung/concurrent/threadlifecycle/TerminatedState.java b/core-java-concurrency/src/main/java/com/baeldung/concurrent/threadlifecycle/TerminatedState.java new file mode 100644 index 0000000000..7c8884dc22 --- /dev/null +++ b/core-java-concurrency/src/main/java/com/baeldung/concurrent/threadlifecycle/TerminatedState.java @@ -0,0 +1,15 @@ +package com.baeldung.concurrent.threadlifecycle; + +public class TerminatedState implements Runnable { + public static void main(String[] args) throws InterruptedException { + Thread t1 = new Thread(new TerminatedState()); + t1.start(); + Thread.sleep(1000); + System.out.println(t1.getState()); + } + + @Override + public void run() { + // No processing in this block + } +} \ No newline at end of file diff --git a/core-java-concurrency/src/main/java/com/baeldung/concurrent/threadlifecycle/TimedWaitingState.java b/core-java-concurrency/src/main/java/com/baeldung/concurrent/threadlifecycle/TimedWaitingState.java new file mode 100644 index 0000000000..8d005352eb --- /dev/null +++ b/core-java-concurrency/src/main/java/com/baeldung/concurrent/threadlifecycle/TimedWaitingState.java @@ -0,0 +1,25 @@ +package com.baeldung.concurrent.threadlifecycle; + +public class TimedWaitingState { + public static void main(String[] args) throws InterruptedException { + DemoThread obj1 = new DemoThread(); + Thread t1 = new Thread(obj1); + t1.start(); + // The following sleep will give enough time for ThreadScheduler + // to start processing of thread t1 + Thread.sleep(1000); + System.out.println(t1.getState()); + } +} + +class DemoThread implements Runnable { + @Override + public void run() { + try { + Thread.sleep(5000); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/core-java-concurrency/src/main/java/com/baeldung/concurrent/threadlifecycle/WaitingState.java b/core-java-concurrency/src/main/java/com/baeldung/concurrent/threadlifecycle/WaitingState.java new file mode 100644 index 0000000000..98a6844309 --- /dev/null +++ b/core-java-concurrency/src/main/java/com/baeldung/concurrent/threadlifecycle/WaitingState.java @@ -0,0 +1,35 @@ +package com.baeldung.concurrent.threadlifecycle; + +public class WaitingState implements Runnable { + public static Thread t1; + + public static void main(String[] args) { + t1 = new Thread(new WaitingState()); + t1.start(); + } + + public void run() { + Thread t2 = new Thread(new DemoThreadWS()); + t2.start(); + + try { + t2.join(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + e.printStackTrace(); + } + } +} + +class DemoThreadWS implements Runnable { + public void run() { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + e.printStackTrace(); + } + + System.out.println(WaitingState.t1.getState()); + } +} \ No newline at end of file From 3d4a179ca3483ac0deb889fc6e3efe10f99d2b08 Mon Sep 17 00:00:00 2001 From: christopherfranklin Date: Mon, 12 Feb 2018 17:36:16 -0500 Subject: [PATCH 40/58] [BAEL-1542] - Simple Tagging with JPA (#3626) * Code samples for Simple Tagging with JPA * Fix pom relative path for spring-jpa --- persistence-modules/spring-jpa/pom.xml | 2 +- .../persistence/dao/StudentRepository.java | 11 +++++ .../inmemory/persistence/model/Student.java | 13 ++++++ .../repository/InMemoryDBIntegrationTest.java | 45 +++++++++++++++++++ 4 files changed, 70 insertions(+), 1 deletion(-) diff --git a/persistence-modules/spring-jpa/pom.xml b/persistence-modules/spring-jpa/pom.xml index 04c64fafc3..bc0b2381f3 100644 --- a/persistence-modules/spring-jpa/pom.xml +++ b/persistence-modules/spring-jpa/pom.xml @@ -13,7 +13,7 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT - ../ + ../../ diff --git a/persistence-modules/spring-jpa/src/main/java/org/baeldung/inmemory/persistence/dao/StudentRepository.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/inmemory/persistence/dao/StudentRepository.java index bfcf6f5cdc..f856b78c52 100644 --- a/persistence-modules/spring-jpa/src/main/java/org/baeldung/inmemory/persistence/dao/StudentRepository.java +++ b/persistence-modules/spring-jpa/src/main/java/org/baeldung/inmemory/persistence/dao/StudentRepository.java @@ -2,6 +2,17 @@ package org.baeldung.inmemory.persistence.dao; import org.baeldung.inmemory.persistence.model.Student; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import java.util.List; public interface StudentRepository extends JpaRepository { + + @Query("SELECT s FROM Student s JOIN s.tags t WHERE t = LOWER(:tag)") + List retrieveByTag(@Param("tag") String tag); + + @Query("SELECT s FROM Student s JOIN s.tags t WHERE s.name = LOWER(:name) AND t = LOWER(:tag)") + List retrieveByNameFilterByTag(@Param("name") String name, @Param("tag") String tag); + } diff --git a/persistence-modules/spring-jpa/src/main/java/org/baeldung/inmemory/persistence/model/Student.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/inmemory/persistence/model/Student.java index b50fe9122e..2e4e3ea2cb 100644 --- a/persistence-modules/spring-jpa/src/main/java/org/baeldung/inmemory/persistence/model/Student.java +++ b/persistence-modules/spring-jpa/src/main/java/org/baeldung/inmemory/persistence/model/Student.java @@ -1,7 +1,10 @@ package org.baeldung.inmemory.persistence.model; +import javax.persistence.ElementCollection; import javax.persistence.Entity; import javax.persistence.Id; +import java.util.ArrayList; +import java.util.List; @Entity public class Student { @@ -10,6 +13,9 @@ public class Student { private long id; private String name; + @ElementCollection + private List tags = new ArrayList<>(); + public Student() { } @@ -35,4 +41,11 @@ public class Student { this.name = name; } + public List getTags() { + return tags; + } + + public void setTags(List tags) { + this.tags.addAll(tags); + } } diff --git a/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/repository/InMemoryDBIntegrationTest.java b/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/repository/InMemoryDBIntegrationTest.java index 8380ab5434..28d7e3772c 100644 --- a/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/repository/InMemoryDBIntegrationTest.java +++ b/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/repository/InMemoryDBIntegrationTest.java @@ -12,6 +12,9 @@ import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; +import java.util.Arrays; +import java.util.List; + import static org.junit.Assert.assertEquals; @RunWith(SpringJUnit4ClassRunner.class) @@ -34,4 +37,46 @@ public class InMemoryDBIntegrationTest { assertEquals("name incorrect", NAME, student2.getName()); } + @Test + public void givenStudentWithTags_whenSave_thenGetByTagOk(){ + Student student = new Student(ID, NAME); + student.setTags(Arrays.asList("full time", "computer science")); + studentRepository.save(student); + + Student student2 = studentRepository.retrieveByTag("full time").get(0); + assertEquals("name incorrect", NAME, student2.getName()); + } + + @Test + public void givenMultipleStudentsWithTags_whenSave_thenGetByTagReturnsCorrectCount(){ + Student student = new Student(0, "Larry"); + student.setTags(Arrays.asList("full time", "computer science")); + studentRepository.save(student); + + Student student2 = new Student(1, "Curly"); + student2.setTags(Arrays.asList("part time", "rocket science")); + studentRepository.save(student2); + + Student student3 = new Student(2, "Moe"); + student3.setTags(Arrays.asList("full time", "philosophy")); + studentRepository.save(student3); + + Student student4 = new Student(3, "Shemp"); + student4.setTags(Arrays.asList("part time", "mathematics")); + studentRepository.save(student4); + + List students = studentRepository.retrieveByTag("full time"); + assertEquals("size incorrect", 2, students.size()); + } + + @Test + public void givenStudentWithTags_whenSave_thenGetByNameAndTagOk(){ + Student student = new Student(ID, NAME); + student.setTags(Arrays.asList("full time", "computer science")); + studentRepository.save(student); + + Student student2 = studentRepository.retrieveByNameFilterByTag("John", "full time").get(0); + assertEquals("name incorrect", NAME, student2.getName()); + } + } From bcc3b6ed95d0d3d5e330299c51efe63190a9c632 Mon Sep 17 00:00:00 2001 From: haseebahmad11 <35659302+haseebahmad11@users.noreply.github.com> Date: Wed, 14 Feb 2018 05:49:46 +0500 Subject: [PATCH 41/58] BAEL-1343 MVC Architecture with Servlets and JSP code (#3624) * BAEL-1343 MVC Architecture with Servlets and JSP code * BAEL-1343 code refactoring * BAEL-1343 code refactoring * BAEL-1343 updated code formatting * BAEL-1343 code refactoring --- .../baeldung/controller/StudentServlet.java | 43 +++++++++++++ .../main/java/com/baeldung/model/Student.java | 62 +++++++++++++++++++ .../com/baeldung/service/StudentService.java | 34 ++++++++++ .../com/baeldung/servlets/FormServlet.java | 2 +- .../main/webapp/WEB-INF/jsp}/index.jsp | 0 .../webapp/WEB-INF/jsp/student-record.jsp | 36 +++++++++++ .../{web => src/main/webapp}/WEB-INF/web.xml | 0 7 files changed, 176 insertions(+), 1 deletion(-) create mode 100644 javax-servlets/src/main/java/com/baeldung/controller/StudentServlet.java create mode 100644 javax-servlets/src/main/java/com/baeldung/model/Student.java create mode 100644 javax-servlets/src/main/java/com/baeldung/service/StudentService.java rename javax-servlets/{web => src/main/webapp/WEB-INF/jsp}/index.jsp (100%) create mode 100644 javax-servlets/src/main/webapp/WEB-INF/jsp/student-record.jsp rename javax-servlets/{web => src/main/webapp}/WEB-INF/web.xml (100%) diff --git a/javax-servlets/src/main/java/com/baeldung/controller/StudentServlet.java b/javax-servlets/src/main/java/com/baeldung/controller/StudentServlet.java new file mode 100644 index 0000000000..3c893eab1a --- /dev/null +++ b/javax-servlets/src/main/java/com/baeldung/controller/StudentServlet.java @@ -0,0 +1,43 @@ +package com.baeldung.controller; + +import java.io.IOException; + +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.baeldung.service.StudentService; + +/** + * + * @author haseeb + * + */ +@WebServlet(name = "StudentServlet", urlPatterns = "/student-record") +public class StudentServlet extends HttpServlet { + + protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + StudentService studentService = new StudentService(); + String studentID = request.getParameter("id"); + if (studentID != null) { + int id = Integer.parseInt(studentID); + request.setAttribute("studentRecord", studentService.getStudent(id)); + } + + RequestDispatcher dispatcher = request.getRequestDispatcher("/WEB-INF/jsp/student-record.jsp"); + dispatcher.forward(request, response); + } + + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + processRequest(request, response); + } + + @Override + protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + processRequest(request, response); + } +} diff --git a/javax-servlets/src/main/java/com/baeldung/model/Student.java b/javax-servlets/src/main/java/com/baeldung/model/Student.java new file mode 100644 index 0000000000..55afe6bc2a --- /dev/null +++ b/javax-servlets/src/main/java/com/baeldung/model/Student.java @@ -0,0 +1,62 @@ +package com.baeldung.model; + +/** + * + * @author haseeb + * + */ +public class Student { + + private int id; + private String firstName; + private String lastName; + + public Student(int id, String firstName, String lastName) { + super(); + this.id = id; + this.firstName = firstName; + this.lastName = lastName; + } + + /** + * @return the id + */ + public int getId() { + return id; + } + + /** + * @param id the id to set + */ + public void setId(int id) { + this.id = id; + } + + /** + * @return the firstName + */ + public String getFirstName() { + return firstName; + } + + /** + * @param firstName the firstName to set + */ + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + /** + * @return the lastName + */ + public String getLastName() { + return lastName; + } + + /** + * @param lastName the lastName to set + */ + public void setLastName(String lastName) { + this.lastName = lastName; + } +} diff --git a/javax-servlets/src/main/java/com/baeldung/service/StudentService.java b/javax-servlets/src/main/java/com/baeldung/service/StudentService.java new file mode 100644 index 0000000000..1666850d50 --- /dev/null +++ b/javax-servlets/src/main/java/com/baeldung/service/StudentService.java @@ -0,0 +1,34 @@ +package com.baeldung.service; + +import com.baeldung.model.Student; + +/** + * + * @author haseeb + * + */ +public class StudentService { + + /** + * + * @param id + * @return + */ + public Student getStudent(int id) { + + Student student = null; + + switch (id) { + case 1: + student = new Student(1, "John", "Doe"); + break; + case 2: + student = new Student(2, "Jane", "Goodall"); + break; + case 3: + student = new Student(3, "Max", "Born"); + break; + } + return student; + } +} diff --git a/javax-servlets/src/main/java/com/baeldung/servlets/FormServlet.java b/javax-servlets/src/main/java/com/baeldung/servlets/FormServlet.java index fcd9143dff..04c5fec42d 100644 --- a/javax-servlets/src/main/java/com/baeldung/servlets/FormServlet.java +++ b/javax-servlets/src/main/java/com/baeldung/servlets/FormServlet.java @@ -25,7 +25,7 @@ public class FormServlet extends HttpServlet { response.setHeader("Test", "Success"); response.setHeader("BMI", String.valueOf(bmi)); - RequestDispatcher dispatcher = request.getRequestDispatcher("index.jsp"); + RequestDispatcher dispatcher = request.getRequestDispatcher("/WEB-INF/jsp/index.jsp"); dispatcher.forward(request, response); } catch (Exception e) { diff --git a/javax-servlets/web/index.jsp b/javax-servlets/src/main/webapp/WEB-INF/jsp/index.jsp similarity index 100% rename from javax-servlets/web/index.jsp rename to javax-servlets/src/main/webapp/WEB-INF/jsp/index.jsp diff --git a/javax-servlets/src/main/webapp/WEB-INF/jsp/student-record.jsp b/javax-servlets/src/main/webapp/WEB-INF/jsp/student-record.jsp new file mode 100644 index 0000000000..4b9d9b378f --- /dev/null +++ b/javax-servlets/src/main/webapp/WEB-INF/jsp/student-record.jsp @@ -0,0 +1,36 @@ +<%@ page language="java" contentType="text/html; charset=ISO-8859-1" + pageEncoding="ISO-8859-1"%> + +<%@ page import="com.baeldung.model.Student"%> + + + + +Student Record + + + <% + if (request.getAttribute("studentRecord") != null) { + Student student = (Student) request.getAttribute("studentRecord"); + %> + +

Student Record

+
+ ID: + <%=student.getId()%>
+
+ First Name: + <%=student.getFirstName()%>
+
+ Last Name: + <%=student.getLastName()%>
+ + <% + } else { + %> +

No student record found.

+ <% + } + %> + + \ No newline at end of file diff --git a/javax-servlets/web/WEB-INF/web.xml b/javax-servlets/src/main/webapp/WEB-INF/web.xml similarity index 100% rename from javax-servlets/web/WEB-INF/web.xml rename to javax-servlets/src/main/webapp/WEB-INF/web.xml From 83bc46ee228db8c44a5b36e37c676a064fc472a5 Mon Sep 17 00:00:00 2001 From: Allan Vital Date: Tue, 13 Feb 2018 23:13:37 -0200 Subject: [PATCH 42/58] BAEL-1368 Infinispan Guide (#3651) * BAEL-1368: infinispan article * BAEL-1368: new method timing method --- .../infinispan/ConfigurationTest.java | 15 ++- .../service/HelloWorldServiceUnitTest.java | 94 ++++++------------- .../service/TransactionalServiceUnitTest.java | 6 +- 3 files changed, 46 insertions(+), 69 deletions(-) diff --git a/libraries/src/test/java/com/baeldung/infinispan/ConfigurationTest.java b/libraries/src/test/java/com/baeldung/infinispan/ConfigurationTest.java index b05314491b..906a887e1a 100644 --- a/libraries/src/test/java/com/baeldung/infinispan/ConfigurationTest.java +++ b/libraries/src/test/java/com/baeldung/infinispan/ConfigurationTest.java @@ -9,13 +9,15 @@ import org.infinispan.manager.DefaultCacheManager; import org.junit.After; import org.junit.Before; +import java.util.concurrent.Callable; + public class ConfigurationTest { private DefaultCacheManager cacheManager; private HelloWorldRepository repository = new HelloWorldRepository(); - protected HelloWorldService helloWorldService; + protected HelloWorldService helloWorldService; protected TransactionalService transactionalService; @Before @@ -53,4 +55,15 @@ public class ConfigurationTest { cacheManager.stop(); } + protected long timeThis(Callable callable) { + try { + long milis = System.currentTimeMillis(); + callable.call(); + return System.currentTimeMillis() - milis; + } catch (Exception e) { + e.printStackTrace(); + } + return 0l; + } + } diff --git a/libraries/src/test/java/com/baeldung/infinispan/service/HelloWorldServiceUnitTest.java b/libraries/src/test/java/com/baeldung/infinispan/service/HelloWorldServiceUnitTest.java index bda2e6886b..c9ecd57995 100644 --- a/libraries/src/test/java/com/baeldung/infinispan/service/HelloWorldServiceUnitTest.java +++ b/libraries/src/test/java/com/baeldung/infinispan/service/HelloWorldServiceUnitTest.java @@ -3,103 +3,69 @@ package com.baeldung.infinispan.service; import com.baeldung.infinispan.ConfigurationTest; import org.junit.Test; +import java.util.concurrent.Callable; +import java.util.function.Consumer; + import static org.assertj.core.api.Java6Assertions.assertThat; public class HelloWorldServiceUnitTest extends ConfigurationTest { @Test public void whenGetIsCalledTwoTimes_thenTheSecondShouldHitTheCache() { - long milis = System.currentTimeMillis(); - helloWorldService.findSimpleHelloWorld(); - long executionTime = System.currentTimeMillis() - milis; + assertThat(timeThis(() -> helloWorldService.findSimpleHelloWorld())) + .isGreaterThanOrEqualTo(1000); - assertThat(executionTime).isGreaterThanOrEqualTo(1000); - - milis = System.currentTimeMillis(); - helloWorldService.findSimpleHelloWorld(); - executionTime = System.currentTimeMillis() - milis; - - assertThat(executionTime).isLessThan(100); + assertThat(timeThis(() -> helloWorldService.findSimpleHelloWorld())) + .isLessThan(100); } @Test public void whenGetIsCalledTwoTimesQuickly_thenTheSecondShouldHitTheCache() { - long milis = System.currentTimeMillis(); - helloWorldService.findExpiringHelloWorld(); - long executionTime = System.currentTimeMillis() - milis; + assertThat(timeThis(() -> helloWorldService.findExpiringHelloWorld())) + .isGreaterThanOrEqualTo(1000); - assertThat(executionTime).isGreaterThanOrEqualTo(1000); - - milis = System.currentTimeMillis(); - helloWorldService.findExpiringHelloWorld(); - executionTime = System.currentTimeMillis() - milis; - - assertThat(executionTime).isLessThan(100); + assertThat(timeThis(() -> helloWorldService.findExpiringHelloWorld())) + .isLessThan(100); } @Test public void whenGetIsCalledTwoTimesSparsely_thenNeitherShouldHitTheCache() - throws InterruptedException { + throws InterruptedException { - long milis = System.currentTimeMillis(); - helloWorldService.findSimpleHelloWorldInExpiringCache(); - long executionTime = System.currentTimeMillis() - milis; - - assertThat(executionTime).isGreaterThanOrEqualTo(1000); + assertThat(timeThis(() -> helloWorldService.findExpiringHelloWorld())) + .isGreaterThanOrEqualTo(1000); Thread.sleep(1100); - milis = System.currentTimeMillis(); - helloWorldService.findSimpleHelloWorldInExpiringCache(); - executionTime = System.currentTimeMillis() - milis; - - assertThat(executionTime).isGreaterThanOrEqualTo(1000); + assertThat(timeThis(() -> helloWorldService.findExpiringHelloWorld())) + .isGreaterThanOrEqualTo(1000); } @Test - public void givenOneEntryIsConfigured_whenTwoAreAdded_thenFirstShouldntBeAvailable() - throws InterruptedException { + public void givenOneEntryIsConfigured_whenTwoAreAdded_thenFirstShouldntBeAvailable() { - long milis = System.currentTimeMillis(); - helloWorldService.findEvictingHelloWorld("key 1"); - long executionTime = System.currentTimeMillis() - milis; + assertThat(timeThis(() -> helloWorldService.findEvictingHelloWorld("key 1"))) + .isGreaterThanOrEqualTo(1000); - assertThat(executionTime).isGreaterThanOrEqualTo(1000); + assertThat(timeThis(() -> helloWorldService.findEvictingHelloWorld("key 2"))) + .isGreaterThanOrEqualTo(1000); - milis = System.currentTimeMillis(); - helloWorldService.findEvictingHelloWorld("key 2"); - executionTime = System.currentTimeMillis() - milis; - - assertThat(executionTime).isGreaterThanOrEqualTo(1000); - - milis = System.currentTimeMillis(); - helloWorldService.findEvictingHelloWorld("key 1"); - executionTime = System.currentTimeMillis() - milis; - - assertThat(executionTime).isGreaterThanOrEqualTo(1000); + assertThat(timeThis(() -> helloWorldService.findEvictingHelloWorld("key 1"))) + .isGreaterThanOrEqualTo(1000); } @Test - public void givenOneEntryIsConfigured_whenTwoAreAdded_thenTheFirstShouldBeAvailable() - throws InterruptedException { + public void givenOneEntryIsConfigured_whenTwoAreAdded_thenTheFirstShouldBeAvailable() { - long milis = System.currentTimeMillis(); - helloWorldService.findPassivatingHelloWorld("key 1"); - long executionTime = System.currentTimeMillis() - milis; + assertThat(timeThis(() -> helloWorldService.findPassivatingHelloWorld("key 1"))) + .isGreaterThanOrEqualTo(1000); - assertThat(executionTime).isGreaterThanOrEqualTo(1000); + assertThat(timeThis(() -> helloWorldService.findPassivatingHelloWorld("key 2"))) + .isGreaterThanOrEqualTo(1000); - milis = System.currentTimeMillis(); - helloWorldService.findPassivatingHelloWorld("key 2"); - executionTime = System.currentTimeMillis() - milis; + assertThat(timeThis(() -> helloWorldService.findPassivatingHelloWorld("key 1"))) + .isLessThan(100); - assertThat(executionTime).isGreaterThanOrEqualTo(1000); - - milis = System.currentTimeMillis(); - helloWorldService.findPassivatingHelloWorld("key 1"); - executionTime = System.currentTimeMillis() - milis; - - assertThat(executionTime).isLessThan(100); } } diff --git a/libraries/src/test/java/com/baeldung/infinispan/service/TransactionalServiceUnitTest.java b/libraries/src/test/java/com/baeldung/infinispan/service/TransactionalServiceUnitTest.java index f529222079..99efacd18a 100644 --- a/libraries/src/test/java/com/baeldung/infinispan/service/TransactionalServiceUnitTest.java +++ b/libraries/src/test/java/com/baeldung/infinispan/service/TransactionalServiceUnitTest.java @@ -14,11 +14,9 @@ public class TransactionalServiceUnitTest extends ConfigurationTest { transactionalService.getQuickHowManyVisits(); backgroundThread.start(); Thread.sleep(100); //lets wait our thread warm up - long milis = System.currentTimeMillis(); - transactionalService.getQuickHowManyVisits(); - long executionTime = System.currentTimeMillis() - milis; - assertThat(executionTime).isGreaterThan(500).isLessThan(1000); + assertThat(timeThis(() -> transactionalService.getQuickHowManyVisits())) + .isGreaterThan(500).isLessThan(1000); } } From 4f6988b134ac47087cbcb9fc9d152d76bcfb01e7 Mon Sep 17 00:00:00 2001 From: Alejandro Gervasio Date: Wed, 14 Feb 2018 00:08:31 -0300 Subject: [PATCH 43/58] Method Overloading and Overriding in Java - BAEL-1507 (#3621) * Initial Commit * Update Multiplier.java * Refactored MethodOverridingUnitTest class * Update Car.java * Update Vehicle.java * Update MethodOverridingUnitTest.java * Update MethodOverridingUnitTest.java * Fix package names --- .../application/Application.java | 26 +++++++ .../model/Car.java | 9 +++ .../model/Vehicle.java | 16 +++++ .../util/Multiplier.java | 16 +++++ .../test/MethodOverloadingUnitTest.java | 41 +++++++++++ .../test/MethodOverridingUnitTest.java | 68 +++++++++++++++++++ 6 files changed, 176 insertions(+) create mode 100644 core-java/src/main/java/com/baeldung/methodoverloadingoverriding/application/Application.java create mode 100644 core-java/src/main/java/com/baeldung/methodoverloadingoverriding/model/Car.java create mode 100644 core-java/src/main/java/com/baeldung/methodoverloadingoverriding/model/Vehicle.java create mode 100644 core-java/src/main/java/com/baeldung/methodoverloadingoverriding/util/Multiplier.java create mode 100644 core-java/src/test/java/com/baeldung/methodoverloadingoverriding/test/MethodOverloadingUnitTest.java create mode 100644 core-java/src/test/java/com/baeldung/methodoverloadingoverriding/test/MethodOverridingUnitTest.java diff --git a/core-java/src/main/java/com/baeldung/methodoverloadingoverriding/application/Application.java b/core-java/src/main/java/com/baeldung/methodoverloadingoverriding/application/Application.java new file mode 100644 index 0000000000..6e023e9fa8 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/methodoverloadingoverriding/application/Application.java @@ -0,0 +1,26 @@ +package com.baeldung.methodoverloadingoverriding.application; + +import com.baeldung.methodoverloadingoverriding.model.Car; +import com.baeldung.methodoverloadingoverriding.model.Vehicle; +import com.baeldung.methodoverloadingoverriding.util.Multiplier; + +public class Application { + + public static void main(String[] args) { + Multiplier multiplier = new Multiplier(); + System.out.println(multiplier.multiply(10, 10)); + System.out.println(multiplier.multiply(10, 10, 10)); + System.out.println(multiplier.multiply(10, 10.5)); + System.out.println(multiplier.multiply(10.5, 10.5)); + + Vehicle vehicle = new Vehicle(); + System.out.println(vehicle.accelerate(100)); + System.out.println(vehicle.run()); + System.out.println(vehicle.stop()); + + Vehicle car = new Car(); + System.out.println(car.accelerate(80)); + System.out.println(car.run()); + System.out.println(car.stop()); + } +} diff --git a/core-java/src/main/java/com/baeldung/methodoverloadingoverriding/model/Car.java b/core-java/src/main/java/com/baeldung/methodoverloadingoverriding/model/Car.java new file mode 100644 index 0000000000..aa5bdcaec9 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/methodoverloadingoverriding/model/Car.java @@ -0,0 +1,9 @@ +package com.baeldung.methodoverloadingoverriding.model; + +public class Car extends Vehicle { + + @Override + public String accelerate(long mph) { + return "The car accelerates at : " + mph + " MPH."; + } +} diff --git a/core-java/src/main/java/com/baeldung/methodoverloadingoverriding/model/Vehicle.java b/core-java/src/main/java/com/baeldung/methodoverloadingoverriding/model/Vehicle.java new file mode 100644 index 0000000000..eb59e8ca23 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/methodoverloadingoverriding/model/Vehicle.java @@ -0,0 +1,16 @@ +package com.baeldung.methodoverloadingoverriding.model; + +public class Vehicle { + + public String accelerate(long mph) { + return "The vehicle accelerates at : " + mph + " MPH."; + } + + public String stop() { + return "The vehicle has stopped."; + } + + public String run() { + return "The vehicle is running."; + } +} diff --git a/core-java/src/main/java/com/baeldung/methodoverloadingoverriding/util/Multiplier.java b/core-java/src/main/java/com/baeldung/methodoverloadingoverriding/util/Multiplier.java new file mode 100644 index 0000000000..c43e61c78f --- /dev/null +++ b/core-java/src/main/java/com/baeldung/methodoverloadingoverriding/util/Multiplier.java @@ -0,0 +1,16 @@ +package com.baeldung.methodoverloadingoverriding.util; + +public class Multiplier { + + public int multiply(int a, int b) { + return a * b; + } + + public int multiply(int a, int b, int c) { + return a * b * c; + } + + public double multiply(double a, double b) { + return a * b; + } +} diff --git a/core-java/src/test/java/com/baeldung/methodoverloadingoverriding/test/MethodOverloadingUnitTest.java b/core-java/src/test/java/com/baeldung/methodoverloadingoverriding/test/MethodOverloadingUnitTest.java new file mode 100644 index 0000000000..081a30c34a --- /dev/null +++ b/core-java/src/test/java/com/baeldung/methodoverloadingoverriding/test/MethodOverloadingUnitTest.java @@ -0,0 +1,41 @@ +package com.baeldung.methodoverloadingoverriding.test; + +import com.baeldung.methodoverloadingoverriding.util.Multiplier; +import org.junit.BeforeClass; +import org.junit.Test; +import static org.assertj.core.api.Assertions.*; + +public class MethodOverloadingUnitTest { + + private static Multiplier multiplier; + + @BeforeClass + public static void setUpMultiplierInstance() { + multiplier = new Multiplier(); + } + + @Test + public void givenMultiplierInstance_whenCalledMultiplyWithTwoIntegers_thenOneAssertion() { + assertThat(multiplier.multiply(10, 10)).isEqualTo(100); + } + + @Test + public void givenMultiplierInstance_whenCalledMultiplyWithTreeIntegers_thenOneAssertion() { + assertThat(multiplier.multiply(10, 10, 10)).isEqualTo(1000); + } + + @Test + public void givenMultiplierInstance_whenCalledMultiplyWithIntDouble_thenOneAssertion() { + assertThat(multiplier.multiply(10, 10.5)).isEqualTo(105.0); + } + + @Test + public void givenMultiplierInstance_whenCalledMultiplyWithDoubleDouble_thenOneAssertion() { + assertThat(multiplier.multiply(10.5, 10.5)).isEqualTo(110.25); + } + + @Test + public void givenMultiplierInstance_whenCalledMultiplyWithIntIntAndMatching_thenNoTypePromotion() { + assertThat(multiplier.multiply(10, 10)).isEqualTo(100); + } +} diff --git a/core-java/src/test/java/com/baeldung/methodoverloadingoverriding/test/MethodOverridingUnitTest.java b/core-java/src/test/java/com/baeldung/methodoverloadingoverriding/test/MethodOverridingUnitTest.java new file mode 100644 index 0000000000..554ac121bc --- /dev/null +++ b/core-java/src/test/java/com/baeldung/methodoverloadingoverriding/test/MethodOverridingUnitTest.java @@ -0,0 +1,68 @@ +package com.baeldung.methodoverloadingoverriding.test; + +import com.baeldung.methodoverloadingoverriding.model.Car; +import com.baeldung.methodoverloadingoverriding.model.Vehicle; +import org.junit.BeforeClass; +import org.junit.Test; +import static org.assertj.core.api.Assertions.*; + +public class MethodOverridingUnitTest { + + private static Vehicle vehicle; + private static Car car; + + @BeforeClass + public static void setUpVehicleInstance() { + vehicle = new Vehicle(); + } + + @BeforeClass + public static void setUpCarInstance() { + car = new Car(); + } + + @Test + public void givenVehicleInstance_whenCalledAccelerate_thenOneAssertion() { + assertThat(vehicle.accelerate(100)).isEqualTo("The vehicle accelerates at : 100 MPH."); + } + + @Test + public void givenVehicleInstance_whenCalledRun_thenOneAssertion() { + assertThat(vehicle.run()).isEqualTo("The vehicle is running."); + } + + @Test + public void givenVehicleInstance_whenCalledStop_thenOneAssertion() { + assertThat(vehicle.stop()).isEqualTo("The vehicle has stopped."); + } + + @Test + public void givenCarInstance_whenCalledAccelerate_thenOneAssertion() { + assertThat(car.accelerate(80)).isEqualTo("The car accelerates at : 80 MPH."); + } + + @Test + public void givenCarInstance_whenCalledRun_thenOneAssertion() { + assertThat(car.run()).isEqualTo("The vehicle is running."); + } + + @Test + public void givenCarInstance_whenCalledStop_thenOneAssertion() { + assertThat(car.stop()).isEqualTo("The vehicle has stopped."); + } + + @Test + public void givenVehicleCarInstances_whenCalledAccelerateWithSameArgument_thenNotEqual() { + assertThat(vehicle.accelerate(100)).isNotEqualTo(car.accelerate(100)); + } + + @Test + public void givenVehicleCarInstances_whenCalledRun_thenEqual() { + assertThat(vehicle.run()).isEqualTo(car.run()); + } + + @Test + public void givenVehicleCarInstances_whenCalledStop_thenEqual() { + assertThat(vehicle.stop()).isEqualTo(car.stop()); + } +} From b8f433859ef3f4f73637de5ff575a35ca331bb5e Mon Sep 17 00:00:00 2001 From: Diaz Novandi Date: Mon, 12 Feb 2018 22:56:48 +0100 Subject: [PATCH 44/58] BAEL-681 Configuring DynamoDB locally for integration tests --- .../spring-data-dynamodb/pom.xml | 79 +++++++++++++++++++ .../ProductInfoRepositoryIntegrationTest.java | 10 ++- .../rule/LocalDynamoDBCreationRule.java | 36 +++++++++ 3 files changed, 121 insertions(+), 4 deletions(-) create mode 100644 persistence-modules/spring-data-dynamodb/src/test/java/com/baeldung/spring/data/dynamodb/repository/rule/LocalDynamoDBCreationRule.java diff --git a/persistence-modules/spring-data-dynamodb/pom.xml b/persistence-modules/spring-data-dynamodb/pom.xml index bf90779c29..0b78aac10e 100644 --- a/persistence-modules/spring-data-dynamodb/pom.xml +++ b/persistence-modules/spring-data-dynamodb/pom.xml @@ -23,6 +23,10 @@ 4.4.1 1.11.64 3.3.7-1 + 1.0.392 + 1.11.106 + 1.11.86 + https://s3.eu-central-1.amazonaws.com/dynamodb-local-frankfurt/release @@ -103,6 +107,57 @@ httpclient ${httpclient.version} + + + + + com.amazonaws + DynamoDBLocal + ${dynamodblocal.version} + test + + + com.almworks.sqlite4java + sqlite4java + ${sqlite4java.version} + test + + + com.almworks.sqlite4java + sqlite4java-win32-x86 + ${sqlite4java.version} + dll + test + + + com.almworks.sqlite4java + sqlite4java-win32-x64 + ${sqlite4java.version} + dll + test + + + com.almworks.sqlite4java + libsqlite4java-osx + ${sqlite4java.version} + dylib + test + + + com.almworks.sqlite4java + libsqlite4java-linux-i386 + ${sqlite4java.version} + so + test + + + com.almworks.sqlite4java + libsqlite4java-linux-amd64 + ${sqlite4java.version} + so + test + +
@@ -120,6 +175,25 @@ org.apache.maven.plugins maven-war-plugin + + org.apache.maven.plugins + maven-dependency-plugin + 2.10 + + + copy-dependencies + test-compile + + copy-dependencies + + + test + so,dll,dylib + ${project.basedir}/native-libs + + + + @@ -142,6 +216,11 @@ false + + dynamodb-local + DynamoDB Local Release Repository + ${dynamodblocal.repository.url} + diff --git a/persistence-modules/spring-data-dynamodb/src/test/java/com/baeldung/spring/data/dynamodb/repository/ProductInfoRepositoryIntegrationTest.java b/persistence-modules/spring-data-dynamodb/src/test/java/com/baeldung/spring/data/dynamodb/repository/ProductInfoRepositoryIntegrationTest.java index 2ff418b4ec..05b21fd2af 100644 --- a/persistence-modules/spring-data-dynamodb/src/test/java/com/baeldung/spring/data/dynamodb/repository/ProductInfoRepositoryIntegrationTest.java +++ b/persistence-modules/spring-data-dynamodb/src/test/java/com/baeldung/spring/data/dynamodb/repository/ProductInfoRepositoryIntegrationTest.java @@ -8,8 +8,9 @@ import com.amazonaws.services.dynamodbv2.model.ResourceInUseException; import com.baeldung.Application; import com.baeldung.spring.data.dynamodb.model.ProductInfo; import com.baeldung.spring.data.dynamodb.repositories.ProductInfoRepository; +import com.baeldung.spring.data.dynamodb.repository.rule.LocalDynamoDBCreationRule; import org.junit.Before; -import org.junit.Ignore; +import org.junit.ClassRule; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; @@ -30,6 +31,9 @@ import static org.junit.Assert.assertTrue; @TestPropertySource(properties = { "amazon.dynamodb.endpoint=http://localhost:8000/", "amazon.aws.accesskey=test1", "amazon.aws.secretkey=test231" }) public class ProductInfoRepositoryIntegrationTest { + @ClassRule + public static LocalDynamoDBCreationRule dynamoDB = new LocalDynamoDBCreationRule(); + private DynamoDBMapper dynamoDBMapper; @Autowired @@ -42,7 +46,6 @@ public class ProductInfoRepositoryIntegrationTest { private static final String EXPECTED_PRICE = "50"; @Before - @Ignore // TODO Remove Ignore annotations when running locally with Local DynamoDB instance public void setup() throws Exception { try { @@ -57,12 +60,11 @@ public class ProductInfoRepositoryIntegrationTest { // Do nothing, table already created } - // TODO How to handle different environments. i.e. AVOID deleting all entries in ProductInfoion table + // TODO How to handle different environments. i.e. AVOID deleting all entries in ProductInfo on table dynamoDBMapper.batchDelete((List) repository.findAll()); } @Test - @Ignore // TODO Remove Ignore annotations when running locally with Local DynamoDB instance public void givenItemWithExpectedCost_whenRunFindAll_thenItemIsFound() { ProductInfo productInfo = new ProductInfo(EXPECTED_COST, EXPECTED_PRICE); diff --git a/persistence-modules/spring-data-dynamodb/src/test/java/com/baeldung/spring/data/dynamodb/repository/rule/LocalDynamoDBCreationRule.java b/persistence-modules/spring-data-dynamodb/src/test/java/com/baeldung/spring/data/dynamodb/repository/rule/LocalDynamoDBCreationRule.java new file mode 100644 index 0000000000..5df377c508 --- /dev/null +++ b/persistence-modules/spring-data-dynamodb/src/test/java/com/baeldung/spring/data/dynamodb/repository/rule/LocalDynamoDBCreationRule.java @@ -0,0 +1,36 @@ +package com.baeldung.spring.data.dynamodb.repository.rule; + +import com.amazonaws.services.dynamodbv2.AmazonDynamoDB; +import com.amazonaws.services.dynamodbv2.local.main.ServerRunner; +import com.amazonaws.services.dynamodbv2.local.server.DynamoDBProxyServer; +import org.junit.rules.ExternalResource; +import org.springframework.beans.factory.annotation.Autowired; + +public class LocalDynamoDBCreationRule extends ExternalResource { + + protected DynamoDBProxyServer server; + protected AmazonDynamoDB amazonDynamoDB; + + @Override + protected void before() throws Exception { + System.setProperty("sqlite4java.library.path", "native-libs"); + String port = "8000"; + this.server = ServerRunner.createServerFromCommandLineArgs(new String[]{"-inMemory", "-port", port}); + server.start(); + } + + @Override + protected void after() { + try { + server.stop(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Autowired + public void setAmazonDynamoDB(AmazonDynamoDB amazonDynamoDB) { + this.amazonDynamoDB = amazonDynamoDB; + } + +} From 9376e8ce692612b0269b446bf48f19d15c233520 Mon Sep 17 00:00:00 2001 From: Diaz Novandi Date: Tue, 13 Feb 2018 13:34:03 +0100 Subject: [PATCH 45/58] Refine test using Hamcrest and refactor JUnit rule --- .../ProductInfoRepositoryIntegrationTest.java | 9 +++++--- .../rule/LocalDynamoDBCreationRule.java | 21 ++++++++++--------- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/persistence-modules/spring-data-dynamodb/src/test/java/com/baeldung/spring/data/dynamodb/repository/ProductInfoRepositoryIntegrationTest.java b/persistence-modules/spring-data-dynamodb/src/test/java/com/baeldung/spring/data/dynamodb/repository/ProductInfoRepositoryIntegrationTest.java index 05b21fd2af..8052aba3df 100644 --- a/persistence-modules/spring-data-dynamodb/src/test/java/com/baeldung/spring/data/dynamodb/repository/ProductInfoRepositoryIntegrationTest.java +++ b/persistence-modules/spring-data-dynamodb/src/test/java/com/baeldung/spring/data/dynamodb/repository/ProductInfoRepositoryIntegrationTest.java @@ -22,7 +22,10 @@ import org.springframework.test.context.web.WebAppConfiguration; import java.util.List; -import static org.junit.Assert.assertTrue; +import static org.hamcrest.Matchers.greaterThan; +import static org.hamcrest.core.Is.is; +import static org.hamcrest.core.IsEqual.equalTo; +import static org.junit.Assert.assertThat; @RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest(classes = Application.class) @@ -71,7 +74,7 @@ public class ProductInfoRepositoryIntegrationTest { repository.save(productInfo); List result = (List) repository.findAll(); - assertTrue("Not empty", result.size() > 0); - assertTrue("Contains item with expected cost", result.get(0).getCost().equals(EXPECTED_COST)); + assertThat(result.size(), is(greaterThan(0))); + assertThat(result.get(0).getCost(), is(equalTo(EXPECTED_COST))); } } diff --git a/persistence-modules/spring-data-dynamodb/src/test/java/com/baeldung/spring/data/dynamodb/repository/rule/LocalDynamoDBCreationRule.java b/persistence-modules/spring-data-dynamodb/src/test/java/com/baeldung/spring/data/dynamodb/repository/rule/LocalDynamoDBCreationRule.java index 5df377c508..62334b6d00 100644 --- a/persistence-modules/spring-data-dynamodb/src/test/java/com/baeldung/spring/data/dynamodb/repository/rule/LocalDynamoDBCreationRule.java +++ b/persistence-modules/spring-data-dynamodb/src/test/java/com/baeldung/spring/data/dynamodb/repository/rule/LocalDynamoDBCreationRule.java @@ -1,19 +1,21 @@ package com.baeldung.spring.data.dynamodb.repository.rule; -import com.amazonaws.services.dynamodbv2.AmazonDynamoDB; import com.amazonaws.services.dynamodbv2.local.main.ServerRunner; import com.amazonaws.services.dynamodbv2.local.server.DynamoDBProxyServer; import org.junit.rules.ExternalResource; -import org.springframework.beans.factory.annotation.Autowired; + +import java.util.Optional; public class LocalDynamoDBCreationRule extends ExternalResource { protected DynamoDBProxyServer server; - protected AmazonDynamoDB amazonDynamoDB; + + public LocalDynamoDBCreationRule() { + System.setProperty("sqlite4java.library.path", "native-libs"); + } @Override protected void before() throws Exception { - System.setProperty("sqlite4java.library.path", "native-libs"); String port = "8000"; this.server = ServerRunner.createServerFromCommandLineArgs(new String[]{"-inMemory", "-port", port}); server.start(); @@ -21,16 +23,15 @@ public class LocalDynamoDBCreationRule extends ExternalResource { @Override protected void after() { + Optional.ofNullable(server).ifPresent(this::stopUnchecked); + } + + protected void stopUnchecked(DynamoDBProxyServer dynamoDbServer) { try { - server.stop(); + dynamoDbServer.stop(); } catch (Exception e) { throw new RuntimeException(e); } } - @Autowired - public void setAmazonDynamoDB(AmazonDynamoDB amazonDynamoDB) { - this.amazonDynamoDB = amazonDynamoDB; - } - } From 93213af112820b61e0a816ec9d9df5a79eec2bde Mon Sep 17 00:00:00 2001 From: linhvovn Date: Fri, 16 Feb 2018 00:22:23 +0800 Subject: [PATCH 46/58] [BAEL 1382] tlinh2110 - Remove unnecessary logs (#3667) * [tlinh2110-BAEL1382] Add Security in SI * [tlinh2110-BAEL1382] Upgrade to Spring 5 & add Logger * [tlinh2110-BAEL-1382] Update Unit Test * [tlinh2110-BAEL1382] Remove unnecessary logs --- spring-integration/pom.xml | 6 ------ spring-integration/src/test/resources/logback-test.xml | 5 +++++ 2 files changed, 5 insertions(+), 6 deletions(-) create mode 100644 spring-integration/src/test/resources/logback-test.xml diff --git a/spring-integration/pom.xml b/spring-integration/pom.xml index 27cc7381e3..43e45dfd17 100644 --- a/spring-integration/pom.xml +++ b/spring-integration/pom.xml @@ -128,12 +128,6 @@ spring-security-test ${spring.version} test - - - org.springframework - spring-test - ${spring.version} - test junit diff --git a/spring-integration/src/test/resources/logback-test.xml b/spring-integration/src/test/resources/logback-test.xml new file mode 100644 index 0000000000..a807be0ca2 --- /dev/null +++ b/spring-integration/src/test/resources/logback-test.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file From 443e990fd128dbb52d98e6916465bb41ee923eb7 Mon Sep 17 00:00:00 2001 From: Magdalena Krause Date: Thu, 15 Feb 2018 12:57:27 -0300 Subject: [PATCH 47/58] BAEL-1543: Spring Batch: Tasklets vs Chunks --- spring-batch/pom.xml | 15 ++- .../chunks/LineProcessor.java | 36 +++++++ .../taskletsvschunks/chunks/LineReader.java | 36 +++++++ .../taskletsvschunks/chunks/LinesWriter.java | 39 ++++++++ .../baeldung/taskletsvschunks/model/Line.java | 55 +++++++++++ .../tasklets/LinesProcessor.java | 49 ++++++++++ .../tasklets/LinesReader.java | 53 +++++++++++ .../tasklets/LinesWriter.java | 50 ++++++++++ .../taskletsvschunks/utils/FileUtils.java | 95 +++++++++++++++++++ spring-batch/src/main/resources/logback.xml | 33 +++++++ .../resources/taskletsvschunks/chunks.xml | 39 ++++++++ .../input/tasklets-vs-chunks.csv | 6 ++ .../resources/taskletsvschunks/tasklets.xml | 47 +++++++++ .../taskletsvschunks/chunks/ChunksTest.java | 24 +++++ .../tasklets/TaskletsTest.java | 24 +++++ 15 files changed, 599 insertions(+), 2 deletions(-) create mode 100644 spring-batch/src/main/java/org/baeldung/taskletsvschunks/chunks/LineProcessor.java create mode 100644 spring-batch/src/main/java/org/baeldung/taskletsvschunks/chunks/LineReader.java create mode 100644 spring-batch/src/main/java/org/baeldung/taskletsvschunks/chunks/LinesWriter.java create mode 100644 spring-batch/src/main/java/org/baeldung/taskletsvschunks/model/Line.java create mode 100644 spring-batch/src/main/java/org/baeldung/taskletsvschunks/tasklets/LinesProcessor.java create mode 100644 spring-batch/src/main/java/org/baeldung/taskletsvschunks/tasklets/LinesReader.java create mode 100644 spring-batch/src/main/java/org/baeldung/taskletsvschunks/tasklets/LinesWriter.java create mode 100644 spring-batch/src/main/java/org/baeldung/taskletsvschunks/utils/FileUtils.java create mode 100644 spring-batch/src/main/resources/logback.xml create mode 100644 spring-batch/src/main/resources/taskletsvschunks/chunks.xml create mode 100644 spring-batch/src/main/resources/taskletsvschunks/input/tasklets-vs-chunks.csv create mode 100644 spring-batch/src/main/resources/taskletsvschunks/tasklets.xml create mode 100644 spring-batch/src/test/java/org/baeldung/taskletsvschunks/chunks/ChunksTest.java create mode 100644 spring-batch/src/test/java/org/baeldung/taskletsvschunks/tasklets/TaskletsTest.java diff --git a/spring-batch/pom.xml b/spring-batch/pom.xml index f372ebd724..f72024d32b 100644 --- a/spring-batch/pom.xml +++ b/spring-batch/pom.xml @@ -18,9 +18,10 @@ UTF-8 - 4.3.4.RELEASE - 3.0.7.RELEASE + 5.0.3.RELEASE + 4.0.0.RELEASE 3.15.1 + 4.1 @@ -51,6 +52,16 @@ spring-batch-core ${spring.batch.version} + + org.springframework.batch + spring-batch-test + ${spring.batch.version} + + + com.opencsv + opencsv + ${opencsv.version} + diff --git a/spring-batch/src/main/java/org/baeldung/taskletsvschunks/chunks/LineProcessor.java b/spring-batch/src/main/java/org/baeldung/taskletsvschunks/chunks/LineProcessor.java new file mode 100644 index 0000000000..5b6cd9add3 --- /dev/null +++ b/spring-batch/src/main/java/org/baeldung/taskletsvschunks/chunks/LineProcessor.java @@ -0,0 +1,36 @@ +package org.baeldung.taskletsvschunks.chunks; + +import org.baeldung.taskletsvschunks.model.Line; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.batch.core.ExitStatus; +import org.springframework.batch.core.StepExecution; +import org.springframework.batch.core.StepExecutionListener; +import org.springframework.batch.item.ItemProcessor; + +import java.time.LocalDate; +import java.time.temporal.ChronoUnit; + +public class LineProcessor implements ItemProcessor, StepExecutionListener { + + private final Logger logger = LoggerFactory.getLogger(LineProcessor.class); + + @Override + public void beforeStep(StepExecution stepExecution) { + logger.debug("Line Processor initialized."); + } + + @Override + public Line process(Line line) throws Exception { + long age = ChronoUnit.YEARS.between(line.getDob(), LocalDate.now()); + logger.debug("Calculated age " + age + " for line " + line.toString()); + line.setAge(age); + return line; + } + + @Override + public ExitStatus afterStep(StepExecution stepExecution) { + logger.debug("Line Processor ended."); + return ExitStatus.COMPLETED; + } +} diff --git a/spring-batch/src/main/java/org/baeldung/taskletsvschunks/chunks/LineReader.java b/spring-batch/src/main/java/org/baeldung/taskletsvschunks/chunks/LineReader.java new file mode 100644 index 0000000000..5f6b6de218 --- /dev/null +++ b/spring-batch/src/main/java/org/baeldung/taskletsvschunks/chunks/LineReader.java @@ -0,0 +1,36 @@ +package org.baeldung.taskletsvschunks.chunks; + +import org.baeldung.taskletsvschunks.model.Line; +import org.baeldung.taskletsvschunks.utils.FileUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.batch.core.ExitStatus; +import org.springframework.batch.core.StepExecution; +import org.springframework.batch.core.StepExecutionListener; +import org.springframework.batch.item.ItemReader; + +public class LineReader implements ItemReader, StepExecutionListener { + + private final Logger logger = LoggerFactory.getLogger(LineReader.class); + private FileUtils fu; + + @Override + public void beforeStep(StepExecution stepExecution) { + fu = new FileUtils("taskletsvschunks/input/tasklets-vs-chunks.csv"); + logger.debug("Line Reader initialized."); + } + + @Override + public Line read() throws Exception { + Line line = fu.readLine(); + if (line != null) logger.debug("Read line: " + line.toString()); + return line; + } + + @Override + public ExitStatus afterStep(StepExecution stepExecution) { + fu.closeReader(); + logger.debug("Line Reader ended."); + return ExitStatus.COMPLETED; + } +} diff --git a/spring-batch/src/main/java/org/baeldung/taskletsvschunks/chunks/LinesWriter.java b/spring-batch/src/main/java/org/baeldung/taskletsvschunks/chunks/LinesWriter.java new file mode 100644 index 0000000000..66f9103a56 --- /dev/null +++ b/spring-batch/src/main/java/org/baeldung/taskletsvschunks/chunks/LinesWriter.java @@ -0,0 +1,39 @@ +package org.baeldung.taskletsvschunks.chunks; + +import org.baeldung.taskletsvschunks.model.Line; +import org.baeldung.taskletsvschunks.utils.FileUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.batch.core.ExitStatus; +import org.springframework.batch.core.StepExecution; +import org.springframework.batch.core.StepExecutionListener; +import org.springframework.batch.item.ItemWriter; + +import java.util.List; + +public class LinesWriter implements ItemWriter, StepExecutionListener { + + private final Logger logger = LoggerFactory.getLogger(LinesWriter.class); + private FileUtils fu; + + @Override + public void beforeStep(StepExecution stepExecution) { + fu = new FileUtils("output.csv"); + logger.debug("Line Writer initialized."); + } + + @Override + public ExitStatus afterStep(StepExecution stepExecution) { + fu.closeWriter(); + logger.debug("Line Writer ended."); + return ExitStatus.COMPLETED; + } + + @Override + public void write(List lines) throws Exception { + for (Line line : lines) { + fu.writeLine(line); + logger.debug("Wrote line " + line.toString()); + } + } +} diff --git a/spring-batch/src/main/java/org/baeldung/taskletsvschunks/model/Line.java b/spring-batch/src/main/java/org/baeldung/taskletsvschunks/model/Line.java new file mode 100644 index 0000000000..fee6fd31a6 --- /dev/null +++ b/spring-batch/src/main/java/org/baeldung/taskletsvschunks/model/Line.java @@ -0,0 +1,55 @@ +package org.baeldung.taskletsvschunks.model; + +import java.io.Serializable; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; + +public class Line implements Serializable { + + private String name; + private LocalDate dob; + private Long age; + + public Line(String name, LocalDate dob) { + this.name = name; + this.dob = dob; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public LocalDate getDob() { + return dob; + } + + public void setDob(LocalDate dob) { + this.dob = dob; + } + + public Long getAge() { + return age; + } + + public void setAge(Long age) { + this.age = age; + } + + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("["); + sb.append(this.name); + sb.append(","); + sb.append(this.dob.format(DateTimeFormatter.ofPattern("MM/dd/yyyy"))); + if (this.age != null) { + sb.append(","); + sb.append(this.age); + } + sb.append("]"); + return sb.toString(); + } +} diff --git a/spring-batch/src/main/java/org/baeldung/taskletsvschunks/tasklets/LinesProcessor.java b/spring-batch/src/main/java/org/baeldung/taskletsvschunks/tasklets/LinesProcessor.java new file mode 100644 index 0000000000..ba7a3088d5 --- /dev/null +++ b/spring-batch/src/main/java/org/baeldung/taskletsvschunks/tasklets/LinesProcessor.java @@ -0,0 +1,49 @@ +package org.baeldung.taskletsvschunks.tasklets; + +import org.baeldung.taskletsvschunks.model.Line; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.batch.core.ExitStatus; +import org.springframework.batch.core.StepContribution; +import org.springframework.batch.core.StepExecution; +import org.springframework.batch.core.StepExecutionListener; +import org.springframework.batch.core.scope.context.ChunkContext; +import org.springframework.batch.core.step.tasklet.Tasklet; +import org.springframework.batch.item.ExecutionContext; +import org.springframework.batch.repeat.RepeatStatus; + +import java.time.LocalDate; +import java.time.temporal.ChronoUnit; +import java.util.List; + +public class LinesProcessor implements Tasklet, StepExecutionListener { + + private final Logger logger = LoggerFactory.getLogger(LinesProcessor.class); + + private List lines; + + @Override + public RepeatStatus execute(StepContribution stepContribution, ChunkContext chunkContext) throws Exception { + for (Line line : lines) { + long age = ChronoUnit.YEARS.between(line.getDob(), LocalDate.now()); + logger.debug("Calculated age " + age + " for line " + line.toString()); + line.setAge(age); + } + return RepeatStatus.FINISHED; + } + + @Override + public void beforeStep(StepExecution stepExecution) { + ExecutionContext executionContext = stepExecution + .getJobExecution() + .getExecutionContext(); + this.lines = (List) executionContext.get("lines"); + logger.debug("Lines Processor initialized."); + } + + @Override + public ExitStatus afterStep(StepExecution stepExecution) { + logger.debug("Lines Processor ended."); + return ExitStatus.COMPLETED; + } +} diff --git a/spring-batch/src/main/java/org/baeldung/taskletsvschunks/tasklets/LinesReader.java b/spring-batch/src/main/java/org/baeldung/taskletsvschunks/tasklets/LinesReader.java new file mode 100644 index 0000000000..9905ee8f8a --- /dev/null +++ b/spring-batch/src/main/java/org/baeldung/taskletsvschunks/tasklets/LinesReader.java @@ -0,0 +1,53 @@ +package org.baeldung.taskletsvschunks.tasklets; + +import org.baeldung.taskletsvschunks.model.Line; +import org.baeldung.taskletsvschunks.utils.FileUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.batch.core.ExitStatus; +import org.springframework.batch.core.StepContribution; +import org.springframework.batch.core.StepExecution; +import org.springframework.batch.core.StepExecutionListener; +import org.springframework.batch.core.scope.context.ChunkContext; +import org.springframework.batch.core.step.tasklet.Tasklet; +import org.springframework.batch.repeat.RepeatStatus; + +import java.util.ArrayList; +import java.util.List; + +public class LinesReader implements Tasklet, StepExecutionListener { + + private final Logger logger = LoggerFactory.getLogger(LinesReader.class); + + private List lines; + private FileUtils fu; + + @Override + public void beforeStep(StepExecution stepExecution) { + lines = new ArrayList(); + fu = new FileUtils("taskletsvschunks/input/tasklets-vs-chunks.csv"); + logger.debug("Lines Reader initialized."); + } + + @Override + public RepeatStatus execute(StepContribution stepContribution, ChunkContext chunkContext) throws Exception { + Line line = fu.readLine(); + while (line != null) { + lines.add(line); + logger.debug("Read line: " + line.toString()); + line = fu.readLine(); + } + return RepeatStatus.FINISHED; + } + + @Override + public ExitStatus afterStep(StepExecution stepExecution) { + fu.closeReader(); + stepExecution + .getJobExecution() + .getExecutionContext() + .put("lines", this.lines); + logger.debug("Lines Reader ended."); + return ExitStatus.COMPLETED; + } +} diff --git a/spring-batch/src/main/java/org/baeldung/taskletsvschunks/tasklets/LinesWriter.java b/spring-batch/src/main/java/org/baeldung/taskletsvschunks/tasklets/LinesWriter.java new file mode 100644 index 0000000000..937288a890 --- /dev/null +++ b/spring-batch/src/main/java/org/baeldung/taskletsvschunks/tasklets/LinesWriter.java @@ -0,0 +1,50 @@ +package org.baeldung.taskletsvschunks.tasklets; + +import org.baeldung.taskletsvschunks.model.Line; +import org.baeldung.taskletsvschunks.utils.FileUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.batch.core.ExitStatus; +import org.springframework.batch.core.StepContribution; +import org.springframework.batch.core.StepExecution; +import org.springframework.batch.core.StepExecutionListener; +import org.springframework.batch.core.scope.context.ChunkContext; +import org.springframework.batch.core.step.tasklet.Tasklet; +import org.springframework.batch.item.ExecutionContext; +import org.springframework.batch.repeat.RepeatStatus; + +import java.util.List; + +public class LinesWriter implements Tasklet, StepExecutionListener { + + private final Logger logger = LoggerFactory.getLogger(LinesWriter.class); + + private List lines; + private FileUtils fu; + + @Override + public void beforeStep(StepExecution stepExecution) { + ExecutionContext executionContext = stepExecution + .getJobExecution() + .getExecutionContext(); + this.lines = (List) executionContext.get("lines"); + fu = new FileUtils("output.csv"); + logger.debug("Lines Writer initialized."); + } + + @Override + public RepeatStatus execute(StepContribution stepContribution, ChunkContext chunkContext) throws Exception { + for (Line line : lines) { + fu.writeLine(line); + logger.debug("Wrote line " + line.toString()); + } + return RepeatStatus.FINISHED; + } + + @Override + public ExitStatus afterStep(StepExecution stepExecution) { + fu.closeWriter(); + logger.debug("Lines Writer ended."); + return ExitStatus.COMPLETED; + } +} diff --git a/spring-batch/src/main/java/org/baeldung/taskletsvschunks/utils/FileUtils.java b/spring-batch/src/main/java/org/baeldung/taskletsvschunks/utils/FileUtils.java new file mode 100644 index 0000000000..df36d5c756 --- /dev/null +++ b/spring-batch/src/main/java/org/baeldung/taskletsvschunks/utils/FileUtils.java @@ -0,0 +1,95 @@ +package org.baeldung.taskletsvschunks.utils; + +import com.opencsv.CSVReader; +import com.opencsv.CSVWriter; +import org.baeldung.taskletsvschunks.model.Line; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; + +public class FileUtils { + + private final Logger logger = LoggerFactory.getLogger(FileUtils.class); + + private String fileName; + private CSVReader CSVReader; + private CSVWriter CSVWriter; + private FileReader fileReader; + private FileWriter fileWriter; + private File file; + + public FileUtils(String fileName) { + this.fileName = fileName; + } + + public Line readLine() { + try { + if (CSVReader == null) initReader(); + String[] line = CSVReader.readNext(); + if (line == null) return null; + return new Line(line[0], LocalDate.parse(line[1], DateTimeFormatter.ofPattern("MM/dd/yyyy"))); + } catch (Exception e) { + logger.error("Error while reading line in file: " + this.fileName); + return null; + } + } + + public void writeLine(Line line) { + try { + if (CSVWriter == null) initWriter(); + String[] lineStr = new String[2]; + lineStr[0] = line.getName(); + lineStr[1] = line + .getAge() + .toString(); + CSVWriter.writeNext(lineStr); + } catch (Exception e) { + logger.error("Error while writing line in file: " + this.fileName); + } + } + + private void initReader() throws Exception { + ClassLoader classLoader = this + .getClass() + .getClassLoader(); + if (file == null) file = new File(classLoader + .getResource(fileName) + .getFile()); + if (fileReader == null) fileReader = new FileReader(file); + if (CSVReader == null) CSVReader = new CSVReader(fileReader); + } + + private void initWriter() throws Exception { + if (file == null) { + file = new File(fileName); + file.createNewFile(); + } + if (fileWriter == null) fileWriter = new FileWriter(file, true); + if (CSVWriter == null) CSVWriter = new CSVWriter(fileWriter); + } + + public void closeWriter() { + try { + CSVWriter.close(); + fileWriter.close(); + } catch (IOException e) { + logger.error("Error while closing writer."); + } + } + + public void closeReader() { + try { + CSVReader.close(); + fileReader.close(); + } catch (IOException e) { + logger.error("Error while closing reader."); + } + } + +} diff --git a/spring-batch/src/main/resources/logback.xml b/spring-batch/src/main/resources/logback.xml new file mode 100644 index 0000000000..dc9218caf3 --- /dev/null +++ b/spring-batch/src/main/resources/logback.xml @@ -0,0 +1,33 @@ + + + + C:\Users\admin\Desktop\Baeldung\repo\magkrause\tutorials\spring-batch\src\main\resources\taskletsvschunks\logs.log + + + %d{yyyy-MM-dd HH:mm:ss} [%thread] %level %logger{35} - %msg%n + + + + + + ${DEV_HOME}/archived/debug.%d{yyyy-MM-dd}.%i.log + + + 10MB + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-batch/src/main/resources/taskletsvschunks/chunks.xml b/spring-batch/src/main/resources/taskletsvschunks/chunks.xml new file mode 100644 index 0000000000..f4b77ac10c --- /dev/null +++ b/spring-batch/src/main/resources/taskletsvschunks/chunks.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-batch/src/main/resources/taskletsvschunks/input/tasklets-vs-chunks.csv b/spring-batch/src/main/resources/taskletsvschunks/input/tasklets-vs-chunks.csv new file mode 100644 index 0000000000..214bd3cb70 --- /dev/null +++ b/spring-batch/src/main/resources/taskletsvschunks/input/tasklets-vs-chunks.csv @@ -0,0 +1,6 @@ +Mae Hodges,10/22/1972 +Gary Potter,02/22/1953 +Betty Wise,02/17/1968 +Wayne Rose,04/06/1977 +Adam Caldwell,09/27/1995 +Lucille Phillips,05/14/1992 \ No newline at end of file diff --git a/spring-batch/src/main/resources/taskletsvschunks/tasklets.xml b/spring-batch/src/main/resources/taskletsvschunks/tasklets.xml new file mode 100644 index 0000000000..34ce2944bc --- /dev/null +++ b/spring-batch/src/main/resources/taskletsvschunks/tasklets.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-batch/src/test/java/org/baeldung/taskletsvschunks/chunks/ChunksTest.java b/spring-batch/src/test/java/org/baeldung/taskletsvschunks/chunks/ChunksTest.java new file mode 100644 index 0000000000..d32edaf2ce --- /dev/null +++ b/spring-batch/src/test/java/org/baeldung/taskletsvschunks/chunks/ChunksTest.java @@ -0,0 +1,24 @@ +package org.baeldung.taskletsvschunks.chunks; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.batch.core.ExitStatus; +import org.springframework.batch.core.JobExecution; +import org.springframework.batch.test.JobLauncherTestUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(locations = "classpath:/taskletsvschunks/chunks.xml") +public class ChunksTest { + + @Autowired private JobLauncherTestUtils jobLauncherTestUtils; + + @Test + public void test() throws Exception { + JobExecution jobExecution = jobLauncherTestUtils.launchJob(); + Assert.assertEquals(ExitStatus.COMPLETED, jobExecution.getExitStatus()); + } +} \ No newline at end of file diff --git a/spring-batch/src/test/java/org/baeldung/taskletsvschunks/tasklets/TaskletsTest.java b/spring-batch/src/test/java/org/baeldung/taskletsvschunks/tasklets/TaskletsTest.java new file mode 100644 index 0000000000..4702b67a5c --- /dev/null +++ b/spring-batch/src/test/java/org/baeldung/taskletsvschunks/tasklets/TaskletsTest.java @@ -0,0 +1,24 @@ +package org.baeldung.taskletsvschunks.tasklets; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.batch.core.ExitStatus; +import org.springframework.batch.core.JobExecution; +import org.springframework.batch.test.JobLauncherTestUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(locations = "classpath:/taskletsvschunks/tasklets.xml") +public class TaskletsTest { + + @Autowired private JobLauncherTestUtils jobLauncherTestUtils; + + @Test + public void test() throws Exception { + JobExecution jobExecution = jobLauncherTestUtils.launchJob(); + Assert.assertEquals(ExitStatus.COMPLETED, jobExecution.getExitStatus()); + } +} \ No newline at end of file From d09a828a58ea258dc30bda6deded16829553d5d7 Mon Sep 17 00:00:00 2001 From: Magdalena Krause Date: Thu, 15 Feb 2018 13:28:56 -0300 Subject: [PATCH 48/58] BAEL-1543: Changing tests names. --- .../java/org/baeldung/taskletsvschunks/chunks/ChunksTest.java | 2 +- .../org/baeldung/taskletsvschunks/tasklets/TaskletsTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/spring-batch/src/test/java/org/baeldung/taskletsvschunks/chunks/ChunksTest.java b/spring-batch/src/test/java/org/baeldung/taskletsvschunks/chunks/ChunksTest.java index d32edaf2ce..34b6315dc4 100644 --- a/spring-batch/src/test/java/org/baeldung/taskletsvschunks/chunks/ChunksTest.java +++ b/spring-batch/src/test/java/org/baeldung/taskletsvschunks/chunks/ChunksTest.java @@ -17,7 +17,7 @@ public class ChunksTest { @Autowired private JobLauncherTestUtils jobLauncherTestUtils; @Test - public void test() throws Exception { + public void givenChunksJob_WhenJobEnds_ThenStatusCompleted() throws Exception { JobExecution jobExecution = jobLauncherTestUtils.launchJob(); Assert.assertEquals(ExitStatus.COMPLETED, jobExecution.getExitStatus()); } diff --git a/spring-batch/src/test/java/org/baeldung/taskletsvschunks/tasklets/TaskletsTest.java b/spring-batch/src/test/java/org/baeldung/taskletsvschunks/tasklets/TaskletsTest.java index 4702b67a5c..53731feed4 100644 --- a/spring-batch/src/test/java/org/baeldung/taskletsvschunks/tasklets/TaskletsTest.java +++ b/spring-batch/src/test/java/org/baeldung/taskletsvschunks/tasklets/TaskletsTest.java @@ -17,7 +17,7 @@ public class TaskletsTest { @Autowired private JobLauncherTestUtils jobLauncherTestUtils; @Test - public void test() throws Exception { + public void givenTaskletsJob_WhenJobEnds_ThenStatusCompleted() throws Exception { JobExecution jobExecution = jobLauncherTestUtils.launchJob(); Assert.assertEquals(ExitStatus.COMPLETED, jobExecution.getExitStatus()); } From 7d0efdb67d0b32f3da5890ed21b5329ec62311e3 Mon Sep 17 00:00:00 2001 From: KevinGilmore Date: Thu, 15 Feb 2018 17:53:22 -0600 Subject: [PATCH 49/58] BAEL-113 README (#3658) * BAEL-973: updated README * BAEL-1069: Updated README * BAEL-817: add README file * BAEL-1084: README update * BAEL-960: Update README * BAEL-1155: updated README * BAEL-1041: updated README * BAEL-973: Updated README * BAEL-1187: updated README * BAEL-1183: Update README * BAEL-1133: Updated README * BAEL-1098: README update * BAEL-719: add README.md * BAEL-1272: README update * BAEL-1272: README update * BAEL-1196: Update README * BAEL-1328: Updated README * BAEL-1371: Update README.md * BAEL-1371: Update README.md * BAEL-1278: Update README * BAEL-1326: Update README * BAEL-399: Update README * BAEL-1297: Update README * BAEL-1218: README * BAEL-1148 README update * BAEL-113 README --- spring-jinq/README.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 spring-jinq/README.md diff --git a/spring-jinq/README.md b/spring-jinq/README.md new file mode 100644 index 0000000000..10d7903f49 --- /dev/null +++ b/spring-jinq/README.md @@ -0,0 +1,4 @@ +## Relevant articles: + +- [Introduction to Jinq with Spring](http://www.baeldung.com/spring-jinq) + From a27e73a57f909a3add358121f7fdb9a1da1de3d7 Mon Sep 17 00:00:00 2001 From: iaforek Date: Fri, 16 Feb 2018 06:13:26 +0000 Subject: [PATCH 50/58] BAEL-1298 - Variable renames (#3653) * Code for Dependency Injection Article. * Added Java based configuration. Downloaded formatter.xml and reformatted all changed files. Manually changed tab into 4 spaces in XML configuration files. * BAEL-434 - Spring Roo project files generated by Spring Roo. No formatting applied. Added POM, java and resources folders. * Moved project from roo to spring-roo folder. * BAEL-838 Initial code showing how to remove last char - helper class and tests. * BAEL-838 Corrected Helper class and associated empty string test case. Added StringUtils.substing tests. * BAEL-838 Refromatted code using formatter.xml. Added Assert.assertEquals import. Renamed test to follow convention. Reordered tests. * BAEL-838 - Added regex method and updated tests. * BAEL-838 Added new line examples. * BAEL-838 Renamed RemoveLastChar class to StringHelper and added Java8 examples. Refactord code. * BAEL-838 Changed method names * BAEL-838 Tiny change to keep code consistant. Return null or empty. * BAEL-838 Removed unresolved conflict. * BAEL-821 New class that shows different rounding techniques. Updated POM. * BAEL-821 - Added unit test for different round methods. * BAEL-821 Changed test method name to follow the convention * BAEL-821 Added more test and updated round methods. * BAEL-837 - initial commit. A few examples of adding doubles. * BAEL-837 - Couple of smaller changes * BAEL-837 - Added jUnit test. * BAEL-579 Updated Spring Cloud Version I was getting error: java.lang.NoSuchMethodError: org.springframework.cloud.config.environment.Environment After version update, all is okay. * BAEL-579 Added actuator to Cloud Config Client. * BAEL-579 Enabled cloud bus and updated dependencies. * BAEL-579 Config Client using Spring Cloud Bus. * BAEL-579 Recreated Basic Config Server. * BAEL-579 Recreated Config Client. * BAEL-579 Removed test Git URL. * BAEL-579 Added Actuator to Config Client * BAEL-579 Added Spring Cloud Bus to Client. * BAEL-579 Server changes for Spring Cloud Bus Added dependencies and removed git.clone-on-start as this was causing server to throw errors after git properties change. * BAEL-579 Removed Git URL. * Revert "BAEL-579 Updated Spring Cloud Version" This reverts commit f775bf91e53a1ecfb9b70596688d7c8202bf495f. * Revert "BAEL-579 Config Client using Spring Cloud Bus." This reverts commit 1d96bc5761994a33af9a7a9aa5ab68604a5b44dc. * Revert "BAEL-579 Enabled cloud bus and updated dependencies." This reverts commit 7845da922d89d53506dd0fff387ea13694c50bc1. * Revert "BAEL-579 Added actuator to Cloud Config Client." This reverts commit 076657a26a57e0aa676989a4d97966a3b9d53e1c. * BAEL-579 Added missing dependency versions. * BAEL-579 Added missing dependency versions. * Updated gitignore * BAEL-1065 Simple performance check StringBuffer vs StringBuilder. * BAEL-1065 Added JMH benchmarks * BAEL-1298 Sudoku - Backtracking Algorithm * BAEL-1298 Sudoku - Backtracking Algorithm * BAEL-1298 Dancing Links Algorithm. Smaller changes to Backtracking * BAEL-1298 Resolve conflict - use most up-to-date POM * Updated code - mostly with CONSTANTS. Extracted methods. * Removed pointless Java8 code. Renamed constant * Extracted 'constraints' methods and renamed coverBoard variable * Extracted 'constraints' methods and renamed coverBoard variable * Renamed variables * More variable renames --- .../sudoku/BacktrackingAlgorithm.java | 48 +++++++++---------- .../sudoku/DancingLinksAlgorithm.java | 40 ++++++++-------- .../algorithms/sudoku/DancingNode.java | 26 +++++----- 3 files changed, 57 insertions(+), 57 deletions(-) diff --git a/algorithms/src/main/java/com/baeldung/algorithms/sudoku/BacktrackingAlgorithm.java b/algorithms/src/main/java/com/baeldung/algorithms/sudoku/BacktrackingAlgorithm.java index ff426cbe68..4b37558aab 100644 --- a/algorithms/src/main/java/com/baeldung/algorithms/sudoku/BacktrackingAlgorithm.java +++ b/algorithms/src/main/java/com/baeldung/algorithms/sudoku/BacktrackingAlgorithm.java @@ -40,15 +40,15 @@ public class BacktrackingAlgorithm { } private boolean solve(int[][] board) { - for (int r = BOARD_START_INDEX; r < BOARD_SIZE; r++) { - for (int c = BOARD_START_INDEX; c < BOARD_SIZE; c++) { - if (board[r][c] == NO_VALUE) { + for (int row = BOARD_START_INDEX; row < BOARD_SIZE; row++) { + for (int column = BOARD_START_INDEX; column < BOARD_SIZE; column++) { + if (board[row][column] == NO_VALUE) { for (int k = MIN_VALUE; k <= MAX_VALUE; k++) { - board[r][c] = k; - if (isValid(board, r, c) && solve(board)) { + board[row][column] = k; + if (isValid(board, row, column) && solve(board)) { return true; } - board[r][c] = NO_VALUE; + board[row][column] = NO_VALUE; } return false; } @@ -57,44 +57,44 @@ public class BacktrackingAlgorithm { return true; } - private boolean isValid(int[][] board, int r, int c) { - return rowConstraint(board, r) && - columnConstraint(board, c) && - subsectionConstraint(board, r, c); + private boolean isValid(int[][] board, int row, int column) { + return rowConstraint(board, row) && + columnConstraint(board, column) && + subsectionConstraint(board, row, column); } - private boolean subsectionConstraint(int[][] board, int r, int c) { + private boolean subsectionConstraint(int[][] board, int row, int column) { boolean[] constraint = new boolean[BOARD_SIZE]; - int subsectionRowStart = (r / SUBSECTION_SIZE) * SUBSECTION_SIZE; + int subsectionRowStart = (row / SUBSECTION_SIZE) * SUBSECTION_SIZE; int subsectionRowEnd = subsectionRowStart + SUBSECTION_SIZE; - int subsectionColumnStart = (c / SUBSECTION_SIZE) * SUBSECTION_SIZE; + int subsectionColumnStart = (column / SUBSECTION_SIZE) * SUBSECTION_SIZE; int subsectionColumnEnd = subsectionColumnStart + SUBSECTION_SIZE; - for (int i = subsectionRowStart; i < subsectionRowEnd; i++) { - for (int j = subsectionColumnStart; j < subsectionColumnEnd; j++) { - if (!checkConstraint(board, i, constraint, j)) return false; + for (int r = subsectionRowStart; r < subsectionRowEnd; r++) { + for (int c = subsectionColumnStart; c < subsectionColumnEnd; c++) { + if (!checkConstraint(board, r, constraint, c)) return false; } } return true; } - private boolean columnConstraint(int[][] board, int c) { + private boolean columnConstraint(int[][] board, int column) { boolean[] constraint = new boolean[BOARD_SIZE]; return IntStream.range(BOARD_START_INDEX, BOARD_SIZE) - .allMatch(i -> checkConstraint(board, i, constraint, c)); + .allMatch(row -> checkConstraint(board, row, constraint, column)); } - private boolean rowConstraint(int[][] board, int r) { + private boolean rowConstraint(int[][] board, int row) { boolean[] constraint = new boolean[BOARD_SIZE]; return IntStream.range(BOARD_START_INDEX, BOARD_SIZE) - .allMatch(i -> checkConstraint(board, r, constraint, i)); + .allMatch(column -> checkConstraint(board, row, constraint, column)); } - private boolean checkConstraint(int[][] board, int r, boolean[] constraint, int c) { - if (board[r][c] != NO_VALUE) { - if (!constraint[board[r][c] - 1]) { - constraint[board[r][c] - 1] = true; + private boolean checkConstraint(int[][] board, int row, boolean[] constraint, int column) { + if (board[row][column] != NO_VALUE) { + if (!constraint[board[row][column] - 1]) { + constraint[board[row][column] - 1] = true; } else { return false; } diff --git a/algorithms/src/main/java/com/baeldung/algorithms/sudoku/DancingLinksAlgorithm.java b/algorithms/src/main/java/com/baeldung/algorithms/sudoku/DancingLinksAlgorithm.java index 76b686afa6..df02ff3d11 100644 --- a/algorithms/src/main/java/com/baeldung/algorithms/sudoku/DancingLinksAlgorithm.java +++ b/algorithms/src/main/java/com/baeldung/algorithms/sudoku/DancingLinksAlgorithm.java @@ -34,8 +34,8 @@ public class DancingLinksAlgorithm { dlx.runSolver(); } - private int getIndex(int row, int col, int num) { - return (row - 1) * BOARD_SIZE * BOARD_SIZE + (col - 1) * BOARD_SIZE + (num - 1); + private int getIndex(int row, int column, int num) { + return (row - 1) * BOARD_SIZE * BOARD_SIZE + (column - 1) * BOARD_SIZE + (num - 1); } private boolean[][] createExactCoverBoard() { @@ -51,12 +51,12 @@ public class DancingLinksAlgorithm { } private int checkSubsectionConstraint(boolean[][] coverBoard, int hBase) { - for (int br = COVER_START_INDEX; br <= BOARD_SIZE; br += SUBSECTION_SIZE) { - for (int bc = COVER_START_INDEX; bc <= BOARD_SIZE; bc += SUBSECTION_SIZE) { + for (int row = COVER_START_INDEX; row <= BOARD_SIZE; row += SUBSECTION_SIZE) { + for (int column = COVER_START_INDEX; column <= BOARD_SIZE; column += SUBSECTION_SIZE) { for (int n = COVER_START_INDEX; n <= BOARD_SIZE; n++, hBase++) { - for (int rDelta = 0; rDelta < SUBSECTION_SIZE; rDelta++) { - for (int cDelta = 0; cDelta < SUBSECTION_SIZE; cDelta++) { - int index = getIndex(br + rDelta, bc + cDelta, n); + for (int rowDelta = 0; rowDelta < SUBSECTION_SIZE; rowDelta++) { + for (int columnDelta = 0; columnDelta < SUBSECTION_SIZE; columnDelta++) { + int index = getIndex(row + rowDelta, column + columnDelta, n); coverBoard[index][hBase] = true; } } @@ -67,10 +67,10 @@ public class DancingLinksAlgorithm { } private int checkColumnConstraint(boolean[][] coverBoard, int hBase) { - for (int c = COVER_START_INDEX; c <= BOARD_SIZE; c++) { + for (int column = COVER_START_INDEX; column <= BOARD_SIZE; column++) { for (int n = COVER_START_INDEX; n <= BOARD_SIZE; n++, hBase++) { - for (int r1 = COVER_START_INDEX; r1 <= BOARD_SIZE; r1++) { - int index = getIndex(r1, c, n); + for (int row = COVER_START_INDEX; row <= BOARD_SIZE; row++) { + int index = getIndex(row, column, n); coverBoard[index][hBase] = true; } } @@ -79,10 +79,10 @@ public class DancingLinksAlgorithm { } private int checkRowConstraint(boolean[][] coverBoard, int hBase) { - for (int r = COVER_START_INDEX; r <= BOARD_SIZE; r++) { + for (int row = COVER_START_INDEX; row <= BOARD_SIZE; row++) { for (int n = COVER_START_INDEX; n <= BOARD_SIZE; n++, hBase++) { - for (int c1 = COVER_START_INDEX; c1 <= BOARD_SIZE; c1++) { - int index = getIndex(r, c1, n); + for (int column = COVER_START_INDEX; column <= BOARD_SIZE; column++) { + int index = getIndex(row, column, n); coverBoard[index][hBase] = true; } } @@ -91,10 +91,10 @@ public class DancingLinksAlgorithm { } private int checkCellConstraint(boolean[][] coverBoard, int hBase) { - for (int r = COVER_START_INDEX; r <= BOARD_SIZE; r++) { - for (int c = COVER_START_INDEX; c <= BOARD_SIZE; c++, hBase++) { + for (int row = COVER_START_INDEX; row <= BOARD_SIZE; row++) { + for (int column = COVER_START_INDEX; column <= BOARD_SIZE; column++, hBase++) { for (int n = COVER_START_INDEX; n <= BOARD_SIZE; n++) { - int index = getIndex(r, c, n); + int index = getIndex(row, column, n); coverBoard[index][hBase] = true; } } @@ -104,13 +104,13 @@ public class DancingLinksAlgorithm { private boolean[][] initializeExactCoverBoard(int[][] board) { boolean[][] coverBoard = createExactCoverBoard(); - for (int i = COVER_START_INDEX; i <= BOARD_SIZE; i++) { - for (int j = COVER_START_INDEX; j <= BOARD_SIZE; j++) { - int n = board[i - 1][j - 1]; + for (int row = COVER_START_INDEX; row <= BOARD_SIZE; row++) { + for (int column = COVER_START_INDEX; column <= BOARD_SIZE; column++) { + int n = board[row - 1][column - 1]; if (n != NO_VALUE) { for (int num = MIN_VALUE; num <= MAX_VALUE; num++) { if (num != n) { - Arrays.fill(coverBoard[getIndex(i, j, num)], false); + Arrays.fill(coverBoard[getIndex(row, column, num)], false); } } } diff --git a/algorithms/src/main/java/com/baeldung/algorithms/sudoku/DancingNode.java b/algorithms/src/main/java/com/baeldung/algorithms/sudoku/DancingNode.java index b494eba9ef..2422ff0dff 100644 --- a/algorithms/src/main/java/com/baeldung/algorithms/sudoku/DancingNode.java +++ b/algorithms/src/main/java/com/baeldung/algorithms/sudoku/DancingNode.java @@ -4,21 +4,21 @@ class DancingNode { DancingNode L, R, U, D; ColumnNode C; - DancingNode hookDown(DancingNode n1) { - assert (this.C == n1.C); - n1.D = this.D; - n1.D.U = n1; - n1.U = this; - this.D = n1; - return n1; + DancingNode hookDown(DancingNode node) { + assert (this.C == node.C); + node.D = this.D; + node.D.U = node; + node.U = this; + this.D = node; + return node; } - DancingNode hookRight(DancingNode n1) { - n1.R = this.R; - n1.R.L = n1; - n1.L = this; - this.R = n1; - return n1; + DancingNode hookRight(DancingNode node) { + node.R = this.R; + node.R.L = node; + node.L = this; + this.R = node; + return node; } void unlinkLR() { From 666c07c7bee789f5f4c07c56f3b3172645879644 Mon Sep 17 00:00:00 2001 From: Harshil Sharma Date: Fri, 16 Feb 2018 19:03:34 +0530 Subject: [PATCH 51/58] BAEL-1539 shuffling collections (#3567) * BAEL-1539 Added list, set and map shuffling code exaamples * #BAEL-1539 fixed a typo * #BAEL-1539 refactored sample code, added unit tests * #BAEL-1539 Added unit tests and example for shuffling with custom randomness * #BAEL-1539 removed source code and kept only tests as tests are sufficient code sample themselves * #BAEL-1539 updated map shuffling example to use lambdas * #BAEL-1539 lambda refactoring * Fixed an indentation --- .../ShufflingCollectionsUnitTest.java | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 core-java-8/src/test/java/com/baeldung/shufflingcollections/ShufflingCollectionsUnitTest.java diff --git a/core-java-8/src/test/java/com/baeldung/shufflingcollections/ShufflingCollectionsUnitTest.java b/core-java-8/src/test/java/com/baeldung/shufflingcollections/ShufflingCollectionsUnitTest.java new file mode 100644 index 0000000000..4823c7178a --- /dev/null +++ b/core-java-8/src/test/java/com/baeldung/shufflingcollections/ShufflingCollectionsUnitTest.java @@ -0,0 +1,70 @@ +package com.baeldung.shufflingcollections; + +import org.junit.Test; + +import java.util.*; +import java.util.stream.Collectors; + +import static org.assertj.core.api.Assertions.assertThat; + +public class ShufflingCollectionsUnitTest { + + @Test + public void whenShufflingList_thenListIsShuffled() { + List students = Arrays.asList("Foo", "Bar", "Baz", "Qux"); + + System.out.println("List before shuffling:"); + System.out.println(students); + + Collections.shuffle(students); + System.out.println("List after shuffling:"); + System.out.println(students); + } + + @Test + public void whenShufflingMapKeys_thenValuesAreShuffled() { + Map studentsById = new HashMap<>(); + studentsById.put(1, "Foo"); + studentsById.put(2, "Bar"); + studentsById.put(3, "Baz"); + studentsById.put(4, "Qux"); + + System.out.println("Students before shuffling:"); + System.out.println(studentsById.values()); + + List shuffledStudentIds = new ArrayList<>(studentsById.keySet()); + Collections.shuffle(shuffledStudentIds); + + List shuffledStudents = shuffledStudentIds.stream() + .map(id -> studentsById.get(id)) + .collect(Collectors.toList()); + + System.out.println("Students after shuffling"); + System.out.println(shuffledStudents); + } + + @Test + public void whenShufflingSet_thenElementsAreShuffled() { + Set students = new HashSet<>(Arrays.asList("Foo", "Bar", "Baz", "Qux")); + + System.out.println("Set before shuffling:"); + System.out.println(students); + + List studentList = new ArrayList<>(students); + + Collections.shuffle(studentList); + System.out.println("Shuffled set elements:"); + System.out.println(studentList); + } + + @Test + public void whenShufflingWithSameRandomness_thenElementsAreShuffledDeterministically() { + List students_1 = Arrays.asList("Foo", "Bar", "Baz", "Qux"); + List students_2 = Arrays.asList("Foo", "Bar", "Baz", "Qux"); + + Collections.shuffle(students_1, new Random(5)); + Collections.shuffle(students_2, new Random(5)); + + assertThat(students_1).isEqualTo(students_2); + } +} From 53529f0c50e1d56af366b972bc75cb65e4f903f6 Mon Sep 17 00:00:00 2001 From: Loredana Crusoveanu Date: Fri, 16 Feb 2018 21:35:11 +0200 Subject: [PATCH 52/58] fix spring-cloud-gateway project setup, update boot version --- .../gateway-service/pom.xml | 79 ------------------- spring-cloud/spring-cloud-gateway/pom.xml | 61 ++++++++++++-- .../spring/cloud/GatewayApplication.java | 0 .../src/main/resources/application.yml | 0 4 files changed, 55 insertions(+), 85 deletions(-) delete mode 100644 spring-cloud/spring-cloud-gateway/gateway-service/pom.xml rename spring-cloud/spring-cloud-gateway/{gateway-service => }/src/main/java/com/baeldung/spring/cloud/GatewayApplication.java (100%) rename spring-cloud/spring-cloud-gateway/{gateway-service => }/src/main/resources/application.yml (100%) diff --git a/spring-cloud/spring-cloud-gateway/gateway-service/pom.xml b/spring-cloud/spring-cloud-gateway/gateway-service/pom.xml deleted file mode 100644 index 14cde4901a..0000000000 --- a/spring-cloud/spring-cloud-gateway/gateway-service/pom.xml +++ /dev/null @@ -1,79 +0,0 @@ - - 4.0.0 - - gateway-service - 1.0.0-SNAPSHOT - jar - - Spring Cloud Gateway Service - - - com.baeldung.spring.cloud - spring-cloud-gateway - 1.0.0-SNAPSHOT - .. - - - - 2.0.0.M2 - - - - - org.springframework.boot - spring-boot-actuator - ${version} - - - org.springframework.boot - spring-boot-starter-webflux - ${version} - - - org.springframework.cloud - spring-cloud-gateway-core - ${version} - - - org.springframework.cloud - spring-cloud-starter-eureka - ${version} - - - org.hibernate - hibernate-validator-cdi - 6.0.2.Final - - - javax.validation - validation-api - 2.0.0.Final - - - io.projectreactor.ipc - reactor-netty - 0.7.0.M1 - - - - - - spring-snapshots - Spring Snapshots - https://repo.spring.io/snapshot - - true - - - - spring-milestones - Spring Milestones - https://repo.spring.io/milestone - - false - - - - - \ No newline at end of file diff --git a/spring-cloud/spring-cloud-gateway/pom.xml b/spring-cloud/spring-cloud-gateway/pom.xml index 5142b25400..90737f369d 100644 --- a/spring-cloud/spring-cloud-gateway/pom.xml +++ b/spring-cloud/spring-cloud-gateway/pom.xml @@ -4,13 +4,8 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - com.baeldung.spring.cloud spring-cloud-gateway - 1.0.0-SNAPSHOT - - gateway-service - - pom + jar Spring Cloud Gateway @@ -25,7 +20,61 @@ UTF-8 3.7.0 1.4.2.RELEASE + 2.0.0.M6 + + + + org.springframework.boot + spring-boot-actuator + ${version} + + + org.springframework.boot + spring-boot-starter-webflux + ${version} + + + org.springframework.cloud + spring-cloud-gateway-core + ${version} + + + + org.hibernate + hibernate-validator-cdi + 6.0.2.Final + + + javax.validation + validation-api + 2.0.0.Final + + + io.projectreactor.ipc + reactor-netty + 0.7.0.M1 + + + + + + spring-snapshots + Spring Snapshots + https://repo.spring.io/snapshot + + true + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + false + + + diff --git a/spring-cloud/spring-cloud-gateway/gateway-service/src/main/java/com/baeldung/spring/cloud/GatewayApplication.java b/spring-cloud/spring-cloud-gateway/src/main/java/com/baeldung/spring/cloud/GatewayApplication.java similarity index 100% rename from spring-cloud/spring-cloud-gateway/gateway-service/src/main/java/com/baeldung/spring/cloud/GatewayApplication.java rename to spring-cloud/spring-cloud-gateway/src/main/java/com/baeldung/spring/cloud/GatewayApplication.java diff --git a/spring-cloud/spring-cloud-gateway/gateway-service/src/main/resources/application.yml b/spring-cloud/spring-cloud-gateway/src/main/resources/application.yml similarity index 100% rename from spring-cloud/spring-cloud-gateway/gateway-service/src/main/resources/application.yml rename to spring-cloud/spring-cloud-gateway/src/main/resources/application.yml From 8af29e8df5729ae1d4b9c3eb3b3d306741427f2a Mon Sep 17 00:00:00 2001 From: Magdalena Krause Date: Fri, 16 Feb 2018 16:54:04 -0300 Subject: [PATCH 53/58] BAEL-1543: Logging to console instead of file. --- spring-batch/src/main/resources/logback.xml | 23 +++++---------------- 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/spring-batch/src/main/resources/logback.xml b/spring-batch/src/main/resources/logback.xml index dc9218caf3..b110d1c226 100644 --- a/spring-batch/src/main/resources/logback.xml +++ b/spring-batch/src/main/resources/logback.xml @@ -1,33 +1,20 @@ - - C:\Users\admin\Desktop\Baeldung\repo\magkrause\tutorials\spring-batch\src\main\resources\taskletsvschunks\logs.log - + + %d{yyyy-MM-dd HH:mm:ss} [%thread] %level %logger{35} - %msg%n - - - - - ${DEV_HOME}/archived/debug.%d{yyyy-MM-dd}.%i.log - - - 10MB - - - + - + - + \ No newline at end of file From 1372a565e2fba6a8a03e5fb427007fdb45488183 Mon Sep 17 00:00:00 2001 From: Alex Vargas Date: Fri, 16 Feb 2018 12:01:12 -0800 Subject: [PATCH 54/58] Adding solidity example file --- libraries/src/main/resources/Greeting.sol | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 libraries/src/main/resources/Greeting.sol diff --git a/libraries/src/main/resources/Greeting.sol b/libraries/src/main/resources/Greeting.sol new file mode 100644 index 0000000000..dde7b36cc3 --- /dev/null +++ b/libraries/src/main/resources/Greeting.sol @@ -0,0 +1,19 @@ +pragma solidity ^0.4.0; + +contract Greeting { + address creator; + string message; + + function Greeting(string _message) { + message = _message; + creator = msg.sender; + } + + function greet() constant returns (string) { + return message; + } + + function setGreeting(string _message) { + message = _message; + } +} \ No newline at end of file From 5d4bfa2e73e13eb0f889dbff1f42d8977aa38439 Mon Sep 17 00:00:00 2001 From: Eugen Paraschiv Date: Sat, 17 Feb 2018 01:02:20 +0200 Subject: [PATCH 55/58] renaming the DSL to configurer --- ...rorLoggingDsl.java => ClientErrorLoggingConfigurer.java} | 6 +++--- .../src/main/java/com/baeldung/dsl/SecurityConfig.java | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) rename spring-5-security/src/main/java/com/baeldung/dsl/{ClientErrorLoggingDsl.java => ClientErrorLoggingConfigurer.java} (76%) diff --git a/spring-5-security/src/main/java/com/baeldung/dsl/ClientErrorLoggingDsl.java b/spring-5-security/src/main/java/com/baeldung/dsl/ClientErrorLoggingConfigurer.java similarity index 76% rename from spring-5-security/src/main/java/com/baeldung/dsl/ClientErrorLoggingDsl.java rename to spring-5-security/src/main/java/com/baeldung/dsl/ClientErrorLoggingConfigurer.java index 6c7c0d2717..5a9479b664 100644 --- a/spring-5-security/src/main/java/com/baeldung/dsl/ClientErrorLoggingDsl.java +++ b/spring-5-security/src/main/java/com/baeldung/dsl/ClientErrorLoggingConfigurer.java @@ -7,15 +7,15 @@ import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; import org.springframework.security.web.access.intercept.FilterSecurityInterceptor; -public class ClientErrorLoggingDsl extends AbstractHttpConfigurer { +public class ClientErrorLoggingConfigurer extends AbstractHttpConfigurer { private List errorCodes; - public ClientErrorLoggingDsl(List errorCodes) { + public ClientErrorLoggingConfigurer(List errorCodes) { this.errorCodes = errorCodes; } - public ClientErrorLoggingDsl() { + public ClientErrorLoggingConfigurer() { } diff --git a/spring-5-security/src/main/java/com/baeldung/dsl/SecurityConfig.java b/spring-5-security/src/main/java/com/baeldung/dsl/SecurityConfig.java index 4494aaa131..382e222f64 100644 --- a/spring-5-security/src/main/java/com/baeldung/dsl/SecurityConfig.java +++ b/spring-5-security/src/main/java/com/baeldung/dsl/SecurityConfig.java @@ -25,8 +25,8 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { } @Bean - public ClientErrorLoggingDsl clientErrorLogging() { - return new ClientErrorLoggingDsl(); + public ClientErrorLoggingConfigurer clientErrorLogging() { + return new ClientErrorLoggingConfigurer(); } @Override From 414d805f6b854cc772a8232cba882eac4d3deae9 Mon Sep 17 00:00:00 2001 From: Eugen Paraschiv Date: Sat, 17 Feb 2018 01:03:29 +0200 Subject: [PATCH 56/58] renaming the DSL to configurer --- ...omDslApplication.java => CustomConfigurerApplication.java} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename spring-5-security/src/main/java/com/baeldung/dsl/{CustomDslApplication.java => CustomConfigurerApplication.java} (66%) diff --git a/spring-5-security/src/main/java/com/baeldung/dsl/CustomDslApplication.java b/spring-5-security/src/main/java/com/baeldung/dsl/CustomConfigurerApplication.java similarity index 66% rename from spring-5-security/src/main/java/com/baeldung/dsl/CustomDslApplication.java rename to spring-5-security/src/main/java/com/baeldung/dsl/CustomConfigurerApplication.java index 3e58bccaf4..2cd3d7fc7f 100644 --- a/spring-5-security/src/main/java/com/baeldung/dsl/CustomDslApplication.java +++ b/spring-5-security/src/main/java/com/baeldung/dsl/CustomConfigurerApplication.java @@ -4,10 +4,10 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication -public class CustomDslApplication { +public class CustomConfigurerApplication { public static void main(String[] args) { - SpringApplication.run(CustomDslApplication.class, args); + SpringApplication.run(CustomConfigurerApplication.class, args); } } From b219245e5b22110d555ec44b9db2da5c4d4ca12e Mon Sep 17 00:00:00 2001 From: Gurinder Singh Date: Sat, 17 Feb 2018 07:39:35 +0530 Subject: [PATCH 57/58] Gurinder spring cloud contract (#3547) * adding producer side sample for spring-cloud-contract * adding consumer side sample for spring-cloud-contract * removing un neccessary code * adding latest version for spring-cloud-contract in both producer and consumer * adding producer dependency in consumer * refactoring after review-1 * refactoring after review-2 * refactoring after review-3 --- spring-cloud/pom.xml | 3 +- spring-cloud/spring-cloud-contract/pom.xml | 23 ++++++ .../spring-cloud-contract-consumer/pom.xml | 68 +++++++++++++++++ ...pringCloudContractConsumerApplication.java | 18 +++++ .../controller/BasicMathController.java | 31 ++++++++ .../src/main/resources/application.yml | 0 .../BasicMathControllerIntegrationTest.java | 44 +++++++++++ .../spring-cloud-contract-producer/pom.xml | 74 +++++++++++++++++++ ...pringCloudContractProducerApplication.java | 11 +++ .../controller/EvenOddController.java | 15 ++++ .../src/main/resources/application.properties | 0 .../BaseTestClass.java | 29 ++++++++ ...uldReturnEvenWhenRequestParamIsEven.groovy | 17 +++++ ...houldReturnOddWhenRequestParamIsOdd.groovy | 17 +++++ 14 files changed, 349 insertions(+), 1 deletion(-) create mode 100644 spring-cloud/spring-cloud-contract/pom.xml create mode 100644 spring-cloud/spring-cloud-contract/spring-cloud-contract-consumer/pom.xml create mode 100644 spring-cloud/spring-cloud-contract/spring-cloud-contract-consumer/src/main/java/com/baeldung/spring/cloud/springcloudcontractconsumer/SpringCloudContractConsumerApplication.java create mode 100644 spring-cloud/spring-cloud-contract/spring-cloud-contract-consumer/src/main/java/com/baeldung/spring/cloud/springcloudcontractconsumer/controller/BasicMathController.java create mode 100644 spring-cloud/spring-cloud-contract/spring-cloud-contract-consumer/src/main/resources/application.yml create mode 100644 spring-cloud/spring-cloud-contract/spring-cloud-contract-consumer/src/test/java/com/baeldung/spring/cloud/springcloudcontractconsumer/controller/BasicMathControllerIntegrationTest.java create mode 100644 spring-cloud/spring-cloud-contract/spring-cloud-contract-producer/pom.xml create mode 100644 spring-cloud/spring-cloud-contract/spring-cloud-contract-producer/src/main/java/com/baeldung/spring/cloud/springcloudcontractproducer/SpringCloudContractProducerApplication.java create mode 100644 spring-cloud/spring-cloud-contract/spring-cloud-contract-producer/src/main/java/com/baeldung/spring/cloud/springcloudcontractproducer/controller/EvenOddController.java create mode 100644 spring-cloud/spring-cloud-contract/spring-cloud-contract-producer/src/main/resources/application.properties create mode 100644 spring-cloud/spring-cloud-contract/spring-cloud-contract-producer/src/test/java/com/baeldung/spring/cloud/springcloudcontractproducer/BaseTestClass.java create mode 100644 spring-cloud/spring-cloud-contract/spring-cloud-contract-producer/src/test/resources/contracts/shouldReturnEvenWhenRequestParamIsEven.groovy create mode 100644 spring-cloud/spring-cloud-contract/spring-cloud-contract-producer/src/test/resources/contracts/shouldReturnOddWhenRequestParamIsOdd.groovy diff --git a/spring-cloud/pom.xml b/spring-cloud/pom.xml index d94b334bc8..c093b87be3 100644 --- a/spring-cloud/pom.xml +++ b/spring-cloud/pom.xml @@ -21,7 +21,8 @@ spring-cloud-aws spring-cloud-consul spring-cloud-zuul-eureka-integration - + spring-cloud-contract + pom spring-cloud diff --git a/spring-cloud/spring-cloud-contract/pom.xml b/spring-cloud/spring-cloud-contract/pom.xml new file mode 100644 index 0000000000..3981aae2ac --- /dev/null +++ b/spring-cloud/spring-cloud-contract/pom.xml @@ -0,0 +1,23 @@ + + + 4.0.0 + + + com.baeldung.spring.cloud + spring-cloud + 1.0.0-SNAPSHOT + + + spring-cloud-contract-producer + spring-cloud-contract-consumer + + pom + + com.baeldung.spring.cloud + spring-cloud-contract + 1.0.0-SNAPSHOT + + + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-contract/spring-cloud-contract-consumer/pom.xml b/spring-cloud/spring-cloud-contract/spring-cloud-contract-consumer/pom.xml new file mode 100644 index 0000000000..67fea178eb --- /dev/null +++ b/spring-cloud/spring-cloud-contract/spring-cloud-contract-consumer/pom.xml @@ -0,0 +1,68 @@ + + + 4.0.0 + + com.baeldung.spring.cloud + spring-cloud-contract-consumer + 1.0.0-SNAPSHOT + jar + + spring-cloud-contract-consumer + Spring Cloud Consumer Sample + + + com.baeldung.spring.cloud + spring-cloud-contract + 1.0.0-SNAPSHOT + .. + + + + UTF-8 + UTF-8 + 1.8 + + + + + org.springframework.cloud + spring-cloud-contract-wiremock + 1.2.2.RELEASE + test + + + org.springframework.cloud + spring-cloud-contract-stub-runner + 1.2.2.RELEASE + test + + + org.springframework.boot + spring-boot-starter-web + 1.5.9.RELEASE + + + org.springframework.boot + spring-boot-starter-data-rest + 1.5.9.RELEASE + + + com.baeldung.spring.cloud + spring-cloud-contract-producer + 1.0.0-SNAPSHOT + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + diff --git a/spring-cloud/spring-cloud-contract/spring-cloud-contract-consumer/src/main/java/com/baeldung/spring/cloud/springcloudcontractconsumer/SpringCloudContractConsumerApplication.java b/spring-cloud/spring-cloud-contract/spring-cloud-contract-consumer/src/main/java/com/baeldung/spring/cloud/springcloudcontractconsumer/SpringCloudContractConsumerApplication.java new file mode 100644 index 0000000000..7383ae5afa --- /dev/null +++ b/spring-cloud/spring-cloud-contract/spring-cloud-contract-consumer/src/main/java/com/baeldung/spring/cloud/springcloudcontractconsumer/SpringCloudContractConsumerApplication.java @@ -0,0 +1,18 @@ +package com.baeldung.spring.cloud.springcloudcontractconsumer; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; +import org.springframework.web.client.RestTemplate; + +@SpringBootApplication +public class SpringCloudContractConsumerApplication { + public static void main(String[] args) { + SpringApplication.run(SpringCloudContractConsumerApplication.class, args); + } + + @Bean + RestTemplate restTemplate() { + return new RestTemplate(); + } +} diff --git a/spring-cloud/spring-cloud-contract/spring-cloud-contract-consumer/src/main/java/com/baeldung/spring/cloud/springcloudcontractconsumer/controller/BasicMathController.java b/spring-cloud/spring-cloud-contract/spring-cloud-contract-consumer/src/main/java/com/baeldung/spring/cloud/springcloudcontractconsumer/controller/BasicMathController.java new file mode 100644 index 0000000000..f164af89e6 --- /dev/null +++ b/spring-cloud/spring-cloud-contract/spring-cloud-contract-consumer/src/main/java/com/baeldung/spring/cloud/springcloudcontractconsumer/controller/BasicMathController.java @@ -0,0 +1,31 @@ +package com.baeldung.spring.cloud.springcloudcontractconsumer.controller; + + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.*; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.client.RestTemplate; + + +@RestController +public class BasicMathController { + + @Autowired + private RestTemplate restTemplate; + + @GetMapping("/calculate") + public String checkOddAndEven(@RequestParam("number") String number) { + HttpHeaders httpHeaders = new HttpHeaders(); + httpHeaders.add("Content-Type", "application/json"); + + ResponseEntity responseEntity = restTemplate.exchange( + "http://localhost:8090/validate/prime-number?number=" + number, + HttpMethod.GET, + new HttpEntity<>(httpHeaders), + String.class); + + return responseEntity.getBody(); + } +} diff --git a/spring-cloud/spring-cloud-contract/spring-cloud-contract-consumer/src/main/resources/application.yml b/spring-cloud/spring-cloud-contract/spring-cloud-contract-consumer/src/main/resources/application.yml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spring-cloud/spring-cloud-contract/spring-cloud-contract-consumer/src/test/java/com/baeldung/spring/cloud/springcloudcontractconsumer/controller/BasicMathControllerIntegrationTest.java b/spring-cloud/spring-cloud-contract/spring-cloud-contract-consumer/src/test/java/com/baeldung/spring/cloud/springcloudcontractconsumer/controller/BasicMathControllerIntegrationTest.java new file mode 100644 index 0000000000..5cf5c6d3b8 --- /dev/null +++ b/spring-cloud/spring-cloud-contract/spring-cloud-contract-consumer/src/test/java/com/baeldung/spring/cloud/springcloudcontractconsumer/controller/BasicMathControllerIntegrationTest.java @@ -0,0 +1,44 @@ +package com.baeldung.spring.cloud.springcloudcontractconsumer.controller; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.json.AutoConfigureJsonTesters; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.cloud.contract.stubrunner.spring.AutoConfigureStubRunner; +import org.springframework.http.MediaType; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; + +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK) +@AutoConfigureMockMvc +@AutoConfigureJsonTesters +@AutoConfigureStubRunner(workOffline = true, + ids = "com.baeldung.spring.cloud:spring-cloud-contract-producer:+:stubs:8090") +public class BasicMathControllerIntegrationTest { + + @Autowired + private MockMvc mockMvc; + + @Test + public void given_WhenPassEvenNumberInQueryParam_ThenReturnEven() throws Exception { + mockMvc.perform(MockMvcRequestBuilders.get("/calculate?number=2") + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(content().string("Even")); + } + + @Test + public void given_WhenPassOddNumberInQueryParam_ThenReturnOdd() throws Exception { + mockMvc.perform(MockMvcRequestBuilders.get("/calculate?number=1") + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(content().string("Odd")); + } +} diff --git a/spring-cloud/spring-cloud-contract/spring-cloud-contract-producer/pom.xml b/spring-cloud/spring-cloud-contract/spring-cloud-contract-producer/pom.xml new file mode 100644 index 0000000000..ac27dbb645 --- /dev/null +++ b/spring-cloud/spring-cloud-contract/spring-cloud-contract-producer/pom.xml @@ -0,0 +1,74 @@ + + + 4.0.0 + + com.baeldung.spring.cloud + spring-cloud-contract-producer + 1.0.0-SNAPSHOT + jar + + spring-cloud-contract-producer + Spring Cloud Producer Sample + + + com.baeldung.spring.cloud + spring-cloud-contract + 1.0.0-SNAPSHOT + .. + + + + UTF-8 + UTF-8 + 1.8 + Edgware.SR1 + + + + + org.springframework.cloud + spring-cloud-starter-contract-verifier + test + + + org.springframework.boot + spring-boot-starter-web + 1.5.9.RELEASE + + + org.springframework.boot + spring-boot-starter-data-rest + 1.5.9.RELEASE + + + + + + org.springframework.cloud + spring-cloud-contract-maven-plugin + 1.2.2.RELEASE + true + + com.baeldung.spring.cloud.springcloudcontractproducer.BaseTestClass + + + + + + + + + + + org.springframework.cloud + spring-cloud-dependencies + ${spring-cloud.version} + pom + import + + + + + + diff --git a/spring-cloud/spring-cloud-contract/spring-cloud-contract-producer/src/main/java/com/baeldung/spring/cloud/springcloudcontractproducer/SpringCloudContractProducerApplication.java b/spring-cloud/spring-cloud-contract/spring-cloud-contract-producer/src/main/java/com/baeldung/spring/cloud/springcloudcontractproducer/SpringCloudContractProducerApplication.java new file mode 100644 index 0000000000..770c68c817 --- /dev/null +++ b/spring-cloud/spring-cloud-contract/spring-cloud-contract-producer/src/main/java/com/baeldung/spring/cloud/springcloudcontractproducer/SpringCloudContractProducerApplication.java @@ -0,0 +1,11 @@ +package com.baeldung.spring.cloud.springcloudcontractproducer; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class SpringCloudContractProducerApplication { + public static void main(String[] args) { + SpringApplication.run(SpringCloudContractProducerApplication.class, args); + } +} diff --git a/spring-cloud/spring-cloud-contract/spring-cloud-contract-producer/src/main/java/com/baeldung/spring/cloud/springcloudcontractproducer/controller/EvenOddController.java b/spring-cloud/spring-cloud-contract/spring-cloud-contract-producer/src/main/java/com/baeldung/spring/cloud/springcloudcontractproducer/controller/EvenOddController.java new file mode 100644 index 0000000000..e61cc1120c --- /dev/null +++ b/spring-cloud/spring-cloud-contract/spring-cloud-contract-producer/src/main/java/com/baeldung/spring/cloud/springcloudcontractproducer/controller/EvenOddController.java @@ -0,0 +1,15 @@ +package com.baeldung.spring.cloud.springcloudcontractproducer.controller; + + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class EvenOddController { + + @GetMapping("/validate/prime-number") + public String isNumberPrime(@RequestParam("number") String number) { + return Integer.parseInt(number) % 2 == 0 ? "Even" : "Odd"; + } +} diff --git a/spring-cloud/spring-cloud-contract/spring-cloud-contract-producer/src/main/resources/application.properties b/spring-cloud/spring-cloud-contract/spring-cloud-contract-producer/src/main/resources/application.properties new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spring-cloud/spring-cloud-contract/spring-cloud-contract-producer/src/test/java/com/baeldung/spring/cloud/springcloudcontractproducer/BaseTestClass.java b/spring-cloud/spring-cloud-contract/spring-cloud-contract-producer/src/test/java/com/baeldung/spring/cloud/springcloudcontractproducer/BaseTestClass.java new file mode 100644 index 0000000000..253924b247 --- /dev/null +++ b/spring-cloud/spring-cloud-contract/spring-cloud-contract-producer/src/test/java/com/baeldung/spring/cloud/springcloudcontractproducer/BaseTestClass.java @@ -0,0 +1,29 @@ +package com.baeldung.spring.cloud.springcloudcontractproducer; + +import com.baeldung.spring.cloud.springcloudcontractproducer.controller.EvenOddController; +import io.restassured.module.mockmvc.RestAssuredMockMvc; +import org.junit.Before; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.cloud.contract.verifier.messaging.boot.AutoConfigureMessageVerifier; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.test.web.servlet.setup.StandaloneMockMvcBuilder; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK) +@DirtiesContext +@AutoConfigureMessageVerifier +public class BaseTestClass { + + @Autowired + private EvenOddController evenOddController; + + @Before + public void setup() { + StandaloneMockMvcBuilder standaloneMockMvcBuilder = MockMvcBuilders.standaloneSetup(evenOddController); + RestAssuredMockMvc.standaloneSetup(standaloneMockMvcBuilder); + } +} diff --git a/spring-cloud/spring-cloud-contract/spring-cloud-contract-producer/src/test/resources/contracts/shouldReturnEvenWhenRequestParamIsEven.groovy b/spring-cloud/spring-cloud-contract/spring-cloud-contract-producer/src/test/resources/contracts/shouldReturnEvenWhenRequestParamIsEven.groovy new file mode 100644 index 0000000000..78c36d7334 --- /dev/null +++ b/spring-cloud/spring-cloud-contract/spring-cloud-contract-producer/src/test/resources/contracts/shouldReturnEvenWhenRequestParamIsEven.groovy @@ -0,0 +1,17 @@ +import org.springframework.cloud.contract.spec.Contract + +Contract.make { + description "should return even when number input is even" + request { + method GET() + url("/validate/prime-number") { + queryParameters { + parameter("number", "2") + } + } + } + response { + body("Even") + status 200 + } +} \ No newline at end of file diff --git a/spring-cloud/spring-cloud-contract/spring-cloud-contract-producer/src/test/resources/contracts/shouldReturnOddWhenRequestParamIsOdd.groovy b/spring-cloud/spring-cloud-contract/spring-cloud-contract-producer/src/test/resources/contracts/shouldReturnOddWhenRequestParamIsOdd.groovy new file mode 100644 index 0000000000..215f987bbf --- /dev/null +++ b/spring-cloud/spring-cloud-contract/spring-cloud-contract-producer/src/test/resources/contracts/shouldReturnOddWhenRequestParamIsOdd.groovy @@ -0,0 +1,17 @@ +import org.springframework.cloud.contract.spec.Contract + +Contract.make { + description "should return odd when number input is odd" + request { + method GET() + url("/validate/prime-number") { + queryParameters { + parameter("number", "1") + } + } + } + response { + body("Odd") + status 200 + } +} \ No newline at end of file From 2a127b3df3e9225b5e8eab5d1bf1b124a7326fff Mon Sep 17 00:00:00 2001 From: Andrea Ligios Date: Sat, 17 Feb 2018 21:40:01 +0100 Subject: [PATCH 58/58] . (#3687) --- .../DecimalFormatExamplesTest.java | 116 ++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 core-java/src/test/java/com/baeldung/decimalformat/DecimalFormatExamplesTest.java diff --git a/core-java/src/test/java/com/baeldung/decimalformat/DecimalFormatExamplesTest.java b/core-java/src/test/java/com/baeldung/decimalformat/DecimalFormatExamplesTest.java new file mode 100644 index 0000000000..8acd4e023e --- /dev/null +++ b/core-java/src/test/java/com/baeldung/decimalformat/DecimalFormatExamplesTest.java @@ -0,0 +1,116 @@ +package com.baeldung.decimalformat; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.math.BigDecimal; +import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; +import java.text.NumberFormat; +import java.text.ParseException; +import java.util.Locale; + +import org.junit.Test; + +public class DecimalFormatExamplesTest { + + double d = 1234567.89; + + @Test + public void givenSimpleDecimal_WhenFormatting_ThenCorrectOutput() { + + assertThat(new DecimalFormat("#.##", new DecimalFormatSymbols(Locale.ENGLISH)).format(d)) + .isEqualTo("1234567.89"); + + assertThat(new DecimalFormat("0.00", new DecimalFormatSymbols(Locale.ENGLISH)).format(d)) + .isEqualTo("1234567.89"); + + assertThat(new DecimalFormat("#########.###", new DecimalFormatSymbols(Locale.ENGLISH)).format(d)) + .isEqualTo("1234567.89"); + + assertThat(new DecimalFormat("000000000.000", new DecimalFormatSymbols(Locale.ENGLISH)).format(d)) + .isEqualTo("001234567.890"); + + } + + @Test + public void givenSmallerDecimalPattern_WhenFormatting_ThenRounding() { + + assertThat(new DecimalFormat("#.#", new DecimalFormatSymbols(Locale.ENGLISH)).format(d)).isEqualTo("1234567.9"); + + assertThat(new DecimalFormat("#", new DecimalFormatSymbols(Locale.ENGLISH)).format(d)).isEqualTo("1234568"); + + } + + @Test + public void givenGroupingSeparator_WhenFormatting_ThenGroupedOutput() { + + assertThat(new DecimalFormat("#,###.#", new DecimalFormatSymbols(Locale.ENGLISH)).format(d)) + .isEqualTo("1,234,567.9"); + + assertThat(new DecimalFormat("#,###", new DecimalFormatSymbols(Locale.ENGLISH)).format(d)) + .isEqualTo("1,234,568"); + + } + + @Test + public void givenMixedPattern_WhenFormatting_ThenCorrectOutput() { + + assertThat(new DecimalFormat("The # number", new DecimalFormatSymbols(Locale.ENGLISH)).format(d)) + .isEqualTo("The 1234568 number"); + + assertThat(new DecimalFormat("The '#' # number", new DecimalFormatSymbols(Locale.ENGLISH)).format(d)) + .isEqualTo("The # 1234568 number"); + + } + + @Test + public void givenLocales_WhenFormatting_ThenCorrectOutput() { + + assertThat(new DecimalFormat("#,###.##", new DecimalFormatSymbols(Locale.ENGLISH)).format(d)) + .isEqualTo("1,234,567.89"); + + assertThat(new DecimalFormat("#,###.##", new DecimalFormatSymbols(Locale.ITALIAN)).format(d)) + .isEqualTo("1.234.567,89"); + + assertThat(new DecimalFormat("#,###.##", DecimalFormatSymbols.getInstance(new Locale("it", "IT"))).format(d)) + .isEqualTo("1.234.567,89"); + + } + + @Test + public void givenE_WhenFormatting_ThenScientificNotation() { + + assertThat(new DecimalFormat("00.#######E0", new DecimalFormatSymbols(Locale.ENGLISH)).format(d)) + .isEqualTo("12.3456789E5"); + + assertThat(new DecimalFormat("000.000000E0", new DecimalFormatSymbols(Locale.ENGLISH)).format(d)) + .isEqualTo("123.456789E4"); + + assertThat(new DecimalFormat("##0.######E0", new DecimalFormatSymbols(Locale.ENGLISH)).format(d)) + .isEqualTo("1.23456789E6"); + + assertThat(new DecimalFormat("###.000000E0", new DecimalFormatSymbols(Locale.ENGLISH)).format(d)) + .isEqualTo("1.23456789E6"); + + } + + @Test + public void givenString_WhenParsing_ThenCorrectOutput() throws ParseException { + + assertThat(new DecimalFormat("", new DecimalFormatSymbols(Locale.ENGLISH)).parse("1234567.89")) + .isEqualTo(1234567.89); + + assertThat(new DecimalFormat("", new DecimalFormatSymbols(Locale.ITALIAN)).parse("1.234.567,89")) + .isEqualTo(1234567.89); + + } + + @Test + public void givenStringAndBigDecimalFlag_WhenParsing_ThenCorrectOutput() throws ParseException { + + NumberFormat nf = new DecimalFormat("", new DecimalFormatSymbols(Locale.ENGLISH)); + ((DecimalFormat) nf).setParseBigDecimal(true); + assertThat(nf.parse("1234567.89")).isEqualTo(BigDecimal.valueOf(1234567.89)); + } + +}