diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 9c5cdb8f2d..0000000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "testgitrepo"] - path = testgitrepo - url = /home/prd/Development/projects/idea/tutorials/spring-boot/src/main/resources/testgitrepo/ diff --git a/apache-meecrowave/pom.xml b/apache-meecrowave/pom.xml new file mode 100644 index 0000000000..cf13aa1c1b --- /dev/null +++ b/apache-meecrowave/pom.xml @@ -0,0 +1,57 @@ + + 4.0.0 + com.baeldung + apache-meecrowave + 0.0.1 + apache-meecrowave + A sample REST API application with Meecrowave + + + 1.8 + 1.8 + + + + + org.apache.meecrowave + meecrowave-core + 1.2.1 + + + + org.apache.meecrowave + meecrowave-jpa + 1.2.1 + + + + com.squareup.okhttp3 + okhttp + 3.10.0 + + + org.apache.meecrowave + meecrowave-junit + 1.2.0 + test + + + + junit + junit + 4.10 + test + + + + + + + org.apache.meecrowave + meecrowave-maven-plugin + 1.2.1 + + + + \ No newline at end of file diff --git a/apache-meecrowave/src/main/java/com/baeldung/meecrowave/Article.java b/apache-meecrowave/src/main/java/com/baeldung/meecrowave/Article.java new file mode 100644 index 0000000000..7925e8ff99 --- /dev/null +++ b/apache-meecrowave/src/main/java/com/baeldung/meecrowave/Article.java @@ -0,0 +1,30 @@ +package com.baeldung.meecrowave; + +public class Article { + private String name; + private String author; + + public Article() { + } + + public Article(String name, String author) { + this.author = author; + this.name = name; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } +} \ No newline at end of file diff --git a/apache-meecrowave/src/main/java/com/baeldung/meecrowave/ArticleEndpoints.java b/apache-meecrowave/src/main/java/com/baeldung/meecrowave/ArticleEndpoints.java new file mode 100644 index 0000000000..6cb7012c64 --- /dev/null +++ b/apache-meecrowave/src/main/java/com/baeldung/meecrowave/ArticleEndpoints.java @@ -0,0 +1,32 @@ +package com.baeldung.meecrowave; + +import javax.enterprise.context.RequestScoped; +import javax.inject.Inject; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; + +@RequestScoped +@Path("article") +public class ArticleEndpoints { + + @Inject + ArticleService articleService; + + @GET + public Response getArticle() { + return Response.ok() + .entity(new Article("name", "author")) + .build(); + + } + + @POST + public Response createArticle(Article article) { + return Response.status(Status.CREATED) + .entity(articleService.createArticle(article)) + .build(); + } +} \ No newline at end of file diff --git a/apache-meecrowave/src/main/java/com/baeldung/meecrowave/ArticleService.java b/apache-meecrowave/src/main/java/com/baeldung/meecrowave/ArticleService.java new file mode 100644 index 0000000000..7bd6b87345 --- /dev/null +++ b/apache-meecrowave/src/main/java/com/baeldung/meecrowave/ArticleService.java @@ -0,0 +1,10 @@ +package com.baeldung.meecrowave; + +import javax.enterprise.context.ApplicationScoped; + +@ApplicationScoped +public class ArticleService { + public Article createArticle(Article article) { + return article; + } +} diff --git a/apache-meecrowave/src/main/java/com/baeldung/meecrowave/Server.java b/apache-meecrowave/src/main/java/com/baeldung/meecrowave/Server.java new file mode 100644 index 0000000000..2aa7d0556f --- /dev/null +++ b/apache-meecrowave/src/main/java/com/baeldung/meecrowave/Server.java @@ -0,0 +1,16 @@ +package com.baeldung.meecrowave; + +import org.apache.meecrowave.Meecrowave; + +public class Server { + public static void main(String[] args) { + final Meecrowave.Builder builder = new Meecrowave.Builder(); + builder.setScanningPackageIncludes("com.baeldung.meecrowave"); + builder.setJaxrsMapping("/api/*"); + builder.setJsonpPrettify(true); + + try (Meecrowave meecrowave = new Meecrowave(builder)) { + meecrowave.bake().await(); + } + } +} diff --git a/apache-meecrowave/src/test/java/com/baeldung/meecrowave/ArticleEndpointsTest.java b/apache-meecrowave/src/test/java/com/baeldung/meecrowave/ArticleEndpointsTest.java new file mode 100644 index 0000000000..0dc9773490 --- /dev/null +++ b/apache-meecrowave/src/test/java/com/baeldung/meecrowave/ArticleEndpointsTest.java @@ -0,0 +1,41 @@ +package com.baeldung.meecrowave; + + +import static org.junit.Assert.assertEquals; + +import java.io.IOException; + +import org.apache.meecrowave.Meecrowave; +import org.apache.meecrowave.junit.MonoMeecrowave; +import org.apache.meecrowave.testing.ConfigurationInject; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; + +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; + +@RunWith(MonoMeecrowave.Runner.class) +public class ArticleEndpointsTest { + + @ConfigurationInject + private Meecrowave.Builder config; + private static OkHttpClient client; + + @BeforeClass + public static void setup() { + client = new OkHttpClient(); + } + + @Test + public void whenRetunedArticle_thenCorrect() throws IOException { + final String base = "http://localhost:"+config.getHttpPort(); + + Request request = new Request.Builder() + .url(base+"/article") + .build(); + Response response = client.newCall(request).execute(); + assertEquals(200, response.code()); + } +} diff --git a/apache-solrj/src/test/java/com/baeldung/solrjava/SolrJavaIntegrationTest.java b/apache-solrj/src/test/java/com/baeldung/solrjava/SolrJavaLiveTest.java similarity index 98% rename from apache-solrj/src/test/java/com/baeldung/solrjava/SolrJavaIntegrationTest.java rename to apache-solrj/src/test/java/com/baeldung/solrjava/SolrJavaLiveTest.java index 8b5fe77c6f..eaf0271b55 100644 --- a/apache-solrj/src/test/java/com/baeldung/solrjava/SolrJavaIntegrationTest.java +++ b/apache-solrj/src/test/java/com/baeldung/solrjava/SolrJavaLiveTest.java @@ -12,7 +12,7 @@ import org.apache.solr.common.SolrDocumentList; import org.junit.Before; import org.junit.Test; -public class SolrJavaIntegrationTest { +public class SolrJavaLiveTest { private SolrJavaIntegration solrJavaIntegration; diff --git a/aws-lambda/README.md b/aws-lambda/README.md new file mode 100644 index 0000000000..921b699bdd --- /dev/null +++ b/aws-lambda/README.md @@ -0,0 +1,3 @@ +### Relevant Articles: +- [Using AWS Lambda with API Gateway](http://www.baeldung.com/aws-lambda-api-gateway) +- [Introduction to AWS Serverless Application Model](http://www.baeldung.com/aws-serverless) diff --git a/core-java-8/src/main/java/com/baeldung/datetime/AddHoursToDate.java b/core-java-8/src/main/java/com/baeldung/datetime/AddHoursToDate.java new file mode 100644 index 0000000000..d9636656b5 --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/datetime/AddHoursToDate.java @@ -0,0 +1,54 @@ +package com.baeldung.datetime; + +import java.time.Duration; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZonedDateTime; +import java.time.temporal.ChronoUnit; +import java.util.Calendar; +import java.util.Date; + +import org.apache.commons.lang3.time.DateUtils; + +public class AddHoursToDate { + + public Date addHoursToJavaUtilDate(Date date, int hours) { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + calendar.add(Calendar.HOUR_OF_DAY, hours); + return calendar.getTime(); + } + + public Date addHoursToDateUsingInstant(Date date, int hours) { + return Date.from(date.toInstant() + .plus(Duration.ofHours(hours))); + } + + public LocalDateTime addHoursToLocalDateTime(LocalDateTime localDateTime, int hours) { + return localDateTime.plusHours(hours); + } + + public LocalDateTime subtractHoursToLocalDateTime(LocalDateTime localDateTime, int hours) { + return localDateTime.minusHours(hours); + } + + public ZonedDateTime addHoursToZonedDateTime(ZonedDateTime zonedDateTime, int hours) { + return zonedDateTime.plusHours(hours); + } + + public ZonedDateTime subtractHoursToZonedDateTime(ZonedDateTime zonedDateTime, int hours) { + return zonedDateTime.minusHours(hours); + } + + public Instant addHoursToInstant(Instant instant, int hours) { + return instant.plus(hours, ChronoUnit.HOURS); + } + + public Instant subtractHoursToInstant(Instant instant, int hours) { + return instant.minus(hours, ChronoUnit.HOURS); + } + + public Date addHoursWithApacheCommons(Date date, int hours) { + return DateUtils.addHours(date, hours); + } +} diff --git a/core-java-8/src/test/java/com/baeldung/datetime/AddHoursToDateUnitTest.java b/core-java-8/src/test/java/com/baeldung/datetime/AddHoursToDateUnitTest.java new file mode 100644 index 0000000000..aa34367f30 --- /dev/null +++ b/core-java-8/src/test/java/com/baeldung/datetime/AddHoursToDateUnitTest.java @@ -0,0 +1,116 @@ +package com.baeldung.datetime; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.Month; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; + +import org.junit.Test; + +public class AddHoursToDateUnitTest { + + private final AddHoursToDate addHoursToDateObj = new AddHoursToDate(); + + @Test + public void givenJavaUtilDate_whenPositiveHours_thenAddHours() { + Date actualDate = new GregorianCalendar(2018, Calendar.JUNE, 25, 5, 0).getTime(); + Date expectedDate = new GregorianCalendar(2018, Calendar.JUNE, 25, 7, 0).getTime(); + + assertThat(addHoursToDateObj.addHoursToJavaUtilDate(actualDate, 2)).isEqualTo(expectedDate); + } + + @Test + public void givenJavaUtilDate_whenNegativeHours_thenMinusHours() { + Date actualDate = new GregorianCalendar(2018, Calendar.JUNE, 25, 5, 0).getTime(); + Date expectedDate = new GregorianCalendar(2018, Calendar.JUNE, 25, 3, 0).getTime(); + + assertThat(addHoursToDateObj.addHoursToJavaUtilDate(actualDate, -2)).isEqualTo(expectedDate); + } + + @Test + public void givenJavaUtilDate_whenUsingToInstantAndPostiveHours_thenAddHours() { + Date actualDate = new GregorianCalendar(2018, Calendar.JUNE, 25, 5, 0).getTime(); + Date expectedDate = new GregorianCalendar(2018, Calendar.JUNE, 25, 7, 0).getTime(); + + assertThat(addHoursToDateObj.addHoursToDateUsingInstant(actualDate, 2)).isEqualTo(expectedDate); + } + + @Test + public void givenJavaUtilDate_whenUsingToInstantAndNegativeHours_thenAddHours() { + Date actualDate = new GregorianCalendar(2018, Calendar.JUNE, 25, 5, 0).getTime(); + Date expectedDate = new GregorianCalendar(2018, Calendar.JUNE, 25, 3, 0).getTime(); + + assertThat(addHoursToDateObj.addHoursToDateUsingInstant(actualDate, -2)).isEqualTo(expectedDate); + } + + @Test + public void givenLocalDateTime_whenUsingAddHoursToLocalDateTime_thenAddHours() { + LocalDateTime actualDateTime = LocalDateTime.of(2018, Month.JUNE, 25, 5, 0); + LocalDateTime expectedDateTime = LocalDateTime.of(2018, Month.JUNE, 25, 7, 0); + + assertThat(addHoursToDateObj.addHoursToLocalDateTime(actualDateTime, 2)).isEqualTo(expectedDateTime); + } + + @Test + public void givenLocalDateTime_whenUsingMinusHoursToLocalDateTime_thenMinusHours() { + LocalDateTime actualDateTime = LocalDateTime.of(2018, Month.JUNE, 25, 5, 0); + LocalDateTime expectedDateTime = LocalDateTime.of(2018, Month.JUNE, 25, 3, 0); + + assertThat(addHoursToDateObj.subtractHoursToLocalDateTime(actualDateTime, 2)).isEqualTo(expectedDateTime); + } + + @Test + public void givenZonedDateTime_whenUsingAddHoursToZonedDateTime_thenAddHours() { + ZonedDateTime actualZonedDateTime = ZonedDateTime.of(LocalDateTime.of(2018, Month.JUNE, 25, 5, 0), ZoneId.systemDefault()); + ZonedDateTime expectedZonedDateTime = ZonedDateTime.of(LocalDateTime.of(2018, Month.JUNE, 25, 7, 0), ZoneId.systemDefault()); + + assertThat(addHoursToDateObj.addHoursToZonedDateTime(actualZonedDateTime, 2)).isEqualTo(expectedZonedDateTime); + } + + @Test + public void givenZonedDateTime_whenUsingMinusHoursToZonedDateTime_thenMinusHours() { + ZonedDateTime actualZonedDateTime = ZonedDateTime.of(LocalDateTime.of(2018, Month.JUNE, 25, 5, 0), ZoneId.systemDefault()); + ZonedDateTime expectedZonedDateTime = ZonedDateTime.of(LocalDateTime.of(2018, Month.JUNE, 25, 3, 0), ZoneId.systemDefault()); + + assertThat(addHoursToDateObj.subtractHoursToZonedDateTime(actualZonedDateTime, 2)).isEqualTo(expectedZonedDateTime); + } + + @Test + public void givenJavaUtilDate_whenUsingPositiveHrsAndAddHoursWithApacheCommons_thenAddHours() { + Date actualDate = new GregorianCalendar(2018, Calendar.JUNE, 25, 5, 0).getTime(); + Date expectedDate = new GregorianCalendar(2018, Calendar.JUNE, 25, 7, 0).getTime(); + + assertThat(addHoursToDateObj.addHoursWithApacheCommons(actualDate, 2)).isEqualTo(expectedDate); + } + + @Test + public void givenJavaUtilDate_whenUsingNegativeHrsAndAddHoursWithApacheCommons_thenMinusHours() { + Date actualDate = new GregorianCalendar(2018, Calendar.JUNE, 25, 7, 0).getTime(); + Date expectedDate = new GregorianCalendar(2018, Calendar.JUNE, 25, 5, 0).getTime(); + + assertThat(addHoursToDateObj.addHoursWithApacheCommons(actualDate, -2)).isEqualTo(expectedDate); + } + + @Test + public void givenInstant_whenUsingAddHoursToInstant_thenAddHours() { + Instant actualValue = Instant.parse("2018-06-25T05:12:35Z"); + Instant expectedValue = Instant.parse("2018-06-25T07:12:35Z"); + + assertThat(addHoursToDateObj.addHoursToInstant(actualValue, 2)).isEqualTo(expectedValue); + } + + @Test + public void givenInstant_whenUsingSubtractHoursToInstant_thenMinusHours() { + Instant actualValue = Instant.parse("2018-06-25T07:12:35Z"); + Instant expectedValue = Instant.parse("2018-06-25T05:12:35Z"); + + assertThat(addHoursToDateObj.subtractHoursToInstant(actualValue, 2)).isEqualTo(expectedValue); + } + +} diff --git a/core-java/README.md b/core-java/README.md index 3aa50e5b86..16378bc169 100644 --- a/core-java/README.md +++ b/core-java/README.md @@ -166,3 +166,4 @@ - [Convert a String to Title Case](http://www.baeldung.com/java-string-title-case) - [How to Get the File Extension of a File in Java](http://www.baeldung.com/java-file-extension) - [Immutable Objects in Java](http://www.baeldung.com/java-immutable-object) +- [Console I/O in Java](http://www.baeldung.com/java-console-input-output) diff --git a/core-java/src/main/java/com/baeldung/encrypt/FileEncrypterDecrypter.java b/core-java/src/main/java/com/baeldung/encrypt/FileEncrypterDecrypter.java new file mode 100644 index 0000000000..b557ccf31a --- /dev/null +++ b/core-java/src/main/java/com/baeldung/encrypt/FileEncrypterDecrypter.java @@ -0,0 +1,60 @@ +package com.baeldung.encrypt; + +import javax.crypto.*; +import javax.crypto.spec.IvParameterSpec; +import java.io.*; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; + +class FileEncrypterDecrypter { + + private SecretKey secretKey; + private Cipher cipher; + + FileEncrypterDecrypter(SecretKey secretKey, String cipher) throws NoSuchPaddingException, NoSuchAlgorithmException { + this.secretKey = secretKey; + this.cipher = Cipher.getInstance(cipher); + } + + void encrypt(String content, String fileName) throws InvalidKeyException, IOException { + cipher.init(Cipher.ENCRYPT_MODE, secretKey); + byte[] iv = cipher.getIV(); + + try ( + FileOutputStream fileOut = new FileOutputStream(fileName); + CipherOutputStream cipherOut = new CipherOutputStream(fileOut, cipher) + ) { + fileOut.write(iv); + cipherOut.write(content.getBytes()); + } + + } + + String decrypt(String fileName) throws InvalidAlgorithmParameterException, InvalidKeyException, IOException { + + String content; + + try (FileInputStream fileIn = new FileInputStream(fileName)) { + byte[] fileIv = new byte[16]; + fileIn.read(fileIv); + cipher.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(fileIv)); + + try ( + CipherInputStream cipherIn = new CipherInputStream(fileIn, cipher); + InputStreamReader inputReader = new InputStreamReader(cipherIn); + BufferedReader reader = new BufferedReader(inputReader) + ) { + + StringBuilder sb = new StringBuilder(); + String line; + while ((line = reader.readLine()) != null) { + sb.append(line); + } + content = sb.toString(); + } + + } + return content; + } +} diff --git a/core-java/src/main/java/com/baeldung/exceptions/Arithmetic.java b/core-java/src/main/java/com/baeldung/exceptions/Arithmetic.java new file mode 100644 index 0000000000..138916ec60 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/exceptions/Arithmetic.java @@ -0,0 +1,20 @@ +package com.baeldung.exceptions; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class Arithmetic { + + private static Logger LOGGER = LoggerFactory.getLogger(Arithmetic.class); + + public static void main(String[] args) { + + try { + int result = 30 / 0; // Trying to divide by zero + } catch (ArithmeticException e) { + LOGGER.error("ArithmeticException caught!"); + } + + } + +} diff --git a/core-java/src/main/java/com/baeldung/exceptions/ArrayIndexOutOfBounds.java b/core-java/src/main/java/com/baeldung/exceptions/ArrayIndexOutOfBounds.java new file mode 100644 index 0000000000..93b53f284c --- /dev/null +++ b/core-java/src/main/java/com/baeldung/exceptions/ArrayIndexOutOfBounds.java @@ -0,0 +1,24 @@ +package com.baeldung.exceptions; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ArrayIndexOutOfBounds { + + private static Logger LOGGER = LoggerFactory.getLogger(ArrayIndexOutOfBounds.class); + + public static void main(String[] args) { + + int[] nums = new int[] { 1, 2, 3 }; + + try { + int numFromNegativeIndex = nums[-1]; // Trying to access at negative index + int numFromGreaterIndex = nums[4]; // Trying to access at greater index + int numFromLengthIndex = nums[3]; // Trying to access at index equal to size of the array + } catch (ArrayIndexOutOfBoundsException e) { + LOGGER.error("ArrayIndexOutOfBoundsException caught"); + } + + } + +} diff --git a/core-java/src/main/java/com/baeldung/exceptions/ClassCast.java b/core-java/src/main/java/com/baeldung/exceptions/ClassCast.java new file mode 100644 index 0000000000..183f8f54a3 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/exceptions/ClassCast.java @@ -0,0 +1,36 @@ +package com.baeldung.exceptions; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +class Animal { + +} + +class Dog extends Animal { + +} + +class Lion extends Animal { + +} + +public class ClassCast { + + private static Logger LOGGER = LoggerFactory.getLogger(ClassCast.class); + + public static void main(String[] args) { + + try { + Animal animalOne = new Dog(); // At runtime the instance is dog + Dog bruno = (Dog) animalOne; // Downcasting + + Animal animalTwo = new Lion(); // At runtime the instance is animal + Dog tommy = (Dog) animalTwo; // Downcasting + } catch (ClassCastException e) { + LOGGER.error("ClassCastException caught!"); + } + + } + +} diff --git a/core-java/src/main/java/com/baeldung/exceptions/FileNotFound.java b/core-java/src/main/java/com/baeldung/exceptions/FileNotFound.java new file mode 100644 index 0000000000..bb9e0bf4ac --- /dev/null +++ b/core-java/src/main/java/com/baeldung/exceptions/FileNotFound.java @@ -0,0 +1,25 @@ +package com.baeldung.exceptions; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class FileNotFound { + + private static Logger LOGGER = LoggerFactory.getLogger(FileNotFound.class); + + public static void main(String[] args) { + + BufferedReader reader = null; + try { + reader = new BufferedReader(new FileReader(new File("/invalid/file/location"))); + } catch (FileNotFoundException e) { + LOGGER.error("FileNotFoundException caught!"); + } + } + +} diff --git a/core-java/src/main/java/com/baeldung/exceptions/GlobalExceptionHandler.java b/core-java/src/main/java/com/baeldung/exceptions/GlobalExceptionHandler.java new file mode 100644 index 0000000000..ab46c83da4 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/exceptions/GlobalExceptionHandler.java @@ -0,0 +1,28 @@ +package com.baeldung.exceptions; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class GlobalExceptionHandler { + + public static void main(String[] args) { + + Handler globalExceptionHandler = new Handler(); + Thread.setDefaultUncaughtExceptionHandler(globalExceptionHandler); + new GlobalExceptionHandler().performArithmeticOperation(10, 0); + } + + public int performArithmeticOperation(int num1, int num2) { + return num1/num2; + } + +} + +class Handler implements Thread.UncaughtExceptionHandler { + + private static Logger LOGGER = LoggerFactory.getLogger(Handler.class); + + public void uncaughtException(Thread t, Throwable e) { + LOGGER.info("Unhandled exception caught!"); + } +} diff --git a/core-java/src/main/java/com/baeldung/exceptions/IllegalArgument.java b/core-java/src/main/java/com/baeldung/exceptions/IllegalArgument.java new file mode 100644 index 0000000000..801536cb2d --- /dev/null +++ b/core-java/src/main/java/com/baeldung/exceptions/IllegalArgument.java @@ -0,0 +1,18 @@ +package com.baeldung.exceptions; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class IllegalArgument { + + private static Logger LOGGER = LoggerFactory.getLogger(IllegalArgument.class); + + public static void main(String[] args) { + try { + Thread.sleep(-1000); + } catch (InterruptedException e) { + LOGGER.error("IllegalArgumentException caught!"); + } + } + +} diff --git a/core-java/src/main/java/com/baeldung/exceptions/IllegalState.java b/core-java/src/main/java/com/baeldung/exceptions/IllegalState.java new file mode 100644 index 0000000000..e8ddcea3c2 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/exceptions/IllegalState.java @@ -0,0 +1,32 @@ +package com.baeldung.exceptions; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class IllegalState { + + private static Logger LOGGER = LoggerFactory.getLogger(IllegalState.class); + + public static void main(String[] args) { + + List intList = new ArrayList<>(); + + for (int i = 0; i < 10; i++) { + intList.add(i); + } + + Iterator intListIterator = intList.iterator(); // Initialized with index at -1 + + try { + intListIterator.remove(); // IllegalStateException + } catch (IllegalStateException e) { + LOGGER.error("IllegalStateException caught!"); + } + + } + +} diff --git a/core-java/src/main/java/com/baeldung/exceptions/InterruptedExceptionExample.java b/core-java/src/main/java/com/baeldung/exceptions/InterruptedExceptionExample.java new file mode 100644 index 0000000000..319fd33591 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/exceptions/InterruptedExceptionExample.java @@ -0,0 +1,28 @@ +package com.baeldung.exceptions; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +class ChildThread extends Thread { + + private static Logger LOGGER = LoggerFactory.getLogger(ChildThread.class); + + public void run() { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + LOGGER.error("InterruptedException caught!"); + } + } + +} + +public class InterruptedExceptionExample { + + public static void main(String[] args) throws InterruptedException { + ChildThread childThread = new ChildThread(); + childThread.start(); + childThread.interrupt(); + } + +} diff --git a/core-java/src/main/java/com/baeldung/exceptions/MalformedURL.java b/core-java/src/main/java/com/baeldung/exceptions/MalformedURL.java new file mode 100644 index 0000000000..57fcddf76b --- /dev/null +++ b/core-java/src/main/java/com/baeldung/exceptions/MalformedURL.java @@ -0,0 +1,25 @@ +package com.baeldung.exceptions; + +import java.net.MalformedURLException; +import java.net.URL; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class MalformedURL { + + private static Logger LOGGER = LoggerFactory.getLogger(MalformedURL.class); + + public static void main(String[] args) { + + URL baeldungURL = null; + + try { + baeldungURL = new URL("malformedurl"); + } catch (MalformedURLException e) { + LOGGER.error("MalformedURLException caught!"); + } + + } + +} diff --git a/core-java/src/main/java/com/baeldung/exceptions/NullPointer.java b/core-java/src/main/java/com/baeldung/exceptions/NullPointer.java new file mode 100644 index 0000000000..2402a786a9 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/exceptions/NullPointer.java @@ -0,0 +1,36 @@ +package com.baeldung.exceptions; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class NullPointer { + + private static Logger LOGGER = LoggerFactory.getLogger(NullPointer.class); + + public static void main(String[] args) { + + Person personObj = null; + + try { + String name = personObj.personName; // Accessing the field of a null object + personObj.personName = "Jon Doe"; // Modifying the field of a null object + } catch (NullPointerException e) { + LOGGER.error("NullPointerException caught!"); + } + + } +} + +class Person { + + public String personName; + + public String getPersonName() { + return personName; + } + + public void setPersonName(String personName) { + this.personName = personName; + } + +} diff --git a/core-java/src/main/java/com/baeldung/exceptions/NumberFormat.java b/core-java/src/main/java/com/baeldung/exceptions/NumberFormat.java new file mode 100644 index 0000000000..7050e70aee --- /dev/null +++ b/core-java/src/main/java/com/baeldung/exceptions/NumberFormat.java @@ -0,0 +1,23 @@ +package com.baeldung.exceptions; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class NumberFormat { + + private static Logger LOGGER = LoggerFactory.getLogger(NumberFormat.class); + + public static void main(String[] args) { + + String str1 = "100ABCD"; + + try { + int x = Integer.parseInt(str1); // Converting string with inappropriate format + int y = Integer.valueOf(str1); + } catch (NumberFormatException e) { + LOGGER.error("NumberFormatException caught!"); + } + + } + +} diff --git a/core-java/src/main/java/com/baeldung/exceptions/ParseExceptionExample.java b/core-java/src/main/java/com/baeldung/exceptions/ParseExceptionExample.java new file mode 100644 index 0000000000..f7fb4c91e4 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/exceptions/ParseExceptionExample.java @@ -0,0 +1,25 @@ +package com.baeldung.exceptions; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ParseExceptionExample { + + private static Logger LOGGER = LoggerFactory.getLogger(ParseExceptionExample.class); + + public static void main(String[] args) { + + DateFormat format = new SimpleDateFormat("MM, dd, yyyy"); + + try { + format.parse("01, , 2010"); + } catch (ParseException e) { + LOGGER.error("ParseException caught!"); + } + } + +} diff --git a/core-java/src/main/java/com/baeldung/exceptions/StringIndexOutOfBounds.java b/core-java/src/main/java/com/baeldung/exceptions/StringIndexOutOfBounds.java new file mode 100644 index 0000000000..bc297be498 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/exceptions/StringIndexOutOfBounds.java @@ -0,0 +1,23 @@ +package com.baeldung.exceptions; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class StringIndexOutOfBounds { + + private static Logger LOGGER = LoggerFactory.getLogger(StringIndexOutOfBounds.class); + + public static void main(String[] args) { + + String str = "Hello World"; + + try { + char charAtNegativeIndex = str.charAt(-1); // Trying to access at negative index + char charAtLengthIndex = str.charAt(11); // Trying to access at index equal to size of the string + } catch (StringIndexOutOfBoundsException e) { + LOGGER.error("StringIndexOutOfBoundsException caught"); + } + + } + +} diff --git a/core-java/src/main/java/com/baeldung/gregorian/calendar/GregorianCalendarExample.java b/core-java/src/main/java/com/baeldung/gregorian/calendar/GregorianCalendarExample.java new file mode 100644 index 0000000000..d8018cefd5 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/gregorian/calendar/GregorianCalendarExample.java @@ -0,0 +1,69 @@ +package com.baeldung.gregorian.calendar; + +import java.time.format.DateTimeFormatter; +import java.util.Calendar; +import java.util.Collections; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.HashSet; +import java.util.Locale; +import java.util.Set; +import java.util.TimeZone; + +import javax.xml.datatype.DatatypeConfigurationException; +import javax.xml.datatype.DatatypeFactory; +import javax.xml.datatype.XMLGregorianCalendar; + +public class GregorianCalendarExample { + + + public Date setMonth(GregorianCalendar calendar, int amount) { + calendar.set(Calendar.MONTH, amount); + return calendar.getTime(); + } + + + public Date rollAdd(GregorianCalendar calendar, int amount) { + calendar.roll(GregorianCalendar.MONTH, amount); + return calendar.getTime(); + } + + public boolean isLeapYearExample(int year) { + GregorianCalendar cal = (GregorianCalendar) GregorianCalendar.getInstance(); + return cal.isLeapYear(year); + } + + + + public Date subtractDays(GregorianCalendar calendar, int daysToSubtract) { + GregorianCalendar cal = calendar; + cal.add(Calendar.DATE, -daysToSubtract); + return cal.getTime(); + } + + public Date addDays(GregorianCalendar calendar, int daysToAdd) { + GregorianCalendar cal = calendar; + cal.add(Calendar.DATE, daysToAdd); + return cal.getTime(); + } + + public XMLGregorianCalendar toXMLGregorianCalendar(GregorianCalendar calendar) throws DatatypeConfigurationException { + DatatypeFactory datatypeFactory = DatatypeFactory.newInstance(); + return datatypeFactory.newXMLGregorianCalendar(calendar); + } + + public Date toDate(XMLGregorianCalendar calendar) { + return calendar.toGregorianCalendar() + .getTime(); + } + + public int compareDates(GregorianCalendar firstDate, GregorianCalendar secondDate) { + return firstDate.compareTo(secondDate); + } + + public String formatDate(GregorianCalendar calendar) { + return calendar.toZonedDateTime() + .format(DateTimeFormatter.ofPattern("d MMM uuuu")); + } + +} diff --git a/core-java/src/test/java/com/baeldung/encrypt/FileEncrypterDecrypterIntegrationTest.java b/core-java/src/test/java/com/baeldung/encrypt/FileEncrypterDecrypterIntegrationTest.java new file mode 100644 index 0000000000..b767a24b16 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/encrypt/FileEncrypterDecrypterIntegrationTest.java @@ -0,0 +1,32 @@ +package com.baeldung.encrypt; + +import org.junit.Test; + +import javax.crypto.KeyGenerator; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.SecretKey; +import java.io.File; +import java.io.IOException; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; + +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + +public class FileEncrypterDecrypterIntegrationTest { + + @Test + public void givenStringAndFilename_whenEncryptingIntoFile_andDecryptingFileAgain_thenOriginalStringIsReturned() throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IOException, InvalidAlgorithmParameterException { + String originalContent = "foobar"; + SecretKey secretKey = KeyGenerator.getInstance("AES").generateKey(); + + FileEncrypterDecrypter fileEncrypterDecrypter = new FileEncrypterDecrypter(secretKey, "AES/CBC/PKCS5Padding"); + fileEncrypterDecrypter.encrypt(originalContent, "baz.enc"); + + String decryptedContent = fileEncrypterDecrypter.decrypt("baz.enc"); + assertThat(decryptedContent, is(originalContent)); + + new File("baz.enc").delete(); // cleanup + } +} diff --git a/core-java/src/test/java/com/baeldung/exceptions/GlobalExceptionHandlerUnitTest.java b/core-java/src/test/java/com/baeldung/exceptions/GlobalExceptionHandlerUnitTest.java new file mode 100644 index 0000000000..394de9c576 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/exceptions/GlobalExceptionHandlerUnitTest.java @@ -0,0 +1,64 @@ +package com.baeldung.exceptions; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; +import org.slf4j.LoggerFactory; +import ch.qos.logback.classic.Level; +import ch.qos.logback.classic.Logger; +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.classic.spi.LoggingEvent; +import ch.qos.logback.core.Appender; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.verify; + +@RunWith(MockitoJUnitRunner.class) +public class GlobalExceptionHandlerUnitTest { + + @Mock + private Appender mockAppender; + + @Captor + private ArgumentCaptor captorLoggingEvent; + + @Before + public void setup() { + final Logger logger = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME); + logger.addAppender(mockAppender); + + Handler globalExceptionHandler = new Handler(); + Thread.setDefaultUncaughtExceptionHandler(globalExceptionHandler); + } + + @After + public void teardown() { + final Logger logger = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME); + logger.detachAppender(mockAppender); + } + + @Test + public void whenArithmeticException_thenUseUncaughtExceptionHandler() throws InterruptedException { + + Thread globalExceptionHandlerThread = new Thread() { + public void run() { + GlobalExceptionHandler globalExceptionHandlerObj = new GlobalExceptionHandler(); + globalExceptionHandlerObj.performArithmeticOperation(99, 0); + } + }; + + globalExceptionHandlerThread.start(); + globalExceptionHandlerThread.join(); + + verify(mockAppender).doAppend(captorLoggingEvent.capture()); + LoggingEvent loggingEvent = captorLoggingEvent.getValue(); + + assertThat(loggingEvent.getLevel()).isEqualTo(Level.INFO); + assertThat(loggingEvent.getFormattedMessage()).isEqualTo("Unhandled exception caught!"); + } + +} diff --git a/core-java/src/test/java/com/baeldung/gregorian/calendar/GregorianCalendarTester.java b/core-java/src/test/java/com/baeldung/gregorian/calendar/GregorianCalendarTester.java new file mode 100644 index 0000000000..a1d084cf9a --- /dev/null +++ b/core-java/src/test/java/com/baeldung/gregorian/calendar/GregorianCalendarTester.java @@ -0,0 +1,228 @@ +package com.baeldung.gregorian.calendar; + +import static org.junit.Assert.*; + +import java.time.format.DateTimeFormatter; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.Locale; +import java.util.TimeZone; + +import javax.xml.datatype.DatatypeConfigurationException; +import javax.xml.datatype.DatatypeFactory; +import javax.xml.datatype.XMLGregorianCalendar; + +import org.junit.Test; + +import com.baeldung.gregorian.calendar.GregorianCalendarExample; + +public class GregorianCalendarTester { + + @Test + public void test_Calendar_Return_Type_Valid() { + Calendar calendar = Calendar.getInstance(); + assert ("gregory".equals(calendar.getCalendarType())); + } + + @Test + public void test_Calendar_Return_Type_InValid() { + Calendar calendar = Calendar.getInstance(); + assertNotEquals("gregorys", calendar.getCalendarType()); + } + + @Test(expected = ClassCastException.class) + public void test_Class_Cast_Exception() { + TimeZone tz = TimeZone.getTimeZone("GMT+9:00"); + Locale loc = new Locale("ja", "JP", "JP"); + Calendar calendar = Calendar.getInstance(loc); + GregorianCalendar gc = (GregorianCalendar) calendar; + } + + @Test + public void test_Getting_Calendar_information() { + GregorianCalendar calendar = new GregorianCalendar(2018, 5, 28); + assertTrue(false == calendar.isLeapYear(calendar.YEAR)); + assertTrue(52 == calendar.getWeeksInWeekYear()); + assertTrue(2018 == calendar.getWeekYear()); + assertTrue(30 == calendar.getActualMaximum(calendar.DAY_OF_MONTH)); + assertTrue(1 == calendar.getActualMinimum(calendar.DAY_OF_MONTH)); + assertTrue(1 == calendar.getGreatestMinimum(calendar.DAY_OF_MONTH)); + assertTrue(28 == calendar.getLeastMaximum(calendar.DAY_OF_MONTH)); + assertTrue(31 == calendar.getMaximum(calendar.DAY_OF_MONTH)); + assertTrue(1 == calendar.getMinimum(calendar.DAY_OF_MONTH)); + assertTrue(52 == calendar.getWeeksInWeekYear()); + } + + @Test + public void test_Compare_Date_FirstDate_Greater_SecondDate() { + GregorianCalendar firstDate = new GregorianCalendar(2018, 6, 28); + GregorianCalendar secondDate = new GregorianCalendar(2018, 5, 28); + assertTrue(1 == firstDate.compareTo(secondDate)); + } + + + @Test + public void test_Compare_Date_FirstDate_Smaller_SecondDate() { + GregorianCalendar firstDate = new GregorianCalendar(2018, 5, 28); + GregorianCalendar secondDate = new GregorianCalendar(2018, 6, 28); + assertTrue(-1 == firstDate.compareTo(secondDate)); + } + + @Test + public void test_Compare_Date_Both_Dates_Equal() { + GregorianCalendar firstDate = new GregorianCalendar(2018, 6, 28); + GregorianCalendar secondDate = new GregorianCalendar(2018, 6, 28); + assertTrue(0 == firstDate.compareTo(secondDate)); + } + + @Test + public void test_date_format() { + GregorianCalendarExample calendarDemo = new GregorianCalendarExample(); + GregorianCalendar calendar = new GregorianCalendar(2018, 6, 28); + assertEquals("28 Jul 2018", calendarDemo.formatDate(calendar)); + } + + @Test + public void test_dateFormatdMMMuuuu() { + String expectedDate = new GregorianCalendar(2018, 6, 28).toZonedDateTime() + .format(DateTimeFormatter.ofPattern("d MMM uuuu")); + assertEquals("28 Jul 2018", expectedDate); + } + + @Test + public void test_addDays() { + GregorianCalendarExample calendarDemo = new GregorianCalendarExample(); + GregorianCalendar calendarActual = new GregorianCalendar(2018, 6, 28); + GregorianCalendar calendarExpected = new GregorianCalendar(2018, 6, 28); + calendarExpected.add(Calendar.DATE, 1); + Date expectedDate = calendarExpected.getTime(); + assertEquals(expectedDate, calendarDemo.addDays(calendarActual, 1)); + } + + @Test + public void test_whenAddOneDay_thenMonthIsChanged() { + final int finalDay1 = 1; + final int finalMonthJul = 6; + GregorianCalendar calendarExpected = new GregorianCalendar(2018, 5, 30); + calendarExpected.add(Calendar.DATE, 1); + System.out.println(calendarExpected.getTime()); + assertEquals(calendarExpected.get(Calendar.DATE), finalDay1); + assertEquals(calendarExpected.get(Calendar.MONTH), finalMonthJul); + } + + @Test + public void test_whenSubtractOneDay_thenMonthIsChanged() { + final int finalDay31 = 31; + final int finalMonthMay = 4; + GregorianCalendar calendarExpected = new GregorianCalendar(2018, 5, 1); + calendarExpected.add(Calendar.DATE, -1); + assertEquals(calendarExpected.get(Calendar.DATE), finalDay31); + assertEquals(calendarExpected.get(Calendar.MONTH), finalMonthMay); + } + + @Test + public void test_subDays() { + GregorianCalendarExample calendarDemo = new GregorianCalendarExample(); + GregorianCalendar calendarActual = new GregorianCalendar(2018, 6, 28); + GregorianCalendar calendarExpected = new GregorianCalendar(2018, 6, 28); + calendarExpected.add(Calendar.DATE, -1); + Date expectedDate = calendarExpected.getTime(); + assertEquals(expectedDate, calendarDemo.subtractDays(calendarActual, 1)); + } + + @Test + public void test_rollAdd() { + GregorianCalendarExample calendarDemo = new GregorianCalendarExample(); + GregorianCalendar calendarActual = new GregorianCalendar(2018, 6, 28); + GregorianCalendar calendarExpected = new GregorianCalendar(2018, 6, 28); + calendarExpected.roll(Calendar.MONTH, 8); + Date expectedDate = calendarExpected.getTime(); + assertEquals(expectedDate, calendarDemo.rollAdd(calendarActual, 8)); + } + + @Test + public void test_whenRollUpOneMonth_thenYearIsUnchanged() { + final int rolledUpMonthJuly = 7, orginalYear2018 = 2018; + GregorianCalendar calendarExpected = new GregorianCalendar(2018, 6, 28); + calendarExpected.roll(Calendar.MONTH, 1); + assertEquals(calendarExpected.get(Calendar.MONTH), rolledUpMonthJuly); + assertEquals(calendarExpected.get(Calendar.YEAR), orginalYear2018); + } + + @Test + public void test_whenRollDownOneMonth_thenYearIsUnchanged() { + final int rolledDownMonthJune = 5, orginalYear2018 = 2018; + GregorianCalendar calendarExpected = new GregorianCalendar(2018, 6, 28); + calendarExpected.roll(Calendar.MONTH, -1); + assertEquals(calendarExpected.get(Calendar.MONTH), rolledDownMonthJune); + assertEquals(calendarExpected.get(Calendar.YEAR), orginalYear2018); + } + + @Test + public void test_rollSubtract() { + GregorianCalendarExample calendarDemo = new GregorianCalendarExample(); + GregorianCalendar calendarActual = new GregorianCalendar(2018, 6, 28); + GregorianCalendar calendarExpected = new GregorianCalendar(2018, 6, 28); + calendarExpected.roll(Calendar.MONTH, -8); + Date expectedDate = calendarExpected.getTime(); + assertEquals(expectedDate, calendarDemo.rollAdd(calendarActual, -8)); + } + + @Test + public void test_setMonth() { + GregorianCalendarExample calendarDemo = new GregorianCalendarExample(); + GregorianCalendar calendarActual = new GregorianCalendar(2018, 6, 28); + GregorianCalendar calendarExpected = new GregorianCalendar(2018, 6, 28); + calendarExpected.set(Calendar.MONTH, 3); + Date expectedDate = calendarExpected.getTime(); + assertEquals(expectedDate, calendarDemo.setMonth(calendarActual, 3)); + } + + @Test + public void test_setMonthApril() { + final int setMonthApril = 3, orginalYear2018 = 2018, originalDate28 = 28; + GregorianCalendar calendarExpected = new GregorianCalendar(2018, 6, 28); + calendarExpected.set(Calendar.MONTH, 3); + assertEquals(calendarExpected.get(Calendar.MONTH), setMonthApril); + assertEquals(calendarExpected.get(Calendar.YEAR), orginalYear2018); + assertEquals(calendarExpected.get(Calendar.DATE), originalDate28); + } + + @Test + public void test_toXMLGregorianCalendar() throws DatatypeConfigurationException { + GregorianCalendarExample calendarDemo = new GregorianCalendarExample(); + DatatypeFactory datatypeFactory = DatatypeFactory.newInstance(); + GregorianCalendar calendarActual = new GregorianCalendar(2018, 6, 28); + GregorianCalendar calendarExpected = new GregorianCalendar(2018, 6, 28); + XMLGregorianCalendar expectedXMLGregorianCalendar = datatypeFactory + .newXMLGregorianCalendar(calendarExpected); + assertEquals(expectedXMLGregorianCalendar, + calendarDemo.toXMLGregorianCalendar(calendarActual)); + } + + @Test + public void test_isLeapYear_True() { + GregorianCalendarExample calendarDemo = new GregorianCalendarExample(); + assertEquals(true, calendarDemo.isLeapYearExample(2016)); + + } + + @Test + public void test_isLeapYear_False() { + GregorianCalendarExample calendarDemo = new GregorianCalendarExample(); + assertEquals(false, calendarDemo.isLeapYearExample(2018)); + + } + + @Test + public void test_toDate() throws DatatypeConfigurationException { + GregorianCalendar calendarActual = new GregorianCalendar(2018, 6, 28); + DatatypeFactory datatypeFactory = DatatypeFactory.newInstance(); + XMLGregorianCalendar expectedXMLGregorianCalendar = datatypeFactory + .newXMLGregorianCalendar(calendarActual); + expectedXMLGregorianCalendar.toGregorianCalendar().getTime(); + assertEquals(calendarActual.getTime(), + expectedXMLGregorianCalendar.toGregorianCalendar().getTime() ); + } +} diff --git a/core-kotlin/README.md b/core-kotlin/README.md index 69ad0a7dae..4695d12a06 100644 --- a/core-kotlin/README.md +++ b/core-kotlin/README.md @@ -32,3 +32,4 @@ - [Processing JSON with Kotlin and Klaxson](http://www.baeldung.com/kotlin-json-klaxson) - [Kotlin String Templates](http://www.baeldung.com/kotlin-string-template) - [Java EE 8 Security API](http://www.baeldung.com/java-ee-8-security) +- [Kotlin with Ktor](http://www.baeldung.com/kotlin-ktor) diff --git a/data-structures/src/main/java/com/baeldung/trie/Trie.java b/data-structures/src/main/java/com/baeldung/trie/Trie.java index dd51d97b2d..dac1a64733 100644 --- a/data-structures/src/main/java/com/baeldung/trie/Trie.java +++ b/data-structures/src/main/java/com/baeldung/trie/Trie.java @@ -1,13 +1,13 @@ package com.baeldung.trie; -public class Trie { +class Trie { private TrieNode root; Trie() { root = new TrieNode(); } - public void insert(String word) { + void insert(String word) { TrieNode current = root; for (int i = 0; i < word.length(); i++) { @@ -16,11 +16,11 @@ public class Trie { current.setEndOfWord(true); } - public boolean delete(String word) { + boolean delete(String word) { return delete(root, word, 0); } - public boolean containsNode(String word) { + boolean containsNode(String word) { TrieNode current = root; for (int i = 0; i < word.length(); i++) { @@ -34,7 +34,7 @@ public class Trie { return current.isEndOfWord(); } - public boolean isEmpty() { + boolean isEmpty() { return root == null; } @@ -51,7 +51,7 @@ public class Trie { if (node == null) { return false; } - boolean shouldDeleteCurrentNode = delete(node, word, index + 1); + boolean shouldDeleteCurrentNode = delete(node, word, index + 1) && !node.isEndOfWord(); if (shouldDeleteCurrentNode) { current.getChildren().remove(ch); diff --git a/data-structures/src/main/java/com/baeldung/trie/TrieNode.java b/data-structures/src/main/java/com/baeldung/trie/TrieNode.java index 25dc753950..73dcdb63f5 100644 --- a/data-structures/src/main/java/com/baeldung/trie/TrieNode.java +++ b/data-structures/src/main/java/com/baeldung/trie/TrieNode.java @@ -4,28 +4,18 @@ import java.util.HashMap; import java.util.Map; class TrieNode { - private Map children; + private final Map children = new HashMap<>(); private boolean endOfWord; - public TrieNode() { - children = new HashMap<>(); - endOfWord = false; - } - - public Map getChildren() { + Map getChildren() { return children; } - public void setChildren(Map children) { - this.children = children; - } - - public boolean isEndOfWord() { + boolean isEndOfWord() { return endOfWord; } - public void setEndOfWord(boolean endOfWord) { + void setEndOfWord(boolean endOfWord) { this.endOfWord = endOfWord; } - } \ No newline at end of file diff --git a/data-structures/src/test/java/com/baeldung/trie/TrieTest.java b/data-structures/src/test/java/com/baeldung/trie/TrieTest.java index be7e5575d8..6f7073651e 100644 --- a/data-structures/src/test/java/com/baeldung/trie/TrieTest.java +++ b/data-structures/src/test/java/com/baeldung/trie/TrieTest.java @@ -1,6 +1,7 @@ package com.baeldung.trie; import org.junit.Test; +import org.junit.jupiter.api.Assertions; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -53,6 +54,19 @@ public class TrieTest { assertFalse(trie.containsNode("Programming")); } + @Test + public void givenATrie_whenDeletingOverlappingElements_thenDontDeleteSubElement() { + + Trie trie1 = new Trie(); + + trie1.insert("pie"); + trie1.insert("pies"); + + trie1.delete("pies"); + + Assertions.assertTrue(trie1.containsNode("pie")); + } + private Trie createExampleTrie() { Trie trie = new Trie(); diff --git a/ethereum/pom.xml b/ethereum/pom.xml index 02b9e5afe1..f07ed2c6a0 100644 --- a/ethereum/pom.xml +++ b/ethereum/pom.xml @@ -1,47 +1,17 @@ + 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.ethereum ethereum 0.0.1-SNAPSHOT ethereum - - - - - UTF-8 - 1.8 - 8.5.4 - 1.5.0-RELEASE - 3.3.1 - 5.0.5.RELEASE - 1.5.6.RELEASE - 2.18.1 - 1.10.19 - 2.5.0 - 1.3 - 2.9.3 - 2.3.1 - 3.1.0 - 2.4.0 - 1.2 - 4.12 - 1.2.3 - 1.7.25 - - - - - Ethereum - Ethereum - https://dl.bintray.com/ethereum/maven/ - - + + parent-spring-5 + com.baeldung + 0.0.1-SNAPSHOT + ../parent-spring-5 + @@ -64,7 +34,7 @@ - + org.springframework spring-core ${springframework.version} @@ -199,7 +169,9 @@ ${jsonpath.version} + + ethereum maven-compiler-plugin @@ -222,21 +194,36 @@ false - - org.apache.maven.plugins - maven-surefire-plugin - ${maven-surefire.version} - - - install - install - - test - - - - - ethereum + + + + Ethereum + Ethereum + https://dl.bintray.com/ethereum/maven/ + + + + + UTF-8 + 1.8 + 8.5.4 + 1.5.0-RELEASE + 3.3.1 + 5.0.5.RELEASE + 1.5.6.RELEASE + 1.10.19 + 2.5.0 + 1.3 + 2.9.3 + 2.3.1 + 3.1.0 + 2.4.0 + 1.2 + 4.12 + 1.2.3 + 1.7.25 + + diff --git a/javax-servlet-init-params/pom.xml b/javax-servlet-init-params/pom.xml deleted file mode 100644 index 4f766a7e2c..0000000000 --- a/javax-servlet-init-params/pom.xml +++ /dev/null @@ -1,56 +0,0 @@ - - - 4.0.0 - com.baeldung.javax-servlet-init-params - javax-servlet-init-params - 1.0 - - - com.baeldung - parent-modules - 1.0.0-SNAPSHOT - - - - - junit - junit - 4.12 - test - - - org.assertj - assertj-core - 3.9.1 - test - - - org.hamcrest - hamcrest-core - 1.3 - test - - - org.mockito - mockito-core - 2.18.3 - test - - - javax - javaee-web-api - 7.0 - provided - - - jstl - jstl - 1.2 - - - javax.el - el-api - 2.2 - - - \ No newline at end of file diff --git a/javax-servlet-init-params/src/main/webapp/WEB-INF/web.xml b/javax-servlet-init-params/src/main/webapp/WEB-INF/web.xml deleted file mode 100644 index 1b801171b3..0000000000 --- a/javax-servlet-init-params/src/main/webapp/WEB-INF/web.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - province - Mendoza - - - country - Argentina - - diff --git a/javax-servlets/pom.xml b/javax-servlets/pom.xml index f64ce67a1f..fadf0216ce 100644 --- a/javax-servlets/pom.xml +++ b/javax-servlets/pom.xml @@ -1,79 +1,104 @@ - - - 4.0.0 - javax-servlets - 1.0-SNAPSHOT - - - com.baeldung - parent-modules - 1.0.0-SNAPSHOT - - - - - - commons-fileupload - commons-fileupload - 1.3.3 - - - commons-io - commons-io - 2.6 - - - - - javax.servlet - javax.servlet-api - 4.0.1 - - - javax.servlet.jsp.jstl - jstl-api - 1.2 - - - javax.servlet.jsp - javax.servlet.jsp-api - 2.3.1 - - - javax.servlet - jstl - 1.2 - - - - org.apache.httpcomponents - httpclient - ${org.apache.httpcomponents.version} - test - - - commons-logging - commons-logging - - - - - com.google.code.gson - gson - ${gson.version} - - - org.springframework - spring-test - ${spring-test.version} - test - - - - - 4.5.3 - 5.0.5.RELEASE - 2.8.2 - - \ No newline at end of file + + + 4.0.0 + com.baeldung.javax-servlets + javax-servlets + 1.0-SNAPSHOT + war + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + + + junit + junit + 4.12 + test + + + org.assertj + assertj-core + 3.9.1 + test + + + org.hamcrest + hamcrest-core + 1.3 + test + + + org.mockito + mockito-core + 2.18.3 + test + + + + + commons-fileupload + commons-fileupload + 1.3.3 + + + commons-io + commons-io + 2.6 + + + + + javax.servlet + javax.servlet-api + 4.0.1 + + + javax.servlet.jsp.jstl + jstl-api + 1.2 + + + javax.servlet.jsp + javax.servlet.jsp-api + 2.3.1 + + + javax.servlet + jstl + 1.2 + + + + org.apache.httpcomponents + httpclient + ${org.apache.httpcomponents.version} + test + + + commons-logging + commons-logging + + + + + com.google.code.gson + gson + ${gson.version} + + + org.springframework + spring-test + ${spring-test.version} + test + + + + 3.1.0 + 4.5.3 + 5.0.5.RELEASE + 2.8.2 + + diff --git a/javax-servlet-init-params/src/main/java/com/baeldung/servlets/UserServlet.java b/javax-servlets/src/main/java/com/baeldung/servlets/UserServlet.java similarity index 97% rename from javax-servlet-init-params/src/main/java/com/baeldung/servlets/UserServlet.java rename to javax-servlets/src/main/java/com/baeldung/servlets/UserServlet.java index e195aa092a..269cee3922 100644 --- a/javax-servlet-init-params/src/main/java/com/baeldung/servlets/UserServlet.java +++ b/javax-servlets/src/main/java/com/baeldung/servlets/UserServlet.java @@ -1,49 +1,49 @@ -package com.baeldung.servlets; - -import java.io.IOException; -import javax.servlet.ServletException; -import javax.servlet.annotation.WebInitParam; -import javax.servlet.annotation.WebServlet; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -@WebServlet(name = "UserServlet", urlPatterns = {"/userServlet"}, initParams={ - @WebInitParam(name="name", value="Not provided"), - @WebInitParam(name="email", value="Not provided")}) -public class UserServlet extends HttpServlet { - - @Override - protected void doGet(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { - } - - @Override - protected void doPost(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { - processRequest(request, response); - forwardRequest(request, response, "/WEB-INF/jsp/result.jsp"); - } - - protected void processRequest(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { - request.setAttribute("name", getRequestParameter(request, "name")); - request.setAttribute("email", getRequestParameter(request, "email")); - request.setAttribute("province", getContextParameter("province")); - request.setAttribute("country", getContextParameter("country")); - } - - protected String getRequestParameter(HttpServletRequest request, String name) { - String param = request.getParameter(name); - return !param.isEmpty() ? param : getInitParameter(name); - } - - protected String getContextParameter(String name) { - return getServletContext().getInitParameter(name); - } - - protected void forwardRequest(HttpServletRequest request, HttpServletResponse response, String path) - throws ServletException, IOException { - request.getRequestDispatcher(path).forward(request, response); - } +package com.baeldung.servlets; + +import java.io.IOException; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebInitParam; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +@WebServlet(name = "UserServlet", urlPatterns = {"/userServlet"}, initParams={ + @WebInitParam(name="name", value="Not provided"), + @WebInitParam(name="email", value="Not provided")}) +public class UserServlet extends HttpServlet { + + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + } + + @Override + protected void doPost(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + processRequest(request, response); + forwardRequest(request, response, "/WEB-INF/jsp/result.jsp"); + } + + protected void processRequest(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + request.setAttribute("name", getRequestParameter(request, "name")); + request.setAttribute("email", getRequestParameter(request, "email")); + request.setAttribute("province", getContextParameter("province")); + request.setAttribute("country", getContextParameter("country")); + } + + protected String getRequestParameter(HttpServletRequest request, String name) { + String param = request.getParameter(name); + return !param.isEmpty() ? param : getInitParameter(name); + } + + protected String getContextParameter(String name) { + return getServletContext().getInitParameter(name); + } + + protected void forwardRequest(HttpServletRequest request, HttpServletResponse response, String path) + throws ServletException, IOException { + request.getRequestDispatcher(path).forward(request, response); + } } \ No newline at end of file diff --git a/javax-servlet-init-params/src/main/webapp/WEB-INF/jsp/result.jsp b/javax-servlets/src/main/webapp/WEB-INF/jsp/result.jsp similarity index 100% rename from javax-servlet-init-params/src/main/webapp/WEB-INF/jsp/result.jsp rename to javax-servlets/src/main/webapp/WEB-INF/jsp/result.jsp diff --git a/javax-servlets/src/main/webapp/WEB-INF/web.xml b/javax-servlets/src/main/webapp/WEB-INF/web.xml index c9a06ac52d..383be7ff25 100644 --- a/javax-servlets/src/main/webapp/WEB-INF/web.xml +++ b/javax-servlets/src/main/webapp/WEB-INF/web.xml @@ -1,9 +1,17 @@ + - + + province + Mendoza + + + country + Argentina + 404 /error-404.html diff --git a/javax-servlet-init-params/src/main/webapp/index.jsp b/javax-servlets/src/main/webapp/user.jsp similarity index 90% rename from javax-servlet-init-params/src/main/webapp/index.jsp rename to javax-servlets/src/main/webapp/user.jsp index ca41942e5d..c6e1bb69f9 100644 --- a/javax-servlet-init-params/src/main/webapp/index.jsp +++ b/javax-servlets/src/main/webapp/user.jsp @@ -3,7 +3,7 @@ - Context and Initialization Servlet Parameters + Context and Servlet Initialization Parameters diff --git a/javax-servlets/src/test/java/com/baeldung/servlets/FormServletLiveTest.java b/javax-servlets/src/test/java/com/baeldung/test/FormServletLiveTest.java similarity index 100% rename from javax-servlets/src/test/java/com/baeldung/servlets/FormServletLiveTest.java rename to javax-servlets/src/test/java/com/baeldung/test/FormServletLiveTest.java diff --git a/javax-servlet-init-params/src/test/java/com/baeldung/test/UserServletUnitTest.java b/javax-servlets/src/test/java/com/baeldung/test/UserServletUnitTest.java similarity index 95% rename from javax-servlet-init-params/src/test/java/com/baeldung/test/UserServletUnitTest.java rename to javax-servlets/src/test/java/com/baeldung/test/UserServletUnitTest.java index ef3d877dd7..d4c93791d2 100644 --- a/javax-servlet-init-params/src/test/java/com/baeldung/test/UserServletUnitTest.java +++ b/javax-servlets/src/test/java/com/baeldung/test/UserServletUnitTest.java @@ -1,52 +1,52 @@ -package com.baeldung.test; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import static org.assertj.core.api.Assertions.assertThat; -import org.junit.BeforeClass; -import org.junit.Test; -import static org.mockito.Mockito.atLeast; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class UserServletUnitTest { - - private static HttpServletRequest request; - private static HttpServletResponse response; - - - @BeforeClass - public static void setUpHttpServletRequestMockInstance() { - request = mock(HttpServletRequest.class); - } - - @BeforeClass - public static void setUpHttpServletResponsetMockInstance() { - response = mock(HttpServletResponse.class); - } - - @Test - public void givenHttpServletRequestMockInstance_whenCalledgetParameter_thenCalledAtLeastOnce() { - request.getParameter("name"); - verify(request, atLeast(1)).getParameter("name"); - } - - @Test - public void givenHttpServletRequestMockInstance_whenCalledgetParameter_thenOneAssertion() { - when(request.getParameter("name")).thenReturn("username"); - assertThat(request.getParameter("name")).isEqualTo("username"); - } - - @Test - public void givenHttpServletResponseMockInstance_whenCalledgetContentType_thenCalledAtLeastOnce() { - response.getContentType(); - verify(response, atLeast(1)).getContentType(); - } - - @Test - public void givenHttpServletResponseMockInstance_whenCalledgetContentType_thenOneAssertion() { - when(response.getContentType()).thenReturn("text/html"); - assertThat(response.getContentType()).isEqualTo("text/html"); - } +package com.baeldung.servlets; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import static org.assertj.core.api.Assertions.assertThat; +import org.junit.BeforeClass; +import org.junit.Test; +import static org.mockito.Mockito.atLeast; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +public class UserServletUnitTest { + + private static HttpServletRequest request; + private static HttpServletResponse response; + + + @BeforeClass + public static void setUpHttpServletRequestMockInstance() { + request = mock(HttpServletRequest.class); + } + + @BeforeClass + public static void setUpHttpServletResponsetMockInstance() { + response = mock(HttpServletResponse.class); + } + + @Test + public void givenHttpServletRequestMockInstance_whenCalledgetParameter_thenCalledAtLeastOnce() { + request.getParameter("name"); + verify(request, atLeast(1)).getParameter("name"); + } + + @Test + public void givenHttpServletRequestMockInstance_whenCalledgetParameter_thenOneAssertion() { + when(request.getParameter("name")).thenReturn("username"); + assertThat(request.getParameter("name")).isEqualTo("username"); + } + + @Test + public void givenHttpServletResponseMockInstance_whenCalledgetContentType_thenCalledAtLeastOnce() { + response.getContentType(); + verify(response, atLeast(1)).getContentType(); + } + + @Test + public void givenHttpServletResponseMockInstance_whenCalledgetContentType_thenOneAssertion() { + when(response.getContentType()).thenReturn("text/html"); + assertThat(response.getContentType()).isEqualTo("text/html"); + } } \ No newline at end of file diff --git a/libraries/pom.xml b/libraries/pom.xml index 70346fd799..a7efd55f1d 100644 --- a/libraries/pom.xml +++ b/libraries/pom.xml @@ -705,6 +705,37 @@ ${jctools.version} + + + io.github.resilience4j + resilience4j-circuitbreaker + ${resilience4j.version} + + + io.github.resilience4j + resilience4j-ratelimiter + ${resilience4j.version} + + + io.github.resilience4j + resilience4j-bulkhead + ${resilience4j.version} + + + io.github.resilience4j + resilience4j-retry + ${resilience4j.version} + + + io.github.resilience4j + resilience4j-cache + ${resilience4j.version} + + + io.github.resilience4j + resilience4j-timelimiter + ${resilience4j.version} + org.apache.commons commons-math3 @@ -951,6 +982,7 @@ 0.9.4.0006L 2.1.2 2.5.11 + 0.12.1 3.6.1 3.5.2 3.6 diff --git a/libraries/src/test/java/com/baeldung/resilience4j/Resilience4jUnitTest.java b/libraries/src/test/java/com/baeldung/resilience4j/Resilience4jUnitTest.java new file mode 100644 index 0000000000..ced95c99cb --- /dev/null +++ b/libraries/src/test/java/com/baeldung/resilience4j/Resilience4jUnitTest.java @@ -0,0 +1,126 @@ +package com.baeldung.resilience4j; + +import io.github.resilience4j.bulkhead.Bulkhead; +import io.github.resilience4j.bulkhead.BulkheadConfig; +import io.github.resilience4j.bulkhead.BulkheadRegistry; +import io.github.resilience4j.circuitbreaker.CircuitBreaker; +import io.github.resilience4j.circuitbreaker.CircuitBreakerConfig; +import io.github.resilience4j.circuitbreaker.CircuitBreakerRegistry; +import io.github.resilience4j.retry.Retry; +import io.github.resilience4j.retry.RetryConfig; +import io.github.resilience4j.retry.RetryRegistry; +import io.github.resilience4j.timelimiter.TimeLimiter; +import io.github.resilience4j.timelimiter.TimeLimiterConfig; +import org.junit.Before; +import org.junit.Test; + +import java.time.Duration; +import java.util.concurrent.*; +import java.util.function.Function; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.fail; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.*; + +public class Resilience4jUnitTest { + + interface RemoteService { + + int process(int i); + } + + private RemoteService service; + + @Before + public void setUp() { + service = mock(RemoteService.class); + } + + @Test + public void whenCircuitBreakerIsUsed_thenItWorksAsExpected() { + CircuitBreakerConfig config = CircuitBreakerConfig.custom() + // Percentage of failures to start short-circuit + .failureRateThreshold(20) + // Min number of call attempts + .ringBufferSizeInClosedState(5) + .build(); + CircuitBreakerRegistry registry = CircuitBreakerRegistry.of(config); + CircuitBreaker circuitBreaker = registry.circuitBreaker("my"); + Function decorated = CircuitBreaker.decorateFunction(circuitBreaker, service::process); + + when(service.process(anyInt())).thenThrow(new RuntimeException()); + + for (int i = 0; i < 10; i++) { + try { + decorated.apply(i); + } catch (Exception ignore) { + } + } + + verify(service, times(5)).process(any(Integer.class)); + } + + @Test + public void whenBulkheadIsUsed_thenItWorksAsExpected() throws InterruptedException { + BulkheadConfig config = BulkheadConfig.custom().maxConcurrentCalls(1).build(); + BulkheadRegistry registry = BulkheadRegistry.of(config); + Bulkhead bulkhead = registry.bulkhead("my"); + Function decorated = Bulkhead.decorateFunction(bulkhead, service::process); + + Future taskInProgress = callAndBlock(decorated); + try { + assertThat(bulkhead.isCallPermitted()).isFalse(); + } finally { + taskInProgress.cancel(true); + } + } + + private Future callAndBlock(Function decoratedService) throws InterruptedException { + CountDownLatch latch = new CountDownLatch(1); + when(service.process(anyInt())).thenAnswer(invocation -> { + latch.countDown(); + Thread.currentThread().join(); + return null; + }); + + ForkJoinTask result = ForkJoinPool.commonPool().submit(() -> { + decoratedService.apply(1); + }); + latch.await(); + return result; + } + + @Test + public void whenRetryIsUsed_thenItWorksAsExpected() { + RetryConfig config = RetryConfig.custom().maxAttempts(2).build(); + RetryRegistry registry = RetryRegistry.of(config); + Retry retry = registry.retry("my"); + Function decorated = Retry.decorateFunction(retry, (Integer s) -> { + service.process(s); + return null; + }); + + when(service.process(anyInt())).thenThrow(new RuntimeException()); + try { + decorated.apply(1); + fail("Expected an exception to be thrown if all retries failed"); + } catch (Exception e) { + verify(service, times(2)).process(any(Integer.class)); + } + } + + @SuppressWarnings("unchecked") + @Test + public void whenTimeLimiterIsUsed_thenItWorksAsExpected() throws Exception { + long ttl = 1; + TimeLimiterConfig config = TimeLimiterConfig.custom().timeoutDuration(Duration.ofMillis(ttl)).build(); + TimeLimiter timeLimiter = TimeLimiter.of(config); + + Future futureMock = mock(Future.class); + Callable restrictedCall = TimeLimiter.decorateFutureSupplier(timeLimiter, () -> futureMock); + restrictedCall.call(); + + verify(futureMock).get(ttl, TimeUnit.MILLISECONDS); + } +} diff --git a/meecrowave/pom.xml b/meecrowave/pom.xml new file mode 100644 index 0000000000..cf13aa1c1b --- /dev/null +++ b/meecrowave/pom.xml @@ -0,0 +1,57 @@ + + 4.0.0 + com.baeldung + apache-meecrowave + 0.0.1 + apache-meecrowave + A sample REST API application with Meecrowave + + + 1.8 + 1.8 + + + + + org.apache.meecrowave + meecrowave-core + 1.2.1 + + + + org.apache.meecrowave + meecrowave-jpa + 1.2.1 + + + + com.squareup.okhttp3 + okhttp + 3.10.0 + + + org.apache.meecrowave + meecrowave-junit + 1.2.0 + test + + + + junit + junit + 4.10 + test + + + + + + + org.apache.meecrowave + meecrowave-maven-plugin + 1.2.1 + + + + \ No newline at end of file diff --git a/meecrowave/src/main/java/com/baeldung/meecrowave/Article.java b/meecrowave/src/main/java/com/baeldung/meecrowave/Article.java new file mode 100644 index 0000000000..7925e8ff99 --- /dev/null +++ b/meecrowave/src/main/java/com/baeldung/meecrowave/Article.java @@ -0,0 +1,30 @@ +package com.baeldung.meecrowave; + +public class Article { + private String name; + private String author; + + public Article() { + } + + public Article(String name, String author) { + this.author = author; + this.name = name; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } +} \ No newline at end of file diff --git a/meecrowave/src/main/java/com/baeldung/meecrowave/ArticleEndpoints.java b/meecrowave/src/main/java/com/baeldung/meecrowave/ArticleEndpoints.java new file mode 100644 index 0000000000..6cb7012c64 --- /dev/null +++ b/meecrowave/src/main/java/com/baeldung/meecrowave/ArticleEndpoints.java @@ -0,0 +1,32 @@ +package com.baeldung.meecrowave; + +import javax.enterprise.context.RequestScoped; +import javax.inject.Inject; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; + +@RequestScoped +@Path("article") +public class ArticleEndpoints { + + @Inject + ArticleService articleService; + + @GET + public Response getArticle() { + return Response.ok() + .entity(new Article("name", "author")) + .build(); + + } + + @POST + public Response createArticle(Article article) { + return Response.status(Status.CREATED) + .entity(articleService.createArticle(article)) + .build(); + } +} \ No newline at end of file diff --git a/meecrowave/src/main/java/com/baeldung/meecrowave/ArticleService.java b/meecrowave/src/main/java/com/baeldung/meecrowave/ArticleService.java new file mode 100644 index 0000000000..7bd6b87345 --- /dev/null +++ b/meecrowave/src/main/java/com/baeldung/meecrowave/ArticleService.java @@ -0,0 +1,10 @@ +package com.baeldung.meecrowave; + +import javax.enterprise.context.ApplicationScoped; + +@ApplicationScoped +public class ArticleService { + public Article createArticle(Article article) { + return article; + } +} diff --git a/meecrowave/src/main/java/com/baeldung/meecrowave/Server.java b/meecrowave/src/main/java/com/baeldung/meecrowave/Server.java new file mode 100644 index 0000000000..2aa7d0556f --- /dev/null +++ b/meecrowave/src/main/java/com/baeldung/meecrowave/Server.java @@ -0,0 +1,16 @@ +package com.baeldung.meecrowave; + +import org.apache.meecrowave.Meecrowave; + +public class Server { + public static void main(String[] args) { + final Meecrowave.Builder builder = new Meecrowave.Builder(); + builder.setScanningPackageIncludes("com.baeldung.meecrowave"); + builder.setJaxrsMapping("/api/*"); + builder.setJsonpPrettify(true); + + try (Meecrowave meecrowave = new Meecrowave(builder)) { + meecrowave.bake().await(); + } + } +} diff --git a/meecrowave/src/test/java/com/baeldung/meecrowave/ArticleEndpointsTest.java b/meecrowave/src/test/java/com/baeldung/meecrowave/ArticleEndpointsTest.java new file mode 100644 index 0000000000..0dc9773490 --- /dev/null +++ b/meecrowave/src/test/java/com/baeldung/meecrowave/ArticleEndpointsTest.java @@ -0,0 +1,41 @@ +package com.baeldung.meecrowave; + + +import static org.junit.Assert.assertEquals; + +import java.io.IOException; + +import org.apache.meecrowave.Meecrowave; +import org.apache.meecrowave.junit.MonoMeecrowave; +import org.apache.meecrowave.testing.ConfigurationInject; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; + +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; + +@RunWith(MonoMeecrowave.Runner.class) +public class ArticleEndpointsTest { + + @ConfigurationInject + private Meecrowave.Builder config; + private static OkHttpClient client; + + @BeforeClass + public static void setup() { + client = new OkHttpClient(); + } + + @Test + public void whenRetunedArticle_thenCorrect() throws IOException { + final String base = "http://localhost:"+config.getHttpPort(); + + Request request = new Request.Builder() + .url(base+"/article") + .build(); + Response response = client.newCall(request).execute(); + assertEquals(200, response.code()); + } +} diff --git a/persistence-modules/java-cockroachdb/src/test/java/com/baeldung/cockroachdb/ArticleRepositoryIntegrationTest.java b/persistence-modules/java-cockroachdb/src/test/java/com/baeldung/cockroachdb/ArticleRepositoryLiveTest.java similarity index 99% rename from persistence-modules/java-cockroachdb/src/test/java/com/baeldung/cockroachdb/ArticleRepositoryIntegrationTest.java rename to persistence-modules/java-cockroachdb/src/test/java/com/baeldung/cockroachdb/ArticleRepositoryLiveTest.java index 9eb00b3651..eda9ca15e4 100644 --- a/persistence-modules/java-cockroachdb/src/test/java/com/baeldung/cockroachdb/ArticleRepositoryIntegrationTest.java +++ b/persistence-modules/java-cockroachdb/src/test/java/com/baeldung/cockroachdb/ArticleRepositoryLiveTest.java @@ -16,7 +16,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -public class ArticleRepositoryIntegrationTest { +public class ArticleRepositoryLiveTest { private static final String TABLE_NAME = "articles"; diff --git a/persistence-modules/java-jpa/pom.xml b/persistence-modules/java-jpa/pom.xml new file mode 100644 index 0000000000..78764f7148 --- /dev/null +++ b/persistence-modules/java-jpa/pom.xml @@ -0,0 +1,32 @@ + + + + parent-modules + com.baeldung + 1.0.0-SNAPSHOT + ../../pom.xml + + 4.0.0 + + java-jpa + + + + org.hibernate + hibernate-core + ${hibernate.version} + + + com.h2database + h2 + ${h2.version} + + + + + 5.3.1.Final + 1.4.197 + + \ No newline at end of file diff --git a/persistence-modules/java-jpa/src/main/java/com/baeldung/sqlresultsetmapping/Employee.java b/persistence-modules/java-jpa/src/main/java/com/baeldung/sqlresultsetmapping/Employee.java new file mode 100644 index 0000000000..bec1b8845a --- /dev/null +++ b/persistence-modules/java-jpa/src/main/java/com/baeldung/sqlresultsetmapping/Employee.java @@ -0,0 +1,43 @@ +package com.baeldung.sqlresultsetmapping; + +import javax.persistence.*; + + +@SqlResultSetMapping( + name="EmployeeResult", + entities={ + @EntityResult( + entityClass = com.baeldung.sqlresultsetmapping.Employee.class, + fields={@FieldResult(name="id",column="employeeNumber"), + @FieldResult(name="name", column="name")} + ) + } +) +@NamedNativeQuery( + name="Employees", + query="SELECT id as employeeNumber, name FROM EMPLOYEE", + resultSetMapping = "EmployeeResult" +) +@Entity +public class Employee { + + @Id + private Long id; + private String name; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/persistence-modules/java-jpa/src/main/java/com/baeldung/sqlresultsetmapping/ScheduledDay.java b/persistence-modules/java-jpa/src/main/java/com/baeldung/sqlresultsetmapping/ScheduledDay.java new file mode 100644 index 0000000000..b72454c506 --- /dev/null +++ b/persistence-modules/java-jpa/src/main/java/com/baeldung/sqlresultsetmapping/ScheduledDay.java @@ -0,0 +1,80 @@ +package com.baeldung.sqlresultsetmapping; + +import javax.persistence.*; + +@SqlResultSetMappings(value = { + @SqlResultSetMapping(name = "ScheduleResult", + classes = { @ConstructorResult(targetClass = com.baeldung.sqlresultsetmapping.ScheduledDay.class, + columns = { @ColumnResult(name = "id", type = Long.class), + @ColumnResult(name = "employeeId", type = Long.class), + @ColumnResult(name = "hourIn"), + @ColumnResult(name = "hourOut"), + @ColumnResult(name = "dayOfWeek") }) }), + @SqlResultSetMapping(name = "FridayEmployeeResult", + columns = { @ColumnResult(name = "employeeId") }), + @SqlResultSetMapping(name = "EmployeeScheduleResults", + entities = { @EntityResult(entityClass = com.baeldung.sqlresultsetmapping.Employee.class), + @EntityResult(entityClass = com.baeldung.sqlresultsetmapping.ScheduledDay.class) + }) }) +@NamedNativeQuery(name = "FridayEmployees", + query = "SELECT employeeId FROM schedule_days WHERE dayOfWeek = 'FRIDAY'", + resultSetMapping = "FridayEmployeeResult") + +@NamedNativeQuery(name = "Schedules", + query = "SELECT * FROM schedule_days WHERE hourIn = 8", + resultSetMapping = "ScheduleResult") +@Entity +@Table(name = "SCHEDULE_DAYS") +public class ScheduledDay { + + @Id + @GeneratedValue + private Long id; + private Long employeeId; + private Integer hourIn; + private Integer hourOut; + private String dayOfWeek; + + public ScheduledDay() { + } + + public ScheduledDay(Long id, Long employeeId, Integer hourIn, Integer hourOut, String dayofWeek) { + this.id = id; + this.employeeId = employeeId; + this.hourIn = hourIn; + this.hourOut = hourOut; + this.dayOfWeek = dayofWeek; + } + + public Long getEmployeeId() { + return employeeId; + } + + public void setEmployeeId(Long employeeId) { + this.employeeId = employeeId; + } + + public Integer getHourIn() { + return hourIn; + } + + public void setHourIn(Integer hourIn) { + this.hourIn = hourIn; + } + + public Integer getHourOut() { + return hourOut; + } + + public void setHourOut(Integer hourOut) { + this.hourOut = hourOut; + } + + public String getDayOfWeek() { + return dayOfWeek; + } + + public void setDayOfWeek(String dayOfWeek) { + this.dayOfWeek = dayOfWeek; + } +} diff --git a/persistence-modules/java-jpa/src/main/resources/META-INF/persistence.xml b/persistence-modules/java-jpa/src/main/resources/META-INF/persistence.xml new file mode 100644 index 0000000000..e9230eb6cd --- /dev/null +++ b/persistence-modules/java-jpa/src/main/resources/META-INF/persistence.xml @@ -0,0 +1,23 @@ + + + + + org.hibernate.jpa.HibernatePersistenceProvider + com.baeldung.sqlresultsetmapping.ScheduledDay + + + + + + + + + + + + \ No newline at end of file diff --git a/persistence-modules/java-jpa/src/main/resources/database.sql b/persistence-modules/java-jpa/src/main/resources/database.sql new file mode 100644 index 0000000000..3310c79a85 --- /dev/null +++ b/persistence-modules/java-jpa/src/main/resources/database.sql @@ -0,0 +1,19 @@ +CREATE TABLE EMPLOYEE +(id BIGINT, + name VARCHAR(10)); + +INSERT INTO EMPLOYEE VALUES (1, 'JOHN'); +INSERT INTO EMPLOYEE VALUES (2, 'MARY'); +INSERT INTO EMPLOYEE VALUES (3, 'FRANK'); + +CREATE TABLE SCHEDULE_DAYS +(id IDENTITY, + employeeId BIGINT, + hourIn int, + hourOut int, + dayOfWeek VARCHAR(10)); + +INSERT INTO SCHEDULE_DAYS (employeeId, hourIn, hourOut, dayOfWeek) VALUES (1, 13, 21, 'FRIDAY'); +INSERT INTO SCHEDULE_DAYS (employeeId, hourIn, hourOut, dayOfWeek) VALUES (2, 8, 4, 'SATURDAY'); +INSERT INTO SCHEDULE_DAYS (employeeId, hourIn, hourOut, dayOfWeek) VALUES (3, 8, 4, 'MONDAY'); +INSERT INTO SCHEDULE_DAYS (employeeId, hourIn, hourOut, dayOfWeek) VALUES (3, 8, 4, 'FRIDAY'); \ No newline at end of file diff --git a/persistence-modules/java-jpa/src/test/java/com/baeldung/sqlresultsetmapping/SqlResultSetMappingUnitTest.java b/persistence-modules/java-jpa/src/test/java/com/baeldung/sqlresultsetmapping/SqlResultSetMappingUnitTest.java new file mode 100644 index 0000000000..7f0cbd3c1d --- /dev/null +++ b/persistence-modules/java-jpa/src/test/java/com/baeldung/sqlresultsetmapping/SqlResultSetMappingUnitTest.java @@ -0,0 +1,71 @@ +package com.baeldung.sqlresultsetmapping; + +import static org.junit.Assert.*; + +import org.junit.jupiter.api.*; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; +import java.util.Collections; +import java.util.List; + +public class SqlResultSetMappingUnitTest { + + private static EntityManager em; + private static EntityManagerFactory emFactory; + + @BeforeAll + public static void setup() { + emFactory = Persistence.createEntityManagerFactory("java-jpa-scheduled-day"); + em = emFactory.createEntityManager(); + } + + @Test + public void whenNamedQuery_thenColumnResult() { + List employeeIds = em.createNamedQuery("FridayEmployees").getResultList(); + assertEquals(2, employeeIds.size()); + } + + @Test + public void whenNamedQuery_thenConstructorResult() { + List scheduleDays = Collections.checkedList(em.createNamedQuery("Schedules", ScheduledDay.class).getResultList(), ScheduledDay.class); + assertEquals(3, scheduleDays.size()); + assertTrue(scheduleDays.stream().allMatch(c -> c.getHourIn().longValue() == 8)); + } + + @Test + public void whenNamedQuery_thenSingleEntityResult() { + List employees = Collections.checkedList(em.createNamedQuery("Employees").getResultList(), Employee.class); + assertEquals(3, employees.size()); + assertTrue(employees.stream().allMatch(c -> c.getClass() == Employee.class)); + } + + @Test + public void whenNamedQuery_thenMultipleEntityResult() { + final Query query = em.createNativeQuery("SELECT e.id, e.name, d.id, d.employeeId, " + + " d.dayOfWeek, d.hourIn, d.hourOut " + + " FROM employee e, schedule_days d " + + " WHERE e.id = d.employeeId", "EmployeeScheduleResults"); + List results = query.getResultList(); + assertEquals(4, results.size()); + assertTrue(results.get(0).length == 2); + + Employee emp = (Employee) results.get(1)[0]; + ScheduledDay day = (ScheduledDay) results.get(1)[1]; + + assertTrue(day.getEmployeeId() == emp.getId()); + } + + @AfterAll + public static void destroy() { + + if (em != null) { + em.close(); + } + if (emFactory != null) { + emFactory.close(); + } + } +} diff --git a/persistence-modules/java-jpa/src/test/resources/employees.sql b/persistence-modules/java-jpa/src/test/resources/employees.sql new file mode 100644 index 0000000000..feace36e2c --- /dev/null +++ b/persistence-modules/java-jpa/src/test/resources/employees.sql @@ -0,0 +1,3 @@ +INSERT INTO employee (1, "JOHN"); +INSERT INTO employee (2, "MARY"); +INSERT INTO employee (3, "FRANK"); \ No newline at end of file diff --git a/persistence-modules/java-jpa/src/test/resources/scheduledDays.sql b/persistence-modules/java-jpa/src/test/resources/scheduledDays.sql new file mode 100644 index 0000000000..df1d4ed09e --- /dev/null +++ b/persistence-modules/java-jpa/src/test/resources/scheduledDays.sql @@ -0,0 +1,10 @@ +INSERT INTO SCHEDULE_DAYS (1, 13, 21, 'FRIDAY'); +INSERT INTO SCHEDULE_DAYS (2, 8, 4, 'SATURDAY'); +INSERT INTO SCHEDULE_DAYS (3, 8, 4, 'FRIDAY'); + + +-- private Long id; +-- private Long employeeId; +-- private Time in; +-- private Time out; +-- private DayOfWeek dayOfWeek; \ No newline at end of file diff --git a/persistence-modules/spring-data-dynamodb/pom.xml b/persistence-modules/spring-data-dynamodb/pom.xml index b1b7c8237b..b19c3b9c93 100644 --- a/persistence-modules/spring-data-dynamodb/pom.xml +++ b/persistence-modules/spring-data-dynamodb/pom.xml @@ -5,8 +5,8 @@ spring-boot-dynamodb 0.0.1-SNAPSHOT jar - Spring Boot Actuator - This is simple boot application for Spring boot actuator test + spring-boot-dynamodb + This is simple boot application for Spring boot dynamodb test parent-boot-1 diff --git a/persistence-modules/spring-data-dynamodb/src/main/java/com/baeldung/spring/data/dynamodb/config/DynamoDBConfig.java b/persistence-modules/spring-data-dynamodb/src/main/java/com/baeldung/spring/data/dynamodb/config/DynamoDBConfig.java index 271c1e29ab..9278c0a12e 100644 --- a/persistence-modules/spring-data-dynamodb/src/main/java/com/baeldung/spring/data/dynamodb/config/DynamoDBConfig.java +++ b/persistence-modules/spring-data-dynamodb/src/main/java/com/baeldung/spring/data/dynamodb/config/DynamoDBConfig.java @@ -1,14 +1,18 @@ package com.baeldung.spring.data.dynamodb.config; +import org.socialsignin.spring.data.dynamodb.repository.config.EnableDynamoDBRepositories; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.util.StringUtils; +import org.springframework.web.servlet.handler.HandlerMappingIntrospector; + import com.amazonaws.auth.AWSCredentials; import com.amazonaws.auth.BasicAWSCredentials; import com.amazonaws.services.dynamodbv2.AmazonDynamoDB; import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient; -import org.socialsignin.spring.data.dynamodb.repository.config.EnableDynamoDBRepositories; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.util.StringUtils; @Configuration @EnableDynamoDBRepositories(basePackages = "com.baeldung.spring.data.dynamodb.repositories") @@ -22,6 +26,9 @@ public class DynamoDBConfig { @Value("${amazon.aws.secretkey}") private String amazonAWSSecretKey; + + @Autowired + private ApplicationContext context; @Bean public AmazonDynamoDB amazonDynamoDB() { @@ -37,4 +44,8 @@ public class DynamoDBConfig { return new BasicAWSCredentials(amazonAWSAccessKey, amazonAWSSecretKey); } + @Bean(name = "mvcHandlerMappingIntrospector") + public HandlerMappingIntrospector mvcHandlerMappingIntrospector() { + return new HandlerMappingIntrospector(context); + } } diff --git a/persistence-modules/spring-data-redis/pom.xml b/persistence-modules/spring-data-redis/pom.xml index c5e0049e83..cef12f5be7 100644 --- a/persistence-modules/spring-data-redis/pom.xml +++ b/persistence-modules/spring-data-redis/pom.xml @@ -70,6 +70,11 @@ spring-data-commons ${spring-data-commons.version} + + com.github.kstyrc + embedded-redis + ${embedded-redis.version} + @@ -79,6 +84,7 @@ 2.9.0 0.10.0 2.0.3.RELEASE + 0.6 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 4ea8bb4bc0..62a7886f46 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,10 @@ package com.baeldung.spring.data.redis.config; +import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.listener.ChannelTopic; @@ -18,6 +20,7 @@ import com.baeldung.spring.data.redis.queue.RedisMessageSubscriber; @Configuration @ComponentScan("com.baeldung.spring.data.redis") @EnableRedisRepositories(basePackages = "com.baeldung.spring.data.redis.repo") +@PropertySource("classpath:application.properties") public class RedisConfig { @Bean diff --git a/persistence-modules/spring-data-redis/src/main/resources/application.properties b/persistence-modules/spring-data-redis/src/main/resources/application.properties new file mode 100644 index 0000000000..49886b3b70 --- /dev/null +++ b/persistence-modules/spring-data-redis/src/main/resources/application.properties @@ -0,0 +1,2 @@ +spring.redis.host=localhost +spring.redis.port=6379 \ No newline at end of file diff --git a/persistence-modules/spring-data-redis/src/test/java/com/baeldung/spring/data/redis/RedisMessageListenerIntegrationTest.java b/persistence-modules/spring-data-redis/src/test/java/com/baeldung/spring/data/redis/RedisMessageListenerIntegrationTest.java index 01dbfcff4d..5bc70069c5 100644 --- a/persistence-modules/spring-data-redis/src/test/java/com/baeldung/spring/data/redis/RedisMessageListenerIntegrationTest.java +++ b/persistence-modules/spring-data-redis/src/test/java/com/baeldung/spring/data/redis/RedisMessageListenerIntegrationTest.java @@ -1,24 +1,44 @@ package com.baeldung.spring.data.redis; -import com.baeldung.spring.data.redis.config.RedisConfig; -import com.baeldung.spring.data.redis.queue.RedisMessageSubscriber; -import com.baeldung.spring.data.redis.queue.RedisMessagePublisher; -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.UUID; - import static org.junit.Assert.assertTrue; +import java.io.IOException; +import java.util.UUID; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.annotation.DirtiesContext.ClassMode; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.baeldung.spring.data.redis.config.RedisConfig; +import com.baeldung.spring.data.redis.queue.RedisMessagePublisher; +import com.baeldung.spring.data.redis.queue.RedisMessageSubscriber; + @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = RedisConfig.class) +@DirtiesContext(classMode = ClassMode.AFTER_CLASS) public class RedisMessageListenerIntegrationTest { + private static redis.embedded.RedisServer redisServer; + @Autowired private RedisMessagePublisher redisMessagePublisher; + + @BeforeClass + public static void startRedisServer() throws IOException { + redisServer = new redis.embedded.RedisServer(6379); + redisServer.start(); + } + + @AfterClass + public static void stopRedisServer() throws IOException { + redisServer.stop(); + } @Test public void testOnMessage() throws Exception { 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 66ef3c21b2..48832a8de9 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 @@ -3,13 +3,17 @@ package com.baeldung.spring.data.redis.repo; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; +import java.io.IOException; import java.util.ArrayList; import java.util.List; -import java.util.Map; +import org.junit.AfterClass; +import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.annotation.DirtiesContext.ClassMode; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @@ -18,10 +22,24 @@ import com.baeldung.spring.data.redis.model.Student; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = RedisConfig.class) +@DirtiesContext(classMode = ClassMode.AFTER_CLASS) public class StudentRepositoryIntegrationTest { @Autowired private StudentRepository studentRepository; + + private static redis.embedded.RedisServer redisServer; + + @BeforeClass + public static void startRedisServer() throws IOException { + redisServer = new redis.embedded.RedisServer(6379); + redisServer.start(); + } + + @AfterClass + public static void stopRedisServer() throws IOException { + redisServer.stop(); + } @Test public void whenSavingStudent_thenAvailableOnRetrieval() throws Exception { diff --git a/persistence-modules/spring-hibernate-3/src/main/resources/exceptionDemoPersistenceConfig.xml b/persistence-modules/spring-hibernate-3/src/main/resources/exceptionDemoPersistenceConfig.xml index 09314c67b1..263e902e7c 100644 --- a/persistence-modules/spring-hibernate-3/src/main/resources/exceptionDemoPersistenceConfig.xml +++ b/persistence-modules/spring-hibernate-3/src/main/resources/exceptionDemoPersistenceConfig.xml @@ -17,7 +17,7 @@ - + diff --git a/persistence-modules/spring-hibernate-3/src/main/resources/persistenceConfig.xml b/persistence-modules/spring-hibernate-3/src/main/resources/persistenceConfig.xml index e7ef9ad765..f39817383b 100644 --- a/persistence-modules/spring-hibernate-3/src/main/resources/persistenceConfig.xml +++ b/persistence-modules/spring-hibernate-3/src/main/resources/persistenceConfig.xml @@ -5,7 +5,7 @@ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd" > - + diff --git a/pom.xml b/pom.xml index f875400fc1..d6c440a194 100644 --- a/pom.xml +++ b/pom.xml @@ -184,14 +184,12 @@ spring-katharsis spring-ldap spring-mockito - spring-mvc-email spring-mvc-forms-jsp spring-mvc-forms-thymeleaf spring-mvc-java spring-mvc-velocity spring-mvc-webflow spring-mvc-xml - spring-mvc-simple spring-mvc-kotlin spring-security-openid spring-protobuf @@ -267,12 +265,13 @@ java-spi performance-tests twilio - spring-boot-ctx-fluent + spring-boot-ctx-fluent java-ee-8-security-api spring-webflux-amqp antlr maven-archetype maven-java-kotlin + apache-meecrowave diff --git a/rxjava/src/main/java/com/baeldung/rxjava/MultipleSubscribersColdObs.java b/rxjava/src/main/java/com/baeldung/rxjava/MultipleSubscribersColdObs.java new file mode 100644 index 0000000000..1d3e1b3f8a --- /dev/null +++ b/rxjava/src/main/java/com/baeldung/rxjava/MultipleSubscribersColdObs.java @@ -0,0 +1,59 @@ +package com.baeldung.rxjava; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import rx.Observable; +import rx.Subscription; +import rx.observables.ConnectableObservable; +import rx.subscriptions.Subscriptions; + +public class MultipleSubscribersColdObs { + private static final Logger LOGGER = LoggerFactory.getLogger(MultipleSubscribersColdObs.class); + + public static void main(String[] args) throws InterruptedException { + defaultBehaviour(); + // subscribeBeforeConnect(); + + } + + private static void defaultBehaviour() { + Observable obs = getObservable(); + + LOGGER.info("Subscribing"); + Subscription s1 = obs.subscribe(i -> LOGGER.info("subscriber#1 is printing " + i)); + Subscription s2 = obs.subscribe(i -> LOGGER.info("subscriber#2 is printing " + i)); + + s1.unsubscribe(); + s2.unsubscribe(); + } + + private static void subscribeBeforeConnect() throws InterruptedException { + ConnectableObservable obs = getObservable().publish(); + + LOGGER.info("Subscribing"); + obs.subscribe(i -> LOGGER.info("subscriber #1 is printing " + i)); + obs.subscribe(i -> LOGGER.info("subscriber #2 is printing " + i)); + Thread.sleep(1000); + LOGGER.info("Connecting"); + Subscription s = obs.connect(); + s.unsubscribe(); + + } + + private static Observable getObservable() { + return Observable.create(subscriber -> { + subscriber.onNext(gettingValue(1)); + subscriber.onNext(gettingValue(2)); + + subscriber.add(Subscriptions.create(() -> { + LOGGER.info("Clear resources"); + })); + }); + } + + private static Integer gettingValue(int i) { + LOGGER.info("Getting " + i); + return i; + } +} diff --git a/rxjava/src/main/java/com/baeldung/rxjava/MultipleSubscribersHotObs.java b/rxjava/src/main/java/com/baeldung/rxjava/MultipleSubscribersHotObs.java new file mode 100644 index 0000000000..686c230003 --- /dev/null +++ b/rxjava/src/main/java/com/baeldung/rxjava/MultipleSubscribersHotObs.java @@ -0,0 +1,152 @@ +package com.baeldung.rxjava; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.lang.reflect.InvocationTargetException; + +import javax.swing.JFrame; +import rx.Observable; +import rx.Subscription; +import rx.observables.ConnectableObservable; +import rx.subscriptions.Subscriptions; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class MultipleSubscribersHotObs { + private static final Logger LOGGER = LoggerFactory.getLogger(MultipleSubscribersHotObs.class); + private static JFrame frame; + + public static void main(String[] args) throws InterruptedException, InvocationTargetException { + + javax.swing.SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + createAndShowGUI(); + } + }); + + defaultBehaviour(); + // subscribeBeforeConnect(); + // connectBeforeSubscribe(); + // autoConnectAndSubscribe(); + // refCountAndSubscribe(); + } + + private static void createAndShowGUI() { + frame = new JFrame("Hot Observable Demo"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.getContentPane().setBackground(Color.GRAY); + frame.setPreferredSize(new Dimension(500, 500)); + frame.pack(); + frame.setVisible(true); + } + + public static void defaultBehaviour() throws InterruptedException { + Observable obs = getObservable(); + + LOGGER.info("subscribing #1"); + Subscription subscription1 = obs.subscribe((i) -> LOGGER.info("subscriber#1 is printing x-coordinate " + i)); + + Thread.sleep(1000); + LOGGER.info("subscribing #2"); + Subscription subscription2 = obs.subscribe((i) -> LOGGER.info("subscriber#2 is printing x-coordinate " + i)); + Thread.sleep(1000); + LOGGER.info("unsubscribe#1"); + subscription1.unsubscribe(); + Thread.sleep(1000); + LOGGER.info("unsubscribe#2"); + subscription2.unsubscribe(); + } + + public static void subscribeBeforeConnect() throws InterruptedException { + + ConnectableObservable obs = getObservable().publish(); + + LOGGER.info("subscribing #1"); + Subscription subscription1 = obs.subscribe((i) -> LOGGER.info("subscriber#1 is printing x-coordinate " + i)); + Thread.sleep(1000); + LOGGER.info("subscribing #2"); + Subscription subscription2 = obs.subscribe((i) -> LOGGER.info("subscriber#2 is printing x-coordinate " + i)); + Thread.sleep(1000); + LOGGER.info("connecting:"); + Subscription s = obs.connect(); + Thread.sleep(1000); + LOGGER.info("unsubscribe connected"); + s.unsubscribe(); + + } + + public static void connectBeforeSubscribe() throws InterruptedException { + + ConnectableObservable obs = getObservable().doOnNext(x -> LOGGER.info("saving " + x)).publish(); + LOGGER.info("connecting:"); + Subscription s = obs.connect(); + Thread.sleep(1000); + LOGGER.info("subscribing #1"); + obs.subscribe((i) -> LOGGER.info("subscriber#1 is printing x-coordinate " + i)); + Thread.sleep(1000); + LOGGER.info("subscribing #2"); + obs.subscribe((i) -> LOGGER.info("subscriber#2 is printing x-coordinate " + i)); + Thread.sleep(1000); + s.unsubscribe(); + + } + + public static void autoConnectAndSubscribe() throws InterruptedException { + Observable obs = getObservable().doOnNext(x -> LOGGER.info("saving " + x)).publish().autoConnect(); + + LOGGER.info("autoconnect()"); + Thread.sleep(1000); + LOGGER.info("subscribing #1"); + Subscription s1 = obs.subscribe((i) -> LOGGER.info("subscriber#1 is printing x-coordinate " + i)); + Thread.sleep(1000); + LOGGER.info("subscribing #2"); + Subscription s2 = obs.subscribe((i) -> LOGGER.info("subscriber#2 is printing x-coordinate " + i)); + + Thread.sleep(1000); + LOGGER.info("unsubscribe 1"); + s1.unsubscribe(); + Thread.sleep(1000); + LOGGER.info("unsubscribe 2"); + s2.unsubscribe(); + } + + public static void refCountAndSubscribe() throws InterruptedException { + Observable obs = getObservable().doOnNext(x -> LOGGER.info("saving " + x)).publish().refCount(); + + LOGGER.info("refcount()"); + Thread.sleep(1000); + LOGGER.info("subscribing #1"); + Subscription subscription1 = obs.subscribe((i) -> LOGGER.info("subscriber#1 is printing x-coordinate " + i)); + Thread.sleep(1000); + LOGGER.info("subscribing #2"); + Subscription subscription2 = obs.subscribe((i) -> LOGGER.info("subscriber#2 is printing x-coordinate " + i)); + + Thread.sleep(1000); + LOGGER.info("unsubscribe#1"); + subscription1.unsubscribe(); + Thread.sleep(1000); + LOGGER.info("unsubscribe#2"); + subscription2.unsubscribe(); + + } + + private static Observable getObservable() { + return Observable.create(subscriber -> { + frame.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + subscriber.onNext(e.getX()); + } + }); + subscriber.add(Subscriptions.create(() -> { + LOGGER.info("Clear resources"); + for (MouseListener listener : frame.getListeners(MouseListener.class)) { + frame.removeMouseListener(listener); + } + })); + }); + } +} diff --git a/spring-5-mvc/src/main/java/com/baeldung/Constants.java b/spring-5-mvc/src/main/java/com/baeldung/Constants.java new file mode 100644 index 0000000000..472f3280b7 --- /dev/null +++ b/spring-5-mvc/src/main/java/com/baeldung/Constants.java @@ -0,0 +1,21 @@ +package com.baeldung; + +public class Constants { + + public static final String GENERIC_EXCEPTION = "Exception encountered!"; + + /** + * API endpoints. + */ + public static final String API_RBE = "/rbe"; + public static final String API_SSE = "/sse"; + public static final String API_SRB = "/srb"; + + /** + * API Responses. + */ + public static final String API_RBE_MSG = "I Was Sent From a Response Body Emitter!"; + public static final String API_SSE_MSG = "I Was Sent From a Sse!"; + public static final String API_SRB_MSG = "I Was Sent From a Streaming Response Body!"; + +} diff --git a/spring-5-mvc/src/main/java/com/baeldung/model/Foo.java b/spring-5-mvc/src/main/java/com/baeldung/model/Foo.java index a9ffee14da..b06f50b742 100644 --- a/spring-5-mvc/src/main/java/com/baeldung/model/Foo.java +++ b/spring-5-mvc/src/main/java/com/baeldung/model/Foo.java @@ -49,8 +49,6 @@ public class Foo { this.name = name; } - // - @Override public int hashCode() { final int prime = 31; diff --git a/spring-5-mvc/src/main/java/com/baeldung/persistence/DataSetupBean.java b/spring-5-mvc/src/main/java/com/baeldung/persistence/DataSetupBean.java index cf78977961..fa07555bba 100644 --- a/spring-5-mvc/src/main/java/com/baeldung/persistence/DataSetupBean.java +++ b/spring-5-mvc/src/main/java/com/baeldung/persistence/DataSetupBean.java @@ -16,8 +16,6 @@ public class DataSetupBean implements InitializingBean { @Autowired private FooRepository repo; - // - @Override public void afterPropertiesSet() throws Exception { IntStream.range(1, 5).forEach(i -> repo.save(new Foo(randomAlphabetic(8)))); diff --git a/spring-5-mvc/src/main/java/com/baeldung/web/ResponseBodyEmitterController.java b/spring-5-mvc/src/main/java/com/baeldung/web/ResponseBodyEmitterController.java new file mode 100644 index 0000000000..4af8eb9bd3 --- /dev/null +++ b/spring-5-mvc/src/main/java/com/baeldung/web/ResponseBodyEmitterController.java @@ -0,0 +1,35 @@ +package com.baeldung.web; + +import com.baeldung.Constants; +import java.util.Date; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyEmitter; + +@Controller +public class ResponseBodyEmitterController { + + @GetMapping(Constants.API_RBE) + public ResponseEntity handleRbe() { + ResponseBodyEmitter emitter = new ResponseBodyEmitter(); + ExecutorService nonBlockingService = Executors.newSingleThreadExecutor(); + + nonBlockingService.execute(() -> { + try { + emitter.send(Constants.API_RBE_MSG + " @ " + new Date(), MediaType.TEXT_PLAIN); + emitter.complete(); + } catch (Exception ex) { + System.out.println(Constants.GENERIC_EXCEPTION); + emitter.completeWithError(ex); + } + }); + + return new ResponseEntity(emitter, HttpStatus.OK); + } + +} diff --git a/spring-5-mvc/src/main/java/com/baeldung/web/SseEmitterController.java b/spring-5-mvc/src/main/java/com/baeldung/web/SseEmitterController.java new file mode 100644 index 0000000000..390178aaef --- /dev/null +++ b/spring-5-mvc/src/main/java/com/baeldung/web/SseEmitterController.java @@ -0,0 +1,32 @@ +package com.baeldung.web; + +import com.baeldung.Constants; +import java.util.Date; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; + +@Controller +public class SseEmitterController { + + @GetMapping(Constants.API_SSE) + public SseEmitter handleSse() { + SseEmitter emitter = new SseEmitter(); + + ExecutorService nonBlockingService = Executors.newSingleThreadExecutor(); + nonBlockingService.execute(() -> { + try { + emitter.send(Constants.API_SSE_MSG + " @ " + new Date()); + emitter.complete(); + } catch (Exception ex) { + System.out.println(Constants.GENERIC_EXCEPTION); + emitter.completeWithError(ex); + } + }); + + return emitter; + } + +} \ No newline at end of file diff --git a/spring-5-mvc/src/main/java/com/baeldung/web/StreamingResponseBodyController.java b/spring-5-mvc/src/main/java/com/baeldung/web/StreamingResponseBodyController.java new file mode 100644 index 0000000000..1722ad85cd --- /dev/null +++ b/spring-5-mvc/src/main/java/com/baeldung/web/StreamingResponseBodyController.java @@ -0,0 +1,23 @@ +package com.baeldung.web; + +import com.baeldung.Constants; +import java.util.Date; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody; + +@Controller +public class StreamingResponseBodyController { + + @GetMapping(Constants.API_SRB) + public ResponseEntity handleRbe() { + StreamingResponseBody stream = out -> { + String msg = Constants.API_SRB_MSG + " @ " + new Date(); + out.write(msg.getBytes()); + }; + return new ResponseEntity(stream, HttpStatus.OK); + } + +} diff --git a/spring-5-mvc/src/main/webapp/WEB-INF/jsp/index.jsp b/spring-5-mvc/src/main/webapp/WEB-INF/jsp/index.jsp new file mode 100644 index 0000000000..df5baf7adb --- /dev/null +++ b/spring-5-mvc/src/main/webapp/WEB-INF/jsp/index.jsp @@ -0,0 +1,86 @@ +<%@taglib uri="http://www.springframework.org/tags" prefix="spring" %> +<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %> +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> +<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1" %> + + + + + + + Spring MVC Async + " rel="stylesheet"> + + +
+

Spring MVC Async

+
+
+
+
+ + + diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/GlobalErrorAttributes.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/GlobalErrorAttributes.java new file mode 100644 index 0000000000..a50651ced7 --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/GlobalErrorAttributes.java @@ -0,0 +1,55 @@ + +package com.baeldung.reactive.errorhandling; + +import java.util.Map; +import org.springframework.boot.web.reactive.error.DefaultErrorAttributes; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.server.ServerRequest; + +@Component +public class GlobalErrorAttributes extends DefaultErrorAttributes{ + + private HttpStatus status = HttpStatus.BAD_REQUEST; + private String message = "please provide a name"; + + public GlobalErrorAttributes() { + super(false); + } + + @Override + public Map getErrorAttributes(ServerRequest request, boolean includeStackTrace) { + Map map = super.getErrorAttributes(request, includeStackTrace); + map.put("status", getStatus()); + map.put("message", getMessage()); + return map; + } + + /** + * @return the status + */ + public HttpStatus getStatus() { + return status; + } + + /** + * @param status the status to set + */ + public void setStatus(HttpStatus status) { + this.status = status; + } + + /** + * @return the message + */ + public String getMessage() { + return message; + } + + /** + * @param message the message to set + */ + public void setMessage(String message) { + this.message = message; + } +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/GlobalErrorWebExceptionHandler.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/GlobalErrorWebExceptionHandler.java new file mode 100644 index 0000000000..09bccb0d5e --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/GlobalErrorWebExceptionHandler.java @@ -0,0 +1,47 @@ + +package com.baeldung.reactive.errorhandling; + +import java.util.Map; +import org.springframework.boot.autoconfigure.web.ResourceProperties; +import org.springframework.boot.autoconfigure.web.reactive.error.AbstractErrorWebExceptionHandler; +import org.springframework.boot.web.reactive.error.ErrorAttributes; +import org.springframework.context.ApplicationContext; +import org.springframework.core.annotation.Order; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.codec.ServerCodecConfigurer; +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.BodyInserters; +import org.springframework.web.reactive.function.server.RequestPredicates; +import org.springframework.web.reactive.function.server.RouterFunction; +import org.springframework.web.reactive.function.server.RouterFunctions; +import org.springframework.web.reactive.function.server.ServerRequest; +import org.springframework.web.reactive.function.server.ServerResponse; +import reactor.core.publisher.Mono; + +@Component +@Order(-2) +public class GlobalErrorWebExceptionHandler extends AbstractErrorWebExceptionHandler { + + public GlobalErrorWebExceptionHandler(GlobalErrorAttributes g, ApplicationContext applicationContext, + ServerCodecConfigurer serverCodecConfigurer) { + super(g, new ResourceProperties(), applicationContext); + super.setMessageWriters(serverCodecConfigurer.getWriters()); + super.setMessageReaders(serverCodecConfigurer.getReaders()); + } + + @Override + protected RouterFunction getRoutingFunction(final ErrorAttributes errorAttributes) { + return RouterFunctions.route(RequestPredicates.all(), this::renderErrorResponse); + } + + private Mono renderErrorResponse(final ServerRequest request) { + + final Map errorPropertiesMap = getErrorAttributes(request, false); + + return ServerResponse.status(HttpStatus.BAD_REQUEST) + .contentType(MediaType.APPLICATION_JSON_UTF8) + .body(BodyInserters.fromObject(errorPropertiesMap)); + } + +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/NameRequiredException.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/NameRequiredException.java new file mode 100644 index 0000000000..38d35544a7 --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/NameRequiredException.java @@ -0,0 +1,12 @@ + +package com.baeldung.reactive.errorhandling; + +import org.springframework.http.HttpStatus; +import org.springframework.web.server.ResponseStatusException; + +public class NameRequiredException extends ResponseStatusException { + + public NameRequiredException(HttpStatus status, String message, Throwable e) { + super(status, message, e); + } +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler1.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler1.java new file mode 100644 index 0000000000..87b78a4654 --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler1.java @@ -0,0 +1,29 @@ + +package com.baeldung.reactive.errorhandling.handlers; + +import org.springframework.http.MediaType; +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.server.ServerRequest; +import org.springframework.web.reactive.function.server.ServerResponse; +import reactor.core.publisher.Mono; + +@Component +public class Handler1 { + + public Mono handleRequest1(ServerRequest request) { + return sayHello(request).onErrorReturn("Hello, Stranger") + .flatMap(s -> ServerResponse.ok() + .contentType(MediaType.TEXT_PLAIN) + .syncBody(s)); + } + + private Mono sayHello(ServerRequest request) { + try { + return Mono.just("Hello, " + request.queryParam("name") + .get()); + } catch (Exception e) { + return Mono.error(e); + } + } + +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler2.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler2.java new file mode 100644 index 0000000000..12172a0f54 --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler2.java @@ -0,0 +1,38 @@ + +package com.baeldung.reactive.errorhandling.handlers; + +import org.springframework.http.MediaType; +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.server.ServerRequest; +import org.springframework.web.reactive.function.server.ServerResponse; +import reactor.core.publisher.Mono; + +@Component +public class Handler2 { + +public Mono handleRequest2(ServerRequest request) { + return + sayHello(request) + .flatMap(s -> ServerResponse.ok() + .contentType(MediaType.TEXT_PLAIN) + .syncBody(s)) + .onErrorResume(e -> sayHelloFallback() + .flatMap(s -> ServerResponse.ok() + .contentType(MediaType.TEXT_PLAIN) + .syncBody(s))); +} + + private Mono sayHello(ServerRequest request) { + try { + return Mono.just("Hello, " + request.queryParam("name") + .get()); + } catch (Exception e) { + return Mono.error(e); + } + } + + private Mono sayHelloFallback() { + return Mono.just("Hello, Stranger"); + } + +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler3.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler3.java new file mode 100644 index 0000000000..e95b039cce --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler3.java @@ -0,0 +1,34 @@ + +package com.baeldung.reactive.errorhandling.handlers; + +import org.springframework.http.MediaType; +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.server.ServerRequest; +import org.springframework.web.reactive.function.server.ServerResponse; +import reactor.core.publisher.Mono; + +@Component +public class Handler3 { + + public Mono handleRequest3(ServerRequest request) { + return + sayHello(request) + .flatMap(s -> ServerResponse.ok() + .contentType(MediaType.TEXT_PLAIN) + .syncBody(s)) + .onErrorResume(e -> (Mono.just("Hi, I looked around for your name but found: " + + e.getMessage())).flatMap(s -> ServerResponse.ok() + .contentType(MediaType.TEXT_PLAIN) + .syncBody(s))); + } + + private Mono sayHello(ServerRequest request) { + try { + return Mono.just("Hello, " + request.queryParam("name") + .get()); + } catch (Exception e) { + return Mono.error(e); + } + } + +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler4.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler4.java new file mode 100644 index 0000000000..3d6ef258d3 --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler4.java @@ -0,0 +1,30 @@ + +package com.baeldung.reactive.errorhandling.handlers; + +import com.baeldung.reactive.errorhandling.NameRequiredException; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.server.ServerRequest; +import org.springframework.web.reactive.function.server.ServerResponse; +import reactor.core.publisher.Mono; + +@Component +public class Handler4 { + +public Mono handleRequest4(ServerRequest request) { + return ServerResponse.ok() + .body(sayHello(request) + .onErrorResume(e -> + Mono.error(new NameRequiredException( + HttpStatus.BAD_REQUEST, "please provide a name", e))), String.class); +} + + private Mono sayHello(ServerRequest request) { + try { + return Mono.just("Hello, " + request.queryParam("name").get()); + } catch (Exception e) { + return Mono.error(e); + } + } + +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler5.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler5.java new file mode 100644 index 0000000000..41605b355b --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler5.java @@ -0,0 +1,22 @@ + +package com.baeldung.reactive.errorhandling.handlers; + +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.server.ServerRequest; +import org.springframework.web.reactive.function.server.ServerResponse; +import reactor.core.publisher.Mono; + +@Component +public class Handler5 { + + public Mono handleRequest5(ServerRequest request) { + return ServerResponse.ok() + .body(sayHello(request), String.class); + + } + + private Mono sayHello(ServerRequest request) { + return Mono.just("Hello, " + request.queryParam("name").get()); + } + +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router1.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router1.java new file mode 100644 index 0000000000..91be24571c --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router1.java @@ -0,0 +1,22 @@ + +package com.baeldung.reactive.errorhandling.routers; + +import com.baeldung.reactive.errorhandling.handlers.Handler1; +import org.springframework.context.annotation.Bean; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.server.RequestPredicates; +import org.springframework.web.reactive.function.server.RouterFunction; +import org.springframework.web.reactive.function.server.RouterFunctions; +import org.springframework.web.reactive.function.server.ServerResponse; + +@Component +public class Router1 { + + @Bean + public RouterFunction routeRequest1(Handler1 handler) { + return RouterFunctions.route(RequestPredicates.GET("/api/endpoint1") + .and(RequestPredicates.accept(MediaType.TEXT_PLAIN)), handler::handleRequest1); + } + +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router2.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router2.java new file mode 100644 index 0000000000..bc7831f494 --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router2.java @@ -0,0 +1,22 @@ + +package com.baeldung.reactive.errorhandling.routers; + +import com.baeldung.reactive.errorhandling.handlers.Handler2; +import org.springframework.context.annotation.Bean; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.server.RequestPredicates; +import org.springframework.web.reactive.function.server.RouterFunction; +import org.springframework.web.reactive.function.server.RouterFunctions; +import org.springframework.web.reactive.function.server.ServerResponse; + +@Component +public class Router2 { + + @Bean + public RouterFunction routeRequest2(Handler2 handler) { + return RouterFunctions.route(RequestPredicates.GET("/api/endpoint2") + .and(RequestPredicates.accept(MediaType.TEXT_PLAIN)), handler::handleRequest2); + } + +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router3.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router3.java new file mode 100644 index 0000000000..461e6fe9e7 --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router3.java @@ -0,0 +1,22 @@ + +package com.baeldung.reactive.errorhandling.routers; + +import com.baeldung.reactive.errorhandling.handlers.Handler3; +import org.springframework.context.annotation.Bean; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.server.RequestPredicates; +import org.springframework.web.reactive.function.server.RouterFunction; +import org.springframework.web.reactive.function.server.RouterFunctions; +import org.springframework.web.reactive.function.server.ServerResponse; + +@Component +public class Router3 { + + @Bean + public RouterFunction routeRequest3(Handler3 handler) { + return RouterFunctions.route(RequestPredicates.GET("/api/endpoint3") + .and(RequestPredicates.accept(MediaType.TEXT_PLAIN)), handler::handleRequest3); + } + +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router4.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router4.java new file mode 100644 index 0000000000..9dccc6858f --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router4.java @@ -0,0 +1,22 @@ + +package com.baeldung.reactive.errorhandling.routers; + +import com.baeldung.reactive.errorhandling.handlers.Handler4; +import org.springframework.context.annotation.Bean; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.server.RequestPredicates; +import org.springframework.web.reactive.function.server.RouterFunction; +import org.springframework.web.reactive.function.server.RouterFunctions; +import org.springframework.web.reactive.function.server.ServerResponse; + +@Component +public class Router4 { + + @Bean + public RouterFunction routeRequest4(Handler4 handler) { + return RouterFunctions.route(RequestPredicates.GET("/api/endpoint4") + .and(RequestPredicates.accept(MediaType.TEXT_PLAIN)), handler::handleRequest4); + } + +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router5.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router5.java new file mode 100644 index 0000000000..59fd587fc8 --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router5.java @@ -0,0 +1,22 @@ + +package com.baeldung.reactive.errorhandling.routers; + +import com.baeldung.reactive.errorhandling.handlers.Handler5; +import org.springframework.context.annotation.Bean; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.server.RequestPredicates; +import org.springframework.web.reactive.function.server.RouterFunction; +import org.springframework.web.reactive.function.server.RouterFunctions; +import org.springframework.web.reactive.function.server.ServerResponse; + +@Component +public class Router5 { + + @Bean + public RouterFunction routeRequest5(Handler5 handler) { + return RouterFunctions.route(RequestPredicates.GET("/api/endpoint5") + .and(RequestPredicates.accept(MediaType.TEXT_PLAIN)), handler::handleRequest5); + } + +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/responseheaders/controllers/ResponseHeaderController.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/responseheaders/controllers/ResponseHeaderController.java new file mode 100644 index 0000000000..5220ea2f4c --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/responseheaders/controllers/ResponseHeaderController.java @@ -0,0 +1,35 @@ +package com.baeldung.reactive.responseheaders.controllers; + +import org.springframework.http.ResponseEntity; +import org.springframework.http.server.reactive.ServerHttpResponse; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import reactor.core.publisher.Mono; + +@RestController +@RequestMapping("/response-header") +public class ResponseHeaderController { + + @GetMapping("/response-entity") + public Mono> usingResponseEntityBuilder() { + String responseHeaderKey = "Baeldung-Example-Header"; + String responseHeaderValue = "Value-ResponseEntityBuilder"; + String responseBody = "Response with header using ResponseEntity (builder)"; + + return Mono.just(ResponseEntity.ok() + .header(responseHeaderKey, responseHeaderValue) + .body(responseBody)); + } + + @GetMapping("/server-http-response") + public Mono usingServerHttpResponse(ServerHttpResponse response) { + String responseHeaderKey = "Baeldung-Example-Header"; + String responseHeaderValue = "Value-ServerHttpResponse"; + String responseBody = "Response with header using ServerHttpResponse"; + + response.getHeaders().add(responseHeaderKey, responseHeaderValue); + return Mono.just(responseBody); + } +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/responseheaders/filter/AddResponseHeaderWebFilter.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/responseheaders/filter/AddResponseHeaderWebFilter.java new file mode 100644 index 0000000000..8d8484f5cd --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/responseheaders/filter/AddResponseHeaderWebFilter.java @@ -0,0 +1,20 @@ +package com.baeldung.reactive.responseheaders.filter; + +import org.springframework.stereotype.Component; +import org.springframework.web.server.ServerWebExchange; +import org.springframework.web.server.WebFilter; +import org.springframework.web.server.WebFilterChain; + +import reactor.core.publisher.Mono; + +@Component +public class AddResponseHeaderWebFilter implements WebFilter { + + @Override + public Mono filter(ServerWebExchange exchange, WebFilterChain chain) { + exchange.getResponse() + .getHeaders() + .add("Baeldung-Example-Filter-Header", "Value-Filter"); + return chain.filter(exchange); + } +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/responseheaders/functional/handlers/ResponseHeaderHandler.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/responseheaders/functional/handlers/ResponseHeaderHandler.java new file mode 100644 index 0000000000..20f76d3b6e --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/responseheaders/functional/handlers/ResponseHeaderHandler.java @@ -0,0 +1,21 @@ +package com.baeldung.reactive.responseheaders.functional.handlers; + +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.server.ServerRequest; +import org.springframework.web.reactive.function.server.ServerResponse; + +import reactor.core.publisher.Mono; + +@Component +public class ResponseHeaderHandler { + + public Mono useHandler(final ServerRequest request) { + String responseHeaderKey = "Baeldung-Example-Header"; + String responseHeaderValue = "Value-Handler"; + String responseBody = "Response with header using Handler"; + + return ServerResponse.ok() + .header(responseHeaderKey, responseHeaderValue) + .body(Mono.just(responseBody),String.class); + } +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/responseheaders/functional/routers/ResponseHeadersRouterFunctions.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/responseheaders/functional/routers/ResponseHeadersRouterFunctions.java new file mode 100644 index 0000000000..63f7c7f036 --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/responseheaders/functional/routers/ResponseHeadersRouterFunctions.java @@ -0,0 +1,20 @@ +package com.baeldung.reactive.responseheaders.functional.routers; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.reactive.function.server.RequestPredicates; +import org.springframework.web.reactive.function.server.RouterFunction; +import org.springframework.web.reactive.function.server.RouterFunctions; +import org.springframework.web.reactive.function.server.ServerResponse; + +import com.baeldung.reactive.responseheaders.functional.handlers.ResponseHeaderHandler; + +@Configuration +public class ResponseHeadersRouterFunctions { + + @Bean + public RouterFunction responseHeaderRoute(@Autowired ResponseHeaderHandler handler) { + return RouterFunctions.route(RequestPredicates.GET("/functional-response-header/single-handler"), handler::useHandler); + } +} diff --git a/spring-5-reactive/src/test/java/com/baeldung/reactive/errorhandling/ErrorHandlingIntegrationTest.java b/spring-5-reactive/src/test/java/com/baeldung/reactive/errorhandling/ErrorHandlingIntegrationTest.java new file mode 100644 index 0000000000..bea2eaa75f --- /dev/null +++ b/spring-5-reactive/src/test/java/com/baeldung/reactive/errorhandling/ErrorHandlingIntegrationTest.java @@ -0,0 +1,168 @@ +package com.baeldung.reactive.errorhandling; + +import java.io.IOException; +import static org.junit.Assert.assertEquals; +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.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.http.MediaType; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.reactive.server.WebTestClient; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = WebEnvironment.DEFINED_PORT) +public class ErrorHandlingIntegrationTest { + + @Autowired + private WebTestClient webTestClient; + + @Test + public void givenErrorReturn_whenUsernamePresent_thenOk() throws IOException { + + String s = webTestClient.get() + .uri("/api/endpoint1?name={username}", "Tony") + .accept(MediaType.TEXT_PLAIN) + .exchange() + .returnResult(String.class) + .getResponseBody() + .blockFirst(); + + assertEquals("Hello, Tony", s); + + } + + @Test + public void givenErrorReturn_whenNoUsername_thenOk() throws IOException { + + String s = webTestClient.get() + .uri("/api/endpoint1") + .accept(MediaType.TEXT_PLAIN) + .exchange() + .returnResult(String.class) + .getResponseBody() + .blockFirst(); + + assertEquals("Hello, Stranger", s); + } + + @Test + public void givenResumeFallback_whenUsernamePresent_thenOk() throws IOException { + + String s = webTestClient.get() + .uri("/api/endpoint2?name={username}", "Tony") + .accept(MediaType.TEXT_PLAIN) + .exchange() + .returnResult(String.class) + .getResponseBody() + .blockFirst(); + + assertEquals("Hello, Tony", s); + } + + @Test + public void givenResumeFallback_whenNoUsername_thenOk() throws IOException { + String s = webTestClient.get() + .uri("/api/endpoint2") + .accept(MediaType.TEXT_PLAIN) + .exchange() + .returnResult(String.class) + .getResponseBody() + .blockFirst(); + + assertEquals("Hello, Stranger", s); + + } + + @Test + public void givenResumeDynamicValue_whenUsernamePresent_thenOk() throws IOException { + + String s = webTestClient.get() + .uri("/api/endpoint3?name={username}", "Tony") + .accept(MediaType.TEXT_PLAIN) + .exchange() + .returnResult(String.class) + .getResponseBody() + .blockFirst(); + + assertEquals("Hello, Tony", s); + } + + @Test + public void givenResumeDynamicValue_whenNoUsername_thenOk() throws IOException { + String s = webTestClient.get() + .uri("/api/endpoint3") + .accept(MediaType.TEXT_PLAIN) + .exchange() + .returnResult(String.class) + .getResponseBody() + .blockFirst(); + + assertEquals("Hi, I looked around for your name but found: No value present", s); + } + + @Test + public void givenResumeRethrow_whenUsernamePresent_thenOk() throws IOException { + String s = webTestClient.get() + .uri("/api/endpoint4?name={username}", "Tony") + .accept(MediaType.TEXT_PLAIN) + .exchange() + .returnResult(String.class) + .getResponseBody() + .blockFirst(); + + assertEquals("Hello, Tony", s); + } + + @Test + public void givenResumeRethrow_whenNoUsername_thenOk() throws IOException { + + webTestClient.get() + .uri("/api/endpoint4") + .accept(MediaType.TEXT_PLAIN) + .exchange() + .expectStatus() + .isBadRequest() + .expectHeader() + .contentType(MediaType.APPLICATION_JSON_UTF8) + .expectBody() + .jsonPath("$.message") + .isNotEmpty() + .jsonPath("$.message") + .isEqualTo("please provide a name"); + } + + @Test + public void givenGlobalErrorHandling_whenUsernamePresent_thenOk() throws IOException { + + String s = webTestClient.get() + .uri("/api/endpoint5?name={username}", "Tony") + .accept(MediaType.TEXT_PLAIN) + .exchange() + .returnResult(String.class) + .getResponseBody() + .blockFirst(); + + assertEquals("Hello, Tony", s); + } + + @Test + public void givenGlobalErrorHandling_whenNoUsername_thenOk() throws IOException { + webTestClient.get() + .uri("/api/endpoint5") + .accept(MediaType.TEXT_PLAIN) + .exchange() + .expectStatus() + .isBadRequest() + .expectHeader() + .contentType(MediaType.APPLICATION_JSON_UTF8) + .expectBody() + .jsonPath("$.message") + .isNotEmpty() + .jsonPath("$.message") + .isEqualTo("please provide a name"); + + } + +} diff --git a/spring-5-reactive/src/test/java/com/baeldung/reactive/responseheaders/ResponseHeaderLiveTest.java b/spring-5-reactive/src/test/java/com/baeldung/reactive/responseheaders/ResponseHeaderLiveTest.java new file mode 100644 index 0000000000..db563e27d1 --- /dev/null +++ b/spring-5-reactive/src/test/java/com/baeldung/reactive/responseheaders/ResponseHeaderLiveTest.java @@ -0,0 +1,63 @@ +package com.baeldung.reactive.responseheaders; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.reactive.server.WebTestClient; +import org.springframework.test.web.reactive.server.WebTestClient.ResponseSpec; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +public class ResponseHeaderLiveTest { + + private static final String BASE_URL = "http://localhost:8080"; + private static final String ANNOTATION_BASE_URL = BASE_URL + "/response-header"; + private static final String FUNCTIONAL_BASE_URL = BASE_URL + "/functional-response-header"; + private static final String SERVICE_SINGLE_RESPONSE_HEADER = "Baeldung-Example-Header"; + private static final String SERVICE_FILTER_RESPONSE_HEADER = "Baeldung-Example-Filter-Header"; + private static final String SERVICE_FILTER_RESPONSE_HEADER_VALUE = "Value-Filter"; + + private static WebTestClient client; + + @BeforeAll + public static void setup() { + client = WebTestClient.bindToServer() + .baseUrl(BASE_URL) + .build(); + } + + @Test + public void whenUsingResponseEntityBuilderRequest_thenObtainResponseWithCorrectHeaders() { + client = WebTestClient.bindToServer() + .baseUrl(BASE_URL) + .build(); + ResponseSpec response = client.get() + .uri(ANNOTATION_BASE_URL + "/response-entity") + .exchange(); + + response.expectHeader().valueEquals(SERVICE_SINGLE_RESPONSE_HEADER, "Value-ResponseEntityBuilder") + .expectHeader().valueEquals(SERVICE_FILTER_RESPONSE_HEADER, SERVICE_FILTER_RESPONSE_HEADER_VALUE); + } + + @Test + public void whenUsingServerHttpResponseRequest_thenObtainResponseWithCorrectHeaders() { + ResponseSpec response = client.get() + .uri(ANNOTATION_BASE_URL + "/server-http-response") + .exchange(); + + response.expectHeader().valueEquals(SERVICE_SINGLE_RESPONSE_HEADER, "Value-ServerHttpResponse") + .expectHeader().valueEquals(SERVICE_FILTER_RESPONSE_HEADER, SERVICE_FILTER_RESPONSE_HEADER_VALUE); + } + + @Test + public void whenUsingFunctionalHandlerRequest_thenObtainResponseWithCorrectHeaders() { + ResponseSpec response = client.get() + .uri(FUNCTIONAL_BASE_URL + "/single-handler") + .exchange(); + + response.expectHeader().valueEquals(SERVICE_SINGLE_RESPONSE_HEADER, "Value-Handler") + .expectHeader().valueEquals(SERVICE_FILTER_RESPONSE_HEADER, SERVICE_FILTER_RESPONSE_HEADER_VALUE); + } +} diff --git a/spring-batch/src/main/java/org/baeldung/batchscheduler/SpringBatchScheduler.java b/spring-batch/src/main/java/org/baeldung/batchscheduler/SpringBatchScheduler.java new file mode 100644 index 0000000000..edb9b7cfa5 --- /dev/null +++ b/spring-batch/src/main/java/org/baeldung/batchscheduler/SpringBatchScheduler.java @@ -0,0 +1,172 @@ +package org.baeldung.batchscheduler; + +import java.util.Date; +import java.util.IdentityHashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.baeldung.batchscheduler.model.Book; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.batch.core.Job; +import org.springframework.batch.core.JobExecution; +import org.springframework.batch.core.JobParametersBuilder; +import org.springframework.batch.core.Step; +import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing; +import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; +import org.springframework.batch.core.configuration.annotation.StepBuilderFactory; +import org.springframework.batch.core.launch.JobLauncher; +import org.springframework.batch.core.launch.support.SimpleJobLauncher; +import org.springframework.batch.core.repository.JobRepository; +import org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean; +import org.springframework.batch.item.ItemWriter; +import org.springframework.batch.item.file.FlatFileItemReader; +import org.springframework.batch.item.file.builder.FlatFileItemReaderBuilder; +import org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper; +import org.springframework.batch.support.transaction.ResourcelessTransactionManager; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.ClassPathResource; +import org.springframework.scheduling.TaskScheduler; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; +import org.springframework.scheduling.support.ScheduledMethodRunnable; + +@Configuration +@EnableBatchProcessing +@EnableScheduling +public class SpringBatchScheduler { + + private final Logger logger = LoggerFactory.getLogger(SpringBatchScheduler.class); + + private AtomicBoolean enabled = new AtomicBoolean(true); + + private Date currentLaunchDate; + + private final Map> scheduledTasks = new IdentityHashMap<>(); + + @Autowired + private JobBuilderFactory jobBuilderFactory; + + @Autowired + private StepBuilderFactory stepBuilderFactory; + + @Scheduled(fixedRate = 2000) + public void launchJob() throws Exception { + Date date = new Date(); + logger.debug("scheduler starts at " + date); + if (enabled.get()) { + currentLaunchDate = date; + JobExecution jobExecution = jobLauncher().run(job(), new JobParametersBuilder().addDate("launchDate", currentLaunchDate) + .toJobParameters()); + logger.debug("Batch job ends with status as " + jobExecution.getStatus()); + } + logger.debug("scheduler ends "); + } + + public Date getCurrentLaunchDate() { + return currentLaunchDate; + } + + public void stop() { + enabled.set(false); + } + + public void start() { + enabled.set(true); + } + + @Bean + public TaskScheduler poolScheduler() { + return new CustomTaskScheduler(); + } + + private class CustomTaskScheduler extends ThreadPoolTaskScheduler { + + private static final long serialVersionUID = -7142624085505040603L; + + @Override + public ScheduledFuture scheduleAtFixedRate(Runnable task, long period) { + ScheduledFuture future = super.scheduleAtFixedRate(task, period); + + ScheduledMethodRunnable runnable = (ScheduledMethodRunnable) task; + scheduledTasks.put(runnable.getTarget(), future); + + return future; + } + + } + + public void cancelFutureSchedulerTasks() { + scheduledTasks.forEach((k, v) -> { + if (k instanceof SpringBatchScheduler) { + v.cancel(false); + } + }); + } + + @Bean + public Job job() { + return jobBuilderFactory.get("job") + .start(readBooks()) + .build(); + } + + @Bean + public JobLauncher jobLauncher() throws Exception { + SimpleJobLauncher jobLauncher = new SimpleJobLauncher(); + jobLauncher.setJobRepository(jobRepository()); + jobLauncher.afterPropertiesSet(); + return jobLauncher; + } + + @Bean + public JobRepository jobRepository() throws Exception { + MapJobRepositoryFactoryBean factory = new MapJobRepositoryFactoryBean(); + factory.setTransactionManager(new ResourcelessTransactionManager()); + return (JobRepository) factory.getObject(); + } + + @Bean + protected Step readBooks() { + return stepBuilderFactory.get("readBooks") + . chunk(2) + .reader(reader()) + .writer(writer()) + .build(); + } + + @Bean + public FlatFileItemReader reader() { + return new FlatFileItemReaderBuilder().name("bookItemReader") + .resource(new ClassPathResource("books.csv")) + .delimited() + .names(new String[] { "id", "name" }) + .fieldSetMapper(new BeanWrapperFieldSetMapper() { + { + setTargetType(Book.class); + } + }) + .build(); + } + + @Bean + public ItemWriter writer() { + return new ItemWriter() { + + @Override + public void write(List items) throws Exception { + logger.debug("writer..." + items.size()); + for (Book item : items) { + logger.debug(item.toString()); + } + + } + }; + } + +} diff --git a/spring-batch/src/main/java/org/baeldung/batchscheduler/model/Book.java b/spring-batch/src/main/java/org/baeldung/batchscheduler/model/Book.java new file mode 100644 index 0000000000..f992bde20e --- /dev/null +++ b/spring-batch/src/main/java/org/baeldung/batchscheduler/model/Book.java @@ -0,0 +1,35 @@ +package org.baeldung.batchscheduler.model; + +public class Book { + private int id; + private String name; + + public Book() {} + + public Book(int id, String name) { + super(); + this.id = id; + this.name = name; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String toString() { + return "Book [id=" + id + ", name=" + name + "]"; + } + +} diff --git a/spring-batch/src/main/resources/books.csv b/spring-batch/src/main/resources/books.csv new file mode 100644 index 0000000000..af68e986a2 --- /dev/null +++ b/spring-batch/src/main/resources/books.csv @@ -0,0 +1,4 @@ +1,SHARP OBJECTS (MOVIE TIE-IN): A NOVEL +2,ARTEMIS: A NOVEL +3,HER PRETTY FACE +4,ALL WE EVER WANTED \ No newline at end of file diff --git a/spring-batch/src/main/resources/logback.xml b/spring-batch/src/main/resources/logback.xml index b110d1c226..0313fb5008 100644 --- a/spring-batch/src/main/resources/logback.xml +++ b/spring-batch/src/main/resources/logback.xml @@ -12,6 +12,10 @@ additivity="false"> + + + + diff --git a/spring-batch/src/test/java/org/baeldung/batchscheduler/SpringBatchSchedulerIntegrationTest.java b/spring-batch/src/test/java/org/baeldung/batchscheduler/SpringBatchSchedulerIntegrationTest.java new file mode 100644 index 0000000000..ef825b900f --- /dev/null +++ b/spring-batch/src/test/java/org/baeldung/batchscheduler/SpringBatchSchedulerIntegrationTest.java @@ -0,0 +1,60 @@ +package org.baeldung.batchscheduler; + +import java.util.Date; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.scheduling.TaskScheduler; +import org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = SpringBatchScheduler.class) +public class SpringBatchSchedulerIntegrationTest { + + private static final int TIMER = 3000; + + @Autowired + private ApplicationContext context; + + @Test + public void stopJobsWhenSchedulerDisabled() throws Exception { + Thread.sleep(TIMER); + SpringBatchScheduler schedulerBean = context.getBean(SpringBatchScheduler.class); + schedulerBean.stop(); + Thread.sleep(TIMER); + Date lastLaunchDate = schedulerBean.getCurrentLaunchDate(); + Thread.sleep(TIMER); + Assert.assertEquals(lastLaunchDate, schedulerBean.getCurrentLaunchDate()); + } + + @Test + public void stopJobSchedulerWhenSchedulerDestroyed() throws Exception { + Thread.sleep(TIMER); + ScheduledAnnotationBeanPostProcessor bean = context.getBean(ScheduledAnnotationBeanPostProcessor.class); + SpringBatchScheduler schedulerBean = context.getBean(SpringBatchScheduler.class); + bean.postProcessBeforeDestruction(schedulerBean, "SpringBatchScheduler"); + Thread.sleep(TIMER); + Date lastLaunchTime = schedulerBean.getCurrentLaunchDate(); + Thread.sleep(TIMER); + Assert.assertEquals(lastLaunchTime, schedulerBean.getCurrentLaunchDate()); + + } + + @Test + public void stopJobSchedulerWhenFutureTasksCancelled() throws Exception { + Thread.sleep(TIMER); + SpringBatchScheduler schedulerBean = context.getBean(SpringBatchScheduler.class); + schedulerBean.cancelFutureSchedulerTasks(); + Thread.sleep(TIMER); + Date lastLaunchTime = schedulerBean.getCurrentLaunchDate(); + Thread.sleep(TIMER); + Assert.assertEquals(lastLaunchTime, schedulerBean.getCurrentLaunchDate()); + + } + +} diff --git a/spring-boot-custom-starter/README.md b/spring-boot-custom-starter/README.md index aae79fe112..f983441ca0 100644 --- a/spring-boot-custom-starter/README.md +++ b/spring-boot-custom-starter/README.md @@ -7,4 +7,6 @@ - **greeter-spring-boot-starter**: The custom starter for the library. -- **greeter-spring-boot-sample-app**: The sample project that uses the custom starter. \ No newline at end of file +- **greeter-spring-boot-sample-app**: The sample project that uses the custom starter. + +- [Multi-Module Project With Spring Boot](http://www.baeldung.com/spring-boot-multiple-modules) diff --git a/spring-boot-logging-log4j2/README.md b/spring-boot-logging-log4j2/README.md new file mode 100644 index 0000000000..7676bd1919 --- /dev/null +++ b/spring-boot-logging-log4j2/README.md @@ -0,0 +1,2 @@ +### Relevant Articles: +- [Logging in Spring Boot](http://www.baeldung.com/spring-boot-logging) diff --git a/spring-boot-ops/README.md b/spring-boot-ops/README.md deleted file mode 100644 index 7eca307924..0000000000 --- a/spring-boot-ops/README.md +++ /dev/null @@ -1,10 +0,0 @@ -### Relevant Articles: - -- [Deploy a Spring Boot WAR into a Tomcat Server](http://www.baeldung.com/spring-boot-war-tomcat-deploy) -- [Spring Boot Dependency Management with a Custom Parent](http://www.baeldung.com/spring-boot-dependency-management-custom-parent) -- [A Custom Data Binder in Spring MVC](http://www.baeldung.com/spring-mvc-custom-data-binder) -- [Create a Fat Jar App with Spring Boot](http://www.baeldung.com/deployable-fat-jar-spring-boot) -- [Introduction to WebJars](http://www.baeldung.com/maven-webjars) -- [Intro to Spring Boot Starters](http://www.baeldung.com/spring-boot-starters) -- [A Quick Guide to Maven Wrapper](http://www.baeldung.com/maven-wrapper) -- [Shutdown a Spring Boot Application](http://www.baeldung.com/spring-boot-shutdown) diff --git a/spring-cloud-data-flow/batch-job/src/main/java/org/baeldung/spring/cloud/BatchJobApplication.java b/spring-cloud-data-flow/batch-job/src/main/java/org/baeldung/spring/cloud/BatchJobApplication.java index f717f0f644..30f6ff6897 100644 --- a/spring-cloud-data-flow/batch-job/src/main/java/org/baeldung/spring/cloud/BatchJobApplication.java +++ b/spring-cloud-data-flow/batch-job/src/main/java/org/baeldung/spring/cloud/BatchJobApplication.java @@ -1,12 +1,10 @@ package org.baeldung.spring.cloud; -import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.task.configuration.EnableTask; @EnableTask -@EnableBatchProcessing @SpringBootApplication public class BatchJobApplication { diff --git a/spring-cloud-data-flow/batch-job/src/main/java/org/baeldung/spring/cloud/JobConfiguration.java b/spring-cloud-data-flow/batch-job/src/main/java/org/baeldung/spring/cloud/JobConfiguration.java index dc6a5e2827..7ce867b60a 100644 --- a/spring-cloud-data-flow/batch-job/src/main/java/org/baeldung/spring/cloud/JobConfiguration.java +++ b/spring-cloud-data-flow/batch-job/src/main/java/org/baeldung/spring/cloud/JobConfiguration.java @@ -2,9 +2,9 @@ package org.baeldung.spring.cloud; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; - import org.springframework.batch.core.Job; import org.springframework.batch.core.StepContribution; +import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing; import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; import org.springframework.batch.core.configuration.annotation.StepBuilderFactory; import org.springframework.batch.core.scope.context.ChunkContext; @@ -15,6 +15,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration +@EnableBatchProcessing public class JobConfiguration { private static final Log logger = LogFactory.getLog(JobConfiguration.class); diff --git a/spring-cloud-data-flow/batch-job/src/test/java/org/baeldung/spring/cloud/BatchJobApplicationIntegrationTest.java b/spring-cloud-data-flow/batch-job/src/test/java/org/baeldung/spring/cloud/BatchJobApplicationIntegrationTest.java index f8dfdec197..1f77351acc 100644 --- a/spring-cloud-data-flow/batch-job/src/test/java/org/baeldung/spring/cloud/BatchJobApplicationIntegrationTest.java +++ b/spring-cloud-data-flow/batch-job/src/test/java/org/baeldung/spring/cloud/BatchJobApplicationIntegrationTest.java @@ -3,10 +3,12 @@ package org.baeldung.spring.cloud; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest +@ContextConfiguration(classes = JobConfiguration.class) public class BatchJobApplicationIntegrationTest { @Test diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/pom.xml b/spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/pom.xml index f3ce213540..e510a687cc 100644 --- a/spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/pom.xml +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/pom.xml @@ -52,7 +52,7 @@ - Camden.SR4 + Edgware.SR4 diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/src/test/java/org/baeldung/SpringCloudRestServerIntegrationTest.java b/spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/src/test/java/org/baeldung/SpringCloudRestServerIntegrationTest.java index e077c42a96..14597d5c2f 100644 --- a/spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/src/test/java/org/baeldung/SpringCloudRestServerIntegrationTest.java +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/src/test/java/org/baeldung/SpringCloudRestServerIntegrationTest.java @@ -2,7 +2,14 @@ package org.baeldung; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Mockito; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.RedisConnection; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.serializer.RedisSerializer; +import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @@ -11,5 +18,25 @@ public class SpringCloudRestServerIntegrationTest { @Test public void contextLoads() { } + + @EnableRedisHttpSession + @Configuration + static class Config { + + @Bean + @SuppressWarnings("unchecked") + public RedisSerializer defaultRedisSerializer() { + return Mockito.mock(RedisSerializer.class); + } -} + @Bean + public RedisConnectionFactory connectionFactory() { + + RedisConnectionFactory factory = Mockito.mock(RedisConnectionFactory.class); + RedisConnection connection = Mockito.mock(RedisConnection.class); + Mockito.when(factory.getConnection()).thenReturn(connection); + + return factory; + } + } +} \ No newline at end of file diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/pom.xml b/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/pom.xml index 27e327110a..cbd495908a 100644 --- a/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/pom.xml +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/pom.xml @@ -18,6 +18,7 @@ 3.0.1 + 0.6 @@ -57,6 +58,11 @@ org.springframework.boot spring-boot-starter-data-redis + + com.github.kstyrc + embedded-redis + ${embedded-redis.version} + diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/test/java/org/baeldung/BookReviewsApiIntegrationTest.java b/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/test/java/org/baeldung/BookReviewsApiIntegrationTest.java index d25e0bee20..98cda102e9 100644 --- a/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/test/java/org/baeldung/BookReviewsApiIntegrationTest.java +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/test/java/org/baeldung/BookReviewsApiIntegrationTest.java @@ -1,13 +1,33 @@ package org.baeldung; +import java.io.IOException; + +import org.junit.AfterClass; +import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; +import redis.embedded.RedisServer; @RunWith(SpringRunner.class) @SpringBootTest public class BookReviewsApiIntegrationTest { + + private static RedisServer redisServer; + private static int port; + + @BeforeClass + public static void setUp() throws IOException { + + redisServer = new RedisServer(6379); + redisServer.start(); + } + + @AfterClass + public static void destroy() { + redisServer.stop(); + } @Test public void contextLoads() { diff --git a/spring-core/src/test/java/com/baeldung/dependson/processor/FileProcessorIntegrationTest.java b/spring-core/src/test/java/com/baeldung/dependson/processor/FileProcessorIntegrationTest.java index 11d9daf3bf..5de53192df 100644 --- a/spring-core/src/test/java/com/baeldung/dependson/processor/FileProcessorIntegrationTest.java +++ b/spring-core/src/test/java/com/baeldung/dependson/processor/FileProcessorIntegrationTest.java @@ -5,7 +5,6 @@ import static org.junit.Assert.assertTrue; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.BeanCreationException; -import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.test.context.ContextConfiguration; @@ -30,7 +29,7 @@ public class FileProcessorIntegrationTest { assertTrue(file.getText().endsWith("processed")); } - @Test(expected=NoSuchBeanDefinitionException.class) + @Test(expected=BeanCreationException.class) public void whenDependentBeanNotAvailable_ThrowsNoSuchBeanDefinitionException(){ context.getBean("dummyFileProcessor"); } diff --git a/spring-cucumber/src/test/java/com/baeldung/CucumberIntegrationTest.java b/spring-cucumber/src/test/java/com/baeldung/CucumberIntegrationTest.java index 56eb810c09..f48ab410ca 100644 --- a/spring-cucumber/src/test/java/com/baeldung/CucumberIntegrationTest.java +++ b/spring-cucumber/src/test/java/com/baeldung/CucumberIntegrationTest.java @@ -1,10 +1,11 @@ package com.baeldung; +import org.junit.runner.RunWith; + import cucumber.api.CucumberOptions; import cucumber.api.junit.Cucumber; -import org.junit.runner.RunWith; @RunWith(Cucumber.class) @CucumberOptions(features = "src/test/resources") -public class CucumberIntegrationTest { +public class CucumberIntegrationTest extends SpringIntegrationTest{ } \ No newline at end of file diff --git a/spring-cucumber/src/test/java/com/baeldung/SpringIntegrationTest.java b/spring-cucumber/src/test/java/com/baeldung/SpringIntegrationTest.java index f4d47d7871..8655a02469 100644 --- a/spring-cucumber/src/test/java/com/baeldung/SpringIntegrationTest.java +++ b/spring-cucumber/src/test/java/com/baeldung/SpringIntegrationTest.java @@ -5,16 +5,17 @@ import java.util.HashMap; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.http.HttpMethod; import org.springframework.http.client.ClientHttpResponse; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.web.client.ResponseErrorHandler; import org.springframework.web.client.RestTemplate; //@RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(classes = SpringDemoApplication.class) -@WebAppConfiguration +@SpringBootTest(classes = SpringDemoApplication.class, webEnvironment = WebEnvironment.DEFINED_PORT) +@ContextConfiguration public class SpringIntegrationTest { static ResponseResults latestResponse = null; diff --git a/spring-data-rest/src/test/java/com/baeldung/projection/SpringDataProjectionIntegrationTest.java b/spring-data-rest/src/test/java/com/baeldung/projection/SpringDataProjectionLiveTest.java similarity index 98% rename from spring-data-rest/src/test/java/com/baeldung/projection/SpringDataProjectionIntegrationTest.java rename to spring-data-rest/src/test/java/com/baeldung/projection/SpringDataProjectionLiveTest.java index 2b1f6d4d4f..702c1521da 100644 --- a/spring-data-rest/src/test/java/com/baeldung/projection/SpringDataProjectionIntegrationTest.java +++ b/spring-data-rest/src/test/java/com/baeldung/projection/SpringDataProjectionLiveTest.java @@ -25,7 +25,7 @@ import com.baeldung.repositories.BookRepository; @RunWith(SpringRunner.class) @SpringBootTest(classes = SpringDataRestApplication.class, webEnvironment = WebEnvironment.DEFINED_PORT) -public class SpringDataProjectionIntegrationTest { +public class SpringDataProjectionLiveTest { private static final String BOOK_ENDPOINT = "http://localhost:8080/books"; private static final String AUTHOR_ENDPOINT = "http://localhost:8080/authors"; diff --git a/spring-data-rest/src/test/java/com/baeldung/relationships/SpringDataRelationshipsIntegrationTest.java b/spring-data-rest/src/test/java/com/baeldung/relationships/SpringDataRelationshipsIntegrationTest.java index e3fe60d487..196dc18d9e 100644 --- a/spring-data-rest/src/test/java/com/baeldung/relationships/SpringDataRelationshipsIntegrationTest.java +++ b/spring-data-rest/src/test/java/com/baeldung/relationships/SpringDataRelationshipsIntegrationTest.java @@ -1,15 +1,14 @@ package com.baeldung.relationships; -import com.baeldung.SpringDataRestApplication; -import com.baeldung.models.Address; -import com.baeldung.models.Author; -import com.baeldung.models.Book; -import com.baeldung.models.Library; +import static org.junit.Assert.assertEquals; + import org.json.JSONArray; +import org.json.JSONException; import org.json.JSONObject; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.web.client.TestRestTemplate; @@ -18,21 +17,27 @@ import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.ResponseEntity; import org.springframework.test.context.junit4.SpringRunner; -import org.json.JSONException; -import static org.junit.Assert.assertEquals; +import com.baeldung.SpringDataRestApplication; +import com.baeldung.models.Address; +import com.baeldung.models.Author; +import com.baeldung.models.Book; +import com.baeldung.models.Library; @RunWith(SpringRunner.class) -@SpringBootTest(classes = SpringDataRestApplication.class, webEnvironment = WebEnvironment.DEFINED_PORT) +@SpringBootTest(classes = SpringDataRestApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT) public class SpringDataRelationshipsIntegrationTest { @Autowired private TestRestTemplate template; + + @Value("${local.server.port}") + private int port; - private static final String BOOK_ENDPOINT = "http://localhost:8080/books/"; - private static final String AUTHOR_ENDPOINT = "http://localhost:8080/authors/"; - private static final String ADDRESS_ENDPOINT = "http://localhost:8080/addresses/"; - private static final String LIBRARY_ENDPOINT = "http://localhost:8080/libraries/"; + private static final String BOOK_ENDPOINT = "http://localhost:%s/books/"; + private static final String AUTHOR_ENDPOINT = "http://localhost:%s/authors/"; + private static final String ADDRESS_ENDPOINT = "http://localhost:%s/addresses/"; + private static final String LIBRARY_ENDPOINT = "http://localhost:%s/libraries/"; private static final String LIBRARY_NAME = "My Library"; private static final String AUTHOR_NAME = "George Orwell"; @@ -40,17 +45,17 @@ public class SpringDataRelationshipsIntegrationTest { @Test public void whenSaveOneToOneRelationship_thenCorrect() throws JSONException { Library library = new Library(LIBRARY_NAME); - template.postForEntity(LIBRARY_ENDPOINT, library, Library.class); + template.postForEntity(String.format(LIBRARY_ENDPOINT, port), library, Library.class); Address address = new Address("Main street, nr 1"); - template.postForEntity(ADDRESS_ENDPOINT, address, Address.class); + template.postForEntity(String.format(ADDRESS_ENDPOINT, port), address, Address.class); HttpHeaders requestHeaders = new HttpHeaders(); requestHeaders.add("Content-type", "text/uri-list"); - HttpEntity httpEntity = new HttpEntity<>(ADDRESS_ENDPOINT + "/1", requestHeaders); - template.exchange(LIBRARY_ENDPOINT + "/1/libraryAddress", HttpMethod.PUT, httpEntity, String.class); + HttpEntity httpEntity = new HttpEntity<>(String.format(ADDRESS_ENDPOINT, port) + "/1", requestHeaders); + template.exchange(String.format(LIBRARY_ENDPOINT, port) + "/1/libraryAddress", HttpMethod.PUT, httpEntity, String.class); - ResponseEntity libraryGetResponse = template.getForEntity(ADDRESS_ENDPOINT + "/1/library", Library.class); + ResponseEntity libraryGetResponse = template.getForEntity(String.format(ADDRESS_ENDPOINT, port) + "/1/library", Library.class); assertEquals("library is incorrect", libraryGetResponse.getBody() .getName(), LIBRARY_NAME); } @@ -58,21 +63,21 @@ public class SpringDataRelationshipsIntegrationTest { @Test public void whenSaveOneToManyRelationship_thenCorrect() throws JSONException{ Library library = new Library(LIBRARY_NAME); - template.postForEntity(LIBRARY_ENDPOINT, library, Library.class); + template.postForEntity(String.format(LIBRARY_ENDPOINT, port), library, Library.class); Book book1 = new Book("Dune"); - template.postForEntity(BOOK_ENDPOINT, book1, Book.class); + template.postForEntity(String.format(BOOK_ENDPOINT, port), book1, Book.class); Book book2 = new Book("1984"); - template.postForEntity(BOOK_ENDPOINT, book2, Book.class); + template.postForEntity(String.format(BOOK_ENDPOINT, port), book2, Book.class); HttpHeaders requestHeaders = new HttpHeaders(); requestHeaders.add("Content-type", "text/uri-list"); - HttpEntity bookHttpEntity = new HttpEntity<>(LIBRARY_ENDPOINT + "/1", requestHeaders); - template.exchange(BOOK_ENDPOINT + "/1/library", HttpMethod.PUT, bookHttpEntity, String.class); - template.exchange(BOOK_ENDPOINT + "/2/library", HttpMethod.PUT, bookHttpEntity, String.class); + HttpEntity bookHttpEntity = new HttpEntity<>(String.format(LIBRARY_ENDPOINT, port) + "/1", requestHeaders); + template.exchange(String.format(BOOK_ENDPOINT, port) + "/1/library", HttpMethod.PUT, bookHttpEntity, String.class); + template.exchange(String.format(BOOK_ENDPOINT, port) + "/2/library", HttpMethod.PUT, bookHttpEntity, String.class); - ResponseEntity libraryGetResponse = template.getForEntity(BOOK_ENDPOINT + "/1/library", Library.class); + ResponseEntity libraryGetResponse = template.getForEntity(String.format(BOOK_ENDPOINT, port) + "/1/library", Library.class); assertEquals("library is incorrect", libraryGetResponse.getBody() .getName(), LIBRARY_NAME); } @@ -80,20 +85,20 @@ public class SpringDataRelationshipsIntegrationTest { @Test public void whenSaveManyToManyRelationship_thenCorrect() throws JSONException{ Author author1 = new Author(AUTHOR_NAME); - template.postForEntity(AUTHOR_ENDPOINT, author1, Author.class); + template.postForEntity(String.format(AUTHOR_ENDPOINT, port), author1, Author.class); Book book1 = new Book("Animal Farm"); - template.postForEntity(BOOK_ENDPOINT, book1, Book.class); + template.postForEntity(String.format(BOOK_ENDPOINT, port), book1, Book.class); Book book2 = new Book("1984"); - template.postForEntity(BOOK_ENDPOINT, book2, Book.class); + template.postForEntity(String.format(BOOK_ENDPOINT, port), book2, Book.class); HttpHeaders requestHeaders = new HttpHeaders(); requestHeaders.add("Content-type", "text/uri-list"); - HttpEntity httpEntity = new HttpEntity<>(BOOK_ENDPOINT + "/1\n" + BOOK_ENDPOINT + "/2", requestHeaders); - template.exchange(AUTHOR_ENDPOINT + "/1/books", HttpMethod.PUT, httpEntity, String.class); + HttpEntity httpEntity = new HttpEntity<>(String.format(BOOK_ENDPOINT, port) + "/1\n" + String.format(BOOK_ENDPOINT, port) + "/2", requestHeaders); + template.exchange(String.format(AUTHOR_ENDPOINT, port) + "/1/books", HttpMethod.PUT, httpEntity, String.class); - String jsonResponse = template.getForObject(BOOK_ENDPOINT + "/1/authors", String.class); + String jsonResponse = template.getForObject(String.format(BOOK_ENDPOINT, port) + "/1/authors", String.class); JSONObject jsonObj = new JSONObject(jsonResponse).getJSONObject("_embedded"); JSONArray jsonArray = jsonObj.getJSONArray("authors"); assertEquals("author is incorrect", jsonArray.getJSONObject(0) diff --git a/spring-data-rest/src/test/java/com/baeldung/validator/SpringDataRestValidatorIntegrationTest.java b/spring-data-rest/src/test/java/com/baeldung/validator/SpringDataRestValidatorIntegrationTest.java index bc321bc686..4c936ffc1c 100644 --- a/spring-data-rest/src/test/java/com/baeldung/validator/SpringDataRestValidatorIntegrationTest.java +++ b/spring-data-rest/src/test/java/com/baeldung/validator/SpringDataRestValidatorIntegrationTest.java @@ -1,31 +1,33 @@ package com.baeldung.validator; -import com.baeldung.SpringDataRestApplication; -import com.baeldung.models.WebsiteUser; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.http.MediaType; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.context.web.WebAppConfiguration; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.web.context.WebApplicationContext; - import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.springframework.test.web.servlet.setup.MockMvcBuilders.webAppContextSetup; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.web.context.WebApplicationContext; + +import com.baeldung.SpringDataRestApplication; +import com.baeldung.models.WebsiteUser; +import com.fasterxml.jackson.databind.ObjectMapper; + @RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = SpringDataRestApplication.class) -@WebAppConfiguration +@SpringBootTest(classes = SpringDataRestApplication.class, webEnvironment = SpringBootTest.WebEnvironment.MOCK) +@AutoConfigureMockMvc public class SpringDataRestValidatorIntegrationTest { public static final String URL = "http://localhost"; + @Autowired private MockMvc mockMvc; @Autowired diff --git a/spring-jenkins-pipeline/pom.xml b/spring-jenkins-pipeline/pom.xml index 9c3b6f14ed..bbc07a4091 100644 --- a/spring-jenkins-pipeline/pom.xml +++ b/spring-jenkins-pipeline/pom.xml @@ -29,6 +29,12 @@ spring-boot-starter-test test + + de.flapdoodle.embed + de.flapdoodle.embed.mongo + ${de.flapdoodle.embed.mongo.version} + test + @@ -73,6 +79,7 @@ UTF-8 1.8 2.17 + 2.0.0 diff --git a/spring-jenkins-pipeline/src/test/java/com/baeldung/SomeIntegrationTest.java b/spring-jenkins-pipeline/src/test/java/com/baeldung/SomeIntegrationTest.java index 092ebb93fd..477a7d2adb 100644 --- a/spring-jenkins-pipeline/src/test/java/com/baeldung/SomeIntegrationTest.java +++ b/spring-jenkins-pipeline/src/test/java/com/baeldung/SomeIntegrationTest.java @@ -13,7 +13,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import static org.junit.Assert.assertNotEquals; @RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest +@SpringBootTest(classes = {SpringJenkinsPipelineApplication.class, TestMongoConfig.class }) public class SomeIntegrationTest { @Autowired private StudentRepository studentRepository; diff --git a/spring-jenkins-pipeline/src/test/java/com/baeldung/TestMongoConfig.java b/spring-jenkins-pipeline/src/test/java/com/baeldung/TestMongoConfig.java new file mode 100644 index 0000000000..a85491cf7e --- /dev/null +++ b/spring-jenkins-pipeline/src/test/java/com/baeldung/TestMongoConfig.java @@ -0,0 +1,11 @@ +package com.baeldung; + +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration; +import org.springframework.context.annotation.Configuration; + +@Configuration +@EnableAutoConfiguration(exclude = { EmbeddedMongoAutoConfiguration.class }) +public class TestMongoConfig { + +} \ No newline at end of file diff --git a/spring-jooq/pom.xml b/spring-jooq/pom.xml index bd8bc6f404..a2ca229031 100644 --- a/spring-jooq/pom.xml +++ b/spring-jooq/pom.xml @@ -5,9 +5,10 @@ 0.0.1-SNAPSHOT - com.baeldung - parent-modules - 1.0.0-SNAPSHOT + org.springframework.boot + spring-boot-starter-parent + 1.4.4.RELEASE + @@ -55,6 +56,10 @@ org.springframework.boot spring-boot-starter-jooq + + org.springframework.boot + spring-boot-starter-test + diff --git a/spring-jooq/src/test/java/com/baeldung/jooq/springboot/SpringBootIntegrationTest.java b/spring-jooq/src/test/java/com/baeldung/jooq/springboot/SpringBootIntegrationTest.java index 25317309ee..5e76fb3c93 100644 --- a/spring-jooq/src/test/java/com/baeldung/jooq/springboot/SpringBootIntegrationTest.java +++ b/spring-jooq/src/test/java/com/baeldung/jooq/springboot/SpringBootIntegrationTest.java @@ -12,14 +12,16 @@ import org.jooq.impl.DSL; 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.dao.DataAccessException; -import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.transaction.annotation.Transactional; -@RunWith(SpringRunner.class) -@SpringBootTest(classes = Application.class) -@Transactional("transactionManager") +import com.baeldung.jooq.introduction.PersistenceContextIntegrationTest; + +@ContextConfiguration(classes = PersistenceContextIntegrationTest.class) +@Transactional(transactionManager = "transactionManager") +@RunWith(SpringJUnit4ClassRunner.class) public class SpringBootIntegrationTest { @Autowired diff --git a/spring-mvc-email/README.md b/spring-mvc-email/README.md deleted file mode 100644 index aa880188d7..0000000000 --- a/spring-mvc-email/README.md +++ /dev/null @@ -1,17 +0,0 @@ -## Relevant articles: - -- [Guide to Spring Email](http://www.baeldung.com/spring-email) - -## Spring MVC Email - -Example Spring MVC project to send email from web form. - -### Installing and Running - -Just run the Spring Boot application. -Type http://localhost:8080 in your browser to open the application. - - -### Sending test emails - -Follow UI links to send simple email, email using template or email with attachment. diff --git a/spring-mvc-email/pom.xml b/spring-mvc-email/pom.xml deleted file mode 100644 index 40d83046ef..0000000000 --- a/spring-mvc-email/pom.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - 4.0.0 - - org.baeldung.spring - spring-mvc-email - 1.0 - spring-mvc-email - war - - - parent-boot-1 - com.baeldung - 0.0.1-SNAPSHOT - ../parent-boot-1 - - - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter-tomcat - - - - org.springframework.boot - spring-boot-starter-mail - - - - javax.servlet - jstl - - - - diff --git a/spring-mvc-email/src/main/java/com/baeldung/spring/Application.java b/spring-mvc-email/src/main/java/com/baeldung/spring/Application.java deleted file mode 100644 index bc5d6b3151..0000000000 --- a/spring-mvc-email/src/main/java/com/baeldung/spring/Application.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.baeldung.spring; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.web.support.SpringBootServletInitializer; - - -@SpringBootApplication -public class Application extends SpringBootServletInitializer { - public static void main(String[] args) { - SpringApplication.run(Application.class, args); - } -} diff --git a/spring-mvc-email/src/main/java/com/baeldung/spring/app/config/AppConfig.java b/spring-mvc-email/src/main/java/com/baeldung/spring/app/config/AppConfig.java deleted file mode 100644 index 9078d44764..0000000000 --- a/spring-mvc-email/src/main/java/com/baeldung/spring/app/config/AppConfig.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.baeldung.spring.app.config; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; -import org.springframework.mail.SimpleMailMessage; -import org.springframework.web.servlet.config.annotation.EnableWebMvc; -import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; -import org.springframework.web.servlet.view.InternalResourceViewResolver; -import org.springframework.web.servlet.view.JstlView; -import org.springframework.web.servlet.view.UrlBasedViewResolver; - -/** - * Created with IntelliJ IDEA. - * User: Olga - */ -@Configuration -@ComponentScan("com.baeldung.spring") -@EnableWebMvc //tha same as -public class AppConfig extends WebMvcConfigurerAdapter { - @Override - public void addResourceHandlers(ResourceHandlerRegistry registry) { - registry.addResourceHandler("/resources/**").addResourceLocations("/resources/"); - } - - @Bean - public UrlBasedViewResolver urlBasedViewResolver() { - UrlBasedViewResolver resolver = new UrlBasedViewResolver(); - resolver.setOrder(0); - resolver.setPrefix("/WEB-INF/views/"); - resolver.setSuffix(".jsp"); - resolver.setCache(false); - resolver.setViewClass(JstlView.class); - return resolver; - } - - @Bean - public InternalResourceViewResolver internalResourceViewResolver() { - InternalResourceViewResolver resolver = new InternalResourceViewResolver(); - resolver.setOrder(1); - resolver.setPrefix("/WEB-INF/views/"); - resolver.setSuffix(".jsp"); - resolver.setViewClass(JstlView.class); - return resolver; - } - - @Bean - public SimpleMailMessage templateSimpleMessage() { - SimpleMailMessage message = new SimpleMailMessage(); - message.setText("This is the test email template for your email:\n%s\n"); - return message; - } -} diff --git a/spring-mvc-email/src/main/java/com/baeldung/spring/controllers/HomeController.java b/spring-mvc-email/src/main/java/com/baeldung/spring/controllers/HomeController.java deleted file mode 100644 index 656e237a9e..0000000000 --- a/spring-mvc-email/src/main/java/com/baeldung/spring/controllers/HomeController.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.baeldung.spring.controllers; - -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; - -/** - * Created with IntelliJ IDEA. - * User: Olga - */ -@Controller -@RequestMapping({"/","/home"}) -public class HomeController { - - @RequestMapping(method = RequestMethod.GET) - public String showHomePage() { - return "home"; - } -} diff --git a/spring-mvc-email/src/main/resources/META-INF/application.xml b/spring-mvc-email/src/main/resources/META-INF/application.xml deleted file mode 100644 index 759a312bd4..0000000000 --- a/spring-mvc-email/src/main/resources/META-INF/application.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - SpringMVCEmail.war - SpringMVCEmail - - - - - web.war - SpringMVCEmailWeb - - - \ No newline at end of file diff --git a/spring-mvc-email/src/main/webapp/WEB-INF/web.xml b/spring-mvc-email/src/main/webapp/WEB-INF/web.xml deleted file mode 100644 index 4cd41216d9..0000000000 --- a/spring-mvc-email/src/main/webapp/WEB-INF/web.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - simpleweb - org.springframework.web.servlet.DispatcherServlet - - contextClass - - org.springframework.web.context.support.AnnotationConfigWebApplicationContext - - - - contextConfigLocation - com.baeldung.spring.app.config.AppConfig - - 1 - - - - simpleweb - / - - - diff --git a/spring-mvc-java/src/main/java/com/baeldung/web/controller/WebsocketSendToUserController.java b/spring-mvc-java/src/main/java/com/baeldung/web/controller/WebsocketSendToUserController.java index d4c15aead9..4b55bcc00f 100644 --- a/spring-mvc-java/src/main/java/com/baeldung/web/controller/WebsocketSendToUserController.java +++ b/spring-mvc-java/src/main/java/com/baeldung/web/controller/WebsocketSendToUserController.java @@ -1,23 +1,19 @@ package com.baeldung.web.controller; -import com.google.gson.Gson; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.messaging.handler.annotation.MessageExceptionHandler; -import org.springframework.messaging.handler.annotation.MessageMapping; -import org.springframework.messaging.handler.annotation.Payload; -import org.springframework.messaging.simp.SimpMessageSendingOperations; -import org.springframework.messaging.simp.annotation.SendToUser; -import org.springframework.stereotype.Controller; - import java.security.Principal; import java.util.Map; +import org.springframework.messaging.handler.annotation.MessageExceptionHandler; +import org.springframework.messaging.handler.annotation.MessageMapping; +import org.springframework.messaging.handler.annotation.Payload; +import org.springframework.messaging.simp.annotation.SendToUser; +import org.springframework.stereotype.Controller; + +import com.google.gson.Gson; + @Controller public class WebsocketSendToUserController { - @Autowired - private SimpMessageSendingOperations messagingTemplate; - private Gson gson = new Gson(); @MessageMapping("/message") diff --git a/spring-mvc-simple/README.md b/spring-mvc-simple/README.md index 3505fb8009..39053534fa 100644 --- a/spring-mvc-simple/README.md +++ b/spring-mvc-simple/README.md @@ -5,3 +5,4 @@ - [Spring 5 and Servlet 4 – The PushBuilder](http://www.baeldung.com/spring-5-push) - [Servlet Redirect vs Forward](http://www.baeldung.com/servlet-redirect-forward) - [Apache Tiles Integration with Spring MVC](http://www.baeldung.com/spring-mvc-apache-tiles) +- [Guide to Spring Email](http://www.baeldung.com/spring-email) diff --git a/spring-mvc-simple/pom.xml b/spring-mvc-simple/pom.xml index 08eab59540..ac112f7e29 100644 --- a/spring-mvc-simple/pom.xml +++ b/spring-mvc-simple/pom.xml @@ -20,6 +20,15 @@ spring-oxm ${spring-oxm.version} + + org.springframework + spring-context-support + + + com.sun.mail + javax.mail + 1.6.1 + javax.servlet javax.servlet-api @@ -122,6 +131,14 @@ json ${json.version} + + org.apache.maven.surefire + surefire-logger-api + ${maven-surefire-plugin.version} + + test + true + @@ -171,7 +188,7 @@ 1.2 2.3.2-b02 4.0.0 - 5.4.1.Final + 6.0.10.Final enter-location-of-server 1.3.2 1.8 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 c28ee02eef..284be6c212 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 @@ -8,6 +8,9 @@ import org.springframework.context.annotation.Configuration; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.StringHttpMessageConverter; import org.springframework.http.converter.feed.RssChannelHttpMessageConverter; +import org.springframework.mail.SimpleMailMessage; +import org.springframework.mail.javamail.JavaMailSender; +import org.springframework.mail.javamail.JavaMailSenderImpl; import org.springframework.web.accept.ContentNegotiationManager; import org.springframework.web.multipart.MultipartResolver; import org.springframework.web.multipart.commons.CommonsMultipartResolver; @@ -20,10 +23,11 @@ import org.springframework.web.servlet.view.InternalResourceViewResolver; import java.util.ArrayList; import java.util.List; +import java.util.Properties; @Configuration @EnableWebMvc -@ComponentScan(basePackages = { "com.baeldung.springmvcforms", "com.baeldung.spring.controller", "com.baeldung.spring.validator" }) +@ComponentScan(basePackages = { "com.baeldung.springmvcforms", "com.baeldung.spring.controller", "com.baeldung.spring.validator", "com.baeldung.spring.mail" }) public class ApplicationConfiguration implements WebMvcConfigurer { @Override @@ -60,4 +64,29 @@ public class ApplicationConfiguration implements WebMvcConfigurer { converters.add(new RssChannelHttpMessageConverter()); converters.add(new JsonChannelHttpMessageConverter()); } + + @Bean + public SimpleMailMessage templateSimpleMessage() { + SimpleMailMessage message = new SimpleMailMessage(); + message.setText("This is the test email template for your email:\n%s\n"); + return message; + } + + @Bean + public JavaMailSender getJavaMailSender() { + JavaMailSenderImpl mailSender = new JavaMailSenderImpl(); + mailSender.setHost("smtp.gmail.com"); + mailSender.setPort(587); + + mailSender.setUsername("my.gmail@gmail.com"); + mailSender.setPassword("password"); + + Properties props = mailSender.getJavaMailProperties(); + props.put("mail.transport.protocol", "smtp"); + props.put("mail.smtp.auth", "true"); + props.put("mail.smtp.starttls.enable", "true"); + props.put("mail.debug", "true"); + + return mailSender; + } } diff --git a/spring-mvc-email/src/main/java/com/baeldung/spring/controllers/MailController.java b/spring-mvc-simple/src/main/java/com/baeldung/spring/controller/MailController.java similarity index 95% rename from spring-mvc-email/src/main/java/com/baeldung/spring/controllers/MailController.java rename to spring-mvc-simple/src/main/java/com/baeldung/spring/controller/MailController.java index ff828ca9ec..16d1202eef 100644 --- a/spring-mvc-email/src/main/java/com/baeldung/spring/controllers/MailController.java +++ b/spring-mvc-simple/src/main/java/com/baeldung/spring/controller/MailController.java @@ -1,9 +1,8 @@ -package com.baeldung.spring.controllers; +package com.baeldung.spring.controller; import com.baeldung.spring.mail.EmailServiceImpl; -import com.baeldung.spring.web.dto.MailObject; +import com.baeldung.spring.domain.MailObject; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.mail.SimpleMailMessage; import org.springframework.stereotype.Controller; @@ -62,6 +61,11 @@ public class MailController { props.put("additionalInfo", "To make sure that you send an attachment with this email, change the value for the 'attachment.invoice' in the application.properties file to the path to the attachment."); labels.put("sendAttachment", props); } + + @RequestMapping(method = RequestMethod.GET) + public String showEmailsPage() { + return "emails"; + } @RequestMapping(value = {"/send", "/sendTemplate", "/sendAttachment"}, method = RequestMethod.GET) public String createMail(Model model, diff --git a/spring-mvc-email/src/main/java/com/baeldung/spring/web/dto/MailObject.java b/spring-mvc-simple/src/main/java/com/baeldung/spring/domain/MailObject.java similarity index 89% rename from spring-mvc-email/src/main/java/com/baeldung/spring/web/dto/MailObject.java rename to spring-mvc-simple/src/main/java/com/baeldung/spring/domain/MailObject.java index 9623ff5d78..aceaf685fa 100644 --- a/spring-mvc-email/src/main/java/com/baeldung/spring/web/dto/MailObject.java +++ b/spring-mvc-simple/src/main/java/com/baeldung/spring/domain/MailObject.java @@ -1,7 +1,6 @@ -package com.baeldung.spring.web.dto; - -import org.hibernate.validator.constraints.Email; +package com.baeldung.spring.domain; +import javax.validation.constraints.Email; import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; diff --git a/spring-mvc-email/src/main/java/com/baeldung/spring/mail/EmailService.java b/spring-mvc-simple/src/main/java/com/baeldung/spring/mail/EmailService.java similarity index 100% rename from spring-mvc-email/src/main/java/com/baeldung/spring/mail/EmailService.java rename to spring-mvc-simple/src/main/java/com/baeldung/spring/mail/EmailService.java diff --git a/spring-mvc-email/src/main/java/com/baeldung/spring/mail/EmailServiceImpl.java b/spring-mvc-simple/src/main/java/com/baeldung/spring/mail/EmailServiceImpl.java similarity index 99% rename from spring-mvc-email/src/main/java/com/baeldung/spring/mail/EmailServiceImpl.java rename to spring-mvc-simple/src/main/java/com/baeldung/spring/mail/EmailServiceImpl.java index ca418a7d90..039b970d8e 100644 --- a/spring-mvc-email/src/main/java/com/baeldung/spring/mail/EmailServiceImpl.java +++ b/spring-mvc-simple/src/main/java/com/baeldung/spring/mail/EmailServiceImpl.java @@ -8,9 +8,10 @@ import org.springframework.mail.javamail.JavaMailSender; import org.springframework.mail.javamail.MimeMessageHelper; import org.springframework.stereotype.Component; +import java.io.File; + import javax.mail.MessagingException; import javax.mail.internet.MimeMessage; -import java.io.File; /** * Created by Olga on 7/15/2016. diff --git a/spring-mvc-email/src/main/resources/application.properties b/spring-mvc-simple/src/main/resources/application.properties similarity index 83% rename from spring-mvc-email/src/main/resources/application.properties rename to spring-mvc-simple/src/main/resources/application.properties index 61a42050e5..9a804c07d8 100644 --- a/spring-mvc-email/src/main/resources/application.properties +++ b/spring-mvc-simple/src/main/resources/application.properties @@ -1,3 +1,5 @@ +#this property file will have to be loaded explicitly as this is not a Spring Boot project + # Gmail SMTP spring.mail.host=smtp.gmail.com spring.mail.port=587 diff --git a/spring-mvc-email/src/main/webapp/WEB-INF/views/home.jsp b/spring-mvc-simple/src/main/webapp/WEB-INF/views/emails.jsp similarity index 100% rename from spring-mvc-email/src/main/webapp/WEB-INF/views/home.jsp rename to spring-mvc-simple/src/main/webapp/WEB-INF/views/emails.jsp diff --git a/spring-mvc-email/src/main/webapp/WEB-INF/views/mail/send.jsp b/spring-mvc-simple/src/main/webapp/WEB-INF/views/mail/send.jsp similarity index 100% rename from spring-mvc-email/src/main/webapp/WEB-INF/views/mail/send.jsp rename to spring-mvc-simple/src/main/webapp/WEB-INF/views/mail/send.jsp diff --git a/spring-mvc-webflow/pom.xml b/spring-mvc-webflow/pom.xml index f0a991912a..ec6ccc8ede 100644 --- a/spring-mvc-webflow/pom.xml +++ b/spring-mvc-webflow/pom.xml @@ -83,10 +83,10 @@ - 4.3.4.RELEASE + 5.0.1.RELEASE - 2.4.4.RELEASE + 2.5.0.RELEASE 3.1.0 1.2 @@ -94,8 +94,6 @@ 4.4.5 4.5.2 - 2.9.0 - 2.6 2.7 diff --git a/spring-mvc-webflow/src/main/java/org/baeldung/spring/WebMvcConfig.java b/spring-mvc-webflow/src/main/java/org/baeldung/spring/WebMvcConfig.java index 434f49615b..46bf322f1d 100644 --- a/spring-mvc-webflow/src/main/java/org/baeldung/spring/WebMvcConfig.java +++ b/spring-mvc-webflow/src/main/java/org/baeldung/spring/WebMvcConfig.java @@ -2,12 +2,10 @@ package org.baeldung.spring; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.ImportResource; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.view.InternalResourceViewResolver; import org.springframework.web.servlet.view.JstlView; import org.springframework.webflow.mvc.servlet.FlowHandlerAdapter; @@ -15,7 +13,7 @@ import org.springframework.webflow.mvc.servlet.FlowHandlerMapping; @EnableWebMvc @Configuration -public class WebMvcConfig extends WebMvcConfigurerAdapter { +public class WebMvcConfig implements WebMvcConfigurer { @Autowired private WebFlowConfig webFlowConfig; diff --git a/spring-mvc-webflow/src/main/webapp/WEB-INF/flows/activation-flow.xml b/spring-mvc-webflow/src/main/webapp/WEB-INF/flows/activation-flow.xml index ab9eb1a9b7..bad5c5f78c 100644 --- a/spring-mvc-webflow/src/main/webapp/WEB-INF/flows/activation-flow.xml +++ b/spring-mvc-webflow/src/main/webapp/WEB-INF/flows/activation-flow.xml @@ -2,7 +2,7 @@ + http://www.springframework.org/schema/webflow/spring-webflow.xsd"> diff --git a/spring-mvc-xml/README.md b/spring-mvc-xml/README.md index 6333b20e11..442a533d1b 100644 --- a/spring-mvc-xml/README.md +++ b/spring-mvc-xml/README.md @@ -10,7 +10,6 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring ### Relevant Articles: - [Spring MVC Tutorial](http://www.baeldung.com/spring-mvc-tutorial) - [Servlet Session Timeout](http://www.baeldung.com/servlet-session-timeout) -- [Basic Forms with Spring MVC](http://www.baeldung.com/spring-mvc-form-tutorial) - [Returning Image/Media Data with Spring MVC](http://www.baeldung.com/spring-mvc-image-media-data) - [Geolocation by IP in Java](http://www.baeldung.com/geolocation-by-ip-with-maxmind) - [Guide to JavaServer Pages (JSP)](http://www.baeldung.com/jsp) diff --git a/spring-mvc-xml/pom.xml b/spring-mvc-xml/pom.xml index 8ec2ff10e5..6979894f6f 100644 --- a/spring-mvc-xml/pom.xml +++ b/spring-mvc-xml/pom.xml @@ -37,13 +37,6 @@ - - com.fasterxml.jackson.core - jackson-databind - 2.9.2 - - - javax.servlet javax.servlet-api @@ -127,10 +120,8 @@ 5.0.2.RELEASE - 4.2.0.RELEASE - 5.2.5.Final 5.1.40 @@ -138,10 +129,10 @@ 4.5.2 - 5.3.3.Final + 6.0.10.Final 1.2 3.1.0 - 2.8.5 + 2.9.6 19.0 @@ -149,9 +140,6 @@ 2.5 2.8.0 - - 2.9.0 - 2.6 1.6.1 diff --git a/spring-mvc-xml/src/main/java/com/baeldung/spring/ClientWebConfig.java b/spring-mvc-xml/src/main/java/com/baeldung/spring/ClientWebConfig.java index b5238b04d5..9752526963 100644 --- a/spring-mvc-xml/src/main/java/com/baeldung/spring/ClientWebConfig.java +++ b/spring-mvc-xml/src/main/java/com/baeldung/spring/ClientWebConfig.java @@ -2,11 +2,11 @@ package com.baeldung.spring; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.ImportResource; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @ImportResource("classpath:webMvcConfig.xml") @Configuration -public class ClientWebConfig extends WebMvcConfigurerAdapter { +public class ClientWebConfig implements WebMvcConfigurer { public ClientWebConfig() { super(); diff --git a/spring-mvc-xml/src/main/java/com/baeldung/spring/ClientWebConfigJava.java b/spring-mvc-xml/src/main/java/com/baeldung/spring/ClientWebConfigJava.java index f299c46dbc..7925fa451d 100644 --- a/spring-mvc-xml/src/main/java/com/baeldung/spring/ClientWebConfigJava.java +++ b/spring-mvc-xml/src/main/java/com/baeldung/spring/ClientWebConfigJava.java @@ -9,13 +9,13 @@ import org.springframework.context.support.MessageSourceResourceBundle; import org.springframework.context.support.ResourceBundleMessageSource; import org.springframework.web.servlet.ViewResolver; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.view.InternalResourceViewResolver; import org.springframework.web.servlet.view.JstlView; //@EnableWebMvc //@Configuration -public class ClientWebConfigJava extends WebMvcConfigurerAdapter { +public class ClientWebConfigJava implements WebMvcConfigurer { public ClientWebConfigJava() { super(); @@ -38,8 +38,6 @@ public class ClientWebConfigJava extends WebMvcConfigurerAdapter { @Override public void addViewControllers(final ViewControllerRegistry registry) { - super.addViewControllers(registry); - registry.addViewController("/sample.html"); } diff --git a/spring-mvc-xml/src/main/java/com/baeldung/spring/controller/EmployeeController.java b/spring-mvc-xml/src/main/java/com/baeldung/spring/controller/EmployeeController.java deleted file mode 100644 index fa76933f8f..0000000000 --- a/spring-mvc-xml/src/main/java/com/baeldung/spring/controller/EmployeeController.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.baeldung.spring.controller; - -import java.util.HashMap; -import java.util.Map; - -import org.springframework.stereotype.Controller; -import org.springframework.ui.ModelMap; -import org.springframework.validation.BindingResult; -import org.springframework.web.bind.annotation.ModelAttribute; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.ResponseBody; -import org.springframework.web.servlet.ModelAndView; - -import com.baeldung.spring.form.Employee; - -@Controller -public class EmployeeController { - - Map employeeMap = new HashMap<>(); - - @RequestMapping(value = "/employee", method = RequestMethod.GET) - public ModelAndView showForm() { - return new ModelAndView("employeeHome", "employee", new Employee()); - } - - @RequestMapping(value = "/employee/{Id}", produces = { "application/json", "application/xml" }, method = RequestMethod.GET) - public @ResponseBody Employee getEmployeeById(@PathVariable final long Id) { - return employeeMap.get(Id); - } - - @RequestMapping(value = "/addEmployee", method = RequestMethod.POST) - public String submit(@ModelAttribute("employee") final Employee employee, final BindingResult result, final ModelMap model) { - if (result.hasErrors()) { - return "error"; - } - model.addAttribute("name", employee.getName()); - model.addAttribute("contactNumber", employee.getContactNumber()); - model.addAttribute("id", employee.getId()); - employeeMap.put(employee.getId(), employee); - return "employeeView"; - } - -} diff --git a/spring-mvc-xml/src/main/java/com/baeldung/spring/controller/GeoIPTestController.java b/spring-mvc-xml/src/main/java/com/baeldung/spring/controller/GeoIPTestController.java index eeaddcf8e0..0e2fe48160 100644 --- a/spring-mvc-xml/src/main/java/com/baeldung/spring/controller/GeoIPTestController.java +++ b/spring-mvc-xml/src/main/java/com/baeldung/spring/controller/GeoIPTestController.java @@ -11,7 +11,8 @@ import org.springframework.web.bind.annotation.ResponseBody; import com.baeldung.spring.form.GeoIP; import com.baeldung.spring.service.RawDBDemoGeoIPLocationService; -@Controller +//@Controller +//add db file and uncomment to see the working example public class GeoIPTestController { private RawDBDemoGeoIPLocationService locationService; diff --git a/spring-mvc-xml/src/main/java/com/baeldung/spring/form/Employee.java b/spring-mvc-xml/src/main/java/com/baeldung/spring/form/Employee.java deleted file mode 100644 index 66b2e9f185..0000000000 --- a/spring-mvc-xml/src/main/java/com/baeldung/spring/form/Employee.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.baeldung.spring.form; - -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; -import javax.xml.bind.annotation.XmlRootElement; - -@XmlRootElement -public class Employee { - - private long id; - - @NotNull - @Size(min = 1) - private String name; - @NotNull - @Size(min = 1) - private String contactNumber; - - public Employee() { - super(); - } - - // - - public String getName() { - return name; - } - - public void setName(final String name) { - this.name = name; - } - - public long getId() { - return id; - } - - public void setId(final long id) { - this.id = id; - } - - public String getContactNumber() { - return contactNumber; - } - - public void setContactNumber(final String contactNumber) { - this.contactNumber = contactNumber; - } - -} diff --git a/spring-mvc-xml/src/main/java/com/baeldung/spring/form/Person.java b/spring-mvc-xml/src/main/java/com/baeldung/spring/form/Person.java index 01638fbe76..307a36b10f 100644 --- a/spring-mvc-xml/src/main/java/com/baeldung/spring/form/Person.java +++ b/spring-mvc-xml/src/main/java/com/baeldung/spring/form/Person.java @@ -2,7 +2,8 @@ package com.baeldung.spring.form; import java.util.List; -import org.hibernate.validator.constraints.NotEmpty; +import javax.validation.constraints.NotEmpty; + import org.springframework.web.multipart.MultipartFile; public class Person { diff --git a/spring-mvc-xml/src/main/resources/contentManagementWebMvcConfig.xml b/spring-mvc-xml/src/main/resources/contentManagementWebMvcConfig.xml index 75d5c1ecd6..8a0671ca87 100644 --- a/spring-mvc-xml/src/main/resources/contentManagementWebMvcConfig.xml +++ b/spring-mvc-xml/src/main/resources/contentManagementWebMvcConfig.xml @@ -4,11 +4,11 @@ xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation=" http://www.springframework.org/schema/beans - http://www.springframework.org/schema/beans/spring-beans-4.3.xsd + http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context - http://www.springframework.org/schema/context/spring-context-4.3.xsd + http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc - http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd"> + http://www.springframework.org/schema/mvc/spring-mvc.xsd"> diff --git a/spring-mvc-xml/src/main/resources/webMvcConfig.xml b/spring-mvc-xml/src/main/resources/webMvcConfig.xml index 37aebe1d1d..4bdb405237 100644 --- a/spring-mvc-xml/src/main/resources/webMvcConfig.xml +++ b/spring-mvc-xml/src/main/resources/webMvcConfig.xml @@ -3,11 +3,11 @@ xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation=" http://www.springframework.org/schema/beans - http://www.springframework.org/schema/beans/spring-beans-4.3.xsd + http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context - http://www.springframework.org/schema/context/spring-context-4.3.xsd + http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc - http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd" + http://www.springframework.org/schema/mvc/spring-mvc.xsd" > diff --git a/spring-mvc-xml/src/main/webapp/WEB-INF/view/employeeHome.jsp b/spring-mvc-xml/src/main/webapp/WEB-INF/view/employeeHome.jsp deleted file mode 100644 index 588678cdcf..0000000000 --- a/spring-mvc-xml/src/main/webapp/WEB-INF/view/employeeHome.jsp +++ /dev/null @@ -1,33 +0,0 @@ -<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> -<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%> - - - -Form Example - Register an Employee - - -

Welcome, Enter The Employee Details

- - - - - - - - - - - - - - - - - - -
Name
Id
Contact Number
-
- - - - \ No newline at end of file diff --git a/spring-mvc-xml/src/main/webapp/WEB-INF/view/employeeView.jsp b/spring-mvc-xml/src/main/webapp/WEB-INF/view/employeeView.jsp deleted file mode 100644 index 1457bc5fc8..0000000000 --- a/spring-mvc-xml/src/main/webapp/WEB-INF/view/employeeView.jsp +++ /dev/null @@ -1,24 +0,0 @@ -<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%> - - -Spring MVC Form Handling - - - -

Submitted Employee Information

- - - - - - - - - - - - - -
Name :${name}
ID :${id}
Contact Number :${contactNumber}
- - \ No newline at end of file diff --git a/spring-mvc-xml/src/test/java/com/baeldung/geoip/GeoIpIntegrationTest.java b/spring-mvc-xml/src/test/java/com/baeldung/geoip/GeoIpIntegrationTest.java index 0e957f3400..0aa23842b1 100644 --- a/spring-mvc-xml/src/test/java/com/baeldung/geoip/GeoIpIntegrationTest.java +++ b/spring-mvc-xml/src/test/java/com/baeldung/geoip/GeoIpIntegrationTest.java @@ -14,10 +14,12 @@ public class GeoIpIntegrationTest { @Test public void givenIP_whenFetchingCity_thenReturnsCityData() throws IOException, GeoIp2Exception { - File database = new File("your-path-to-db-file"); + + ClassLoader classLoader = getClass().getClassLoader(); + File database = new File(classLoader.getResource("GeoLite2-City.mmdb").getFile()); DatabaseReader dbReader = new DatabaseReader.Builder(database).build(); - InetAddress ipAddress = InetAddress.getByName("your-public-ip"); + InetAddress ipAddress = InetAddress.getByName("google.com"); CityResponse response = dbReader.city(ipAddress); String countryName = response.getCountry().getName(); diff --git a/spring-mvc-xml/src/test/resources/.gitignore b/spring-mvc-xml/src/test/resources/.gitignore deleted file mode 100644 index 83c05e60c8..0000000000 --- a/spring-mvc-xml/src/test/resources/.gitignore +++ /dev/null @@ -1,13 +0,0 @@ -*.class - -#folders# -/target -/neoDb* -/data -/src/main/webapp/WEB-INF/classes -*/META-INF/* - -# Packaged files # -*.jar -*.war -*.ear \ No newline at end of file diff --git a/spring-mvc-xml/src/test/resources/GeoLite2-City.mmdb b/spring-mvc-xml/src/test/resources/GeoLite2-City.mmdb new file mode 100644 index 0000000000..6de839a7ed Binary files /dev/null and b/spring-mvc-xml/src/test/resources/GeoLite2-City.mmdb differ diff --git a/spring-rest/src/main/java/com/baeldung/responseheaders/ResponseHeadersApplication.java b/spring-rest/src/main/java/com/baeldung/responseheaders/ResponseHeadersApplication.java new file mode 100644 index 0000000000..ebc18a130b --- /dev/null +++ b/spring-rest/src/main/java/com/baeldung/responseheaders/ResponseHeadersApplication.java @@ -0,0 +1,14 @@ +package com.baeldung.responseheaders; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.servlet.ServletComponentScan; + +@ServletComponentScan +@SpringBootApplication +public class ResponseHeadersApplication { + + public static void main(String[] args) { + SpringApplication.run(ResponseHeadersApplication.class, args); + } +} diff --git a/spring-rest/src/main/java/com/baeldung/responseheaders/controllers/FilterResponseHeaderController.java b/spring-rest/src/main/java/com/baeldung/responseheaders/controllers/FilterResponseHeaderController.java new file mode 100644 index 0000000000..c92d4afafd --- /dev/null +++ b/spring-rest/src/main/java/com/baeldung/responseheaders/controllers/FilterResponseHeaderController.java @@ -0,0 +1,24 @@ +package com.baeldung.responseheaders.controllers; + +import javax.servlet.http.HttpServletResponse; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/filter-response-header") +public class FilterResponseHeaderController { + + @GetMapping("/no-extra-header") + public String FilterHeaderResponseWithNoExtraHeader() { + return "Response body with Filter header and no extra header"; + } + + @GetMapping("/extra-header") + public String FilterHeaderResponseWithExtraHeader(HttpServletResponse response) { + response.addHeader("Baeldung-Example-Header", "Value-ExtraHeader"); + return "Response body with Filter header and one extra header"; + } + +} diff --git a/spring-rest/src/main/java/com/baeldung/responseheaders/controllers/ResponseHeaderController.java b/spring-rest/src/main/java/com/baeldung/responseheaders/controllers/ResponseHeaderController.java new file mode 100644 index 0000000000..d93964b815 --- /dev/null +++ b/spring-rest/src/main/java/com/baeldung/responseheaders/controllers/ResponseHeaderController.java @@ -0,0 +1,70 @@ +package com.baeldung.responseheaders.controllers; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import javax.servlet.http.HttpServletResponse; + +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/single-response-header") +public class ResponseHeaderController { + + @GetMapping("/http-servlet-response") + public String usingHttpServletResponse(HttpServletResponse response) { + response.addHeader("Baeldung-Example-Header", "Value-HttpServletResponse"); + return "Response with header using HttpServletResponse"; + } + + @GetMapping("/response-entity-constructor") + public ResponseEntity usingResponseEntityConstructor() { + HttpHeaders responseHeaders = new HttpHeaders(); + responseHeaders.set("Baeldung-Example-Header", "Value-ResponseEntityContructor"); + String responseBody = "Response with header using ResponseEntity (constructor)"; + HttpStatus responseStatus = HttpStatus.OK; + + return new ResponseEntity(responseBody, responseHeaders, responseStatus); + } + + @GetMapping("/response-entity-contructor-multiple-headers") + public ResponseEntity usingResponseEntityConstructorAndMultipleHeaders() { + List acceptableMediaTypes = new ArrayList<>(Arrays.asList(MediaType.APPLICATION_JSON)); + HttpHeaders responseHeaders = new HttpHeaders(); + responseHeaders.set("Baeldung-Example-Header", "Value-ResponseEntityConstructorAndHeaders"); + responseHeaders.setAccept(acceptableMediaTypes); + String responseBody = "Response with header using ResponseEntity (constructor)"; + HttpStatus responseStatus = HttpStatus.OK; + + return new ResponseEntity(responseBody, responseHeaders, responseStatus); + } + + @GetMapping("/response-entity-builder") + public ResponseEntity usingResponseEntityBuilder() { + String responseHeaderKey = "Baeldung-Example-Header"; + String responseHeaderValue = "Value-ResponseEntityBuilder"; + String responseBody = "Response with header using ResponseEntity (builder)"; + + return ResponseEntity.ok() + .header(responseHeaderKey, responseHeaderValue) + .body(responseBody); + } + + @GetMapping("/response-entity-builder-with-http-headers") + public ResponseEntity usingResponseEntityBuilderAndHttpHeaders() { + HttpHeaders responseHeaders = new HttpHeaders(); + responseHeaders.set("Baeldung-Example-Header", "Value-ResponseEntityBuilderWithHttpHeaders"); + String responseBody = "Response with header using ResponseEntity (builder)"; + + return ResponseEntity.ok() + .headers(responseHeaders) + .body(responseBody); + } +} diff --git a/spring-rest/src/main/java/com/baeldung/responseheaders/filter/AddResponseHeaderFilter.java b/spring-rest/src/main/java/com/baeldung/responseheaders/filter/AddResponseHeaderFilter.java new file mode 100644 index 0000000000..7d4ffb1391 --- /dev/null +++ b/spring-rest/src/main/java/com/baeldung/responseheaders/filter/AddResponseHeaderFilter.java @@ -0,0 +1,41 @@ +package com.baeldung.responseheaders.filter; + +import java.io.IOException; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.annotation.WebFilter; +import javax.servlet.http.HttpServletResponse; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@WebFilter("/filter-response-header/*") +public class AddResponseHeaderFilter implements Filter { + + private static final Logger LOGGER = LoggerFactory.getLogger(AddResponseHeaderFilter.class); + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + // add special initialization requirements here + LOGGER.trace("Initializing filter..."); + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + HttpServletResponse httpServletResponse = (HttpServletResponse) response; + httpServletResponse.setHeader("Baeldung-Example-Filter-Header", "Value-Filter"); + chain.doFilter(request, response); + } + + @Override + public void destroy() { + // clean up any resource being held by the filter here + LOGGER.trace("Destroying filter..."); + } + +} diff --git a/spring-rest/src/test/java/com/baeldung/responseheaders/ResponseHeaderLiveTest.java b/spring-rest/src/test/java/com/baeldung/responseheaders/ResponseHeaderLiveTest.java new file mode 100644 index 0000000000..bed0de55bd --- /dev/null +++ b/spring-rest/src/test/java/com/baeldung/responseheaders/ResponseHeaderLiveTest.java @@ -0,0 +1,103 @@ +package com.baeldung.responseheaders; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Arrays; + +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.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +public class ResponseHeaderLiveTest { + + private static final String BASE_URL = "http://localhost:8082/spring-rest"; + private static final String SINGLE_BASE_URL = BASE_URL + "/single-response-header"; + private static final String FILTER_BASE_URL = BASE_URL + "/filter-response-header"; + private static final String SERVICE_SINGLE_RESPONSE_HEADER = "Baeldung-Example-Header"; + private static final String SERVICE_FILTER_RESPONSE_HEADER = "Baeldung-Example-Filter-Header"; + + @Autowired + private TestRestTemplate template; + + @Test + public void whenHttpServletResponseRequest_thenObtainResponseWithCorrectHeader() { + final String requestUrl = "/http-servlet-response"; + ResponseEntity response = template.getForEntity(SINGLE_BASE_URL + requestUrl, String.class); + HttpHeaders responseHeaders = response.getHeaders(); + + assertThat(responseHeaders).isNotEmpty(); + assertThat(responseHeaders).containsEntry(SERVICE_SINGLE_RESPONSE_HEADER, Arrays.asList("Value-HttpServletResponse")); + } + + @Test + public void whenResponseEntityConstructorRequest_thenObtainResponseWithCorrectHeader() { + final String requestUrl = "/response-entity-constructor"; + ResponseEntity response = template.getForEntity(SINGLE_BASE_URL + requestUrl, String.class); + HttpHeaders responseHeaders = response.getHeaders(); + + assertThat(responseHeaders).isNotEmpty(); + assertThat(responseHeaders).containsEntry(SERVICE_SINGLE_RESPONSE_HEADER, Arrays.asList("Value-ResponseEntityContructor")); + } + + @Test + public void whenResponseEntityConstructorAndMultipleHeadersRequest_thenObtainResponseWithCorrectHeaders() { + final String requestUrl = "/response-entity-contructor-multiple-headers"; + ResponseEntity response = template.getForEntity(SINGLE_BASE_URL + requestUrl, String.class); + HttpHeaders responseHeaders = response.getHeaders(); + + assertThat(responseHeaders).isNotEmpty(); + assertThat(responseHeaders).containsEntry(SERVICE_SINGLE_RESPONSE_HEADER, Arrays.asList("Value-ResponseEntityConstructorAndHeaders")); + assertThat(responseHeaders).containsEntry("Accept", Arrays.asList(MediaType.APPLICATION_JSON.toString())); + } + + @Test + public void whenResponseEntityBuilderRequest_thenObtainResponseWithCorrectHeader() { + final String requestUrl = "/response-entity-builder"; + ResponseEntity response = template.getForEntity(SINGLE_BASE_URL + requestUrl, String.class); + HttpHeaders responseHeaders = response.getHeaders(); + + assertThat(responseHeaders).isNotEmpty(); + assertThat(responseHeaders).containsEntry(SERVICE_SINGLE_RESPONSE_HEADER, Arrays.asList("Value-ResponseEntityBuilder")); + } + + @Test + public void whenResponseEntityBuilderAndHttpHeadersRequest_thenObtainResponseWithCorrectHeader() { + final String requestUrl = "/response-entity-builder-with-http-headers"; + ResponseEntity response = template.getForEntity(SINGLE_BASE_URL + requestUrl, String.class); + HttpHeaders responseHeaders = response.getHeaders(); + + assertThat(responseHeaders).isNotEmpty(); + assertThat(responseHeaders).containsEntry(SERVICE_SINGLE_RESPONSE_HEADER, Arrays.asList("Value-ResponseEntityBuilderWithHttpHeaders")); + } + + @Test + public void whenFilterWithNoExtraHeaderRequest_thenObtainResponseWithCorrectHeader() { + final String requestUrl = "/no-extra-header"; + ResponseEntity response = template.getForEntity(FILTER_BASE_URL + requestUrl, String.class); + HttpHeaders responseHeaders = response.getHeaders(); + + assertThat(responseHeaders).isNotEmpty(); + assertThat(responseHeaders).containsEntry(SERVICE_FILTER_RESPONSE_HEADER, Arrays.asList("Value-Filter")); + } + + @Test + public void whenFilterWithExtraHeaderRequest_thenObtainResponseWithCorrectHeaders() { + final String requestUrl = "/extra-header"; + ResponseEntity response = template.getForEntity(FILTER_BASE_URL + requestUrl, String.class); + HttpHeaders responseHeaders = response.getHeaders(); + + assertThat(responseHeaders).isNotEmpty(); + assertThat(responseHeaders).containsEntry(SERVICE_FILTER_RESPONSE_HEADER, Arrays.asList("Value-Filter")); + assertThat(responseHeaders).containsEntry(SERVICE_SINGLE_RESPONSE_HEADER, Arrays.asList("Value-ExtraHeader")); + } + +} diff --git a/spring-rest/src/test/java/org/baeldung/resttemplate/RestTemplateIntegrationTest.java b/spring-rest/src/test/java/org/baeldung/resttemplate/RestTemplateLiveTest.java similarity index 97% rename from spring-rest/src/test/java/org/baeldung/resttemplate/RestTemplateIntegrationTest.java rename to spring-rest/src/test/java/org/baeldung/resttemplate/RestTemplateLiveTest.java index e0c24c32b1..4f00bebdf4 100644 --- a/spring-rest/src/test/java/org/baeldung/resttemplate/RestTemplateIntegrationTest.java +++ b/spring-rest/src/test/java/org/baeldung/resttemplate/RestTemplateLiveTest.java @@ -21,7 +21,7 @@ import com.baeldung.transfer.LoginForm; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = RestClientConfig.class) -public class RestTemplateIntegrationTest { +public class RestTemplateLiveTest { @Autowired RestTemplate restTemplate; diff --git a/spring-security-sso/pom.xml b/spring-security-sso/pom.xml index f68b9addac..764e899640 100644 --- a/spring-security-sso/pom.xml +++ b/spring-security-sso/pom.xml @@ -9,10 +9,10 @@ pom - parent-boot-1 + parent-boot-2 com.baeldung 0.0.1-SNAPSHOT - ../parent-boot-1 + ../parent-boot-2 @@ -22,7 +22,9 @@ - 3.0.1 - - + 3.1.0 + 2.3.3.RELEASE + 2.0.1.RELEASE +
+ \ No newline at end of file diff --git a/spring-security-sso/spring-security-sso-auth-server/pom.xml b/spring-security-sso/spring-security-sso-auth-server/pom.xml index 0d0086beb0..f506deccf7 100644 --- a/spring-security-sso/spring-security-sso-auth-server/pom.xml +++ b/spring-security-sso/spring-security-sso-auth-server/pom.xml @@ -21,6 +21,7 @@ org.springframework.security.oauth spring-security-oauth2 + ${oauth.version} diff --git a/spring-security-sso/spring-security-sso-auth-server/src/main/java/org/baeldung/config/AuthServerConfig.java b/spring-security-sso/spring-security-sso-auth-server/src/main/java/org/baeldung/config/AuthServerConfig.java index 20cde21073..56229d4d38 100644 --- a/spring-security-sso/spring-security-sso-auth-server/src/main/java/org/baeldung/config/AuthServerConfig.java +++ b/spring-security-sso/spring-security-sso-auth-server/src/main/java/org/baeldung/config/AuthServerConfig.java @@ -2,19 +2,20 @@ package org.baeldung.config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; -import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer; -import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer; import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer; + @Configuration @EnableAuthorizationServer public class AuthServerConfig extends AuthorizationServerConfigurerAdapter { - @Autowired - private AuthenticationManager authenticationManager; - + + @Autowired + private BCryptPasswordEncoder passwordEncoder; + @Override public void configure(final AuthorizationServerSecurityConfigurer oauthServer) throws Exception { oauthServer.tokenKeyAccess("permitAll()") @@ -25,17 +26,14 @@ public class AuthServerConfig extends AuthorizationServerConfigurerAdapter { public void configure(final ClientDetailsServiceConfigurer clients) throws Exception { clients.inMemory() .withClient("SampleClientId") - .secret("secret") + .secret(passwordEncoder.encode("secret")) .authorizedGrantTypes("authorization_code") .scopes("user_info") .autoApprove(true) + .redirectUris("http://localhost:8082/ui/login","http://localhost:8083/ui2/login") // .accessTokenValiditySeconds(3600) ; // 1 hour } - @Override - public void configure(final AuthorizationServerEndpointsConfigurer endpoints) throws Exception { - endpoints.authenticationManager(authenticationManager); - } } diff --git a/spring-security-sso/spring-security-sso-auth-server/src/main/java/org/baeldung/config/AuthorizationServerApplication.java b/spring-security-sso/spring-security-sso-auth-server/src/main/java/org/baeldung/config/AuthorizationServerApplication.java index 5b0b39b444..b74d2f144c 100644 --- a/spring-security-sso/spring-security-sso-auth-server/src/main/java/org/baeldung/config/AuthorizationServerApplication.java +++ b/spring-security-sso/spring-security-sso-auth-server/src/main/java/org/baeldung/config/AuthorizationServerApplication.java @@ -2,7 +2,7 @@ package org.baeldung.config; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.web.support.SpringBootServletInitializer; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; @SpringBootApplication diff --git a/spring-security-sso/spring-security-sso-auth-server/src/main/java/org/baeldung/config/SecurityConfig.java b/spring-security-sso/spring-security-sso-auth-server/src/main/java/org/baeldung/config/SecurityConfig.java index a568c22eec..5cebf4f4d2 100644 --- a/spring-security-sso/spring-security-sso-auth-server/src/main/java/org/baeldung/config/SecurityConfig.java +++ b/spring-security-sso/spring-security-sso-auth-server/src/main/java/org/baeldung/config/SecurityConfig.java @@ -1,18 +1,17 @@ package org.baeldung.config; -import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.core.annotation.Order; 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; @Configuration +@Order(1) public class SecurityConfig extends WebSecurityConfigurerAdapter { - - @Autowired - private AuthenticationManager authenticationManager; - + @Override protected void configure(HttpSecurity http) throws Exception { // @formatter:off http.requestMatchers() @@ -28,11 +27,14 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { // @formatter:off - auth.parentAuthenticationManager(authenticationManager) - .inMemoryAuthentication() + auth.inMemoryAuthentication() .withUser("john") - .password("123") + .password(passwordEncoder().encode("123")) .roles("USER"); } // @formatter:on + @Bean + public BCryptPasswordEncoder passwordEncoder(){ + return new BCryptPasswordEncoder(); + } } diff --git a/spring-security-sso/spring-security-sso-auth-server/src/main/resources/application.properties b/spring-security-sso/spring-security-sso-auth-server/src/main/resources/application.properties index 32a0993b04..066123118f 100644 --- a/spring-security-sso/spring-security-sso-auth-server/src/main/resources/application.properties +++ b/spring-security-sso/spring-security-sso-auth-server/src/main/resources/application.properties @@ -1,4 +1,3 @@ server.port=8081 -server.context-path=/auth -security.basic.enabled=false +server.servlet.context-path=/auth #logging.level.org.springframework=DEBUG \ No newline at end of file diff --git a/spring-security-sso/spring-security-sso-ui-2/pom.xml b/spring-security-sso/spring-security-sso-ui-2/pom.xml index a2323a044d..c38c855a30 100644 --- a/spring-security-sso/spring-security-sso-ui-2/pom.xml +++ b/spring-security-sso/spring-security-sso-ui-2/pom.xml @@ -25,8 +25,9 @@
- org.springframework.security.oauth - spring-security-oauth2 + org.springframework.security.oauth.boot + spring-security-oauth2-autoconfigure + ${oauth-auto.version} diff --git a/spring-security-sso/spring-security-sso-ui-2/src/main/java/org/baeldung/config/UiApplication.java b/spring-security-sso/spring-security-sso-ui-2/src/main/java/org/baeldung/config/UiApplication.java index a222224c59..0c20853aed 100644 --- a/spring-security-sso/spring-security-sso-ui-2/src/main/java/org/baeldung/config/UiApplication.java +++ b/spring-security-sso/spring-security-sso-ui-2/src/main/java/org/baeldung/config/UiApplication.java @@ -2,7 +2,7 @@ package org.baeldung.config; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.web.support.SpringBootServletInitializer; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; import org.springframework.context.annotation.Bean; import org.springframework.web.context.request.RequestContextListener; diff --git a/spring-security-sso/spring-security-sso-ui-2/src/main/java/org/baeldung/config/UiSecurityConfig.java b/spring-security-sso/spring-security-sso-ui-2/src/main/java/org/baeldung/config/UiSecurityConfig.java index f9119e20f5..de81ada9e0 100644 --- a/spring-security-sso/spring-security-sso-ui-2/src/main/java/org/baeldung/config/UiSecurityConfig.java +++ b/spring-security-sso/spring-security-sso-ui-2/src/main/java/org/baeldung/config/UiSecurityConfig.java @@ -5,6 +5,7 @@ import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; + @EnableOAuth2Sso @Configuration public class UiSecurityConfig extends WebSecurityConfigurerAdapter { diff --git a/spring-security-sso/spring-security-sso-ui-2/src/main/resources/application.yml b/spring-security-sso/spring-security-sso-ui-2/src/main/resources/application.yml index 6b0d3db5ad..97c8de7839 100644 --- a/spring-security-sso/spring-security-sso-ui-2/src/main/resources/application.yml +++ b/spring-security-sso/spring-security-sso-ui-2/src/main/resources/application.yml @@ -1,6 +1,7 @@ server: port: 8083 - context-path: /ui2 + servlet: + context-path: /ui2 session: cookie: name: UI2SESSION diff --git a/spring-security-sso/spring-security-sso-ui/pom.xml b/spring-security-sso/spring-security-sso-ui/pom.xml index dbb167b61c..6a0b630502 100644 --- a/spring-security-sso/spring-security-sso-ui/pom.xml +++ b/spring-security-sso/spring-security-sso-ui/pom.xml @@ -23,11 +23,13 @@ org.springframework.boot spring-boot-starter-security - + - org.springframework.security.oauth - spring-security-oauth2 + org.springframework.security.oauth.boot + spring-security-oauth2-autoconfigure + ${oauth-auto.version} + org.springframework.boot diff --git a/spring-security-sso/spring-security-sso-ui/src/main/java/org/baeldung/config/UiApplication.java b/spring-security-sso/spring-security-sso-ui/src/main/java/org/baeldung/config/UiApplication.java index e186046e83..07d875d805 100644 --- a/spring-security-sso/spring-security-sso-ui/src/main/java/org/baeldung/config/UiApplication.java +++ b/spring-security-sso/spring-security-sso-ui/src/main/java/org/baeldung/config/UiApplication.java @@ -2,7 +2,7 @@ package org.baeldung.config; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.web.support.SpringBootServletInitializer; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; import org.springframework.context.annotation.Bean; import org.springframework.web.context.request.RequestContextListener; diff --git a/spring-security-sso/spring-security-sso-ui/src/main/java/org/baeldung/config/UiSecurityConfig.java b/spring-security-sso/spring-security-sso-ui/src/main/java/org/baeldung/config/UiSecurityConfig.java index f9119e20f5..de81ada9e0 100644 --- a/spring-security-sso/spring-security-sso-ui/src/main/java/org/baeldung/config/UiSecurityConfig.java +++ b/spring-security-sso/spring-security-sso-ui/src/main/java/org/baeldung/config/UiSecurityConfig.java @@ -5,6 +5,7 @@ import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; + @EnableOAuth2Sso @Configuration public class UiSecurityConfig extends WebSecurityConfigurerAdapter { diff --git a/spring-security-sso/spring-security-sso-ui/src/main/resources/application.yml b/spring-security-sso/spring-security-sso-ui/src/main/resources/application.yml index bb4bd92033..d1d9ea6ebc 100644 --- a/spring-security-sso/spring-security-sso-ui/src/main/resources/application.yml +++ b/spring-security-sso/spring-security-sso-ui/src/main/resources/application.yml @@ -1,6 +1,7 @@ server: port: 8082 - context-path: /ui + servlet: + context-path: /ui session: cookie: name: UISESSION diff --git a/spring-session/pom.xml b/spring-session/pom.xml index 4c256663b0..277b033f43 100644 --- a/spring-session/pom.xml +++ b/spring-session/pom.xml @@ -30,6 +30,15 @@ org.springframework.boot spring-boot-starter-web + + com.github.kstyrc + embedded-redis + ${embedded-redis.version} + + + + 0.6 + \ No newline at end of file diff --git a/spring-session/src/test/java/com/baeldung/spring/session/SessionControllerIntegrationTest.java b/spring-session/src/test/java/com/baeldung/spring/session/SessionControllerIntegrationTest.java index 84dd2bc139..f739aeb3ab 100644 --- a/spring-session/src/test/java/com/baeldung/spring/session/SessionControllerIntegrationTest.java +++ b/spring-session/src/test/java/com/baeldung/spring/session/SessionControllerIntegrationTest.java @@ -1,27 +1,55 @@ package com.baeldung.spring.session; -import org.junit.Before; -import org.junit.Test; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.http.*; -import redis.clients.jedis.Jedis; - -import java.util.Set; - import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import java.io.IOException; +import java.util.Set; + +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.junit4.SpringRunner; + +import redis.clients.jedis.Jedis; +import redis.embedded.RedisServer; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = SessionWebApplication.class, webEnvironment = WebEnvironment.DEFINED_PORT) public class SessionControllerIntegrationTest { private Jedis jedis; + private static RedisServer redisServer; private TestRestTemplate testRestTemplate; private TestRestTemplate testRestTemplateWithAuth; private String testUrl = "http://localhost:8080/"; + @BeforeClass + public static void startRedisServer() throws IOException { + redisServer = new RedisServer(6379); + redisServer.start(); + } + + @AfterClass + public static void stopRedisServer() throws IOException { + redisServer.stop(); + } + @Before public void clearRedisData() { + testRestTemplate = new TestRestTemplate(); - testRestTemplateWithAuth = new TestRestTemplate("admin", "password", null); + testRestTemplateWithAuth = new TestRestTemplate("admin", "password"); jedis = new Jedis("localhost", 6379); jedis.flushAll(); diff --git a/spring-userservice/pom.xml b/spring-userservice/pom.xml index c372beaa3c..a6acfe3fc6 100644 --- a/spring-userservice/pom.xml +++ b/spring-userservice/pom.xml @@ -217,11 +217,11 @@ 4.2.6.RELEASE - 1.4.2.RELEASE + 1.5.14.RELEASE 3.21.0-GA - 5.2.5.Final + 5.2.10.Final 5.1.40 1.10.5.RELEASE 1.4.193 diff --git a/spring-userservice/src/main/resources/persistence-derby.properties b/spring-userservice/src/main/resources/persistence-derby.properties index e808fdc288..b76c5de12f 100644 --- a/spring-userservice/src/main/resources/persistence-derby.properties +++ b/spring-userservice/src/main/resources/persistence-derby.properties @@ -7,6 +7,6 @@ jdbc.pass=tutorialpass # hibernate.X hibernate.dialect=org.hibernate.dialect.DerbyDialect hibernate.show_sql=false -hibernate.hbm2ddl.auto=create +hibernate.hbm2ddl.auto=update hibernate.cache.use_second_level_cache=false hibernate.cache.use_query_cache=false \ No newline at end of file diff --git a/spring-userservice/src/test/java/org/baeldung/userservice/CustomUserDetailsServiceIntegrationTest.java b/spring-userservice/src/test/java/org/baeldung/userservice/CustomUserDetailsServiceIntegrationTest.java index f46a3a070f..1cd38228b8 100644 --- a/spring-userservice/src/test/java/org/baeldung/userservice/CustomUserDetailsServiceIntegrationTest.java +++ b/spring-userservice/src/test/java/org/baeldung/userservice/CustomUserDetailsServiceIntegrationTest.java @@ -1,5 +1,10 @@ package org.baeldung.userservice; +import static org.junit.Assert.assertEquals; + +import java.util.logging.Level; +import java.util.logging.Logger; + import org.baeldung.custom.config.MvcConfig; import org.baeldung.custom.config.PersistenceDerbyJPAConfig; import org.baeldung.custom.config.SecSecurityConfig; @@ -8,22 +13,16 @@ import org.baeldung.web.MyUserDto; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.SpringApplicationConfiguration; -import org.springframework.dao.DuplicateKeyException; +import org.springframework.boot.test.context.SpringBootTest; import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; -import org.springframework.security.core.userdetails.UsernameNotFoundException; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.context.web.WebAppConfiguration; -import static org.junit.Assert.*; -import java.util.logging.Level; -import java.util.logging.Logger; - -@RunWith(SpringJUnit4ClassRunner.class) -@SpringApplicationConfiguration(classes = { MvcConfig.class, PersistenceDerbyJPAConfig.class, SecSecurityConfig.class }) +@RunWith(SpringRunner.class) +@SpringBootTest(classes = { MvcConfig.class, PersistenceDerbyJPAConfig.class, SecSecurityConfig.class }) @WebAppConfiguration public class CustomUserDetailsServiceIntegrationTest {