diff --git a/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/CasSecuredAppApplication.java b/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/CasSecuredAppApplication.java
index fc05e3b38f..25cbb9bc9b 100644
--- a/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/CasSecuredAppApplication.java
+++ b/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/CasSecuredAppApplication.java
@@ -40,14 +40,14 @@ public class CasSecuredAppApplication {
@Primary
public AuthenticationEntryPoint authenticationEntryPoint(ServiceProperties sP) {
CasAuthenticationEntryPoint entryPoint = new CasAuthenticationEntryPoint();
- entryPoint.setLoginUrl("https://localhost:8443/cas/login");
+ entryPoint.setLoginUrl("https://localhost:6443/cas/login");
entryPoint.setServiceProperties(sP);
return entryPoint;
}
@Bean
public TicketValidator ticketValidator() {
- return new Cas30ServiceTicketValidator("https://localhost:8443/cas");
+ return new Cas30ServiceTicketValidator("https://localhost:6443/cas");
}
@Bean
@@ -71,7 +71,7 @@ public class CasSecuredAppApplication {
@Bean
public LogoutFilter logoutFilter() {
LogoutFilter logoutFilter = new LogoutFilter(
- "https://localhost:8443/cas/logout", securityContextLogoutHandler());
+ "https://localhost:6443/cas/logout", securityContextLogoutHandler());
logoutFilter.setFilterProcessesUrl("/logout/cas");
return logoutFilter;
}
@@ -79,7 +79,7 @@ public class CasSecuredAppApplication {
@Bean
public SingleSignOutFilter singleSignOutFilter() {
SingleSignOutFilter singleSignOutFilter = new SingleSignOutFilter();
- singleSignOutFilter.setCasServerUrlPrefix("https://localhost:8443/cas");
+ singleSignOutFilter.setCasServerUrlPrefix("https://localhost:6443/cas");
singleSignOutFilter.setIgnoreInitConfiguration(true);
return singleSignOutFilter;
}
diff --git a/cas/cas-server/etc/cas/thekeystore b/cas/cas-server/etc/cas/thekeystore
deleted file mode 100644
index 15f9af2dae..0000000000
Binary files a/cas/cas-server/etc/cas/thekeystore and /dev/null differ
diff --git a/cas/cas-server/etc/cas/thekeystore.crt b/cas/cas-server/etc/cas/thekeystore.crt
deleted file mode 100644
index 5c7543f0c6..0000000000
Binary files a/cas/cas-server/etc/cas/thekeystore.crt and /dev/null differ
diff --git a/cas/cas-server/src/main/resources/application.properties b/cas/cas-server/src/main/resources/application.properties
index 2d5e9a7277..afacd4cbc1 100644
--- a/cas/cas-server/src/main/resources/application.properties
+++ b/cas/cas-server/src/main/resources/application.properties
@@ -2,9 +2,9 @@
# CAS Server Context Configuration
#
server.context-path=/cas
-server.port=8443
+server.port=6443
-server.ssl.key-store=file:/etc/cas/thekeystore
+server.ssl.key-store=classpath:/etc/cas/thekeystore
server.ssl.key-store-password=changeit
server.ssl.key-password=changeit
# server.ssl.ciphers=
@@ -40,6 +40,12 @@ spring.http.encoding.charset=UTF-8
spring.http.encoding.enabled=true
spring.http.encoding.force=true
+##
+#CAS CONFIG LOCATION
+#
+cas.standalone.config=classpath:/etc/cas/config
+
+
##
# CAS Cloud Bus Configuration
#
@@ -82,6 +88,7 @@ spring.thymeleaf.mode=HTML
# CAS Log4j Configuration
#
# logging.config=file:/etc/cas/log4j2.xml
+
server.context-parameters.isLog4jAutoInitializationDisabled=true
##
@@ -104,9 +111,10 @@ cas.authn.jdbc.query[0].dialect=org.hibernate.dialect.MySQLDialect
cas.authn.jdbc.query[0].user=root
cas.authn.jdbc.query[0].password=
cas.authn.jdbc.query[0].ddlAuto=none
-cas.authn.jdbc.query[0].driverClass=com.mysql.jdbc.Driver
+#cas.authn.jdbc.query[0].driverClass=com.mysql.jdbc.Driver
+cas.authn.jdbc.query[0].driverClass=com.mysql.cj.jdbc.Driver
cas.authn.jdbc.query[0].fieldPassword=password
-cas.authn.jdbc.query[0].passwordEncoder.type=BCRYPT
+cas.authn.jdbc.query[0].passwordEncoder.type=NONE
##
diff --git a/cas/cas-server/src/main/resources/cas.properties b/cas/cas-server/src/main/resources/cas.properties
index be2babcd14..f80f22fc11 100644
--- a/cas/cas-server/src/main/resources/cas.properties
+++ b/cas/cas-server/src/main/resources/cas.properties
@@ -1,16 +1,15 @@
-cas.server.name: https://localhost:8443
-cas.server.prefix: https://localhost:8443/cas
+cas.server.name: https://localhost:6443
+cas.server.prefix: https://localhost:643/cas
cas.adminPagesSecurity.ip=127\.0\.0\.1
-logging.config: file:/etc/cas/config/log4j2.xml
-
cas.serviceRegistry.initFromJson=true
cas.serviceRegistry.config.location=classpath:/services
cas.authn.accept.users=
cas.authn.accept.name=
+
#CAS Database Authentication Property
# cas.authn.jdbc.query[0].healthQuery=
diff --git a/cas/cas-server/src/main/resources/etc/cas/config/application.yml b/cas/cas-server/src/main/resources/etc/cas/config/application.yml
new file mode 100644
index 0000000000..be1f7c3edd
--- /dev/null
+++ b/cas/cas-server/src/main/resources/etc/cas/config/application.yml
@@ -0,0 +1,2 @@
+info:
+ description: CAS Configuration
\ No newline at end of file
diff --git a/cas/cas-server/src/main/resources/etc/cas/config/cas.properties b/cas/cas-server/src/main/resources/etc/cas/config/cas.properties
new file mode 100644
index 0000000000..47a1477308
--- /dev/null
+++ b/cas/cas-server/src/main/resources/etc/cas/config/cas.properties
@@ -0,0 +1,7 @@
+cas.server.name: https://cas.example.org:8443
+cas.server.prefix: https://cas.example.org:8443/cas
+
+cas.adminPagesSecurity.ip=127\.0\.0\.1
+
+logging.config: file:/etc/cas/config/log4j2.xml
+# cas.serviceRegistry.config.location: classpath:/services
diff --git a/cas/cas-server/src/main/resources/etc/cas/config/log4j2.xml b/cas/cas-server/src/main/resources/etc/cas/config/log4j2.xml
new file mode 100644
index 0000000000..53b30b4228
--- /dev/null
+++ b/cas/cas-server/src/main/resources/etc/cas/config/log4j2.xml
@@ -0,0 +1,117 @@
+
+
+
+
+
+ .
+
+ warn
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/cas/cas-server/src/main/resources/etc/cas/thekeystore b/cas/cas-server/src/main/resources/etc/cas/thekeystore
new file mode 100644
index 0000000000..86170dff16
Binary files /dev/null and b/cas/cas-server/src/main/resources/etc/cas/thekeystore differ
diff --git a/cas/cas-server/src/main/resources/etc/cas/thekeystore.crt b/cas/cas-server/src/main/resources/etc/cas/thekeystore.crt
new file mode 100644
index 0000000000..5bd9d5baba
Binary files /dev/null and b/cas/cas-server/src/main/resources/etc/cas/thekeystore.crt differ
diff --git a/core-java-concurrency/src/main/java/com/baeldung/concurrent/executorservice/DelayedCallable.java b/core-java-concurrency/src/main/java/com/baeldung/concurrent/executorservice/DelayedCallable.java
index 2f0796b491..16d9aa4c9f 100644
--- a/core-java-concurrency/src/main/java/com/baeldung/concurrent/executorservice/DelayedCallable.java
+++ b/core-java-concurrency/src/main/java/com/baeldung/concurrent/executorservice/DelayedCallable.java
@@ -1,11 +1,18 @@
package com.baeldung.concurrent.executorservice;
import java.util.concurrent.Callable;
+import java.util.concurrent.CountDownLatch;
public class DelayedCallable implements Callable {
private String name;
private long period;
+ private CountDownLatch latch;
+
+ public DelayedCallable(String name, long period, CountDownLatch latch) {
+ this(name, period);
+ this.latch = latch;
+ }
public DelayedCallable(String name, long period) {
this.name = name;
@@ -16,9 +23,15 @@ public class DelayedCallable implements Callable {
try {
Thread.sleep(period);
+
+ if (latch != null) {
+ latch.countDown();
+ }
+
} catch (InterruptedException ex) {
// handle exception
ex.printStackTrace();
+ Thread.currentThread().interrupt();
}
return name;
diff --git a/core-java-concurrency/src/test/java/com/baeldung/concurrent/executorservice/WaitingForThreadsToFinishTest.java b/core-java-concurrency/src/test/java/com/baeldung/concurrent/executorservice/WaitingForThreadsToFinishTest.java
index 0f461909ea..17b71aa35b 100644
--- a/core-java-concurrency/src/test/java/com/baeldung/concurrent/executorservice/WaitingForThreadsToFinishTest.java
+++ b/core-java-concurrency/src/test/java/com/baeldung/concurrent/executorservice/WaitingForThreadsToFinishTest.java
@@ -9,22 +9,91 @@ import java.util.List;
import java.util.concurrent.*;
import static junit.framework.TestCase.assertTrue;
+import static org.junit.Assert.fail;
public class WaitingForThreadsToFinishTest {
private static final Logger LOG = LoggerFactory.getLogger(WaitingForThreadsToFinishTest.class);
private final static ExecutorService WORKER_THREAD_POOL = Executors.newFixedThreadPool(10);
+ public void awaitTerminationAfterShutdown(ExecutorService threadPool) {
+ threadPool.shutdown();
+ try {
+ if (!threadPool.awaitTermination(60, TimeUnit.SECONDS)) {
+ threadPool.shutdownNow();
+ }
+ } catch (InterruptedException ex) {
+ threadPool.shutdownNow();
+ Thread.currentThread().interrupt();
+ }
+ }
+
+ @Test
+ public void givenMultipleThreads_whenUsingCountDownLatch_thenMainShoudWaitForAllToFinish() {
+
+ ExecutorService WORKER_THREAD_POOL = Executors.newFixedThreadPool(10);
+
+ try {
+ long startTime = System.currentTimeMillis();
+
+ // create a CountDownLatch that waits for the 2 threads to finish
+ CountDownLatch latch = new CountDownLatch(2);
+
+ for (int i = 0; i < 2; i++) {
+ WORKER_THREAD_POOL.submit(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ Thread.sleep(1000);
+ latch.countDown();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ Thread.currentThread().interrupt();
+ }
+ }
+ });
+ }
+
+ // wait for the latch to be decremented by the two threads
+ latch.await();
+
+ long processingTime = System.currentTimeMillis() - startTime;
+ assertTrue(processingTime >= 1000);
+
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+
+ awaitTerminationAfterShutdown(WORKER_THREAD_POOL);
+ }
+
@Test
public void givenMultipleThreads_whenInvokeAll_thenMainThreadShouldWaitForAllToFinish() {
ExecutorService WORKER_THREAD_POOL = Executors.newFixedThreadPool(10);
- List> callables = Arrays.asList(new DelayedCallable("fast thread", 100), new DelayedCallable("slow thread", 3000));
-
+ List> callables = Arrays.asList(
+ new DelayedCallable("fast thread", 100),
+ new DelayedCallable("slow thread", 3000));
+
try {
long startProcessingTime = System.currentTimeMillis();
List> futures = WORKER_THREAD_POOL.invokeAll(callables);
+
+ awaitTerminationAfterShutdown(WORKER_THREAD_POOL);
+
+ try {
+ WORKER_THREAD_POOL.submit(new Callable() {
+ @Override
+ public String call() throws Exception {
+ fail("This thread should have been rejected !");
+ Thread.sleep(1000000);
+ return null;
+ }
+ });
+ } catch (RejectedExecutionException ex) {
+ //
+ }
long totalProcessingTime = System.currentTimeMillis() - startProcessingTime;
assertTrue(totalProcessingTime >= 3000);
@@ -39,9 +108,7 @@ public class WaitingForThreadsToFinishTest {
} catch (ExecutionException | InterruptedException ex) {
ex.printStackTrace();
- }
-
- WORKER_THREAD_POOL.shutdown();
+ }
}
@Test
@@ -49,14 +116,14 @@ public class WaitingForThreadsToFinishTest {
CompletionService service = new ExecutorCompletionService<>(WORKER_THREAD_POOL);
- List> callables = Arrays.asList(new DelayedCallable("fast thread", 100), new DelayedCallable("slow thread", 3000));
+ List> callables = Arrays.asList(
+ new DelayedCallable("fast thread", 100),
+ new DelayedCallable("slow thread", 3000));
for (Callable callable : callables) {
service.submit(callable);
}
- WORKER_THREAD_POOL.shutdown();
-
try {
long startProcessingTime = System.currentTimeMillis();
@@ -79,8 +146,9 @@ public class WaitingForThreadsToFinishTest {
} catch (ExecutionException | InterruptedException ex) {
ex.printStackTrace();
+ } finally {
+ awaitTerminationAfterShutdown(WORKER_THREAD_POOL);
}
-
}
@Test
@@ -142,6 +210,6 @@ public class WaitingForThreadsToFinishTest {
e.printStackTrace();
}
- WORKER_THREAD_POOL.shutdown();
+ awaitTerminationAfterShutdown(WORKER_THREAD_POOL);
}
}
diff --git a/core-java/pom.xml b/core-java/pom.xml
index bb3958f36c..cea5e9b3ec 100644
--- a/core-java/pom.xml
+++ b/core-java/pom.xml
@@ -249,7 +249,7 @@
**/*LongRunningUnitTest.java
**/*ManualTest.java
- true
+
diff --git a/core-java/src/main/java/com/baeldung/breakcontinue/BreakContinue.java b/core-java/src/main/java/com/baeldung/breakcontinue/BreakContinue.java
new file mode 100644
index 0000000000..ce85b487c1
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/breakcontinue/BreakContinue.java
@@ -0,0 +1,138 @@
+package com.baeldung.breakcontinue;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+/**
+ * @author Santosh
+ *
+ */
+public class BreakContinue {
+
+ public static int unlabeledBreak() {
+ String searchName = "Wilson";
+ int counter = 0;
+ List names = Arrays.asList("John", "Peter", "Robert", "Wilson", "Anthony", "Donald", "Richard");
+
+ for (String name : names) {
+ counter++;
+ if (name.equalsIgnoreCase(searchName)) {
+ break;
+ }
+ }
+
+ return counter;
+ }
+
+ public static int unlabeledBreakNestedLoops() {
+ String searchName = "Wilson";
+ int counter = 0;
+ Map> nameMap = new HashMap<>();
+ nameMap.put("Grade1", Arrays.asList("John", "Peter", "Robert", "Wilson"));
+ nameMap.put("Grade2", Arrays.asList("Anthony", "Donald", "Richard", "Arnold"));
+ nameMap.put("Grade3", Arrays.asList("Wilson", "Michael", "Stephen", "Ryan"));
+
+ Iterator>> iterator = nameMap.entrySet()
+ .iterator();
+ Entry> entry = null;
+ List names = null;
+ while (iterator.hasNext()) {
+ entry = iterator.next();
+ names = entry.getValue();
+ for (String name : names) {
+ if (name.equalsIgnoreCase(searchName)) {
+ counter++;
+ break;
+ }
+ }
+ }
+
+ return counter;
+ }
+
+ public static int labeledBreak() {
+ String searchName = "Wilson";
+ int counter = 0;
+ Map> nameMap = new HashMap<>();
+ nameMap.put("Grade1", Arrays.asList("John", "Peter", "Robert", "Wilson"));
+ nameMap.put("Grade2", Arrays.asList("Anthony", "Donald", "Richard", "Arnold"));
+ nameMap.put("Grade3", Arrays.asList("Wilson", "Michael", "Stephen", "Ryan"));
+
+ Iterator>> iterator = nameMap.entrySet()
+ .iterator();
+ Entry> entry = null;
+ List names = null;
+ compare:
+ while (iterator.hasNext()) {
+ entry = iterator.next();
+ names = entry.getValue();
+ for (String name : names) {
+ if (name.equalsIgnoreCase(searchName)) {
+ counter++;
+ break compare;
+ }
+ }
+ }
+
+ return counter;
+ }
+
+ public static int unlabeledContinue() {
+ String searchName = "Wilson";
+ int counter = 0;
+ Map> nameMap = new HashMap<>();
+ nameMap.put("Grade1", Arrays.asList("John", "Wilson", "Robert", "Wilson"));
+ nameMap.put("Grade2", Arrays.asList("Anthony", "Donald", "Wilson", "Arnold"));
+ nameMap.put("Grade3", Arrays.asList("Wilson", "Michael", "Wilson", "Ryan"));
+
+ Iterator>> iterator = nameMap.entrySet()
+ .iterator();
+ Entry> entry = null;
+ List names = null;
+ while (iterator.hasNext()) {
+ entry = iterator.next();
+ names = entry.getValue();
+ for (String name : names) {
+ if (!name.equalsIgnoreCase(searchName)) {
+ continue;
+ }
+
+ counter++;
+ }
+ }
+
+ return counter;
+ }
+
+ public static int labeledContinue() {
+ String searchName = "Wilson";
+ int counter = 0;
+ Map> nameMap = new HashMap<>();
+ nameMap.put("Grade1", Arrays.asList("John", "Wilson", "Robert", "Wilson"));
+ nameMap.put("Grade2", Arrays.asList("Anthony", "Donald", "Wilson", "Arnold"));
+ nameMap.put("Grade3", Arrays.asList("Wilson", "Michael", "Wilson", "Ryan"));
+
+ Iterator>> iterator = nameMap.entrySet()
+ .iterator();
+ Entry> entry = null;
+ List names = null;
+ compare:
+ while (iterator.hasNext()) {
+ entry = iterator.next();
+ names = entry.getValue();
+ for (String name : names) {
+ if (name.equalsIgnoreCase(searchName)) {
+ counter++;
+ continue compare;
+ }
+ }
+ }
+
+ return counter;
+ }
+
+}
diff --git a/core-java/src/test/java/com/baeldung/breakcontinue/BreakContinueTest.java b/core-java/src/test/java/com/baeldung/breakcontinue/BreakContinueTest.java
new file mode 100644
index 0000000000..1980497cd3
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/breakcontinue/BreakContinueTest.java
@@ -0,0 +1,39 @@
+package com.baeldung.breakcontinue;
+
+import static com.baeldung.breakcontinue.BreakContinue.labeledBreak;
+import static com.baeldung.breakcontinue.BreakContinue.labeledContinue;
+import static com.baeldung.breakcontinue.BreakContinue.unlabeledBreak;
+import static com.baeldung.breakcontinue.BreakContinue.unlabeledBreakNestedLoops;
+import static com.baeldung.breakcontinue.BreakContinue.unlabeledContinue;
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+public class BreakContinueTest {
+
+ @Test
+ public void whenUnlabeledBreak_ThenEqual() {
+ assertEquals(4, unlabeledBreak());
+ }
+
+ @Test
+ public void whenUnlabeledBreakNestedLoops_ThenEqual() {
+ assertEquals(2, unlabeledBreakNestedLoops());
+ }
+
+ @Test
+ public void whenLabeledBreak_ThenEqual() {
+ assertEquals(1, labeledBreak());
+ }
+
+ @Test
+ public void whenUnlabeledContinue_ThenEqual() {
+ assertEquals(5, unlabeledContinue());
+ }
+
+ @Test
+ public void whenLabeledContinue_ThenEqual() {
+ assertEquals(3, labeledContinue());
+ }
+
+}
diff --git a/core-kotlin/README.md b/core-kotlin/README.md
index 720187dc44..4b5f921f7b 100644
--- a/core-kotlin/README.md
+++ b/core-kotlin/README.md
@@ -15,5 +15,6 @@
- [Data Classes in Kotlin](http://www.baeldung.com/kotlin-data-classes)
- [Delegated Properties in Kotlin](http://www.baeldung.com/kotlin-delegated-properties)
- [Sealed Classes in Kotlin](http://www.baeldung.com/kotlin-sealed-classes)
+- [JUnit 5 for Kotlin Developers](http://www.baeldung.com/junit-5-kotlin)
diff --git a/guest/spring-mvc/README.md b/guest/spring-mvc/README.md
new file mode 100644
index 0000000000..9e5cd64a04
--- /dev/null
+++ b/guest/spring-mvc/README.md
@@ -0,0 +1,17 @@
+## Building
+
+To build the module, use Maven's `package` goal:
+
+```
+mvn clean package
+```
+
+## Running
+
+To run the application, use Spring Boot's `run` goal:
+
+```
+mvn spring-boot:run
+```
+
+The application will be accessible at [http://localhost:8080/](http://localhost:8080/)
diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/HibernateUtil.java b/hibernate5/src/main/java/com/baeldung/hibernate/HibernateUtil.java
index 91392bd454..0282673218 100644
--- a/hibernate5/src/main/java/com/baeldung/hibernate/HibernateUtil.java
+++ b/hibernate5/src/main/java/com/baeldung/hibernate/HibernateUtil.java
@@ -3,6 +3,7 @@ package com.baeldung.hibernate;
import com.baeldung.hibernate.pojo.Employee;
import com.baeldung.hibernate.pojo.EntityDescription;
import com.baeldung.hibernate.pojo.Phone;
+import com.baeldung.hibernate.pojo.TemporalValues;
import org.hibernate.SessionFactory;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.MetadataSources;
@@ -31,6 +32,7 @@ public class HibernateUtil {
metadataSources.addAnnotatedClass(Employee.class);
metadataSources.addAnnotatedClass(Phone.class);
metadataSources.addAnnotatedClass(EntityDescription.class);
+ metadataSources.addAnnotatedClass(TemporalValues.class);
Metadata metadata = metadataSources.buildMetadata();
return metadata.getSessionFactoryBuilder()
diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/pojo/TemporalValues.java b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/TemporalValues.java
new file mode 100644
index 0000000000..f3fe095cae
--- /dev/null
+++ b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/TemporalValues.java
@@ -0,0 +1,195 @@
+package com.baeldung.hibernate.pojo;
+
+import javax.persistence.*;
+import java.io.Serializable;
+import java.sql.Date;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.time.*;
+import java.util.Calendar;
+
+@Entity
+public class TemporalValues implements Serializable {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private long id;
+
+ @Basic
+ private java.sql.Date sqlDate;
+
+ @Basic
+ private java.sql.Time sqlTime;
+
+ @Basic
+ private java.sql.Timestamp sqlTimestamp;
+
+ @Basic
+ @Temporal(TemporalType.DATE)
+ private java.util.Date utilDate;
+
+ @Basic
+ @Temporal(TemporalType.TIME)
+ private java.util.Date utilTime;
+
+ @Basic
+ @Temporal(TemporalType.TIMESTAMP)
+ private java.util.Date utilTimestamp;
+
+ @Basic
+ @Temporal(TemporalType.DATE)
+ private java.util.Calendar calendarDate;
+
+ @Basic
+ @Temporal(TemporalType.TIMESTAMP)
+ private java.util.Calendar calendarTimestamp;
+
+ @Basic
+ private java.time.LocalDate localDate;
+
+ @Basic
+ private java.time.LocalTime localTime;
+
+ @Basic
+ private java.time.OffsetTime offsetTime;
+
+ @Basic
+ private java.time.Instant instant;
+
+ @Basic
+ private java.time.LocalDateTime localDateTime;
+
+ @Basic
+ private java.time.OffsetDateTime offsetDateTime;
+
+ @Basic
+ private java.time.ZonedDateTime zonedDateTime;
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public Date getSqlDate() {
+ return sqlDate;
+ }
+
+ public void setSqlDate(Date sqlDate) {
+ this.sqlDate = sqlDate;
+ }
+
+ public Time getSqlTime() {
+ return sqlTime;
+ }
+
+ public void setSqlTime(Time sqlTime) {
+ this.sqlTime = sqlTime;
+ }
+
+ public Timestamp getSqlTimestamp() {
+ return sqlTimestamp;
+ }
+
+ public void setSqlTimestamp(Timestamp sqlTimestamp) {
+ this.sqlTimestamp = sqlTimestamp;
+ }
+
+ public java.util.Date getUtilDate() {
+ return utilDate;
+ }
+
+ public void setUtilDate(java.util.Date utilDate) {
+ this.utilDate = utilDate;
+ }
+
+ public java.util.Date getUtilTime() {
+ return utilTime;
+ }
+
+ public void setUtilTime(java.util.Date utilTime) {
+ this.utilTime = utilTime;
+ }
+
+ public java.util.Date getUtilTimestamp() {
+ return utilTimestamp;
+ }
+
+ public void setUtilTimestamp(java.util.Date utilTimestamp) {
+ this.utilTimestamp = utilTimestamp;
+ }
+
+ public Calendar getCalendarDate() {
+ return calendarDate;
+ }
+
+ public void setCalendarDate(Calendar calendarDate) {
+ this.calendarDate = calendarDate;
+ }
+
+ public Calendar getCalendarTimestamp() {
+ return calendarTimestamp;
+ }
+
+ public void setCalendarTimestamp(Calendar calendarTimestamp) {
+ this.calendarTimestamp = calendarTimestamp;
+ }
+
+ public LocalDate getLocalDate() {
+ return localDate;
+ }
+
+ public void setLocalDate(LocalDate localDate) {
+ this.localDate = localDate;
+ }
+
+ public LocalTime getLocalTime() {
+ return localTime;
+ }
+
+ public void setLocalTime(LocalTime localTime) {
+ this.localTime = localTime;
+ }
+
+ public OffsetTime getOffsetTime() {
+ return offsetTime;
+ }
+
+ public void setOffsetTime(OffsetTime offsetTime) {
+ this.offsetTime = offsetTime;
+ }
+
+ public Instant getInstant() {
+ return instant;
+ }
+
+ public void setInstant(Instant instant) {
+ this.instant = instant;
+ }
+
+ public LocalDateTime getLocalDateTime() {
+ return localDateTime;
+ }
+
+ public void setLocalDateTime(LocalDateTime localDateTime) {
+ this.localDateTime = localDateTime;
+ }
+
+ public OffsetDateTime getOffsetDateTime() {
+ return offsetDateTime;
+ }
+
+ public void setOffsetDateTime(OffsetDateTime offsetDateTime) {
+ this.offsetDateTime = offsetDateTime;
+ }
+
+ public ZonedDateTime getZonedDateTime() {
+ return zonedDateTime;
+ }
+
+ public void setZonedDateTime(ZonedDateTime zonedDateTime) {
+ this.zonedDateTime = zonedDateTime;
+ }
+}
diff --git a/hibernate5/src/test/java/com/baeldung/hibernate/TemporalValuesTest.java b/hibernate5/src/test/java/com/baeldung/hibernate/TemporalValuesTest.java
new file mode 100644
index 0000000000..ec8afc8db2
--- /dev/null
+++ b/hibernate5/src/test/java/com/baeldung/hibernate/TemporalValuesTest.java
@@ -0,0 +1,126 @@
+package com.baeldung.hibernate;
+
+import com.baeldung.hibernate.pojo.TemporalValues;
+import org.hibernate.Session;
+import org.hibernate.Transaction;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.time.*;
+import java.util.Calendar;
+import java.util.TimeZone;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class TemporalValuesTest {
+
+ private Session session;
+
+ private Transaction transaction;
+
+ @Before
+ public void setUp() throws IOException {
+ session = HibernateUtil.getSessionFactory().withOptions()
+ .jdbcTimeZone(TimeZone.getTimeZone("UTC"))
+ .openSession();
+ transaction = session.beginTransaction();
+ session.createNativeQuery("delete from temporalvalues").executeUpdate();
+ }
+
+ @After
+ public void tearDown() {
+ transaction.rollback();
+ session.close();
+ }
+
+ @Test
+ public void givenEntity_whenMappingSqlTypes_thenTemporalIsSelectedAutomatically() {
+ TemporalValues temporalValues = new TemporalValues();
+ temporalValues.setSqlDate(java.sql.Date.valueOf("2017-11-15"));
+ temporalValues.setSqlTime(java.sql.Time.valueOf("15:30:14"));
+ temporalValues.setSqlTimestamp(java.sql.Timestamp.valueOf("2017-11-15 15:30:14.332"));
+
+ session.save(temporalValues);
+ session.flush();
+ session.clear();
+
+ temporalValues = session.get(TemporalValues.class, temporalValues.getId());
+ assertThat(temporalValues.getSqlDate()).isEqualTo(java.sql.Date.valueOf("2017-11-15"));
+ assertThat(temporalValues.getSqlTime()).isEqualTo(java.sql.Time.valueOf("15:30:14"));
+ assertThat(temporalValues.getSqlTimestamp()).isEqualTo(java.sql.Timestamp.valueOf("2017-11-15 15:30:14.332"));
+
+ }
+
+ @Test
+ public void givenEntity_whenMappingUtilDateType_thenTemporalIsSpecifiedExplicitly() throws Exception {
+ TemporalValues temporalValues = new TemporalValues();
+ temporalValues.setUtilDate(new SimpleDateFormat("yyyy-MM-dd").parse("2017-11-15"));
+ temporalValues.setUtilTime(new SimpleDateFormat("HH:mm:ss").parse("15:30:14"));
+ temporalValues.setUtilTimestamp(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").parse("2017-11-15 15:30:14.332"));
+
+ session.save(temporalValues);
+ session.flush();
+ session.clear();
+
+ temporalValues = session.get(TemporalValues.class, temporalValues.getId());
+ assertThat(temporalValues.getUtilDate()).isEqualTo(new SimpleDateFormat("yyyy-MM-dd").parse("2017-11-15"));
+ assertThat(temporalValues.getUtilTime()).isEqualTo(new SimpleDateFormat("HH:mm:ss").parse("15:30:14"));
+ assertThat(temporalValues.getUtilTimestamp()).isEqualTo(java.sql.Timestamp.valueOf("2017-11-15 15:30:14.332"));
+
+ }
+
+ @Test
+ public void givenEntity_whenMappingCalendarType_thenTemporalIsSpecifiedExplicitly() throws Exception {
+ TemporalValues temporalValues = new TemporalValues();
+
+ Calendar calendarDate = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
+ calendarDate.set(Calendar.YEAR, 2017);
+ calendarDate.set(Calendar.MONTH, 10);
+ calendarDate.set(Calendar.DAY_OF_MONTH, 15);
+ temporalValues.setCalendarDate(calendarDate);
+
+ Calendar calendarTimestamp = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
+ calendarTimestamp.setTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").parse("2017-11-15 15:30:14.322"));
+ temporalValues.setCalendarTimestamp(calendarTimestamp);
+
+ session.save(temporalValues);
+ session.flush();
+ session.clear();
+
+ temporalValues = session.get(TemporalValues.class, temporalValues.getId());
+ assertThat(temporalValues.getCalendarDate().getTime()).isEqualTo(new SimpleDateFormat("yyyy-MM-dd").parse("2017-11-15"));
+ assertThat(temporalValues.getCalendarTimestamp().getTime()).isEqualTo(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").parse("2017-11-15 15:30:14.322"));
+
+ }
+
+ @Test
+ public void givenEntity_whenMappingJavaTimeTypes_thenTemporalIsSelectedAutomatically() {
+ TemporalValues temporalValues = new TemporalValues();
+
+ temporalValues.setLocalDate(LocalDate.parse("2017-11-15"));
+ temporalValues.setLocalTime(LocalTime.parse("15:30:18"));
+ temporalValues.setOffsetTime(OffsetTime.parse("08:22:12+01:00"));
+ temporalValues.setInstant(Instant.parse("2017-11-15T08:22:12Z"));
+ temporalValues.setLocalDateTime(LocalDateTime.parse("2017-11-15T08:22:12"));
+ temporalValues.setOffsetDateTime(OffsetDateTime.parse("2017-11-15T08:22:12+01:00"));
+ temporalValues.setZonedDateTime(ZonedDateTime.parse("2017-11-15T08:22:12+01:00[Europe/Paris]"));
+
+ session.save(temporalValues);
+ session.flush();
+ session.clear();
+
+ temporalValues = session.get(TemporalValues.class, temporalValues.getId());
+ assertThat(temporalValues.getLocalDate()).isEqualTo(LocalDate.parse("2017-11-15"));
+ assertThat(temporalValues.getLocalTime()).isEqualTo(LocalTime.parse("15:30:18"));
+ assertThat(temporalValues.getOffsetTime()).isEqualTo(OffsetTime.parse("08:22:12+01:00"));
+ assertThat(temporalValues.getInstant()).isEqualTo(Instant.parse("2017-11-15T08:22:12Z"));
+ assertThat(temporalValues.getLocalDateTime()).isEqualTo(LocalDateTime.parse("2017-11-15T08:22:12"));
+ assertThat(temporalValues.getOffsetDateTime()).isEqualTo(OffsetDateTime.parse("2017-11-15T08:22:12+01:00"));
+ assertThat(temporalValues.getZonedDateTime()).isEqualTo(ZonedDateTime.parse("2017-11-15T08:22:12+01:00[Europe/Paris]"));
+
+ }
+
+}
diff --git a/junit5/pom.xml b/junit5/pom.xml
index b820d7b7bc..b8a7622b3d 100644
--- a/junit5/pom.xml
+++ b/junit5/pom.xml
@@ -29,6 +29,7 @@
3.6.0
2.19.1
4.12
+ 5.0.1.RELEASE
@@ -111,6 +112,17 @@
${junit4.version}
test
+
+ org.springframework
+ spring-test
+ ${spring.version}
+ test
+
+
+ org.springframework
+ spring-context
+ ${spring.version}
+
diff --git a/junit5/src/test/java/com/baeldung/junit5/spring/GreetingsSpringTest.java b/junit5/src/test/java/com/baeldung/junit5/spring/GreetingsSpringTest.java
new file mode 100644
index 0000000000..e7a8a1c1e7
--- /dev/null
+++ b/junit5/src/test/java/com/baeldung/junit5/spring/GreetingsSpringTest.java
@@ -0,0 +1,21 @@
+package com.baeldung.junit5.spring;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+
+import com.baeldung.junit5.Greetings;
+
+@ExtendWith(SpringExtension.class)
+@ContextConfiguration(classes = { SpringTestConfiguration.class })
+public class GreetingsSpringTest {
+
+ @Test
+ void whenCallingSayHello_thenReturnHello() {
+ assertTrue("Hello".equals(Greetings.sayHello()));
+ }
+
+}
diff --git a/junit5/src/test/java/com/baeldung/junit5/spring/SpringTestConfiguration.java b/junit5/src/test/java/com/baeldung/junit5/spring/SpringTestConfiguration.java
new file mode 100644
index 0000000000..7651b2bd41
--- /dev/null
+++ b/junit5/src/test/java/com/baeldung/junit5/spring/SpringTestConfiguration.java
@@ -0,0 +1,8 @@
+package com.baeldung.junit5.spring;
+
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class SpringTestConfiguration {
+
+}
diff --git a/libraries/src/test/java/com/baeldung/serenity/MemberStatusIntegrationTest.java b/libraries/src/test/java/com/baeldung/serenity/MemberStatusIntegrationTest.java
index 18488f9380..e95b63aa96 100644
--- a/libraries/src/test/java/com/baeldung/serenity/MemberStatusIntegrationTest.java
+++ b/libraries/src/test/java/com/baeldung/serenity/MemberStatusIntegrationTest.java
@@ -51,7 +51,6 @@ public class MemberStatusIntegrationTest {
/**
* This test should fail, comment out @Ignore to see how failed test can be reflected in Serenity report.
- * Remember to add <testFailureIgnore>true</testFailureIgnore> under maven-surefire-plugin configuration.
*/
@Test
@Ignore
diff --git a/log4j/pom.xml b/log4j/pom.xml
index 2e73baac49..20906c4c05 100644
--- a/log4j/pom.xml
+++ b/log4j/pom.xml
@@ -26,12 +26,6 @@
${log4j.version}
-
- log4j
- apache-log4j-extras
- ${log4j.version}
-
-
org.apache.logging.log4j
diff --git a/mustache/pom.xml b/mustache/pom.xml
index 8aab038313..230aeecd60 100644
--- a/mustache/pom.xml
+++ b/mustache/pom.xml
@@ -85,7 +85,6 @@
**/JdbcTest.java
**/*LiveTest.java
- true
diff --git a/parent-boot-4/pom.xml b/parent-boot-4/pom.xml
index 2af36e9365..608e57ddaf 100644
--- a/parent-boot-4/pom.xml
+++ b/parent-boot-4/pom.xml
@@ -63,7 +63,7 @@
**/JdbcTest.java
**/*LiveTest.java
- true
+
diff --git a/parent-boot-5/pom.xml b/parent-boot-5/pom.xml
index 57e9ed3c67..2fa397f298 100644
--- a/parent-boot-5/pom.xml
+++ b/parent-boot-5/pom.xml
@@ -65,7 +65,6 @@
**/*EntryPointsTest.java
**/*LiveTest.java
- true
diff --git a/pom.xml b/pom.xml
index 9aa45b1d5d..bc8e35ba94 100644
--- a/pom.xml
+++ b/pom.xml
@@ -149,6 +149,7 @@
spring-batch
spring-bom
spring-boot
+ spring-boot-keycloak
spring-boot-bootstrap
spring-cloud-data-flow
spring-cloud
@@ -230,6 +231,8 @@
spring-zuul
spring-reactor
spring-vertx
+
+ spring-rest-embedded-tomcat
testing
@@ -339,7 +342,7 @@
**/JdbcTest.java
**/*LiveTest.java
- true
+
diff --git a/selenium-junit-testng/pom.xml b/selenium-junit-testng/pom.xml
index 5b695ca900..faad194b59 100644
--- a/selenium-junit-testng/pom.xml
+++ b/selenium-junit-testng/pom.xml
@@ -27,7 +27,6 @@
**/*LiveTest.java
- false
diff --git a/spring-5-mvc/pom.xml b/spring-5-mvc/pom.xml
index 7b7ddcba88..b188ee590a 100644
--- a/spring-5-mvc/pom.xml
+++ b/spring-5-mvc/pom.xml
@@ -152,7 +152,7 @@
org.apache.maven.plugins
maven-surefire-plugin
- true
+
false
**/*IntegrationTest.java
diff --git a/spring-activiti/pom.xml b/spring-activiti/pom.xml
index c5289b20a6..92d9618b65 100644
--- a/spring-activiti/pom.xml
+++ b/spring-activiti/pom.xml
@@ -19,9 +19,11 @@
+ com.example.activitiwithspring.ActivitiWithSpringApplication
UTF-8
UTF-8
1.8
+ 6.0.0
@@ -30,9 +32,14 @@
activiti-spring-boot-starter-basic
6.0.0
+
+ org.activiti
+ activiti-spring-boot-starter-security
+ ${activiti.version}
+
org.springframework.boot
- spring-boot-starter-web
+ spring-boot-starter-thymeleaf
@@ -67,7 +74,7 @@
**/JdbcTest.java
**/*LiveTest.java
- true
+
diff --git a/spring-activiti/src/main/java/com/baeldung/activiti/security.rar b/spring-activiti/src/main/java/com/baeldung/activiti/security.rar
new file mode 100644
index 0000000000..38c4946168
Binary files /dev/null and b/spring-activiti/src/main/java/com/baeldung/activiti/security.rar differ
diff --git a/spring-activiti/src/main/java/com/baeldung/activiti/security/config/MvcConfig.java b/spring-activiti/src/main/java/com/baeldung/activiti/security/config/MvcConfig.java
new file mode 100644
index 0000000000..f9394742cd
--- /dev/null
+++ b/spring-activiti/src/main/java/com/baeldung/activiti/security/config/MvcConfig.java
@@ -0,0 +1,20 @@
+package com.baeldung.activiti.security.config;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.EnableWebMvc;
+import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
+
+@Configuration
+@EnableWebMvc
+public class MvcConfig extends WebMvcConfigurerAdapter {
+
+ @Override
+ public void addViewControllers(ViewControllerRegistry registry) {
+ registry.addViewController("/login")
+ .setViewName("login");
+ registry.addViewController("/homepage")
+ .setViewName("homepage");
+ }
+
+}
diff --git a/spring-activiti/src/main/java/com/baeldung/activiti/security/config/ProcessController.java b/spring-activiti/src/main/java/com/baeldung/activiti/security/config/ProcessController.java
new file mode 100644
index 0000000000..671b246328
--- /dev/null
+++ b/spring-activiti/src/main/java/com/baeldung/activiti/security/config/ProcessController.java
@@ -0,0 +1,54 @@
+package com.baeldung.activiti.security.config;
+
+import java.util.List;
+
+import org.activiti.engine.IdentityService;
+import org.activiti.engine.RuntimeService;
+import org.activiti.engine.TaskService;
+import org.activiti.engine.runtime.ProcessInstance;
+import org.activiti.engine.task.Task;
+import org.activiti.spring.SpringProcessEngineConfiguration;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+public class ProcessController {
+
+ @Autowired
+ private RuntimeService runtimeService;
+
+ @Autowired
+ private TaskService taskService;
+
+ @Autowired
+ private IdentityService identityService;
+
+ @Autowired
+ SpringProcessEngineConfiguration config;
+
+ @GetMapping("/protected-process")
+ public String startProcess() {
+
+ String userId = SecurityContextHolder.getContext()
+ .getAuthentication()
+ .getName();
+
+ identityService.setAuthenticatedUserId(userId);
+
+ ProcessInstance pi = runtimeService.startProcessInstanceByKey("protected-process");
+
+ List usertasks = taskService.createTaskQuery()
+ .processInstanceId(pi.getId())
+ .list();
+
+ taskService.complete(usertasks.iterator()
+ .next()
+ .getId());
+
+ return "Process started. Number of currently running process instances = " + runtimeService.createProcessInstanceQuery()
+ .count();
+ }
+
+}
diff --git a/spring-activiti/src/main/java/com/baeldung/activiti/security/config/SpringSecurityGroupManager.java b/spring-activiti/src/main/java/com/baeldung/activiti/security/config/SpringSecurityGroupManager.java
new file mode 100644
index 0000000000..00fc674e22
--- /dev/null
+++ b/spring-activiti/src/main/java/com/baeldung/activiti/security/config/SpringSecurityGroupManager.java
@@ -0,0 +1,86 @@
+package com.baeldung.activiti.security.config;
+
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import org.activiti.engine.identity.Group;
+import org.activiti.engine.identity.GroupQuery;
+import org.activiti.engine.impl.GroupQueryImpl;
+import org.activiti.engine.impl.Page;
+import org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl;
+import org.activiti.engine.impl.persistence.entity.GroupEntityImpl;
+import org.activiti.engine.impl.persistence.entity.GroupEntityManagerImpl;
+import org.activiti.engine.impl.persistence.entity.data.GroupDataManager;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.provisioning.JdbcUserDetailsManager;
+
+public class SpringSecurityGroupManager extends GroupEntityManagerImpl {
+
+ private JdbcUserDetailsManager userManager;
+
+ public SpringSecurityGroupManager(ProcessEngineConfigurationImpl processEngineConfiguration, GroupDataManager groupDataManager) {
+ super(processEngineConfiguration, groupDataManager);
+ }
+
+ @Override
+ public List findGroupByQueryCriteria(GroupQueryImpl query, Page page) {
+
+ if (query.getUserId() != null) {
+ return findGroupsByUser(query.getUserId());
+ }
+ return null;
+ }
+
+ @Override
+ public long findGroupCountByQueryCriteria(GroupQueryImpl query) {
+ return findGroupByQueryCriteria(query, null).size();
+ }
+
+ @Override
+ public List findGroupsByUser(String userId) {
+ UserDetails userDetails = userManager.loadUserByUsername(userId);
+ System.out.println("group manager");
+ if (userDetails != null) {
+ List groups = userDetails.getAuthorities()
+ .stream()
+ .map(a -> a.getAuthority())
+ .map(a -> {
+ Group g = new GroupEntityImpl();
+ g.setId(a);
+ return g;
+ })
+ .collect(Collectors.toList());
+ return groups;
+ }
+ return null;
+ }
+
+ public void setUserManager(JdbcUserDetailsManager userManager) {
+ this.userManager = userManager;
+ }
+
+ public Group createNewGroup(String groupId) {
+ throw new UnsupportedOperationException("This operation is not supported!");
+
+ }
+
+ @Override
+ public void delete(String groupId) {
+ throw new UnsupportedOperationException("This operation is not supported!");
+
+ }
+
+ public GroupQuery createNewGroupQuery() {
+ throw new UnsupportedOperationException("This operation is not supported!");
+ }
+
+ public List findGroupsByNativeQuery(Map parameterMap, int firstResult, int maxResults) {
+ throw new UnsupportedOperationException("This operation is not supported!");
+ }
+
+ public long findGroupCountByNativeQuery(Map parameterMap) {
+ throw new UnsupportedOperationException("This operation is not supported!");
+ }
+
+}
diff --git a/spring-activiti/src/main/java/com/baeldung/activiti/security/config/SpringSecurityUserManager.java b/spring-activiti/src/main/java/com/baeldung/activiti/security/config/SpringSecurityUserManager.java
new file mode 100644
index 0000000000..ce9863eb6c
--- /dev/null
+++ b/spring-activiti/src/main/java/com/baeldung/activiti/security/config/SpringSecurityUserManager.java
@@ -0,0 +1,144 @@
+package com.baeldung.activiti.security.config;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import org.activiti.engine.identity.Group;
+import org.activiti.engine.identity.User;
+import org.activiti.engine.identity.UserQuery;
+import org.activiti.engine.impl.Page;
+import org.activiti.engine.impl.UserQueryImpl;
+import org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl;
+import org.activiti.engine.impl.persistence.entity.GroupEntityImpl;
+import org.activiti.engine.impl.persistence.entity.UserEntity;
+import org.activiti.engine.impl.persistence.entity.UserEntityImpl;
+import org.activiti.engine.impl.persistence.entity.UserEntityManagerImpl;
+import org.activiti.engine.impl.persistence.entity.data.UserDataManager;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.provisioning.JdbcUserDetailsManager;
+
+public class SpringSecurityUserManager extends UserEntityManagerImpl {
+
+ private JdbcUserDetailsManager userManager;
+
+ public SpringSecurityUserManager(ProcessEngineConfigurationImpl processEngineConfiguration, UserDataManager userDataManager, JdbcUserDetailsManager userManager) {
+ super(processEngineConfiguration, userDataManager);
+ this.userManager = userManager;
+ }
+
+ @Override
+ public UserEntity findById(String userId) {
+ UserDetails userDetails = userManager.loadUserByUsername(userId);
+ if (userDetails != null) {
+ UserEntityImpl user = new UserEntityImpl();
+ user.setId(userId);
+ return user;
+ }
+ return null;
+
+ }
+
+ @Override
+ public List findUserByQueryCriteria(UserQueryImpl query, Page page) {
+ List users = null;
+ if (query.getGroupId() != null) {
+ users = userManager.findUsersInGroup(query.getGroupId())
+ .stream()
+ .map(username -> {
+ User user = new UserEntityImpl();
+ user.setId(username);
+ return user;
+ })
+ .collect(Collectors.toList());
+ if (page != null) {
+ return users.subList(page.getFirstResult(), page.getFirstResult() + page.getMaxResults());
+
+ }
+ return users;
+ }
+
+ if (query.getId() != null) {
+ UserDetails userDetails = userManager.loadUserByUsername(query.getId());
+ if (userDetails != null) {
+ UserEntityImpl user = new UserEntityImpl();
+ user.setId(query.getId());
+ return Collections.singletonList(user);
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public Boolean checkPassword(String userId, String password) {
+ return true;
+ }
+
+ public void setUserManager(JdbcUserDetailsManager userManager) {
+ this.userManager = userManager;
+ }
+
+ public User createNewUser(String userId) {
+ throw new UnsupportedOperationException("This operation is not supported!");
+ }
+
+ public void updateUser(User updatedUser) {
+ throw new UnsupportedOperationException("This operation is not supported!");
+
+ }
+
+ public void delete(UserEntity userEntity) {
+ throw new UnsupportedOperationException("This operation is not supported!");
+
+ }
+
+ @Override
+ public void deletePicture(User user) {
+ UserEntity userEntity = (UserEntity) user;
+ if (userEntity.getPictureByteArrayRef() != null) {
+ userEntity.getPictureByteArrayRef()
+ .delete();
+ }
+ }
+
+ public void delete(String userId) {
+ throw new UnsupportedOperationException("This operation is not supported!");
+
+ }
+
+ public long findUserCountByQueryCriteria(UserQueryImpl query) {
+ return findUserByQueryCriteria(query, null).size();
+ }
+
+ public List findGroupsByUser(String userId) {
+ UserDetails userDetails = userManager.loadUserByUsername(userId);
+ if (userDetails != null) {
+ List groups = userDetails.getAuthorities()
+ .stream()
+ .map(a -> a.getAuthority())
+ .map(a -> {
+ Group g = new GroupEntityImpl();
+ g.setId(a);
+ return g;
+ })
+ .collect(Collectors.toList());
+ return groups;
+ }
+ return null;
+ }
+
+ public UserQuery createNewUserQuery() {
+ throw new UnsupportedOperationException("This operation is not supported!");
+ }
+
+ public List findUsersByNativeQuery(Map parameterMap, int firstResult, int maxResults) {
+ throw new UnsupportedOperationException("This operation is not supported!");
+ }
+
+ public long findUserCountByNativeQuery(Map parameterMap) {
+ throw new UnsupportedOperationException("This operation is not supported!");
+
+ }
+
+}
diff --git a/spring-activiti/src/main/java/com/baeldung/activiti/security/withactiviti/SecurityConfig.java b/spring-activiti/src/main/java/com/baeldung/activiti/security/withactiviti/SecurityConfig.java
new file mode 100644
index 0000000000..f471600553
--- /dev/null
+++ b/spring-activiti/src/main/java/com/baeldung/activiti/security/withactiviti/SecurityConfig.java
@@ -0,0 +1,47 @@
+package com.baeldung.activiti.security.withactiviti;
+
+import org.activiti.engine.IdentityService;
+import org.activiti.spring.security.IdentityServiceUserDetailsService;
+import org.springframework.beans.factory.annotation.Autowired;
+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;
+
+@Configuration
+public class SecurityConfig extends WebSecurityConfigurerAdapter {
+
+ protected void configure(HttpSecurity http) throws Exception {
+ http.antMatcher("/**")
+ .authorizeRequests()
+ .antMatchers("/protected-process*")
+ .authenticated()
+ .anyRequest()
+ .permitAll()
+ .and()
+ .formLogin()
+ .loginPage("/login")
+ .defaultSuccessUrl("/homepage")
+ .failureUrl("/login?error=true")
+ .and()
+ .csrf()
+ .disable()
+ .logout()
+ .logoutSuccessUrl("/login");
+ }
+
+ @Autowired
+ private IdentityService identityService;
+
+ @Bean
+ public IdentityServiceUserDetailsService userDetailsService() {
+ return new IdentityServiceUserDetailsService(identityService);
+ }
+
+ @Autowired
+ public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
+ auth.userDetailsService(userDetailsService());
+ }
+
+}
diff --git a/spring-activiti/src/main/java/com/baeldung/activiti/security/withactiviti/SpringSecurityActivitiApplication.java b/spring-activiti/src/main/java/com/baeldung/activiti/security/withactiviti/SpringSecurityActivitiApplication.java
new file mode 100644
index 0000000000..2270a4d684
--- /dev/null
+++ b/spring-activiti/src/main/java/com/baeldung/activiti/security/withactiviti/SpringSecurityActivitiApplication.java
@@ -0,0 +1,34 @@
+package com.baeldung.activiti.security.withactiviti;
+
+import org.activiti.engine.IdentityService;
+import org.activiti.engine.identity.Group;
+import org.activiti.engine.identity.User;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.Bean;
+
+@SpringBootApplication(scanBasePackages = { "com.baeldung.activiti.security.config", "com.baeldung.activiti.security.withactiviti" })
+public class SpringSecurityActivitiApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(SpringSecurityActivitiApplication.class, args);
+ }
+
+ @Bean
+ InitializingBean usersAndGroupsInitializer(IdentityService identityService) {
+ return new InitializingBean() {
+ public void afterPropertiesSet() throws Exception {
+ User user = identityService.newUser("activiti_user");
+ user.setPassword("pass");
+ identityService.saveUser(user);
+
+ Group group = identityService.newGroup("user");
+ group.setName("ROLE_USER");
+ group.setType("USER");
+ identityService.saveGroup(group);
+ identityService.createMembership(user.getId(), group.getId());
+ }
+ };
+ }
+}
diff --git a/spring-activiti/src/main/java/com/baeldung/activiti/security/withspring/ActivitiSpringSecurityApplication.java b/spring-activiti/src/main/java/com/baeldung/activiti/security/withspring/ActivitiSpringSecurityApplication.java
new file mode 100644
index 0000000000..5878a5d678
--- /dev/null
+++ b/spring-activiti/src/main/java/com/baeldung/activiti/security/withspring/ActivitiSpringSecurityApplication.java
@@ -0,0 +1,39 @@
+package com.baeldung.activiti.security.withspring;
+
+import org.activiti.engine.impl.persistence.entity.data.impl.MybatisGroupDataManager;
+import org.activiti.engine.impl.persistence.entity.data.impl.MybatisUserDataManager;
+import org.activiti.spring.SpringProcessEngineConfiguration;
+import org.activiti.spring.boot.SecurityAutoConfiguration;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.Bean;
+import org.springframework.security.provisioning.JdbcUserDetailsManager;
+
+import com.baeldung.activiti.security.config.SpringSecurityGroupManager;
+import com.baeldung.activiti.security.config.SpringSecurityUserManager;
+
+@SpringBootApplication(exclude = SecurityAutoConfiguration.class, scanBasePackages = { "com.baeldung.activiti.security.config", "com.baeldung.activiti.security.withspring" })
+public class ActivitiSpringSecurityApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(ActivitiSpringSecurityApplication.class, args);
+ }
+
+ @Autowired
+ private SpringProcessEngineConfiguration processEngineConfiguration;
+
+ @Autowired
+ private JdbcUserDetailsManager userManager;
+
+ @Bean
+ InitializingBean processEngineInitializer() {
+ return new InitializingBean() {
+ public void afterPropertiesSet() throws Exception {
+ processEngineConfiguration.setUserEntityManager(new SpringSecurityUserManager(processEngineConfiguration, new MybatisUserDataManager(processEngineConfiguration), userManager));
+ processEngineConfiguration.setGroupEntityManager(new SpringSecurityGroupManager(processEngineConfiguration, new MybatisGroupDataManager(processEngineConfiguration)));
+ }
+ };
+ }
+}
diff --git a/spring-activiti/src/main/java/com/baeldung/activiti/security/withspring/SecurityConfig.java b/spring-activiti/src/main/java/com/baeldung/activiti/security/withspring/SecurityConfig.java
new file mode 100644
index 0000000000..df1991c3e4
--- /dev/null
+++ b/spring-activiti/src/main/java/com/baeldung/activiti/security/withspring/SecurityConfig.java
@@ -0,0 +1,50 @@
+package com.baeldung.activiti.security.withspring;
+
+import javax.sql.DataSource;
+
+import org.springframework.beans.factory.annotation.Autowired;
+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.provisioning.JdbcUserDetailsManager;
+
+@Configuration
+public class SecurityConfig extends WebSecurityConfigurerAdapter {
+
+ @Autowired
+ private DataSource dataSource;
+
+ protected void configure(HttpSecurity http) throws Exception {
+ http.antMatcher("/**")
+ .authorizeRequests()
+ .antMatchers("/protected-process*")
+ .authenticated()
+ .anyRequest()
+ .permitAll()
+ .and()
+ .formLogin()
+ .loginPage("/login")
+ .defaultSuccessUrl("/homepage")
+ .failureUrl("/login?error=true")
+ .and()
+ .csrf()
+ .disable()
+ .logout()
+ .logoutSuccessUrl("/login");
+ }
+
+ @Bean
+ public JdbcUserDetailsManager userDetailsManager() {
+ JdbcUserDetailsManager manager = new JdbcUserDetailsManager();
+ manager.setDataSource(dataSource);
+ return manager;
+ }
+
+ @Autowired
+ public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
+ auth.userDetailsService(userDetailsManager());
+ }
+
+}
diff --git a/spring-activiti/src/main/resources/data.sql b/spring-activiti/src/main/resources/data.sql
new file mode 100644
index 0000000000..cb9b72617a
--- /dev/null
+++ b/spring-activiti/src/main/resources/data.sql
@@ -0,0 +1,3 @@
+insert into users(username, password, enabled) values ('spring_user', 'pass', true);
+
+insert into authorities(username, authority) values ('spring_user','ROLE_USER');
\ No newline at end of file
diff --git a/spring-activiti/src/main/resources/processes/protected-process.bpmn20.xml b/spring-activiti/src/main/resources/processes/protected-process.bpmn20.xml
new file mode 100644
index 0000000000..b7e04515cd
--- /dev/null
+++ b/spring-activiti/src/main/resources/processes/protected-process.bpmn20.xml
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+ ROLE_USER
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-activiti/src/main/resources/schema.sql b/spring-activiti/src/main/resources/schema.sql
new file mode 100644
index 0000000000..bf882895fd
--- /dev/null
+++ b/spring-activiti/src/main/resources/schema.sql
@@ -0,0 +1,3 @@
+create table users(username varchar(255), password varchar(255), enabled boolean);
+
+create table authorities(username varchar(255),authority varchar(255));
\ No newline at end of file
diff --git a/spring-activiti/src/main/resources/templates/login.html b/spring-activiti/src/main/resources/templates/login.html
new file mode 100644
index 0000000000..53077fd5f3
--- /dev/null
+++ b/spring-activiti/src/main/resources/templates/login.html
@@ -0,0 +1,21 @@
+
+
+
+ Login
+
+
+
\ No newline at end of file
diff --git a/spring-activiti/src/test/java/com/example/activitiwithspring/ActivitiSpringSecurityIntegrationTest.java b/spring-activiti/src/test/java/com/example/activitiwithspring/ActivitiSpringSecurityIntegrationTest.java
new file mode 100644
index 0000000000..c2eeb96555
--- /dev/null
+++ b/spring-activiti/src/test/java/com/example/activitiwithspring/ActivitiSpringSecurityIntegrationTest.java
@@ -0,0 +1,31 @@
+package com.example.activitiwithspring;
+
+import org.activiti.engine.IdentityService;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.security.core.userdetails.UsernameNotFoundException;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.context.web.WebAppConfiguration;
+
+import com.baeldung.activiti.security.withspring.ActivitiSpringSecurityApplication;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = ActivitiSpringSecurityApplication.class)
+@WebAppConfiguration
+public class ActivitiSpringSecurityIntegrationTest {
+ @Autowired
+ private IdentityService identityService;
+
+ @Test
+ public void whenUserExists_thenOk() {
+ identityService.setUserPicture("spring_user", null);
+ }
+
+ @Test(expected = UsernameNotFoundException.class)
+ public void whenUserNonExistent_thenSpringException() {
+ identityService.setUserPicture("user3", null);
+ }
+
+}
diff --git a/spring-aop/src/main/java/org/baeldung/performancemonitor/AopConfiguration.java b/spring-aop/src/main/java/org/baeldung/performancemonitor/AopConfiguration.java
index a5f36fb716..00026baf07 100644
--- a/spring-aop/src/main/java/org/baeldung/performancemonitor/AopConfiguration.java
+++ b/spring-aop/src/main/java/org/baeldung/performancemonitor/AopConfiguration.java
@@ -16,10 +16,10 @@ import java.time.Month;
@EnableAspectJAutoProxy
public class AopConfiguration {
- @Pointcut("execution(public String com.baeldung.performancemonitor.PersonService.getFullName(..))")
+ @Pointcut("execution(public String org.baeldung.performancemonitor.PersonService.getFullName(..))")
public void monitor() { }
- @Pointcut("execution(public int com.baeldung.performancemonitor.PersonService.getAge(..))")
+ @Pointcut("execution(public int org.baeldung.performancemonitor.PersonService.getAge(..))")
public void myMonitor() { }
@Bean
@@ -30,7 +30,7 @@ public class AopConfiguration {
@Bean
public Advisor performanceMonitorAdvisor() {
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
- pointcut.setExpression("com.baeldung.performancemonitor.AopConfiguration.monitor()");
+ pointcut.setExpression("org.baeldung.performancemonitor.AopConfiguration.monitor()");
return new DefaultPointcutAdvisor(pointcut, performanceMonitorInterceptor());
}
@@ -52,7 +52,7 @@ public class AopConfiguration {
@Bean
public Advisor myPerformanceMonitorAdvisor() {
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
- pointcut.setExpression("com.baeldung.performancemonitor.AopConfiguration.myMonitor()");
+ pointcut.setExpression("org.baeldung.performancemonitor.AopConfiguration.myMonitor()");
return new DefaultPointcutAdvisor(pointcut, myPerformanceMonitorInterceptor());
}
diff --git a/spring-boot-admin/pom.xml b/spring-boot-admin/pom.xml
index 918eeaabeb..9c1eeeabff 100644
--- a/spring-boot-admin/pom.xml
+++ b/spring-boot-admin/pom.xml
@@ -13,6 +13,7 @@
UTF-8
+ 1.5.8.RELEASE
@@ -20,4 +21,16 @@
spring-boot-admin-client
+
+
+
+ org.springframework.boot
+ spring-boot-dependencies
+ ${spring.boot.version}
+ pom
+ import
+
+
+
+
\ No newline at end of file
diff --git a/spring-boot-admin/spring-boot-admin-client/pom.xml b/spring-boot-admin/spring-boot-admin-client/pom.xml
index accedca5cb..d119450e0b 100644
--- a/spring-boot-admin/spring-boot-admin-client/pom.xml
+++ b/spring-boot-admin/spring-boot-admin-client/pom.xml
@@ -11,10 +11,10 @@
Spring Boot Admin Client
- parent-boot-5
+ spring-boot-admin
com.baeldung
0.0.1-SNAPSHOT
- ../../parent-boot-5
+ ../../spring-boot-admin
diff --git a/spring-boot-admin/spring-boot-admin-server/pom.xml b/spring-boot-admin/spring-boot-admin-server/pom.xml
index 4922d56878..f28b7a3dc9 100644
--- a/spring-boot-admin/spring-boot-admin-server/pom.xml
+++ b/spring-boot-admin/spring-boot-admin-server/pom.xml
@@ -11,10 +11,10 @@
Spring Boot Admin Server
- parent-boot-5
+ spring-boot-admin
com.baeldung
0.0.1-SNAPSHOT
- ../../parent-boot-5
+ ../../spring-boot-admin
diff --git a/spring-boot-keycloak/pom.xml b/spring-boot-keycloak/pom.xml
index 657f96a265..ab76d0af43 100644
--- a/spring-boot-keycloak/pom.xml
+++ b/spring-boot-keycloak/pom.xml
@@ -12,10 +12,12 @@
This is a simple application demonstrating integration between Keycloak and Spring Boot.
- org.springframework.boot
- spring-boot-starter-parent
- 1.5.8.RELEASE
-
+
+ com.baeldung
+ parent-boot-4
+ 0.0.1-SNAPSHOT
+ ../parent-boot-4
+
diff --git a/spring-boot/README.MD b/spring-boot/README.MD
index 5d7eb11954..f126df00af 100644
--- a/spring-boot/README.MD
+++ b/spring-boot/README.MD
@@ -27,4 +27,5 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring
- [A Java Client for a WebSockets API](http://www.baeldung.com/websockets-api-java-spring-client)
- [Spring Boot and Togglz Aspect](http://www.baeldung.com/spring-togglz)
- [Getting Started with GraphQL and Spring Boot](http://www.baeldung.com/spring-graphql)
+- [Guide to Spring Type Conversions](http://www.baeldung.com/spring-type-conversions)
diff --git a/spring-boot/pom.xml b/spring-boot/pom.xml
index 5e5f01013d..d6ee022522 100644
--- a/spring-boot/pom.xml
+++ b/spring-boot/pom.xml
@@ -24,10 +24,6 @@
org.springframework.boot
spring-boot-starter-web
-
- org.keycloak
- keycloak-spring-boot-starter
-
org.springframework.boot
spring-boot-starter-data-jpa
@@ -172,17 +168,6 @@
artemis-server
-
-
-
- org.keycloak.bom
- keycloak-adapter-bom
- 3.3.0.CR2
- pom
- import
-
-
-
spring-boot
@@ -282,7 +267,7 @@
- org.baeldung.boot.DemoApplication
+ org.baeldung.demo.DemoApplication
4.3.4.RELEASE
2.2.1
3.1.1
diff --git a/spring-boot/src/main/java/org/baeldung/Application.java b/spring-boot/src/main/java/org/baeldung/boot/Application.java
similarity index 95%
rename from spring-boot/src/main/java/org/baeldung/Application.java
rename to spring-boot/src/main/java/org/baeldung/boot/Application.java
index 1c1e466afc..78e95455b8 100644
--- a/spring-boot/src/main/java/org/baeldung/Application.java
+++ b/spring-boot/src/main/java/org/baeldung/boot/Application.java
@@ -1,4 +1,4 @@
-package org.baeldung;
+package org.baeldung.boot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
diff --git a/spring-boot/src/main/java/org/baeldung/client/Details.java b/spring-boot/src/main/java/org/baeldung/boot/client/Details.java
similarity index 93%
rename from spring-boot/src/main/java/org/baeldung/client/Details.java
rename to spring-boot/src/main/java/org/baeldung/boot/client/Details.java
index 2ae3adc38f..1e3ddf7b21 100644
--- a/spring-boot/src/main/java/org/baeldung/client/Details.java
+++ b/spring-boot/src/main/java/org/baeldung/boot/client/Details.java
@@ -1,4 +1,4 @@
-package org.baeldung.client;
+package org.baeldung.boot.client;
public class Details {
diff --git a/spring-boot/src/main/java/org/baeldung/client/DetailsServiceClient.java b/spring-boot/src/main/java/org/baeldung/boot/client/DetailsServiceClient.java
similarity index 93%
rename from spring-boot/src/main/java/org/baeldung/client/DetailsServiceClient.java
rename to spring-boot/src/main/java/org/baeldung/boot/client/DetailsServiceClient.java
index 51fa7c6181..f2b9d6d030 100644
--- a/spring-boot/src/main/java/org/baeldung/client/DetailsServiceClient.java
+++ b/spring-boot/src/main/java/org/baeldung/boot/client/DetailsServiceClient.java
@@ -1,4 +1,4 @@
-package org.baeldung.client;
+package org.baeldung.boot.client;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.stereotype.Service;
diff --git a/spring-boot/src/main/java/org/baeldung/config/H2JpaConfig.java b/spring-boot/src/main/java/org/baeldung/boot/config/H2JpaConfig.java
similarity index 89%
rename from spring-boot/src/main/java/org/baeldung/config/H2JpaConfig.java
rename to spring-boot/src/main/java/org/baeldung/boot/config/H2JpaConfig.java
index 62791bf180..4e4b2e06bd 100644
--- a/spring-boot/src/main/java/org/baeldung/config/H2JpaConfig.java
+++ b/spring-boot/src/main/java/org/baeldung/boot/config/H2JpaConfig.java
@@ -1,4 +1,4 @@
-package org.baeldung.config;
+package org.baeldung.boot.config;
import java.util.Properties;
@@ -18,7 +18,7 @@ import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@Configuration
-@EnableJpaRepositories(basePackages = { "org.baeldung.repository", "org.baeldung.boot.repository", "org.baeldung.boot.boottest" })
+@EnableJpaRepositories(basePackages = { "org.baeldung.boot.repository", "org.baeldung.boot.boottest","org.baeldung.repository" })
@PropertySource("classpath:persistence-generic-entity.properties")
@EnableTransactionManagement
public class H2JpaConfig {
@@ -41,7 +41,7 @@ public class H2JpaConfig {
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource());
- em.setPackagesToScan(new String[] { "org.baeldung.domain", "org.baeldung.boot.model", "org.baeldung.boot.boottest" });
+ em.setPackagesToScan(new String[] { "org.baeldung.boot.domain", "org.baeldung.boot.model", "org.baeldung.boot.boottest", "org.baeldung.model" });
em.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
em.setJpaProperties(additionalProperties());
return em;
diff --git a/spring-boot/src/main/java/org/baeldung/config/WebConfig.java b/spring-boot/src/main/java/org/baeldung/boot/config/WebConfig.java
similarity index 74%
rename from spring-boot/src/main/java/org/baeldung/config/WebConfig.java
rename to spring-boot/src/main/java/org/baeldung/boot/config/WebConfig.java
index 6609791c69..caf88c3be7 100644
--- a/spring-boot/src/main/java/org/baeldung/config/WebConfig.java
+++ b/spring-boot/src/main/java/org/baeldung/boot/config/WebConfig.java
@@ -1,9 +1,9 @@
-package org.baeldung.config;
+package org.baeldung.boot.config;
-import org.baeldung.converter.GenericBigDecimalConverter;
-import org.baeldung.converter.StringToEnumConverterFactory;
-import org.baeldung.converter.StringToEmployeeConverter;
-import org.baeldung.web.resolver.HeaderVersionArgumentResolver;
+import org.baeldung.boot.converter.GenericBigDecimalConverter;
+import org.baeldung.boot.converter.StringToEmployeeConverter;
+import org.baeldung.boot.converter.StringToEnumConverterFactory;
+import org.baeldung.boot.web.resolver.HeaderVersionArgumentResolver;
import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
diff --git a/spring-boot/src/main/java/org/baeldung/controller/GenericEntityController.java b/spring-boot/src/main/java/org/baeldung/boot/controller/GenericEntityController.java
similarity index 92%
rename from spring-boot/src/main/java/org/baeldung/controller/GenericEntityController.java
rename to spring-boot/src/main/java/org/baeldung/boot/controller/GenericEntityController.java
index a9e7dee0b7..8b038e0335 100644
--- a/spring-boot/src/main/java/org/baeldung/controller/GenericEntityController.java
+++ b/spring-boot/src/main/java/org/baeldung/boot/controller/GenericEntityController.java
@@ -1,8 +1,8 @@
-package org.baeldung.controller;
+package org.baeldung.boot.controller;
-import org.baeldung.domain.GenericEntity;
-import org.baeldung.domain.Modes;
-import org.baeldung.web.resolver.Version;
+import org.baeldung.boot.domain.GenericEntity;
+import org.baeldung.boot.domain.Modes;
+import org.baeldung.boot.web.resolver.Version;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
diff --git a/spring-boot/src/main/java/org/baeldung/controller/servlet/HelloWorldServlet.java b/spring-boot/src/main/java/org/baeldung/boot/controller/servlet/HelloWorldServlet.java
similarity index 93%
rename from spring-boot/src/main/java/org/baeldung/controller/servlet/HelloWorldServlet.java
rename to spring-boot/src/main/java/org/baeldung/boot/controller/servlet/HelloWorldServlet.java
index 9adaf7fd29..34ad11254c 100644
--- a/spring-boot/src/main/java/org/baeldung/controller/servlet/HelloWorldServlet.java
+++ b/spring-boot/src/main/java/org/baeldung/boot/controller/servlet/HelloWorldServlet.java
@@ -1,43 +1,43 @@
-package org.baeldung.controller.servlet;
-
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.Objects;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-public class HelloWorldServlet extends HttpServlet {
- private static final long serialVersionUID = 1L;
-
- public HelloWorldServlet() {
- super();
- }
-
- protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- PrintWriter out = null;
- try {
- out = response.getWriter();
- out.println("HelloWorldServlet: GET METHOD");
- out.flush();
- } finally {
- if (!Objects.isNull(out))
- out.close();
- }
- }
-
- protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- PrintWriter out = null;
- try {
- out = response.getWriter();
- out.println("HelloWorldServlet: POST METHOD");
- out.flush();
- } finally {
- if (!Objects.isNull(out))
- out.close();
- }
- }
-
-}
+package org.baeldung.boot.controller.servlet;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.Objects;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+public class HelloWorldServlet extends HttpServlet {
+ private static final long serialVersionUID = 1L;
+
+ public HelloWorldServlet() {
+ super();
+ }
+
+ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ PrintWriter out = null;
+ try {
+ out = response.getWriter();
+ out.println("HelloWorldServlet: GET METHOD");
+ out.flush();
+ } finally {
+ if (!Objects.isNull(out))
+ out.close();
+ }
+ }
+
+ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ PrintWriter out = null;
+ try {
+ out = response.getWriter();
+ out.println("HelloWorldServlet: POST METHOD");
+ out.flush();
+ } finally {
+ if (!Objects.isNull(out))
+ out.close();
+ }
+ }
+
+}
diff --git a/spring-boot/src/main/java/org/baeldung/controller/servlet/SpringHelloWorldServlet.java b/spring-boot/src/main/java/org/baeldung/boot/controller/servlet/SpringHelloWorldServlet.java
similarity index 93%
rename from spring-boot/src/main/java/org/baeldung/controller/servlet/SpringHelloWorldServlet.java
rename to spring-boot/src/main/java/org/baeldung/boot/controller/servlet/SpringHelloWorldServlet.java
index 9a62bdbbf2..91547683c6 100644
--- a/spring-boot/src/main/java/org/baeldung/controller/servlet/SpringHelloWorldServlet.java
+++ b/spring-boot/src/main/java/org/baeldung/boot/controller/servlet/SpringHelloWorldServlet.java
@@ -1,43 +1,43 @@
-package org.baeldung.controller.servlet;
-
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.Objects;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-public class SpringHelloWorldServlet extends HttpServlet {
- private static final long serialVersionUID = 1L;
-
- public SpringHelloWorldServlet() {
- super();
- }
-
- protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- PrintWriter out = null;
- try {
- out = response.getWriter();
- out.println("SpringHelloWorldServlet: GET METHOD");
- out.flush();
- } finally {
- if (!Objects.isNull(out))
- out.close();
- }
- }
-
- protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- PrintWriter out = null;
- try {
- out = response.getWriter();
- out.println("SpringHelloWorldServlet: POST METHOD");
- out.flush();
- } finally {
- if (!Objects.isNull(out))
- out.close();
- }
- }
-
-}
+package org.baeldung.boot.controller.servlet;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.Objects;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+public class SpringHelloWorldServlet extends HttpServlet {
+ private static final long serialVersionUID = 1L;
+
+ public SpringHelloWorldServlet() {
+ super();
+ }
+
+ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ PrintWriter out = null;
+ try {
+ out = response.getWriter();
+ out.println("SpringHelloWorldServlet: GET METHOD");
+ out.flush();
+ } finally {
+ if (!Objects.isNull(out))
+ out.close();
+ }
+ }
+
+ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ PrintWriter out = null;
+ try {
+ out = response.getWriter();
+ out.println("SpringHelloWorldServlet: POST METHOD");
+ out.flush();
+ } finally {
+ if (!Objects.isNull(out))
+ out.close();
+ }
+ }
+
+}
diff --git a/spring-boot/src/main/java/org/baeldung/converter/GenericBigDecimalConverter.java b/spring-boot/src/main/java/org/baeldung/boot/converter/GenericBigDecimalConverter.java
similarity index 97%
rename from spring-boot/src/main/java/org/baeldung/converter/GenericBigDecimalConverter.java
rename to spring-boot/src/main/java/org/baeldung/boot/converter/GenericBigDecimalConverter.java
index 1dbb7df6de..decd8ac5db 100644
--- a/spring-boot/src/main/java/org/baeldung/converter/GenericBigDecimalConverter.java
+++ b/spring-boot/src/main/java/org/baeldung/boot/converter/GenericBigDecimalConverter.java
@@ -1,4 +1,4 @@
-package org.baeldung.converter;
+package org.baeldung.boot.converter;
import com.google.common.collect.ImmutableSet;
import org.springframework.core.convert.TypeDescriptor;
diff --git a/spring-boot/src/main/java/org/baeldung/converter/StringToEmployeeConverter.java b/spring-boot/src/main/java/org/baeldung/boot/converter/StringToEmployeeConverter.java
similarity index 90%
rename from spring-boot/src/main/java/org/baeldung/converter/StringToEmployeeConverter.java
rename to spring-boot/src/main/java/org/baeldung/boot/converter/StringToEmployeeConverter.java
index 5f680972b7..de9cf3f55a 100644
--- a/spring-boot/src/main/java/org/baeldung/converter/StringToEmployeeConverter.java
+++ b/spring-boot/src/main/java/org/baeldung/boot/converter/StringToEmployeeConverter.java
@@ -1,4 +1,4 @@
-package org.baeldung.converter;
+package org.baeldung.boot.converter;
import com.baeldung.toggle.Employee;
diff --git a/spring-boot/src/main/java/org/baeldung/converter/StringToEnumConverterFactory.java b/spring-boot/src/main/java/org/baeldung/boot/converter/StringToEnumConverterFactory.java
similarity index 95%
rename from spring-boot/src/main/java/org/baeldung/converter/StringToEnumConverterFactory.java
rename to spring-boot/src/main/java/org/baeldung/boot/converter/StringToEnumConverterFactory.java
index 17c6fd06de..6fa51bfdcc 100644
--- a/spring-boot/src/main/java/org/baeldung/converter/StringToEnumConverterFactory.java
+++ b/spring-boot/src/main/java/org/baeldung/boot/converter/StringToEnumConverterFactory.java
@@ -1,4 +1,4 @@
-package org.baeldung.converter;
+package org.baeldung.boot.converter;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.converter.ConverterFactory;
diff --git a/spring-boot/src/main/java/org/baeldung/converter/StringToLocalDateTimeConverter.java b/spring-boot/src/main/java/org/baeldung/boot/converter/StringToLocalDateTimeConverter.java
similarity index 92%
rename from spring-boot/src/main/java/org/baeldung/converter/StringToLocalDateTimeConverter.java
rename to spring-boot/src/main/java/org/baeldung/boot/converter/StringToLocalDateTimeConverter.java
index cbb9e6ddb4..8a08b438f2 100644
--- a/spring-boot/src/main/java/org/baeldung/converter/StringToLocalDateTimeConverter.java
+++ b/spring-boot/src/main/java/org/baeldung/boot/converter/StringToLocalDateTimeConverter.java
@@ -1,4 +1,4 @@
-package org.baeldung.converter;
+package org.baeldung.boot.converter;
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;
diff --git a/spring-boot/src/main/java/org/baeldung/boot/converter/controller/StringToEmployeeConverterController.java b/spring-boot/src/main/java/org/baeldung/boot/converter/controller/StringToEmployeeConverterController.java
new file mode 100644
index 0000000000..ad921c2c43
--- /dev/null
+++ b/spring-boot/src/main/java/org/baeldung/boot/converter/controller/StringToEmployeeConverterController.java
@@ -0,0 +1,16 @@
+package org.baeldung.boot.converter.controller;
+
+import com.baeldung.toggle.Employee;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+@RestController
+@RequestMapping("/string-to-employee")
+public class StringToEmployeeConverterController {
+
+ @GetMapping
+ public ResponseEntity