diff --git a/algorithms-miscellaneous-5/pom.xml b/algorithms-miscellaneous-5/pom.xml index 32ecce58a6..c68ac96c38 100644 --- a/algorithms-miscellaneous-5/pom.xml +++ b/algorithms-miscellaneous-5/pom.xml @@ -34,11 +34,6 @@ guava ${guava.version} - - org.junit.platform - junit-platform-commons - ${junit-platform.version} - org.assertj assertj-core diff --git a/algorithms-miscellaneous-6/pom.xml b/algorithms-miscellaneous-6/pom.xml index 6d5f211c8a..a9eb75cf1e 100644 --- a/algorithms-miscellaneous-6/pom.xml +++ b/algorithms-miscellaneous-6/pom.xml @@ -19,11 +19,6 @@ guava ${guava.version} - - org.junit.platform - junit-platform-commons - ${junit-platform.version} - org.assertj assertj-core diff --git a/algorithms-sorting-2/pom.xml b/algorithms-sorting-2/pom.xml index b673af9d70..c9bec354f3 100644 --- a/algorithms-sorting-2/pom.xml +++ b/algorithms-sorting-2/pom.xml @@ -29,12 +29,6 @@ ${lombok.version} provided - - org.junit.jupiter - junit-jupiter-api - ${junit-jupiter.version} - test - org.assertj assertj-core diff --git a/algorithms-sorting/pom.xml b/algorithms-sorting/pom.xml index b853fd80ee..e916d0aae5 100644 --- a/algorithms-sorting/pom.xml +++ b/algorithms-sorting/pom.xml @@ -30,12 +30,6 @@ ${lombok.version} provided - - org.junit.jupiter - junit-jupiter-api - ${junit-jupiter.version} - test - org.assertj assertj-core diff --git a/apache-poi/README.md b/apache-poi/README.md index d500787536..d19af8d6ef 100644 --- a/apache-poi/README.md +++ b/apache-poi/README.md @@ -12,3 +12,4 @@ This module contains articles about Apache POI - [Read Excel Cell Value Rather Than Formula With Apache POI](https://www.baeldung.com/apache-poi-read-cell-value-formula) - [Setting Formulas in Excel with Apache POI](https://www.baeldung.com/java-apache-poi-set-formulas) - [Insert a Row in Excel Using Apache POI](https://www.baeldung.com/apache-poi-insert-excel-row) +- [Multiline Text in Excel Cell Using Apache POI](https://www.baeldung.com/apache-poi-write-multiline-text) diff --git a/apache-poi/src/main/java/com/baeldung/poi/excel/cellstyle/CellStyleHandler.java b/apache-poi/src/main/java/com/baeldung/poi/excel/cellstyle/CellStyleHandler.java new file mode 100644 index 0000000000..4d97fe50cb --- /dev/null +++ b/apache-poi/src/main/java/com/baeldung/poi/excel/cellstyle/CellStyleHandler.java @@ -0,0 +1,30 @@ +package com.baeldung.poi.excel.cellstyle; + +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.CellStyle; +import org.apache.poi.ss.usermodel.FillPatternType; +import org.apache.poi.ss.usermodel.IndexedColors; + +public class CellStyleHandler { + + public void changeCellBackgroundColor(Cell cell) { + CellStyle cellStyle = cell.getCellStyle(); + if(cellStyle == null) { + cellStyle = cell.getSheet().getWorkbook().createCellStyle(); + } + cellStyle.setFillForegroundColor(IndexedColors.LIGHT_BLUE.getIndex()); + cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); + cell.setCellStyle(cellStyle); + } + + public void changeCellBackgroundColorWithPattern(Cell cell) { + CellStyle cellStyle = cell.getCellStyle(); + if(cellStyle == null) { + cellStyle = cell.getSheet().getWorkbook().createCellStyle(); + } + cellStyle.setFillBackgroundColor(IndexedColors.BLACK.index); + cellStyle.setFillPattern(FillPatternType.BIG_SPOTS); + cellStyle.setFillForegroundColor(IndexedColors.LIGHT_BLUE.getIndex()); + cell.setCellStyle(cellStyle); + } +} diff --git a/apache-poi/src/main/resources/cellstyle/CellStyleHandlerTest.xlsx b/apache-poi/src/main/resources/cellstyle/CellStyleHandlerTest.xlsx new file mode 100644 index 0000000000..29f128211b Binary files /dev/null and b/apache-poi/src/main/resources/cellstyle/CellStyleHandlerTest.xlsx differ diff --git a/apache-poi/src/test/java/com/baeldung/poi/excel/cellstyle/CellStyleHandlerUnitTest.java b/apache-poi/src/test/java/com/baeldung/poi/excel/cellstyle/CellStyleHandlerUnitTest.java new file mode 100644 index 0000000000..e131db8e56 --- /dev/null +++ b/apache-poi/src/test/java/com/baeldung/poi/excel/cellstyle/CellStyleHandlerUnitTest.java @@ -0,0 +1,56 @@ +package com.baeldung.poi.excel.cellstyle; + +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.junit.Before; +import org.junit.Test; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.net.URISyntaxException; +import java.nio.file.Paths; + +import static org.junit.Assert.assertEquals; + +public class CellStyleHandlerUnitTest { + private static final String FILE_NAME = "cellstyle/CellStyleHandlerTest.xlsx"; + private static final int SHEET_INDEX = 0; + private static final int ROW_INDEX = 0; + private static final int CELL_INDEX = 0; + + private String fileLocation; + private CellStyleHandler cellStyleHandler; + + @Before + public void setup() throws URISyntaxException { + fileLocation = Paths.get(ClassLoader.getSystemResource(FILE_NAME).toURI()).toString(); + cellStyleHandler = new CellStyleHandler(); + } + + @Test + public void givenWorkbookCell_whenChangeCellBackgroundColor() throws IOException { + Workbook workbook = new XSSFWorkbook(fileLocation); + Sheet sheet = workbook.getSheetAt(SHEET_INDEX); + Row row = sheet.getRow(ROW_INDEX); + Cell cell = row.getCell(CELL_INDEX); + + cellStyleHandler.changeCellBackgroundColor(cell); + + assertEquals(IndexedColors.LIGHT_BLUE.index, cell.getCellStyle().getFillForegroundColor()); + workbook.close(); + } + + @Test + public void givenWorkbookCell_whenChangeCellBackgroundColorWithPattern() throws IOException { + Workbook workbook = new XSSFWorkbook(fileLocation); + Sheet sheet = workbook.getSheetAt(SHEET_INDEX); + Row row = sheet.getRow(ROW_INDEX); + Cell cell = row.getCell(CELL_INDEX + 1); + + cellStyleHandler.changeCellBackgroundColorWithPattern(cell); + + assertEquals(IndexedColors.LIGHT_BLUE.index, cell.getCellStyle().getFillForegroundColor()); + workbook.close(); + } +} diff --git a/atomikos/pom.xml b/atomikos/pom.xml index cb10168c0d..cd798825d1 100644 --- a/atomikos/pom.xml +++ b/atomikos/pom.xml @@ -71,12 +71,6 @@ derby ${derby.version} - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - javax.transaction diff --git a/core-java-modules/core-java-11-2/pom.xml b/core-java-modules/core-java-11-2/pom.xml index 4c16ec7032..863c9b0717 100644 --- a/core-java-modules/core-java-11-2/pom.xml +++ b/core-java-modules/core-java-11-2/pom.xml @@ -31,24 +31,6 @@ mockserver-junit-jupiter ${mockserver.version} - - org.junit.jupiter - junit-jupiter-engine - ${junit-jupiter.version} - test - - - org.junit.jupiter - junit-jupiter-params - ${junit-jupiter.version} - test - - - org.junit.jupiter - junit-jupiter-api - ${junit-jupiter.version} - test - org.apache.commons commons-lang3 diff --git a/core-java-modules/core-java-14/pom.xml b/core-java-modules/core-java-14/pom.xml index 4b0d030a34..3967ce3455 100644 --- a/core-java-modules/core-java-14/pom.xml +++ b/core-java-modules/core-java-14/pom.xml @@ -21,18 +21,6 @@ ${assertj.version} test - - org.junit.jupiter - junit-jupiter-engine - ${junit-jupiter.version} - test - - - org.junit.jupiter - junit-jupiter-api - ${junit-jupiter.version} - test - diff --git a/core-java-modules/core-java-15/pom.xml b/core-java-modules/core-java-15/pom.xml index 091f0568a7..a71987c23a 100644 --- a/core-java-modules/core-java-15/pom.xml +++ b/core-java-modules/core-java-15/pom.xml @@ -27,18 +27,6 @@ ${assertj.version} test - - org.junit.jupiter - junit-jupiter-engine - ${junit-jupiter.version} - test - - - org.junit.jupiter - junit-jupiter-api - ${junit-jupiter.version} - test - diff --git a/core-java-modules/core-java-16/pom.xml b/core-java-modules/core-java-16/pom.xml index d003ca9ae7..14f15cdd92 100644 --- a/core-java-modules/core-java-16/pom.xml +++ b/core-java-modules/core-java-16/pom.xml @@ -28,18 +28,6 @@ commons-lang3 3.12.0 - - org.junit.jupiter - junit-jupiter-engine - ${junit-jupiter.version} - test - - - org.junit.jupiter - junit-jupiter-api - ${junit-jupiter.version} - test - diff --git a/core-java-modules/core-java-17/pom.xml b/core-java-modules/core-java-17/pom.xml index 7024705cc2..3cee27b276 100644 --- a/core-java-modules/core-java-17/pom.xml +++ b/core-java-modules/core-java-17/pom.xml @@ -23,18 +23,6 @@ ${assertj.version} test - - org.junit.jupiter - junit-jupiter-engine - ${junit-jupiter.version} - test - - - org.junit.jupiter - junit-jupiter-api - ${junit-jupiter.version} - test - @@ -56,6 +44,7 @@ ${surefire.plugin.version} --enable-preview + --enable-native-access=core.java 1 diff --git a/core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP356.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP356.java new file mode 100644 index 0000000000..0890b025be --- /dev/null +++ b/core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP356.java @@ -0,0 +1,20 @@ +package com.baeldung.features; + +import java.util.random.RandomGeneratorFactory; +import java.util.stream.IntStream; +import java.util.stream.Stream; + +public class JEP356 { + + public Stream getAllAlgorithms() { + return RandomGeneratorFactory.all().map(RandomGeneratorFactory::name); + } + + public IntStream getPseudoInts(String algorithm, int streamSize) { + // returns an IntStream with size @streamSize of random numbers generated using the @algorithm + // where the lower bound is 0 and the upper is 100 (exclusive) + return RandomGeneratorFactory.of(algorithm) + .create() + .ints(streamSize, 0,100); + } +} diff --git a/core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP406.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP406.java new file mode 100644 index 0000000000..2bc3a664d1 --- /dev/null +++ b/core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP406.java @@ -0,0 +1,28 @@ +package com.baeldung.features; + +import com.baeldung.features.JEP409.Circle; +import com.baeldung.features.JEP409.Shape; +import com.baeldung.features.JEP409.Triangle; + +public class JEP406 { + + static record Human (String name, int age, String profession) {} + + public String checkObject(Object obj) { + return switch (obj) { + case Human h -> "Name: %s, age: %s and profession: %s".formatted(h.name(), h.age(), h.profession()); + case Circle c -> "This is a circle"; + case Shape s -> "It is just a shape"; + case null -> "It is null"; + default -> "It is an object"; + }; + } + + public String checkShape(Shape shape) { + return switch (shape) { + case Triangle t && (t.getNumberOfSides() != 3) -> "This is a weird triangle"; + case Circle c && (c.getNumberOfSides() != 0) -> "This is a weird circle"; + default -> "Just a normal shape"; + }; + } +} diff --git a/core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP409.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP409.java new file mode 100644 index 0000000000..0fc3d6f467 --- /dev/null +++ b/core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP409.java @@ -0,0 +1,38 @@ +package com.baeldung.features; + +public class JEP409 { + + sealed interface Shape permits Rectangle, Circle, Square, Triangle { + int getNumberOfSides(); + } + + static final class Rectangle implements Shape { + @Override + public int getNumberOfSides() { + return 4; + } + } + + static final class Circle implements Shape { + @Override + public int getNumberOfSides() { + return 0; + } + } + + static final class Square implements Shape { + @Override + public int getNumberOfSides() { + return 4; + } + } + + static non-sealed class Triangle implements Shape { + + @Override + public int getNumberOfSides() { + return 3; + } + } + +} diff --git a/core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP412.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP412.java new file mode 100644 index 0000000000..8c998629c9 --- /dev/null +++ b/core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP412.java @@ -0,0 +1,56 @@ +package com.baeldung.features; + +import jdk.incubator.foreign.CLinker; +import jdk.incubator.foreign.FunctionDescriptor; +import jdk.incubator.foreign.MemoryAddress; +import jdk.incubator.foreign.SymbolLookup; + +import java.io.IOException; +import java.lang.invoke.MethodType; + +import static jdk.incubator.foreign.ResourceScope.newImplicitScope; + +public class JEP412 { + + private static final SymbolLookup libLookup; + + static { + var resource = JEP412.class.getResource("/compile_c.sh"); + try { + var process = new ProcessBuilder("sh", resource.getPath()).start(); + while (process.isAlive()) {} + } catch (IOException ex) { + throw new RuntimeException(ex); + } + + var path = JEP412.class.getResource("/print_name.so").getPath(); + System.load(path); + libLookup = SymbolLookup.loaderLookup(); + } + + public String getPrintNameFormat(String name){ + + var printMethod = libLookup.lookup("printName"); + + if (printMethod.isPresent()) { + var methodReference = CLinker.getInstance() + .downcallHandle( + printMethod.get(), + MethodType.methodType(MemoryAddress.class, MemoryAddress.class), + FunctionDescriptor.of(CLinker.C_POINTER, CLinker.C_POINTER) + ); + + try { + var nativeString = CLinker.toCString(name, newImplicitScope()); + var invokeReturn = methodReference.invoke(nativeString.address()); + var memoryAddress = (MemoryAddress) invokeReturn; + return CLinker.toJavaString(memoryAddress); + } catch (Throwable throwable) { + throw new RuntimeException(throwable); + } + } + throw new RuntimeException("printName function not found."); + } +} + + diff --git a/core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP414.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP414.java new file mode 100644 index 0000000000..aaccc4a665 --- /dev/null +++ b/core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP414.java @@ -0,0 +1,27 @@ +package com.baeldung.features; + +import jdk.incubator.vector.FloatVector; +import jdk.incubator.vector.VectorSpecies; + +public class JEP414 { + + private static final VectorSpecies SPECIES = FloatVector.SPECIES_PREFERRED; + + + public void newVectorComputation(float[] a, float[] b, float[] c) { + for (var i = 0; i < a.length; i += SPECIES.length()) { + var m = SPECIES.indexInRange(i, a.length); + var va = FloatVector.fromArray(SPECIES, a, i, m); + var vb = FloatVector.fromArray(SPECIES, b, i, m); + var vc = va.mul(vb); + vc.intoArray(c, i, m); + } + } + + public void commonVectorComputation(float[] a, float[] b, float[] c) { + for (var i = 0; i < a.length; i ++) { + c[i] = a[i] * b[i]; + } + } + +} diff --git a/core-java-modules/core-java-17/src/main/java/module-info.java b/core-java-modules/core-java-17/src/main/java/module-info.java new file mode 100644 index 0000000000..b1ce62aa68 --- /dev/null +++ b/core-java-modules/core-java-17/src/main/java/module-info.java @@ -0,0 +1,4 @@ +module core.java { + requires jdk.incubator.vector; + requires jdk.incubator.foreign; +} \ No newline at end of file diff --git a/core-java-modules/core-java-17/src/main/resources/compile_c.sh b/core-java-modules/core-java-17/src/main/resources/compile_c.sh new file mode 100755 index 0000000000..d2e0629cc5 --- /dev/null +++ b/core-java-modules/core-java-17/src/main/resources/compile_c.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +SCRIPTPATH="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" + +gcc -c -fPIC $SCRIPTPATH/print_name.c +gcc -shared -rdynamic -o print_name.so print_name.o + +mv print_name.so $SCRIPTPATH/ +mv print_name.o $SCRIPTPATH/ \ No newline at end of file diff --git a/core-java-modules/core-java-17/src/main/resources/print_name.c b/core-java-modules/core-java-17/src/main/resources/print_name.c new file mode 100644 index 0000000000..7bda12e352 --- /dev/null +++ b/core-java-modules/core-java-17/src/main/resources/print_name.c @@ -0,0 +1,8 @@ +#include +#include + +char* printName(char *name) { + char* newString = (char*)malloc((15 + sizeof(name))*sizeof(char)); + sprintf(newString, "Your name is %s", name); + return newString; +} \ No newline at end of file diff --git a/core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP356UnitTest.java b/core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP356UnitTest.java new file mode 100644 index 0000000000..b4f61a6f24 --- /dev/null +++ b/core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP356UnitTest.java @@ -0,0 +1,19 @@ +package com.baeldung.features; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +public class JEP356UnitTest { + + @Test + void getPseudoInts_whenUsingAlgorithmXoroshiro128PlusPlus_shouldReturnStreamOfRandomInteger() { + var algorithm = "Xoshiro256PlusPlus"; + var streamSize = 100; + + JEP356 jep356 = new JEP356(); + + jep356.getPseudoInts(algorithm, streamSize) + .forEach(value -> assertThat(value).isLessThanOrEqualTo(99)); + } +} diff --git a/core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP406UnitTest.java b/core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP406UnitTest.java new file mode 100644 index 0000000000..87e6f3bec6 --- /dev/null +++ b/core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP406UnitTest.java @@ -0,0 +1,33 @@ +package com.baeldung.features; + +import com.baeldung.features.JEP406.Human; +import com.baeldung.features.JEP409.Square; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class JEP406UnitTest { + + @Test + void checkObject_shouldMatchWithHuman() { + var jep406 = new JEP406(); + + var human = new Human("John", 31, "Developer"); + + var checkResult = jep406.checkObject(human); + + assertEquals("Name: John, age: 31 and profession: Developer", checkResult); + } + + @Test + void checkShape_shouldMatchWithShape() { + var jep406 = new JEP406(); + + var square = new Square(); + + var checkResult = jep406.checkShape(square); + + assertEquals("Just a normal shape", checkResult); + } + +} \ No newline at end of file diff --git a/core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP409UnitTest.java b/core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP409UnitTest.java new file mode 100644 index 0000000000..41380ec2bb --- /dev/null +++ b/core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP409UnitTest.java @@ -0,0 +1,39 @@ +package com.baeldung.features; + +import com.baeldung.features.JEP409.*; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; + +class JEP409UnitTest { + + static class WeirdTriangle extends Triangle { + @Override public int getNumberOfSides() { + return 40; + } + } + + @Test + void testSealedClass_shouldInvokeRightClass() { + + Shape shape = spy(new WeirdTriangle()); + + int numberOfSides = getNumberOfSides(shape); + + assertEquals(40, numberOfSides); + verify(shape).getNumberOfSides(); + } + + int getNumberOfSides(Shape shape) { + return switch (shape) { + case WeirdTriangle t -> t.getNumberOfSides(); + case Circle c -> c.getNumberOfSides(); + case Triangle t -> t.getNumberOfSides(); + case Rectangle r -> r.getNumberOfSides(); + case Square s -> s.getNumberOfSides(); + }; + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP412UnitTest.java b/core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP412UnitTest.java new file mode 100644 index 0000000000..66e7d952c7 --- /dev/null +++ b/core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP412UnitTest.java @@ -0,0 +1,17 @@ +package com.baeldung.features; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class JEP412UnitTest { + + @Test + void getPrintNameFormat_whenPassingAName_shouldReceiveItFormatted() { + var jep412 = new JEP412(); + + var formattedName = jep412.getPrintNameFormat("John"); + + assertEquals("Your name is John", formattedName); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP414UnitTest.java b/core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP414UnitTest.java new file mode 100644 index 0000000000..459344d907 --- /dev/null +++ b/core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP414UnitTest.java @@ -0,0 +1,38 @@ +package com.baeldung.features; + +import org.junit.jupiter.api.Test; + +import static java.util.stream.Collectors.toList; +import static org.junit.jupiter.api.Assertions.assertEquals; + +class JEP414UnitTest { + + @Test + void vectorComputation_shouldMultiplyVectors() { + var jep414 = new JEP414(); + + float[] a = initArray(100); + float[] b = initArray(100); + float[] c = new float[100]; + float[] d = new float[100]; + + jep414.newVectorComputation(a, b, c); + jep414.commonVectorComputation(a, b, d); + + for (int i = 0; i < a.length; i++) { + assertEquals(c[i], d[i]); + } + } + + private float[] initArray(int size) { + final var jep356 = new JEP356(); + final var values = new float[size]; + final var pseudoInts = jep356.getPseudoInts("Xoshiro256PlusPlus", size).mapToObj(Float::valueOf).collect(toList()); + + for (int i = 0; i < pseudoInts.size(); i++) { + values[i] = pseudoInts.get(i); + } + + return values; + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-17/src/test/java/com/baeldung/hexformat/ByteHexadecimalConversionUnitTest.java b/core-java-modules/core-java-17/src/test/java/com/baeldung/hexformat/ByteHexadecimalConversionUnitTest.java new file mode 100644 index 0000000000..29b6eb1bee --- /dev/null +++ b/core-java-modules/core-java-17/src/test/java/com/baeldung/hexformat/ByteHexadecimalConversionUnitTest.java @@ -0,0 +1,23 @@ +package com.baeldung.hexformat; + +import java.util.HexFormat; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; + +class ByteHexadecimalConversionUnitTest { + + private HexFormat hexFormat = HexFormat.of(); + + @Test + void givenInitialisedHexFormat_whenHexStringIsPassed_thenByteArrayRepresentationIsReturned() { + byte[] hexBytes = hexFormat.parseHex("ABCDEF0123456789"); + assertArrayEquals(new byte[] { -85, -51, -17, 1, 35, 69, 103, -119 }, hexBytes); + } + + @Test + void givenInitialisedHexFormat_whenByteArrayIsPassed_thenHexStringRepresentationIsReturned() { + String bytesAsString = hexFormat.formatHex(new byte[] { -85, -51, -17, 1, 35, 69, 103, -119}); + assertEquals("abcdef0123456789", bytesAsString); + } +} diff --git a/core-java-modules/core-java-17/src/test/java/com/baeldung/hexformat/PrimitiveTypeHexadecimalConversionUnitTest.java b/core-java-modules/core-java-17/src/test/java/com/baeldung/hexformat/PrimitiveTypeHexadecimalConversionUnitTest.java new file mode 100644 index 0000000000..6f26a8351c --- /dev/null +++ b/core-java-modules/core-java-17/src/test/java/com/baeldung/hexformat/PrimitiveTypeHexadecimalConversionUnitTest.java @@ -0,0 +1,22 @@ +package com.baeldung.hexformat; + +import java.util.HexFormat; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class PrimitiveTypeHexadecimalConversionUnitTest { + + private HexFormat hexFormat = HexFormat.of(); + + @Test + void givenInitialisedHexFormat_whenPrimitiveByteIsPassed_thenHexStringRepresentationIsReturned() { + String fromByte = hexFormat.toHexDigits((byte)64); + assertEquals("40", fromByte); + } + + @Test + void givenInitialisedHexFormat_whenPrimitiveLongIsPassed_thenHexStringRepresentationIsReturned() { + String fromLong = hexFormat.toHexDigits(1234_5678_9012_3456L); + assertEquals("000462d53c8abac0", fromLong); + } +} diff --git a/core-java-modules/core-java-17/src/test/java/com/baeldung/hexformat/StringFormattingUnitTest.java b/core-java-modules/core-java-17/src/test/java/com/baeldung/hexformat/StringFormattingUnitTest.java new file mode 100644 index 0000000000..28189d0e8c --- /dev/null +++ b/core-java-modules/core-java-17/src/test/java/com/baeldung/hexformat/StringFormattingUnitTest.java @@ -0,0 +1,15 @@ +package com.baeldung.hexformat; + +import java.util.HexFormat; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class StringFormattingUnitTest { + + private HexFormat hexFormat = HexFormat.of().withPrefix("[").withSuffix("]").withDelimiter(", "); + + @Test + public void givenInitialisedHexFormatWithFormattedStringOptions_whenByteArrayIsPassed_thenHexStringRepresentationFormattedCorrectlyIsReturned() { + assertEquals("[48], [0c], [11]", hexFormat.formatHex(new byte[] {72, 12, 17})); + } +} diff --git a/core-java-modules/core-java-17/src/test/java/com/baeldung/hexformat/UppercaseLowercaseOutputUnitTest.java b/core-java-modules/core-java-17/src/test/java/com/baeldung/hexformat/UppercaseLowercaseOutputUnitTest.java new file mode 100644 index 0000000000..c2a33fb4b5 --- /dev/null +++ b/core-java-modules/core-java-17/src/test/java/com/baeldung/hexformat/UppercaseLowercaseOutputUnitTest.java @@ -0,0 +1,40 @@ +package com.baeldung.hexformat; + +import java.util.HexFormat; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class UppercaseLowercaseOutputUnitTest { + + @Test + public void givenInitialisedHexFormat_whenByteArrayIsPassed_thenLowerCaseHexStringRepresentationIsReturned() { + HexFormat hexFormat = HexFormat.of(); + String bytesAsString = hexFormat.formatHex(new byte[] { -85, -51, -17, 1, 35, 69, 103, -119}); + assertTrue(isLowerCase(bytesAsString)); + } + + @Test + public void givenInitialisedHexFormatWithUpperCaseOption_whenByteArrayIsPassed_thenLowerCaseHexStringRepresentationIsReturned() { + HexFormat hexFormat = HexFormat.of().withUpperCase(); + String bytesAsString = hexFormat.formatHex(new byte[] { -85, -51, -17, 1, 35, 69, 103, -119}); + assertTrue(isUpperCase(bytesAsString)); + } + + private boolean isLowerCase(String str) { + char[] charArray = str.toCharArray(); + for (int i=0; i < charArray.length; i++) { + if (Character.isUpperCase(charArray[i])) + return false; + } + return true; + } + + private boolean isUpperCase(String str) { + char[] charArray = str.toCharArray(); + for (int i=0; i < charArray.length; i++) { + if (Character.isLowerCase(charArray[i])) + return false; + } + return true; + } +} diff --git a/core-java-modules/core-java-collections-maps-4/pom.xml b/core-java-modules/core-java-collections-maps-4/pom.xml index bfb91515fa..2109804ff0 100644 --- a/core-java-modules/core-java-collections-maps-4/pom.xml +++ b/core-java-modules/core-java-collections-maps-4/pom.xml @@ -1,34 +1,55 @@ - 4.0.0 - core-java-collections-maps-4 - 0.1.0-SNAPSHOT - core-java-collections-maps-4 - jar + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 + core-java-collections-maps-4 + 0.1.0-SNAPSHOT + core-java-collections-maps-4 + jar - - com.baeldung.core-java-modules - core-java-modules - 0.0.1-SNAPSHOT - ../pom.xml - + + com.baeldung.core-java-modules + core-java-modules + 0.0.1-SNAPSHOT + ../pom.xml + + + + UTF-8 + 1.8 + 1.8 + - - - - - org.apache.maven.plugins - maven-surefire-plugin - 3.0.0-M5 - - - !performance - - - - - + + + junit + junit + ${junit.version} + test + + + org.hamcrest + hamcrest-all + ${hamcrest-all.version} + test + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.0.0-M5 + + + !performance + + + + + \ No newline at end of file diff --git a/core-java-modules/core-java-collections-maps-4/src/main/java/com/baeldung/nestedhashmaps/Address.java b/core-java-modules/core-java-collections-maps-4/src/main/java/com/baeldung/nestedhashmaps/Address.java new file mode 100644 index 0000000000..410758405e --- /dev/null +++ b/core-java-modules/core-java-collections-maps-4/src/main/java/com/baeldung/nestedhashmaps/Address.java @@ -0,0 +1,32 @@ +package com.baeldung.nestedhashmaps; + +public class Address { + + private Integer addressId; + private String addressLocation; + + public Address() { + } + + public Address(Integer addressId, String addressLocation) { + this.addressId = addressId; + this.addressLocation = addressLocation; + } + + public Integer getAddressId() { + return addressId; + } + + public void setAddressId(Integer addressId) { + this.addressId = addressId; + } + + public String getAddressLocation() { + return addressLocation; + } + + public void setAddressLocation(String addressLocation) { + this.addressLocation = addressLocation; + } + +} diff --git a/core-java-modules/core-java-collections-maps-4/src/main/java/com/baeldung/nestedhashmaps/Employee.java b/core-java-modules/core-java-collections-maps-4/src/main/java/com/baeldung/nestedhashmaps/Employee.java new file mode 100644 index 0000000000..2ab54ff17c --- /dev/null +++ b/core-java-modules/core-java-collections-maps-4/src/main/java/com/baeldung/nestedhashmaps/Employee.java @@ -0,0 +1,43 @@ +package com.baeldung.nestedhashmaps; + +public class Employee { + + private Integer employeeId; + private Address address; + private String employeeName; + + public Employee() { + super(); + } + + public Employee(Integer employeeId, Address address, String employeeName) { + this.employeeId = employeeId; + this.address = address; + this.employeeName = employeeName; + } + + public Integer getEmployeeId() { + return employeeId; + } + + public void setEmployeeId(Integer employeeId) { + this.employeeId = employeeId; + } + + public Address getAddress() { + return address; + } + + public void setAddress(Address address) { + this.address = address; + } + + public String getEmployeeName() { + return employeeName; + } + + public void setEmployeeName(String employeeName) { + this.employeeName = employeeName; + } + +} diff --git a/core-java-modules/core-java-collections-maps-4/src/main/java/com/baeldung/nestedhashmaps/MapsUtil.java b/core-java-modules/core-java-collections-maps-4/src/main/java/com/baeldung/nestedhashmaps/MapsUtil.java new file mode 100644 index 0000000000..53781b0bc1 --- /dev/null +++ b/core-java-modules/core-java-collections-maps-4/src/main/java/com/baeldung/nestedhashmaps/MapsUtil.java @@ -0,0 +1,57 @@ +package com.baeldung.nestedhashmaps; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.stream.Collectors; + +public class MapsUtil { + + MapsUtil() { + super(); + } + + public Map buildInnerMap(List batterList) { + Map innerBatterMap = new HashMap(); + + int index = 1; + for (String item : batterList) { + innerBatterMap.put(index, item); + index++; + } + + return innerBatterMap; + } + + public Map> createNestedMapfromStream(List listEmployee) { + Map> employeeAddressMap = listEmployee.stream() + .collect(Collectors.groupingBy(e -> e.getAddress().getAddressId(), + Collectors.toMap(f -> f.getAddress().getAddressLocation(), Employee::getEmployeeName))); + return employeeAddressMap; + } + + public Map> createNestedObjectMap(List listEmployee) { + Map> employeeMap = new HashMap<>(); + + employeeMap = listEmployee.stream().collect(Collectors.groupingBy((Employee emp) -> emp.getEmployeeId(), + Collectors.toMap((Employee emp) -> emp.getAddress().getAddressId(), fEmpObj -> fEmpObj.getAddress()))); + + return employeeMap; + } + + public Map flattenMap(Map source) { + Map converted = new HashMap<>(); + + for (Entry entry : source.entrySet()) { + if (entry.getValue() instanceof Map) { + flattenMap((Map) entry.getValue()) + .forEach((key, value) -> converted.put(entry.getKey() + "." + key, value)); + } else { + converted.put(entry.getKey().toString(), entry.getValue().toString()); + } + } + return converted; + } + +} diff --git a/core-java-modules/core-java-collections-maps-4/src/main/java/com/baeldung/nestedhashmaps/NestedHashMapExamplesClass.java b/core-java-modules/core-java-collections-maps-4/src/main/java/com/baeldung/nestedhashmaps/NestedHashMapExamplesClass.java new file mode 100644 index 0000000000..ce63b72527 --- /dev/null +++ b/core-java-modules/core-java-collections-maps-4/src/main/java/com/baeldung/nestedhashmaps/NestedHashMapExamplesClass.java @@ -0,0 +1,118 @@ +package com.baeldung.nestedhashmaps; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +import java.util.List; + +public class NestedHashMapExamplesClass { + public static void main(String[] args) { + + MapsUtil mUtil = new MapsUtil(); + + List batterList = new ArrayList<>(); + Map> outerBakedGoodsMap = new HashMap<>(); + Map> outerBakedGoodsMap2 = new HashMap<>(); + Map> outerBakedGoodsMap3 = new HashMap<>(); + Map> outerBakedGoodsMap4 = new HashMap<>(); + + batterList.add("Mulberry"); + batterList.add("Cranberry"); + batterList.add("Blackberry"); + batterList.add("Mixed fruit"); + batterList.add("Orange"); + + outerBakedGoodsMap.put("Cake", mUtil.buildInnerMap(batterList)); + + batterList.clear(); + batterList.add("Candy"); + batterList.add("Dark Chocolate"); + batterList.add("Chocolate"); + batterList.add("Jam filled"); + batterList.add("Pineapple"); + + outerBakedGoodsMap.put("Donut", mUtil.buildInnerMap(batterList)); + + outerBakedGoodsMap2.put("Eclair", mUtil.buildInnerMap(batterList)); + outerBakedGoodsMap2.put("Donut", mUtil.buildInnerMap(batterList)); + + outerBakedGoodsMap3.put("Cake", mUtil.buildInnerMap(batterList)); + batterList.clear(); + batterList.add("Banana"); + batterList.add("Red Velvet"); + batterList.add("Blackberry"); + batterList.add("Passion fruit"); + batterList.add("Kiwi"); + + outerBakedGoodsMap3.put("Donut", mUtil.buildInnerMap(batterList)); + + outerBakedGoodsMap4.putAll(outerBakedGoodsMap); + + System.out.println(outerBakedGoodsMap.equals(outerBakedGoodsMap2)); + System.out.println(outerBakedGoodsMap.equals(outerBakedGoodsMap3)); + System.out.println(outerBakedGoodsMap.equals(outerBakedGoodsMap4)); + + outerBakedGoodsMap.get("Cake") + .put(6, "Cranberry"); + System.out.println(outerBakedGoodsMap); + + outerBakedGoodsMap.get("Cake") + .remove(5); + System.out.println(outerBakedGoodsMap); + + outerBakedGoodsMap.put("Eclair", new HashMap() { + { + put(1, "Dark Chocolate"); + } + }); + + System.out.println(outerBakedGoodsMap); + outerBakedGoodsMap.remove("Eclair"); + System.out.println(outerBakedGoodsMap); + System.out.println("Baked Goods Map Flattened: " + mUtil.flattenMap(outerBakedGoodsMap)); + + // Employees Map + List listEmployee = new ArrayList(); + + listEmployee.add(new Employee(1, new Address(124, "Timbuktoo"), "Thorin Oakenshield")); + listEmployee.add(new Employee(2, new Address(100, "Misty Lanes"), "Balin")); + listEmployee.add(new Employee(3, new Address(156, "Bramles Lane"), "Bofur")); + listEmployee.add(new Employee(4, new Address(200, "Bag End"), "Bilbo Baggins")); + listEmployee.add(new Employee(5, new Address(23, "Rivendell"), "Elrond")); + + Map> employeeAddressMap = mUtil.createNestedMapfromStream(listEmployee); + + Map> employeeMap = mUtil.createNestedObjectMap(listEmployee); + Map> employeeMap2 = mUtil.createNestedObjectMap(listEmployee); + + listEmployee.clear(); + listEmployee.add(new Employee(1, new Address(500, "Timbuktoo"), "Thorin Oakenshield")); + listEmployee.add(new Employee(2, new Address(600, "Misty Lanes"), "Balin")); + listEmployee.add(new Employee(3, new Address(700, "Bramles Lane"), "Bofur")); + listEmployee.add(new Employee(4, new Address(800, "Bag End"), "Bilbo Baggins")); + listEmployee.add(new Employee(5, new Address(900, "Rivendell"), "Elrond")); + + Map> employeeAddressMap1 = mUtil.createNestedMapfromStream(listEmployee); + + Map> employeeMap1 = mUtil.createNestedObjectMap(listEmployee); + + System.out.println(employeeMap.equals(employeeMap1)); + System.out.println(employeeMap.equals(employeeMap2)); + + for (Map.Entry> outerBakedGoodsMapEntrySet : outerBakedGoodsMap.entrySet()) { + Map valueMap = outerBakedGoodsMapEntrySet.getValue(); + System.out.println(valueMap.entrySet()); + } + + for (Map.Entry> employeeEntrySet : employeeAddressMap.entrySet()) { + Map valueMap = employeeEntrySet.getValue(); + System.out.println(valueMap.entrySet()); + } + + System.out.println("Employee Address Map Flattened: " + mUtil.flattenMap(employeeAddressMap)); + + System.out.println(employeeAddressMap.equals(employeeAddressMap1)); + } + +} diff --git a/core-java-modules/core-java-collections-maps-4/src/test/java/com/baeldung/nestedhashmaps/NestedHashMapExamplesClassUnitTest.java b/core-java-modules/core-java-collections-maps-4/src/test/java/com/baeldung/nestedhashmaps/NestedHashMapExamplesClassUnitTest.java new file mode 100644 index 0000000000..a86e329bea --- /dev/null +++ b/core-java-modules/core-java-collections-maps-4/src/test/java/com/baeldung/nestedhashmaps/NestedHashMapExamplesClassUnitTest.java @@ -0,0 +1,243 @@ +package com.baeldung.nestedhashmaps; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.notNullValue; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNotSame; +import static org.junit.Assert.assertThat; +import org.hamcrest.collection.IsMapContaining; + +public class NestedHashMapExamplesClassUnitTest { + private MapsUtil mUtil = new MapsUtil(); + private List batterList = new ArrayList<>(); + private List listEmployee = new ArrayList(); + private Map> actualBakedGoodsMap = new HashMap<>(); + private Map> actualEmployeeAddressMap = new HashMap<>(); + private Map> actualEmployeeMap = new HashMap<>(); + + @Test + public void whenCreateNestedHashMap_thenNestedMap() { + assertThat(mUtil.buildInnerMap(batterList), is(notNullValue())); + Assert.assertEquals(actualBakedGoodsMap.keySet().size(), 2); + Assert.assertThat(actualBakedGoodsMap, IsMapContaining.hasValue(equalTo(mUtil.buildInnerMap(batterList)))); + } + + private Map> setup() { + Map> expectedMap = new HashMap<>(); + expectedMap.put(Integer.valueOf(100), new HashMap() { + { + put("Misty Lanes", "Balin"); + } + }); + expectedMap.put(Integer.valueOf(200), new HashMap() { + { + put("Bag End", "Bilbo Baggins"); + } + }); + expectedMap.put(Integer.valueOf(156), new HashMap() { + { + put("Brambles Lane", "Bofur"); + } + }); + expectedMap.put(Integer.valueOf(124), new HashMap() { + { + put("Timbuktoo", "Thorin Oakenshield"); + } + }); + expectedMap.put(Integer.valueOf(23), new HashMap() { + { + put("Rivendell", "Elrond"); + } + }); + + return expectedMap; + } + + @Test + public void whenCreateNestedHashMapwithStreams_thenNestedMap() { + + Map> expectedMap = setup(); + + assertThat(actualEmployeeAddressMap, equalTo(expectedMap)); + } + + @Test + public void whenCompareTwoHashMapswithDifferenctValues_usingEquals_thenFail() { + Map> outerBakedGoodsMap2 = new HashMap<>(); + outerBakedGoodsMap2.put("Eclair", mUtil.buildInnerMap(batterList)); + outerBakedGoodsMap2.put("Donut", mUtil.buildInnerMap(batterList)); + assertNotEquals(outerBakedGoodsMap2, actualBakedGoodsMap); + + Map> outerBakedGoodsMap3 = new HashMap>(); + outerBakedGoodsMap3.put("Cake", mUtil.buildInnerMap(batterList)); + batterList = new ArrayList<>(); + batterList = Arrays.asList("Banana", "Red Velvet", "Blackberry", "Passion fruit", "Kiwi"); + + outerBakedGoodsMap3.put("Donut", mUtil.buildInnerMap(batterList)); + + assertNotEquals(outerBakedGoodsMap2, actualBakedGoodsMap); + + listEmployee.clear(); + listEmployee.add(new Employee(1, new Address(500, "Timbuktoo"), "Thorin Oakenshield")); + listEmployee.add(new Employee(2, new Address(600, "Misty Lanes"), "Balin")); + listEmployee.add(new Employee(3, new Address(700, "Bramles Lane"), "Bofur")); + listEmployee.add(new Employee(4, new Address(800, "Bag End"), "Bilbo Baggins")); + listEmployee.add(new Employee(5, new Address(900, "Rivendell"), "Elrond")); + + Map> employeeAddressMap1 = mUtil.createNestedMapfromStream(listEmployee); + + Map> employeeMap1 = mUtil.createNestedObjectMap(listEmployee); + + assertNotEquals(employeeAddressMap1, actualEmployeeAddressMap); + + assertNotEquals(employeeMap1, actualEmployeeMap); + } + + @Test + public void whencomparingDifferentObjectValuesUsingEquals_thenFail() { + listEmployee.clear(); + listEmployee.add(new Employee(1, new Address(124, "Timbuktoo"), "Thorin Oakenshield")); + listEmployee.add(new Employee(2, new Address(100, "Misty Lanes"), "Balin")); + listEmployee.add(new Employee(3, new Address(156, "Brambles Lane"), "Bofur")); + listEmployee.add(new Employee(4, new Address(200, "Bag End"), "Bilbo Baggins")); + listEmployee.add(new Employee(5, new Address(23, "Rivendell"), "Elrond")); + + Map> employeeMap1 = listEmployee.stream().collect(Collectors.groupingBy( + (Employee emp) -> emp.getEmployeeId(), + Collectors.toMap((Employee emp) -> emp.getAddress().getAddressId(), fEmpObj -> fEmpObj.getAddress()))); + + assertNotSame(employeeMap1, actualEmployeeMap); + assertNotEquals(employeeMap1, actualEmployeeMap); + + Map> expectedMap = setupAddressObjectMap(); + assertNotSame(expectedMap, actualEmployeeMap); + assertNotEquals(expectedMap, actualEmployeeMap); + + } + + @Test + public void whenCompareTwoHashMapsUsingEquals_thenSuccess() { + Map> outerBakedGoodsMap4 = new HashMap<>(); + outerBakedGoodsMap4.putAll(actualBakedGoodsMap); + + assertEquals(actualBakedGoodsMap, outerBakedGoodsMap4); + + Map> employeeMap1 = new HashMap<>(); + employeeMap1.putAll(actualEmployeeMap); + assertEquals(actualEmployeeMap, employeeMap1); + } + + @Test + public void whenAddElementinHashMaps_thenSuccess() { + assertEquals(actualBakedGoodsMap.get("Cake").size(), 5); + actualBakedGoodsMap.get("Cake").put(6, "Cranberry"); + assertEquals(actualBakedGoodsMap.get("Cake").size(), 6); + } + + @Test + public void whenDeleteElementinHashMaps_thenSuccess() { + assertNotEquals(actualBakedGoodsMap.get("Cake").get(5), null); + actualBakedGoodsMap.get("Cake").remove(5); + assertEquals(actualBakedGoodsMap.get("Cake").get(5), null); + + actualBakedGoodsMap.put("Eclair", new HashMap() { + { + put(1, "Dark Chocolate"); + } + }); + + assertNotEquals(actualBakedGoodsMap.get("Eclair").get(1), null); + actualBakedGoodsMap.get("Eclair").remove(1); + assertEquals(actualBakedGoodsMap.get("Eclair").get(1), null); + + actualBakedGoodsMap.put("Eclair", new HashMap() { + { + put(1, "Dark Chocolate"); + } + }); + + assertNotEquals(actualBakedGoodsMap.get("Eclair"), null); + actualBakedGoodsMap.remove("Eclair"); + assertEquals(actualBakedGoodsMap.get("Eclair"), null); + } + + @Test + public void whenFlattenMap_thenRemovesNesting() { + + Map flattenedBakedGoodsMap = mUtil.flattenMap(actualBakedGoodsMap); + assertThat(flattenedBakedGoodsMap, IsMapContaining.hasKey("Donut.2")); + + Map flattenedEmployeeAddressMap = mUtil.flattenMap(actualEmployeeAddressMap); + assertThat(flattenedEmployeeAddressMap, IsMapContaining.hasKey("200.Bag End")); + } + + @Before + public void buildMaps() { + + batterList = Arrays.asList("Mulberry", "Cranberry", "Blackberry", "Mixed fruit", "Orange"); + + actualBakedGoodsMap.put("Cake", mUtil.buildInnerMap(batterList)); + + batterList = new ArrayList<>(); + batterList = Arrays.asList("Candy", "Dark Chocolate", "Chocolate", "Jam filled", "Pineapple"); + + actualBakedGoodsMap.put("Donut", mUtil.buildInnerMap(batterList)); + + listEmployee.add(new Employee(1, new Address(124, "Timbuktoo"), "Thorin Oakenshield")); + listEmployee.add(new Employee(2, new Address(100, "Misty Lanes"), "Balin")); + listEmployee.add(new Employee(3, new Address(156, "Brambles Lane"), "Bofur")); + listEmployee.add(new Employee(4, new Address(200, "Bag End"), "Bilbo Baggins")); + listEmployee.add(new Employee(5, new Address(23, "Rivendell"), "Elrond")); + + actualEmployeeAddressMap = mUtil.createNestedMapfromStream(listEmployee); + + actualEmployeeMap = mUtil.createNestedObjectMap(listEmployee); + + } + + private Map> setupAddressObjectMap() { + + Map> expectedMap = new HashMap<>(); + + expectedMap.put(1, new HashMap() { + { + put(124, new Address(124, "Timbuktoo")); + } + }); + expectedMap.put(2, new HashMap() { + { + put(100, new Address(100, "Misty Lanes")); + } + }); + expectedMap.put(3, new HashMap() { + { + put(156, new Address(156, "Brambles Lane")); + } + }); + expectedMap.put(4, new HashMap() { + { + put(200, new Address(200, "Bag End")); + } + }); + expectedMap.put(5, new HashMap() { + { + put(23, new Address(23, "Rivendell")); + } + }); + return expectedMap; + } + +} diff --git a/core-java-modules/core-java-concurrency-2/pom.xml b/core-java-modules/core-java-concurrency-2/pom.xml index b8a1d641d4..c61f28a6b3 100644 --- a/core-java-modules/core-java-concurrency-2/pom.xml +++ b/core-java-modules/core-java-concurrency-2/pom.xml @@ -15,11 +15,6 @@ - - org.junit.vintage - junit-vintage-engine - test - com.googlecode.thread-weaver threadweaver @@ -31,6 +26,12 @@ tempus-fugit ${tempus-fugit.version} test + + + junit + junit + + com.googlecode.multithreadedtc diff --git a/core-java-modules/core-java-jndi/README.md b/core-java-modules/core-java-jndi/README.md index d9fb324c9a..b0b23fc0d0 100644 --- a/core-java-modules/core-java-jndi/README.md +++ b/core-java-modules/core-java-jndi/README.md @@ -2,3 +2,4 @@ ### Relevant Articles: - [Java Naming and Directory Interface Overview](https://www.baeldung.com/jndi) +- [LDAP Authentication Using Pure Java](https://www.baeldung.com/java-ldap-auth) diff --git a/core-java-modules/core-java-jndi/pom.xml b/core-java-modules/core-java-jndi/pom.xml index f1b374b2b5..6b7c4e1359 100644 --- a/core-java-modules/core-java-jndi/pom.xml +++ b/core-java-modules/core-java-jndi/pom.xml @@ -15,23 +15,6 @@ - - org.junit.jupiter - junit-jupiter - ${junit-jupiter.version} - test - - - org.junit.jupiter - junit-jupiter-api - ${junit-jupiter.version} - test - - - org.junit.jupiter - junit-jupiter-engine - ${junit-jupiter.version} - org.springframework spring-core @@ -58,6 +41,18 @@ h2 ${h2.version} + + org.apache.directory.server + apacheds-test-framework + ${apacheds.version} + test + + + org.assertj + assertj-core + 3.21.0 + test + @@ -76,6 +71,7 @@ 5.0.9.RELEASE 1.4.199 + 2.0.0.AM26 1.8 1.8 diff --git a/core-java-modules/core-java-jndi/src/test/java/com/baeldung/jndi/ldap/auth/JndiLdapAuthManualTest.java b/core-java-modules/core-java-jndi/src/test/java/com/baeldung/jndi/ldap/auth/JndiLdapAuthManualTest.java new file mode 100644 index 0000000000..5a675c62c9 --- /dev/null +++ b/core-java-modules/core-java-jndi/src/test/java/com/baeldung/jndi/ldap/auth/JndiLdapAuthManualTest.java @@ -0,0 +1,165 @@ +package com.baeldung.jndi.ldap.auth; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; + +import java.util.Hashtable; + +import javax.naming.AuthenticationException; +import javax.naming.Context; +import javax.naming.NamingEnumeration; +import javax.naming.directory.Attributes; +import javax.naming.directory.DirContext; +import javax.naming.directory.InitialDirContext; +import javax.naming.directory.SearchControls; +import javax.naming.directory.SearchResult; + +import org.apache.directory.server.annotations.CreateLdapServer; +import org.apache.directory.server.annotations.CreateTransport; +import org.apache.directory.server.core.annotations.ApplyLdifFiles; +import org.apache.directory.server.core.annotations.CreateDS; +import org.apache.directory.server.core.annotations.CreatePartition; +import org.apache.directory.server.core.integ.AbstractLdapTestUnit; +import org.apache.directory.server.core.integ.FrameworkRunner; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(FrameworkRunner.class) +@CreateLdapServer(transports = { @CreateTransport(protocol = "LDAP", address = "localhost", port = 10390)}) +@CreateDS( + allowAnonAccess = false, partitions = {@CreatePartition(name = "TestPartition", suffix = "dc=baeldung,dc=com")}) +@ApplyLdifFiles({"users.ldif"}) +// class marked as manual test, as it has to run independently from the other unit tests in the module +public class JndiLdapAuthManualTest extends AbstractLdapTestUnit { + + private static void authenticateUser(Hashtable environment) throws Exception { + DirContext context = new InitialDirContext(environment); + context.close(); + } + + @Test + public void givenPreloadedLDAPUserJoe_whenAuthUserWithCorrectPW_thenAuthSucceeds() throws Exception { + + Hashtable environment = new Hashtable(); + environment.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); + environment.put(Context.PROVIDER_URL, "ldap://localhost:10390"); + environment.put(Context.SECURITY_AUTHENTICATION, "simple"); + + environment.put(Context.SECURITY_PRINCIPAL, "cn=Joe Simms,ou=Users,dc=baeldung,dc=com"); + environment.put(Context.SECURITY_CREDENTIALS, "12345"); + + assertThatCode(() -> authenticateUser(environment)).doesNotThrowAnyException(); + } + + @Test + public void givenPreloadedLDAPUserJoe_whenAuthUserWithWrongPW_thenAuthFails() throws Exception { + + Hashtable environment = new Hashtable(); + environment.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); + environment.put(Context.PROVIDER_URL, "ldap://localhost:10390"); + environment.put(Context.SECURITY_AUTHENTICATION, "simple"); + + environment.put(Context.SECURITY_PRINCIPAL, "cn=Joe Simms,ou=Users,dc=baeldung,dc=com"); + environment.put(Context.SECURITY_CREDENTIALS, "wronguserpw"); + + assertThatExceptionOfType(AuthenticationException.class).isThrownBy(() -> authenticateUser(environment)); + } + + @Test + public void givenPreloadedLDAPUserJoe_whenSearchAndAuthUserWithCorrectPW_thenAuthSucceeds() throws Exception { + + // first authenticate against LDAP as admin to search up DN of user : Joe Simms + + Hashtable environment = new Hashtable(); + environment.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); + environment.put(Context.PROVIDER_URL, "ldap://localhost:10390"); + environment.put(Context.SECURITY_AUTHENTICATION, "simple"); + environment.put(Context.SECURITY_PRINCIPAL, "uid=admin,ou=system"); + environment.put(Context.SECURITY_CREDENTIALS, "secret"); + + DirContext adminContext = new InitialDirContext(environment); + + // define the search filter to find the person with CN : Joe Simms + String filter = "(&(objectClass=person)(cn=Joe Simms))"; + + // declare the attributes we want returned for the object being searched + String[] attrIDs = { "cn" }; + + // define the search controls + SearchControls searchControls = new SearchControls(); + searchControls.setReturningAttributes(attrIDs); + searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE); + + // search for User with filter cn=Joe Simms + NamingEnumeration searchResults = adminContext.search("dc=baeldung,dc=com", filter, searchControls); + if (searchResults.hasMore()) { + + SearchResult result = (SearchResult) searchResults.next(); + Attributes attrs = result.getAttributes(); + + String distinguishedName = result.getNameInNamespace(); + assertThat(distinguishedName).isEqualTo("cn=Joe Simms,ou=Users,dc=baeldung,dc=com"); + + String commonName = attrs.get("cn").toString(); + assertThat(commonName).isEqualTo("cn: Joe Simms"); + + // authenticate new context with DN for user Joe Simms, using correct password + + environment.put(Context.SECURITY_PRINCIPAL, distinguishedName); + environment.put(Context.SECURITY_CREDENTIALS, "12345"); + + assertThatCode(() -> authenticateUser(environment)).doesNotThrowAnyException(); + } + + adminContext.close(); + } + + @Test + public void givenPreloadedLDAPUserJoe_whenSearchAndAuthUserWithWrongPW_thenAuthFails() throws Exception { + + // first authenticate against LDAP as admin to search up DN of user : Joe Simms + + Hashtable environment = new Hashtable(); + environment.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); + environment.put(Context.PROVIDER_URL, "ldap://localhost:10390"); + environment.put(Context.SECURITY_AUTHENTICATION, "simple"); + environment.put(Context.SECURITY_PRINCIPAL, "uid=admin,ou=system"); + environment.put(Context.SECURITY_CREDENTIALS, "secret"); + DirContext adminContext = new InitialDirContext(environment); + + // define the search filter to find the person with CN : Joe Simms + String filter = "(&(objectClass=person)(cn=Joe Simms))"; + + // declare the attributes we want returned for the object being searched + String[] attrIDs = { "cn" }; + + // define the search controls + SearchControls searchControls = new SearchControls(); + searchControls.setReturningAttributes(attrIDs); + searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE); + + // search for User with filter cn=Joe Simms + NamingEnumeration searchResults = adminContext.search("dc=baeldung,dc=com", filter, searchControls); + if (searchResults.hasMore()) { + + SearchResult result = (SearchResult) searchResults.next(); + Attributes attrs = result.getAttributes(); + + String distinguishedName = result.getNameInNamespace(); + assertThat(distinguishedName).isEqualTo("cn=Joe Simms,ou=Users,dc=baeldung,dc=com"); + + String commonName = attrs.get("cn").toString(); + assertThat(commonName).isEqualTo("cn: Joe Simms"); + + // authenticate new context with DN for user Joe Simms, using wrong password + + environment.put(Context.SECURITY_PRINCIPAL, distinguishedName); + environment.put(Context.SECURITY_CREDENTIALS, "wronguserpassword"); + + assertThatExceptionOfType(AuthenticationException.class).isThrownBy(() -> authenticateUser(environment)); + } + + adminContext.close(); + } +} diff --git a/core-java-modules/core-java-jndi/src/test/resources/logback.xml b/core-java-modules/core-java-jndi/src/test/resources/logback.xml new file mode 100644 index 0000000000..e55b365ba4 --- /dev/null +++ b/core-java-modules/core-java-jndi/src/test/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + diff --git a/core-java-modules/core-java-jndi/src/test/resources/users.ldif b/core-java-modules/core-java-jndi/src/test/resources/users.ldif new file mode 100644 index 0000000000..c1996586d5 --- /dev/null +++ b/core-java-modules/core-java-jndi/src/test/resources/users.ldif @@ -0,0 +1,20 @@ +version: 1 +dn: dc=baeldung,dc=com +objectClass: domain +objectClass: top +dc: baeldung + +dn: ou=Users,dc=baeldung,dc=com +objectClass: organizationalUnit +objectClass: top +ou: Users + +dn: cn=Joe Simms,ou=Users,dc=baeldung,dc=com +objectClass: inetOrgPerson +objectClass: organizationalPerson +objectClass: person +objectClass: top +cn: Joe Simms +sn: Simms +uid: user1 +userPassword: 12345 diff --git a/core-java-modules/core-java-jvm-2/pom.xml b/core-java-modules/core-java-jvm-2/pom.xml index 173cf27955..b34aac5a78 100644 --- a/core-java-modules/core-java-jvm-2/pom.xml +++ b/core-java-modules/core-java-jvm-2/pom.xml @@ -15,11 +15,6 @@ - - org.junit.vintage - junit-vintage-engine - test - org.assertj assertj-core @@ -31,11 +26,23 @@ jol-core ${jol-core.version} + + org.reflections + reflections + ${reflections.version} + + + com.google.guava + guava + ${guava.version} + 3.6.1 0.10 + 0.10.2 + 31.0.1-jre - \ No newline at end of file + diff --git a/core-java-modules/core-java-jvm-2/src/main/java/com/baeldung/loadedclasslisting/ListLoadedClass.java b/core-java-modules/core-java-jvm-2/src/main/java/com/baeldung/loadedclasslisting/ListLoadedClass.java new file mode 100644 index 0000000000..b4a290e70d --- /dev/null +++ b/core-java-modules/core-java-jvm-2/src/main/java/com/baeldung/loadedclasslisting/ListLoadedClass.java @@ -0,0 +1,35 @@ +package com.baeldung.loadedclasslisting; + +import java.io.IOException; +import java.util.Set; +import java.util.stream.Collectors; + +import org.reflections.Reflections; +import org.reflections.scanners.SubTypesScanner; + +import com.google.common.collect.ImmutableSet; +import com.google.common.reflect.ClassPath; +import com.google.common.reflect.ClassPath.ClassInfo; + +public class ListLoadedClass { + + public ImmutableSet listClassLoaded() throws IOException { + return ClassPath.from(ListLoadedClass.class.getClassLoader()) + .getAllClasses(); + } + + public Set listClassLoaded(String packageName) throws IOException { + return ClassPath.from(ClassLoader.getSystemClassLoader()).getAllClasses().stream() + .filter(clazz -> clazz.getPackageName().equals(packageName)) + .map(ClassInfo::load) + .collect(Collectors.toSet()); + } + + public Set findAllClassesUsingReflectionsLibrary(String packageName) { + Reflections reflections = new Reflections(packageName, new SubTypesScanner(false)); + return reflections.getSubTypesOf(Object.class) + .stream() + .collect(Collectors.toSet()); + } + +} diff --git a/core-java-modules/core-java-jvm-2/src/test/java/com/baeldung/loadedclasslisting/ListLoadedClassUnitTest.java b/core-java-modules/core-java-jvm-2/src/test/java/com/baeldung/loadedclasslisting/ListLoadedClassUnitTest.java new file mode 100644 index 0000000000..c3e29b27b6 --- /dev/null +++ b/core-java-modules/core-java-jvm-2/src/test/java/com/baeldung/loadedclasslisting/ListLoadedClassUnitTest.java @@ -0,0 +1,41 @@ +package com.baeldung.loadedclasslisting; + +import java.io.IOException; +import java.util.Set; + +import org.junit.Test; +import org.junit.jupiter.api.Assertions; + +import com.baeldung.loadedclasslisting.ListLoadedClass; +import com.google.common.collect.ImmutableSet; +import com.google.common.reflect.ClassPath; +import com.google.common.reflect.ClassPath.ClassInfo; + +public class ListLoadedClassUnitTest { + + private static final String PACKAGE_NAME = "com.baeldung.loadedclasslisting"; + + @Test + public void when_findAllClassesUsingReflectionsLibrary_thenSuccess() { + ListLoadedClass instance = new ListLoadedClass(); + Set classes = instance.findAllClassesUsingReflectionsLibrary(PACKAGE_NAME); + + Assertions.assertEquals(4, classes.size()); + } + + @Test + public void when_findAllClassesUsingGuavaLibrary_InPackage_thenSuccess() throws IOException { + ListLoadedClass instance = new ListLoadedClass(); + Set classes = instance.listClassLoaded(PACKAGE_NAME); + + Assertions.assertEquals(4, classes.size()); + } + + @Test + public void when_findAllClassesUsingGuavaLibrary_thenSuccess() throws IOException { + ListLoadedClass instance = new ListLoadedClass(); + Set classes = instance.listClassLoaded(); + + Assertions.assertTrue(4 - - org.junit.vintage - junit-vintage-engine - test - org.apache.commons commons-lang3 diff --git a/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/constructorchaining/Customer.java b/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/constructorchaining/Customer.java new file mode 100644 index 0000000000..62dbdef297 --- /dev/null +++ b/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/constructorchaining/Customer.java @@ -0,0 +1,34 @@ +package com.baeldung.constructorchaining; + +import java.util.Objects; + +public class Customer extends Person { + private final String loyaltyCardId; + + public Customer(String firstName, String lastName, int age, String loyaltyCardId) { + this(firstName, null, lastName, age, loyaltyCardId); + } + + public Customer(String firstName, String middleName, String lastName, int age, String loyaltyCardId) { + super(firstName, middleName, lastName, age); + this.loyaltyCardId = loyaltyCardId; + } + + public String getLoyaltyCardId() { + return loyaltyCardId; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + Customer customer = (Customer) o; + return Objects.equals(loyaltyCardId, customer.loyaltyCardId); + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), loyaltyCardId); + } +} diff --git a/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/constructorchaining/Person.java b/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/constructorchaining/Person.java new file mode 100644 index 0000000000..02ce2220ba --- /dev/null +++ b/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/constructorchaining/Person.java @@ -0,0 +1,51 @@ +package com.baeldung.constructorchaining; + +import java.util.Objects; + +public class Person { + private final String firstName; + private final String middleName; + private final String lastName; + private final int age; + + public Person(String firstName, String lastName, int age) { + this(firstName, null, lastName, age); + } + + + public Person(String firstName, String middleName, String lastName, int age) { + this.firstName = firstName; + this.middleName = middleName; + this.lastName = lastName; + this.age = age; + } + + public String getFirstName() { + return firstName; + } + + public String getLastName() { + return lastName; + } + + public int getAge() { + return age; + } + + public String getMiddleName() { + return middleName; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Person person = (Person) o; + return age == person.age && Objects.equals(firstName, person.firstName) && Objects.equals(middleName, person.middleName) && Objects.equals(lastName, person.lastName); + } + + @Override + public int hashCode() { + return Objects.hash(firstName, middleName, lastName, age); + } +} diff --git a/core-java-modules/core-java-lang-4/src/test/java/com/baeldung/constructorchaining/CustomerUnitTest.java b/core-java-modules/core-java-lang-4/src/test/java/com/baeldung/constructorchaining/CustomerUnitTest.java new file mode 100644 index 0000000000..ad00ea65b8 --- /dev/null +++ b/core-java-modules/core-java-lang-4/src/test/java/com/baeldung/constructorchaining/CustomerUnitTest.java @@ -0,0 +1,31 @@ +package com.baeldung.constructorchaining; + +import org.junit.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; + +public class CustomerUnitTest { + + @Test + public void givenNameLastNameAndAge_whenUsingDedicatedConstructor_shouldInitializeFieldsAndNullifyMiddleName() { + Customer mark = new Customer("Mark", "Johnson", 23, "abcd1234"); + + assertEquals(23, mark.getAge()); + assertEquals("Mark", mark.getFirstName()); + assertEquals("Johnson", mark.getLastName()); + assertEquals("abcd1234", mark.getLoyaltyCardId()); + assertNull(mark.getMiddleName()); + } + + @Test + public void givenAllFieldsRequired_whenUsingDedicatedConstructor_shouldInitializeAllFields() { + Customer mark = new Customer("Mark", "Andrew", "Johnson", 23, "abcd1234"); + + assertEquals(23, mark.getAge()); + assertEquals("Mark", mark.getFirstName()); + assertEquals("Andrew", mark.getMiddleName()); + assertEquals("Johnson", mark.getLastName()); + assertEquals("abcd1234", mark.getLoyaltyCardId()); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-lang-4/src/test/java/com/baeldung/constructorchaining/PersonUnitTest.java b/core-java-modules/core-java-lang-4/src/test/java/com/baeldung/constructorchaining/PersonUnitTest.java new file mode 100644 index 0000000000..8322917951 --- /dev/null +++ b/core-java-modules/core-java-lang-4/src/test/java/com/baeldung/constructorchaining/PersonUnitTest.java @@ -0,0 +1,29 @@ +package com.baeldung.constructorchaining; + +import org.junit.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; + +public class PersonUnitTest { + + @Test + public void givenNameLastNameAndAge_whenUsingDedicatedConstructor_shouldInitializeFieldsAndNullifyMiddleName() { + Person mark = new Person("Mark", "Johnson", 23); + + assertEquals(23, mark.getAge()); + assertEquals("Mark", mark.getFirstName()); + assertEquals("Johnson", mark.getLastName()); + assertNull(mark.getMiddleName()); + } + + @Test + public void givenAllFieldsRequired_whenUsingDedicatedConstructor_shouldInitializeAllFields() { + Person mark = new Person("Mark", "Andrew", "Johnson", 23); + + assertEquals(23, mark.getAge()); + assertEquals("Mark", mark.getFirstName()); + assertEquals("Andrew", mark.getMiddleName()); + assertEquals("Johnson", mark.getLastName()); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-networking-3/pom.xml b/core-java-modules/core-java-networking-3/pom.xml index 4a05af8b25..1579418b54 100644 --- a/core-java-modules/core-java-networking-3/pom.xml +++ b/core-java-modules/core-java-networking-3/pom.xml @@ -35,11 +35,6 @@ ${assertj.version} test - - org.junit.vintage - junit-vintage-engine - test - com.sun.mail javax.mail diff --git a/core-java-modules/core-java-os/pom.xml b/core-java-modules/core-java-os/pom.xml index b163052ea2..8265e47192 100644 --- a/core-java-modules/core-java-os/pom.xml +++ b/core-java-modules/core-java-os/pom.xml @@ -15,51 +15,45 @@ ../ - - - org.junit.jupiter - junit-jupiter-engine - ${junit-jupiter.version} - test - - - org.apache.commons - commons-collections4 - ${commons-collections4.version} - - - commons-io - commons-io - ${commons-io.version} - - - org.apache.commons - commons-lang3 - ${commons-lang3.version} - - - log4j - log4j - ${log4j.version} - - - - org.assertj - assertj-core - ${assertj.version} - test - - - org.unix4j - unix4j-command - ${unix4j.version} - - - com.googlecode.grep4j - grep4j - ${grep4j.version} - - + + + org.apache.commons + commons-collections4 + ${commons-collections4.version} + + + commons-io + commons-io + ${commons-io.version} + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + + + log4j + log4j + ${log4j.version} + + + + org.assertj + assertj-core + ${assertj.version} + test + + + org.unix4j + unix4j-command + ${unix4j.version} + + + com.googlecode.grep4j + grep4j + ${grep4j.version} + + core-java-os diff --git a/core-java-modules/core-java-security-3/src/main/java/com/baeldung/crypto/CryptoDriver.java b/core-java-modules/core-java-security-3/src/main/java/com/baeldung/crypto/CryptoDriver.java new file mode 100644 index 0000000000..552bd5d474 --- /dev/null +++ b/core-java-modules/core-java-security-3/src/main/java/com/baeldung/crypto/CryptoDriver.java @@ -0,0 +1,86 @@ +package com.baeldung.crypto; + +import javax.crypto.Cipher; +import javax.crypto.SecretKey; +import javax.crypto.spec.GCMParameterSpec; +import javax.crypto.spec.IvParameterSpec; +import java.security.GeneralSecurityException; + +import com.baeldung.crypto.utils.CryptoUtils; + +public class CryptoDriver { + + public byte[] ecbEncrypt(SecretKey key, byte[] data) throws GeneralSecurityException { + Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); + cipher.init(Cipher.ENCRYPT_MODE, key); + return cipher.doFinal(data); + } + + public byte[] ecbDecrypt(SecretKey key, byte[] cipherText) throws GeneralSecurityException { + Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); + cipher.init(Cipher.DECRYPT_MODE, key); + return cipher.doFinal(cipherText); + } + + public byte[] cbcEncrypt(SecretKey key, IvParameterSpec iv, byte[] data) throws GeneralSecurityException { + Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); + cipher.init(Cipher.ENCRYPT_MODE, key, iv); + return cipher.doFinal(data); + } + + public byte[] cbcDecrypt(SecretKey key, IvParameterSpec iv, byte[] cipherText) throws GeneralSecurityException { + Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); + cipher.init(Cipher.DECRYPT_MODE, key, iv); + return cipher.doFinal(cipherText); + } + + public byte[] cfbEncrypt(SecretKey key, IvParameterSpec iv, byte[] data) throws GeneralSecurityException { + Cipher cipher = Cipher.getInstance("AES/CFB/NoPadding"); + cipher.init(Cipher.ENCRYPT_MODE, key, iv); + return cipher.doFinal(data); + } + + public byte[] cfbDecrypt(SecretKey key, IvParameterSpec iv, byte[] cipherText) throws GeneralSecurityException { + Cipher cipher = Cipher.getInstance("AES/CFB/NoPadding"); + cipher.init(Cipher.DECRYPT_MODE, key, iv); + return cipher.doFinal(cipherText); + } + + public byte[] ofbEncrypt(SecretKey key, IvParameterSpec iv, byte[] data) throws GeneralSecurityException { + Cipher cipher = Cipher.getInstance("AES/OFB32/PKCS5Padding"); + cipher.init(Cipher.ENCRYPT_MODE, key, iv); + return cipher.doFinal(data); + } + + public byte[] ofbDecrypt(SecretKey key, IvParameterSpec iv, byte[] cipherText) throws GeneralSecurityException { + Cipher cipher = Cipher.getInstance("AES/OFB32/PKCS5Padding"); + cipher.init(Cipher.DECRYPT_MODE, key, iv); + return cipher.doFinal(cipherText); + } + + public byte[][] ctrEncrypt(SecretKey key, IvParameterSpec iv, byte[] data) throws GeneralSecurityException { + Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding"); + cipher.init(Cipher.ENCRYPT_MODE, key, iv); + return new byte[][] { cipher.getIV(), cipher.doFinal(data) }; + } + + public byte[] ctrDecrypt(SecretKey key, byte[] iv, byte[] cipherText) throws GeneralSecurityException { + Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding"); + cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv)); + return cipher.doFinal(cipherText); + } + + public byte[][] gcmEncrypt(SecretKey key, byte[] iv, byte[] data) throws GeneralSecurityException { + Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding"); + cipher.init(Cipher.ENCRYPT_MODE, key, new GCMParameterSpec(128, iv)); + byte[] ciphertext = cipher.doFinal(data); + return new byte[][] { iv, ciphertext }; + } + + public byte[] gcmDecrypt(SecretKey key, byte[] iv, byte[] ciphertext) throws GeneralSecurityException { + Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding"); + cipher.init(Cipher.DECRYPT_MODE, key, new GCMParameterSpec(128, iv)); + byte[] plaintext = cipher.doFinal(ciphertext); + return plaintext; + } +} diff --git a/core-java-modules/core-java-security-3/src/main/java/com/baeldung/crypto/utils/CryptoUtils.java b/core-java-modules/core-java-security-3/src/main/java/com/baeldung/crypto/utils/CryptoUtils.java new file mode 100644 index 0000000000..2d3df231ff --- /dev/null +++ b/core-java-modules/core-java-security-3/src/main/java/com/baeldung/crypto/utils/CryptoUtils.java @@ -0,0 +1,53 @@ +package com.baeldung.crypto.utils; + +import java.security.AlgorithmParameters; +import java.security.GeneralSecurityException; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.security.spec.InvalidParameterSpecException; + +import javax.crypto.Cipher; +import javax.crypto.KeyGenerator; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.SecretKey; +import javax.crypto.spec.IvParameterSpec; + +public class CryptoUtils { + + public static SecretKey generateKey() throws GeneralSecurityException { + KeyGenerator keyGenerator = KeyGenerator.getInstance("AES"); + keyGenerator.init(256); + return keyGenerator.generateKey(); + } + + public static IvParameterSpec getIV() { + SecureRandom secureRandom = new SecureRandom(); + byte[] iv = new byte[128 / 8]; + byte[] nonce = new byte[96 / 8]; + secureRandom.nextBytes(nonce); + System.arraycopy(nonce, 0, iv, 0, nonce.length); + return new IvParameterSpec(nonce); + } + + public static IvParameterSpec getIVSecureRandom(String algorithm) throws NoSuchAlgorithmException, NoSuchPaddingException { + SecureRandom random = SecureRandom.getInstanceStrong(); + byte[] iv = new byte[Cipher.getInstance(algorithm) + .getBlockSize()]; + random.nextBytes(iv); + return new IvParameterSpec(iv); + } + + public static IvParameterSpec getIVInternal(Cipher cipher) throws InvalidParameterSpecException { + AlgorithmParameters params = cipher.getParameters(); + byte[] iv = params.getParameterSpec(IvParameterSpec.class) + .getIV(); + return new IvParameterSpec(iv); + } + + public static byte[] getRandomIVWithSize(int size) { + byte[] nonce = new byte[size]; + new SecureRandom().nextBytes(nonce); + return nonce; + } + +} \ No newline at end of file diff --git a/core-java-modules/core-java-security-3/src/test/java/com/baeldung/crypto/CryptoDriverIVUnitTest.java b/core-java-modules/core-java-security-3/src/test/java/com/baeldung/crypto/CryptoDriverIVUnitTest.java new file mode 100644 index 0000000000..f3bed310dd --- /dev/null +++ b/core-java-modules/core-java-security-3/src/test/java/com/baeldung/crypto/CryptoDriverIVUnitTest.java @@ -0,0 +1,86 @@ +package com.baeldung.crypto; + +import javax.crypto.SecretKey; +import javax.crypto.spec.IvParameterSpec; +import java.security.GeneralSecurityException; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import com.baeldung.crypto.utils.CryptoUtils; + +public class CryptoDriverIVUnitTest{ + private CryptoDriver driver = new CryptoDriver(); + private String TEST_DATA = "Encrypt this for testing"; + + @Test + public void givenString_whenAesEcb_thenSuccess() throws GeneralSecurityException { + SecretKey key = CryptoUtils.generateKey(); + byte[] plaintext = TEST_DATA.getBytes(); + + byte[] ciphertext = driver.ecbEncrypt(key, plaintext); + byte[] decryptedtext = driver.ecbDecrypt(key, ciphertext); + + Assertions.assertEquals(new String(decryptedtext), TEST_DATA); + } + + @Test + public void givenString_whenAesCbc_thenSuccess() throws GeneralSecurityException { + SecretKey key = CryptoUtils.generateKey(); + IvParameterSpec iv = CryptoUtils.getIVSecureRandom("AES"); + byte[] plaintext = TEST_DATA.getBytes(); + + byte[] ciphertext = driver.cbcEncrypt(key, iv, plaintext); + byte[] decryptedtext = driver.cbcDecrypt(key, iv, ciphertext); + + Assertions.assertEquals(new String(decryptedtext), TEST_DATA); + } + + @Test + public void givenString_whenAesCfb_thenSuccess() throws GeneralSecurityException { + SecretKey key = CryptoUtils.generateKey(); + IvParameterSpec iv = CryptoUtils.getIVSecureRandom("AES/CFB/NoPadding"); + byte[] plaintext = TEST_DATA.getBytes(); + + byte[] ciphertext = driver.cfbEncrypt(key, iv, plaintext); + byte[] decryptedtext = driver.cfbDecrypt(key, iv, ciphertext); + + Assertions.assertEquals(new String(decryptedtext), TEST_DATA); + } + + @Test + public void givenString_whenAesOfb_thenSuccess() throws GeneralSecurityException { + SecretKey key = CryptoUtils.generateKey(); + IvParameterSpec iv = CryptoUtils.getIVSecureRandom("AES/OFB32/PKCS5Padding"); + byte[] plaintext = TEST_DATA.getBytes(); + + byte[] ciphertext = driver.ofbEncrypt(key, iv, plaintext); + byte[] decryptedtext = driver.ofbDecrypt(key, iv, ciphertext); + + Assertions.assertEquals(new String(decryptedtext), TEST_DATA); + } + + @Test + public void givenString_whenAesCtr_thenSuccess() throws GeneralSecurityException { + SecretKey key = CryptoUtils.generateKey(); + IvParameterSpec iv = CryptoUtils.getIVSecureRandom("AES/CTR/NoPadding"); + byte[] plaintext = TEST_DATA.getBytes(); + + byte[][] ciphertext = driver.ctrEncrypt(key, iv, plaintext); + byte[] decryptedtext = driver.ctrDecrypt(key, ciphertext[0], ciphertext[1]); + + Assertions.assertEquals(new String(decryptedtext), TEST_DATA); + } + + @Test + void givenString_whenAesGcm_thenSuccess() throws GeneralSecurityException { + SecretKey key = CryptoUtils.generateKey(); + byte[] iv = CryptoUtils.getRandomIVWithSize(12); + byte[] plaintext = (TEST_DATA).getBytes(); + + byte[][] ciphertext = driver.gcmEncrypt(key, iv, plaintext); + byte[] decryptedtext = driver.gcmDecrypt(key, ciphertext[0], ciphertext[1]); + + Assertions.assertEquals(new String(decryptedtext), TEST_DATA); + } +} diff --git a/core-java-modules/core-java-streams-2/pom.xml b/core-java-modules/core-java-streams-2/pom.xml index 087a8378b1..08b82bcc11 100644 --- a/core-java-modules/core-java-streams-2/pom.xml +++ b/core-java-modules/core-java-streams-2/pom.xml @@ -30,11 +30,6 @@ log4j ${log4j.version} - - org.junit.vintage - junit-vintage-engine - test - org.assertj assertj-core diff --git a/core-java-modules/core-java-string-algorithms-2/src/test/java/com/baeldung/isuppercase/StringFirstCharacterUppercase.java b/core-java-modules/core-java-string-algorithms-2/src/test/java/com/baeldung/isuppercase/StringFirstCharacterUppercase.java new file mode 100644 index 0000000000..0d9d3b6431 --- /dev/null +++ b/core-java-modules/core-java-string-algorithms-2/src/test/java/com/baeldung/isuppercase/StringFirstCharacterUppercase.java @@ -0,0 +1,32 @@ +package com.baeldung.isuppercase; + +import com.google.common.base.Ascii; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.matchesPattern; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +public class StringFirstCharacterUppercase { + + @Test + public void givenString_whenCheckingWithCharacterIsUpperCase_thenStringCapitalized() { + String example = "Katie"; + Assertions.assertTrue(Character.isUpperCase(example.charAt(0))); + } + + @Test + public void givenString_whenCheckingWithRegex_thenStringCapitalized() { + String example = "Katie"; + String regEx = "[A-Z]\\w*"; + assertThat(example, matchesPattern(regEx)); + } + + @Test + public void givenString_whenCheckingWithGuava_thenStringCapitalized() { + String example = "Katie"; + Assertions.assertTrue(Ascii.isUpperCase(example.charAt(0))); + } +} diff --git a/core-java-modules/core-java-string-algorithms-3/pom.xml b/core-java-modules/core-java-string-algorithms-3/pom.xml index 67a6443bc6..88a3029cf1 100644 --- a/core-java-modules/core-java-string-algorithms-3/pom.xml +++ b/core-java-modules/core-java-string-algorithms-3/pom.xml @@ -26,11 +26,6 @@ guava ${guava.version} - - org.junit.jupiter - junit-jupiter - test - commons-validator commons-validator diff --git a/core-java-modules/core-java-string-conversions-2/pom.xml b/core-java-modules/core-java-string-conversions-2/pom.xml index ff4955726b..68be7d2c08 100644 --- a/core-java-modules/core-java-string-conversions-2/pom.xml +++ b/core-java-modules/core-java-string-conversions-2/pom.xml @@ -20,11 +20,6 @@ guava ${guava.version} - - org.junit.vintage - junit-vintage-engine - test - org.hamcrest hamcrest diff --git a/core-java-modules/core-java-string-operations-3/README.md b/core-java-modules/core-java-string-operations-3/README.md index 1a131c57ac..dc42862e5d 100644 --- a/core-java-modules/core-java-string-operations-3/README.md +++ b/core-java-modules/core-java-string-operations-3/README.md @@ -7,3 +7,5 @@ - [Validate String as Filename in Java](https://www.baeldung.com/java-validate-filename) - [Count Spaces in a Java String](https://www.baeldung.com/java-string-count-spaces) - [Remove Accents and Diacritics From a String in Java](https://www.baeldung.com/java-remove-accents-from-text) +- [Remove Beginning and Ending Double Quotes from a String](https://www.baeldung.com/java-remove-start-end-double-quote) +- [Splitting a Java String by Multiple Delimiters](https://www.baeldung.com/java-string-split-multiple-delimiters) diff --git a/core-java-modules/core-java-string-operations-3/src/main/java/com/baeldung/firstword/FirstWordGetter.java b/core-java-modules/core-java-string-operations-3/src/main/java/com/baeldung/firstword/FirstWordGetter.java new file mode 100644 index 0000000000..03c134752a --- /dev/null +++ b/core-java-modules/core-java-string-operations-3/src/main/java/com/baeldung/firstword/FirstWordGetter.java @@ -0,0 +1,20 @@ +package com.baeldung.firstword; + +public class FirstWordGetter { + + public static void main(String[] args) { + String input = "Roberto \"I wish you a bug-free day\""; + System.out.println("Using split: " + getFirstWordUsingSplit(input)); + System.out.println("Using subString: " + getFirstWordUsingSubString(input)); + } + + public static String getFirstWordUsingSubString(String input) { + int index = input.contains(" ") ? input.indexOf(" ") : 0; + return input.substring(0, index); + } + + public static String getFirstWordUsingSplit(String input) { + String[] tokens = input.split(" ", 2); + return tokens[0]; + } +} diff --git a/core-java-modules/core-java-string-operations-3/src/test/java/com/baeldung/firstword/FirstWordGetterUnitTest.java b/core-java-modules/core-java-string-operations-3/src/test/java/com/baeldung/firstword/FirstWordGetterUnitTest.java new file mode 100644 index 0000000000..bdaa25180e --- /dev/null +++ b/core-java-modules/core-java-string-operations-3/src/test/java/com/baeldung/firstword/FirstWordGetterUnitTest.java @@ -0,0 +1,30 @@ +package com.baeldung.firstword; + +import static com.baeldung.firstword.FirstWordGetter.getFirstWordUsingSplit; +import static com.baeldung.firstword.FirstWordGetter.getFirstWordUsingSubString; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class FirstWordGetterUnitTest { + + @Test + public void givenString_whenSplit_thenFirstWordIsReturned() { + assertEquals("Roberto", getFirstWordUsingSplit("Roberto \"I wish you a bug-free day\"")); + } + + @Test + public void givenStringWithNoSpace_whenSplit_thenFirstWordIsReturned() { + assertEquals("StringWithNoSpace", getFirstWordUsingSplit("StringWithNoSpace")); + } + + @Test + public void givenString_whenPassedToSubstring_thenFirstWordIsReturned() { + assertEquals("Roberto", getFirstWordUsingSubString("Roberto \"I wish you a bug-free day\"")); + } + + @Test + public void givenStringWithNoSpace_whenPassedToSubstring_thenFirstWordIsReturned() { + assertEquals("", getFirstWordUsingSubString("StringWithNoSpace")); + } +} diff --git a/core-java-modules/core-java-string-operations-3/src/test/java/com/baeldung/multipledelimiterssplit/MultipleDelimitersSplitUnitTest.java b/core-java-modules/core-java-string-operations-3/src/test/java/com/baeldung/multipledelimiterssplit/MultipleDelimitersSplitUnitTest.java index c8f8fc2d98..2da8955645 100644 --- a/core-java-modules/core-java-string-operations-3/src/test/java/com/baeldung/multipledelimiterssplit/MultipleDelimitersSplitUnitTest.java +++ b/core-java-modules/core-java-string-operations-3/src/test/java/com/baeldung/multipledelimiterssplit/MultipleDelimitersSplitUnitTest.java @@ -17,7 +17,7 @@ public class MultipleDelimitersSplitUnitTest { @Test public void givenString_whenSplittingByMultipleDelimitersWithRegEx_thenStringSplit() { String example = "Mary;Thomas:Jane-Kate"; - String[] names = example.split(";|:|-"); + String[] names = example.split("[;:-]"); String[] expectedNames = new String[]{"Mary", "Thomas", "Jane", "Kate"}; Assertions.assertEquals(4, names.length); Assertions.assertArrayEquals(expectedNames, names); @@ -38,7 +38,7 @@ public class MultipleDelimitersSplitUnitTest { String example = "Mary;Thomas:Jane-Kate"; String[] expectedArray = new String[]{"Mary", "Thomas", "Jane", "Kate"}; Iterable expected = Arrays.asList(expectedArray); - Iterable names = Splitter.on(Pattern.compile(";|:|-")).split(example); + Iterable names = Splitter.on(Pattern.compile("[;:-]")).split(example); Assertions.assertEquals(4, Iterators.size(names.iterator())); Assertions.assertIterableEquals(expected, names); } @@ -48,7 +48,7 @@ public class MultipleDelimitersSplitUnitTest { String example = "Mary;Thomas:Jane-Kate"; String[] expectedArray = new String[]{"Mary", "Thomas", "Jane", "Kate"}; Iterable expected = Arrays.asList(expectedArray); - Iterable names = Splitter.onPattern(";|:|-").split(example); + Iterable names = Splitter.onPattern("[;:-]").split(example); Assertions.assertEquals(4, Iterators.size(names.iterator())); Assertions.assertIterableEquals(expected, names); } diff --git a/core-java-modules/core-java-time-measurements/pom.xml b/core-java-modules/core-java-time-measurements/pom.xml index 69de5c04fa..d3c351b385 100644 --- a/core-java-modules/core-java-time-measurements/pom.xml +++ b/core-java-modules/core-java-time-measurements/pom.xml @@ -74,8 +74,8 @@ + org.apache.maven.plugins maven-surefire-plugin - ${maven-surefire-plugin.version} -javaagent:${settings.localRepository}/org/jmockit/jmockit/${jmockit.version}/jmockit-${jmockit.version}.jar @@ -96,8 +96,6 @@ 1.8.9 2.0.7 1.44 - - 2.22.1 \ No newline at end of file diff --git a/core-java-modules/core-java/pom.xml b/core-java-modules/core-java/pom.xml index db2b1edc70..42262be29a 100644 --- a/core-java-modules/core-java/pom.xml +++ b/core-java-modules/core-java/pom.xml @@ -61,6 +61,11 @@ moneta ${javamoney.moneta.version} + + org.springframework + spring-core + ${spring.core.version} + @@ -187,6 +192,7 @@ 3.0.0-M1 1.8 1.8 + 4.3.20.RELEASE \ No newline at end of file diff --git a/core-java-modules/core-java/src/main/java/com/baeldung/util/MySerializationUtils.java b/core-java-modules/core-java/src/main/java/com/baeldung/util/MySerializationUtils.java new file mode 100644 index 0000000000..bfaa91313c --- /dev/null +++ b/core-java-modules/core-java/src/main/java/com/baeldung/util/MySerializationUtils.java @@ -0,0 +1,44 @@ +package com.baeldung.util; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; + +public class MySerializationUtils { + + public static byte[] serialize(T obj) throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(baos); + oos.writeObject(obj); + oos.close(); + return baos.toByteArray(); + } + + public static T deserialize(byte[] b, Class cl) throws IOException, ClassNotFoundException { + ByteArrayInputStream bais = new ByteArrayInputStream(b); + ObjectInputStream ois = new ObjectInputStream(bais); + Object o = ois.readObject(); + return cl.cast(o); + } + + public static boolean isSerializable(Class it) { + boolean serializable = it.isPrimitive() || it.isInterface() || Serializable.class.isAssignableFrom(it); + if (!serializable) { + return serializable; + } + Field[] declaredFields = it.getDeclaredFields(); + for (Field field : declaredFields) { + if (Modifier.isVolatile(field.getModifiers()) || Modifier.isTransient(field.getModifiers()) || Modifier.isStatic(field.getModifiers())) { + continue; + } + Class fieldType = field.getType(); + return isSerializable(fieldType); + } + return serializable; + } +} diff --git a/core-java-modules/core-java/src/test/java/com/baeldung/serialization/SerializationUnitTest.java b/core-java-modules/core-java/src/test/java/com/baeldung/serialization/SerializationUnitTest.java new file mode 100644 index 0000000000..a8c4009386 --- /dev/null +++ b/core-java-modules/core-java/src/test/java/com/baeldung/serialization/SerializationUnitTest.java @@ -0,0 +1,111 @@ +package com.baeldung.serialization; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.NotSerializableException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; + +import org.apache.commons.lang3.SerializationUtils; +import org.junit.Test; + +import com.baeldung.util.MySerializationUtils; + +public class SerializationUnitTest { + + @Test(expected = NotSerializableException.class) + public void whenSerializing_ThenThrowsError() throws IOException { + Address address = new Address(); + address.setHouseNumber(10); + FileOutputStream fileOutputStream = new FileOutputStream("yofile.txt"); + try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream)) { + objectOutputStream.writeObject(address); + } + } + + @Test + public void whenSerializingAndDeserializing_ThenObjectIsTheSame() throws IOException, ClassNotFoundException { + Person p = new Person(); + p.setAge(20); + p.setName("Joe"); + + FileOutputStream fileOutputStream = new FileOutputStream("yofile.txt"); + try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream)) { + objectOutputStream.writeObject(p); + } + + FileInputStream fileInputStream = new FileInputStream("yofile.txt"); + try (ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream)) { + Person p2 = (Person) objectInputStream.readObject(); + assertEquals(p2.getAge(), p.getAge()); + assertEquals(p2.getName(), p.getName()); + } + } + + @Test(expected = ClassCastException.class) + public void whenSerializingUsingApacheCommons_ThenThrowsError() { + Address address = new Address(); + address.setHouseNumber(10); + SerializationUtils.serialize((Serializable) address); + } + + @Test + public void whenSerializingAndDeserializingUsingApacheCommons_ThenObjectIsTheSame() { + Person p = new Person(); + p.setAge(20); + p.setName("Joe"); + byte[] serialize = SerializationUtils.serialize(p); + Person p2 = (Person) SerializationUtils.deserialize(serialize); + assertEquals(p2.getAge(), p.getAge()); + assertEquals(p2.getName(), p.getName()); + } + + @Test(expected = ClassCastException.class) + public void whenSerializingUsingSpringSerializationUtils_ThenThrowsError() { + Address address = new Address(); + address.setHouseNumber(10); + org.springframework.util.SerializationUtils.serialize((Serializable) address); + } + + @Test + public void whenSerializingAndDeserializingUsingSpringSerializationUtils_ThenObjectIsTheSame() { + Person p = new Person(); + p.setAge(20); + p.setName("Joe"); + byte[] serialize = org.springframework.util.SerializationUtils.serialize(p); + Person p2 = (Person) org.springframework.util.SerializationUtils.deserialize(serialize); + assertEquals(p2.getAge(), p.getAge()); + assertEquals(p2.getName(), p.getName()); + } + + @Test(expected = ClassCastException.class) + public void whenSerializingUsingCustomSerializationUtils_ThenThrowsError() throws IOException { + Address address = new Address(); + address.setHouseNumber(10); + MySerializationUtils.serialize((Serializable) address); + } + + @Test + public void whenSerializingAndDeserializingUsingCustomSerializationUtils_ThenObjectIsTheSame() throws IOException, ClassNotFoundException { + Person p = new Person(); + p.setAge(20); + p.setName("Joe"); + byte[] serialize = MySerializationUtils.serialize(p); + Person p2 = MySerializationUtils.deserialize(serialize, Person.class); + assertEquals(p2.getAge(), p.getAge()); + assertEquals(p2.getName(), p.getName()); + } + + @Test + public void whenSerializingUsingCustomSerializationUtils_ThanOk() { + assertFalse(MySerializationUtils.isSerializable(Address.class)); + assertTrue(MySerializationUtils.isSerializable(Person.class)); + assertTrue(MySerializationUtils.isSerializable(Integer.class)); + } +} diff --git a/core-java-modules/pom.xml b/core-java-modules/pom.xml index 9f184310e9..c3d17e7637 100644 --- a/core-java-modules/pom.xml +++ b/core-java-modules/pom.xml @@ -99,6 +99,7 @@ core-java-reflection-2 core-java-security core-java-security-2 + core-java-security-3 core-java-streams core-java-streams-2 core-java-streams-3 @@ -134,8 +135,4 @@ - - 2.22.2 - - diff --git a/docker/docker-sample-app/Dockerfile b/docker/docker-sample-app/Dockerfile new file mode 100644 index 0000000000..71fc1a29d9 --- /dev/null +++ b/docker/docker-sample-app/Dockerfile @@ -0,0 +1,3 @@ +FROM openjdk:11 +COPY target/docker-sample-app-0.0.1.jar app.jar +ENTRYPOINT ["java","-jar","/app.jar"] diff --git a/docker/docker-sample-app/README.md b/docker/docker-sample-app/README.md new file mode 100644 index 0000000000..6aeaa1d2a3 --- /dev/null +++ b/docker/docker-sample-app/README.md @@ -0,0 +1,3 @@ +### Relevant Articles: + +- How to Get Docker-Compose to Always Use the Latest Image diff --git a/docker/docker-sample-app/docker-compose-build-image.yaml b/docker/docker-sample-app/docker-compose-build-image.yaml new file mode 100644 index 0000000000..27c1d8ee44 --- /dev/null +++ b/docker/docker-sample-app/docker-compose-build-image.yaml @@ -0,0 +1,8 @@ +version: '2.4' +services: + db: + image: postgres + my_app: + build: . + ports: + - "8080:8080" diff --git a/docker/docker-sample-app/docker-compose-with-image.yaml b/docker/docker-sample-app/docker-compose-with-image.yaml new file mode 100644 index 0000000000..9a8822f762 --- /dev/null +++ b/docker/docker-sample-app/docker-compose-with-image.yaml @@ -0,0 +1,9 @@ +version: '2.4' +services: + db: + image: postgres + my_app: + image: "eugen/test-app:latest" + ports: + - "8080:8080" + diff --git a/docker/docker-sample-app/pom.xml b/docker/docker-sample-app/pom.xml new file mode 100644 index 0000000000..6841fabcee --- /dev/null +++ b/docker/docker-sample-app/pom.xml @@ -0,0 +1,45 @@ + + + 4.0.0 + + com.baeldung.docker + docker + 0.0.1 + + + docker-sample-app + docker-sample-app + Demo project for Spring Boot and Docker + + + 11 + + + + + org.springframework.boot + spring-boot-starter + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/docker/docker-sample-app/src/main/java/com/baeldung/docker/app/DockAppApplication.java b/docker/docker-sample-app/src/main/java/com/baeldung/docker/app/DockAppApplication.java new file mode 100644 index 0000000000..e7ff52015c --- /dev/null +++ b/docker/docker-sample-app/src/main/java/com/baeldung/docker/app/DockAppApplication.java @@ -0,0 +1,13 @@ +package com.baeldung.docker.app; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class DockAppApplication { + + public static void main(String[] args) { + SpringApplication.run(DockAppApplication.class, args); + } + +} diff --git a/docker/docker-sample-app/src/main/java/com/baeldung/docker/app/endpoint/MyController.java b/docker/docker-sample-app/src/main/java/com/baeldung/docker/app/endpoint/MyController.java new file mode 100644 index 0000000000..d46c57e606 --- /dev/null +++ b/docker/docker-sample-app/src/main/java/com/baeldung/docker/app/endpoint/MyController.java @@ -0,0 +1,13 @@ +package com.baeldung.docker.app.endpoint; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class MyController { + + @GetMapping + public String version() { + return "1.7"; + } +} diff --git a/docker/docker-sample-app/src/main/resources/application.properties b/docker/docker-sample-app/src/main/resources/application.properties new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/docker/docker-sample-app/src/main/resources/application.properties @@ -0,0 +1 @@ + diff --git a/docker/docker-sample-app/src/test/java/com/baeldung/docker/app/DockAppApplicationUnitTest.java b/docker/docker-sample-app/src/test/java/com/baeldung/docker/app/DockAppApplicationUnitTest.java new file mode 100644 index 0000000000..7220766988 --- /dev/null +++ b/docker/docker-sample-app/src/test/java/com/baeldung/docker/app/DockAppApplicationUnitTest.java @@ -0,0 +1,13 @@ +package com.baeldung.docker.app; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class DockAppApplicationUnitTest { + + @Test + void contextLoads() { + } + +} diff --git a/docker/pom.xml b/docker/pom.xml index 3fcc9ca94f..f481f1b8b7 100644 --- a/docker/pom.xml +++ b/docker/pom.xml @@ -25,6 +25,7 @@ docker-internal-dto docker-spring-boot + docker-sample-app diff --git a/ethereum/pom.xml b/ethereum/pom.xml index 7fc4057341..95dd1c0955 100644 --- a/ethereum/pom.xml +++ b/ethereum/pom.xml @@ -144,18 +144,6 @@ test - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - - - org.hamcrest - hamcrest-core - - - org.hamcrest hamcrest diff --git a/google-web-toolkit/pom.xml b/google-web-toolkit/pom.xml index 1a49ced021..bcccc136a4 100644 --- a/google-web-toolkit/pom.xml +++ b/google-web-toolkit/pom.xml @@ -44,12 +44,6 @@ gwt-dev provided - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - diff --git a/grpc/pom.xml b/grpc/pom.xml index f034b2b517..6f0c3b5c91 100644 --- a/grpc/pom.xml +++ b/grpc/pom.xml @@ -37,12 +37,6 @@ ${io.grpc.version} test - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - javax.annotation javax.annotation-api diff --git a/guava-modules/guava-collections-list/pom.xml b/guava-modules/guava-collections-list/pom.xml index b90f70764f..30d684d673 100644 --- a/guava-modules/guava-collections-list/pom.xml +++ b/guava-modules/guava-collections-list/pom.xml @@ -26,18 +26,6 @@ ${commons-lang3.version} - - org.junit.jupiter - junit-jupiter - ${junit-jupiter.version} - test - - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - org.assertj assertj-core diff --git a/guava-modules/guava-collections-map/pom.xml b/guava-modules/guava-collections-map/pom.xml index e34d1a33a6..04beaa13a1 100644 --- a/guava-modules/guava-collections-map/pom.xml +++ b/guava-modules/guava-collections-map/pom.xml @@ -14,21 +14,6 @@ 0.0.1-SNAPSHOT - - - org.junit.jupiter - junit-jupiter - ${junit-jupiter.version} - test - - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - - - guava-collections-map diff --git a/guava-modules/guava-collections-set/pom.xml b/guava-modules/guava-collections-set/pom.xml index 1953ade44f..bd58645adc 100644 --- a/guava-modules/guava-collections-set/pom.xml +++ b/guava-modules/guava-collections-set/pom.xml @@ -15,18 +15,6 @@ - - org.junit.jupiter - junit-jupiter - ${junit-jupiter.version} - test - - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - org.assertj assertj-core diff --git a/guava-modules/guava-collections/pom.xml b/guava-modules/guava-collections/pom.xml index be75f93d29..91e3efcd8c 100644 --- a/guava-modules/guava-collections/pom.xml +++ b/guava-modules/guava-collections/pom.xml @@ -31,18 +31,6 @@ ${jool.version} - - org.junit.jupiter - junit-jupiter - ${junit-jupiter.version} - test - - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - org.assertj assertj-core diff --git a/guava-modules/guava-io/pom.xml b/guava-modules/guava-io/pom.xml index de1ab926dc..2ea91c5e4f 100644 --- a/guava-modules/guava-io/pom.xml +++ b/guava-modules/guava-io/pom.xml @@ -13,21 +13,6 @@ 0.0.1-SNAPSHOT - - - org.junit.jupiter - junit-jupiter - ${junit-jupiter.version} - test - - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - - - guava-io diff --git a/guava-modules/guava-utilities/pom.xml b/guava-modules/guava-utilities/pom.xml index deac03b406..debf014ac7 100644 --- a/guava-modules/guava-utilities/pom.xml +++ b/guava-modules/guava-utilities/pom.xml @@ -20,18 +20,6 @@ ${commons-lang3.version} - - org.junit.jupiter - junit-jupiter - ${junit-jupiter.version} - test - - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - org.assertj assertj-core diff --git a/guava-modules/pom.xml b/guava-modules/pom.xml index cbfb47fa0f..019776ad3d 100644 --- a/guava-modules/pom.xml +++ b/guava-modules/pom.xml @@ -34,22 +34,9 @@ guava ${guava.version} - - org.junit.jupiter - junit-jupiter - ${junit-jupiter.version} - test - - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - - 2.22.2 29.0-jre diff --git a/guest/junit5-example/pom.xml b/guest/junit5-example/pom.xml index a88f739891..cc52b0e3d7 100644 --- a/guest/junit5-example/pom.xml +++ b/guest/junit5-example/pom.xml @@ -40,15 +40,8 @@ + org.apache.maven.plugins maven-surefire-plugin - ${maven-surefire-plugin.version} - - - org.junit.platform - junit-platform-surefire-provider - ${junit-platform-surefire-provider.version} - - math diff --git a/jackson-modules/jackson-conversions-2/README.md b/jackson-modules/jackson-conversions-2/README.md index 9986fe75b5..bddbb60bd7 100644 --- a/jackson-modules/jackson-conversions-2/README.md +++ b/jackson-modules/jackson-conversions-2/README.md @@ -10,4 +10,5 @@ This module contains articles about Jackson conversions. - [How to Process YAML with Jackson](https://www.baeldung.com/jackson-yaml) - [Jackson Streaming API](https://www.baeldung.com/jackson-streaming-api) - [Jackson: java.util.LinkedHashMap cannot be cast to X](https://www.baeldung.com/jackson-linkedhashmap-cannot-be-cast) +- [Deserialize Snake Case to Camel Case With Jackson](https://www.baeldung.com/jackson-deserialize-snake-to-camel-case) - More articles: [[<-- prev]](../jackson-conversions) diff --git a/jackson-modules/jackson-conversions-2/src/main/java/com/baeldung/jackson/snakecase/User.java b/jackson-modules/jackson-conversions-2/src/main/java/com/baeldung/jackson/snakecase/User.java new file mode 100644 index 0000000000..17bf6f898b --- /dev/null +++ b/jackson-modules/jackson-conversions-2/src/main/java/com/baeldung/jackson/snakecase/User.java @@ -0,0 +1,22 @@ +package com.baeldung.jackson.snakecase; + +public class User { + private String firstName; + private String lastName; + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } +} diff --git a/jackson-modules/jackson-conversions-2/src/main/java/com/baeldung/jackson/snakecase/UserWithPropertyNames.java b/jackson-modules/jackson-conversions-2/src/main/java/com/baeldung/jackson/snakecase/UserWithPropertyNames.java new file mode 100644 index 0000000000..f9f36243ad --- /dev/null +++ b/jackson-modules/jackson-conversions-2/src/main/java/com/baeldung/jackson/snakecase/UserWithPropertyNames.java @@ -0,0 +1,26 @@ +package com.baeldung.jackson.snakecase; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class UserWithPropertyNames { + @JsonProperty("first_name") + private String firstName; + @JsonProperty("last_name") + private String lastName; + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } +} diff --git a/jackson-modules/jackson-conversions-2/src/main/java/com/baeldung/jackson/snakecase/UserWithSnakeStrategy.java b/jackson-modules/jackson-conversions-2/src/main/java/com/baeldung/jackson/snakecase/UserWithSnakeStrategy.java new file mode 100644 index 0000000000..ffec940ed8 --- /dev/null +++ b/jackson-modules/jackson-conversions-2/src/main/java/com/baeldung/jackson/snakecase/UserWithSnakeStrategy.java @@ -0,0 +1,26 @@ +package com.baeldung.jackson.snakecase; + +import com.fasterxml.jackson.databind.PropertyNamingStrategy; +import com.fasterxml.jackson.databind.annotation.JsonNaming; + +@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class) +public class UserWithSnakeStrategy { + private String firstName; + private String lastName; + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } +} diff --git a/jackson-modules/jackson-conversions-2/src/test/java/com/baeldung/jackson/snakecase/SnakeCaseUnitTest.java b/jackson-modules/jackson-conversions-2/src/test/java/com/baeldung/jackson/snakecase/SnakeCaseUnitTest.java new file mode 100644 index 0000000000..c72908ccce --- /dev/null +++ b/jackson-modules/jackson-conversions-2/src/test/java/com/baeldung/jackson/snakecase/SnakeCaseUnitTest.java @@ -0,0 +1,44 @@ +package com.baeldung.jackson.snakecase; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.PropertyNamingStrategy; +import com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class SnakeCaseUnitTest { + + private static final String JSON = "{\"first_name\": \"Jackie\", \"last_name\": \"Chan\"}"; + + @Test(expected = UnrecognizedPropertyException.class) + public void whenExceptionThrown_thenExpectationSatisfied() throws Exception { + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.readValue(JSON, User.class); + } + + @Test + public void givenSnakeCaseJson_whenParseWithJsonPropertyAnnotation_thenGetExpectedObject() throws Exception { + ObjectMapper objectMapper = new ObjectMapper(); + UserWithPropertyNames user = objectMapper.readValue(JSON, UserWithPropertyNames.class); + assertEquals("Jackie", user.getFirstName()); + assertEquals("Chan", user.getLastName()); + } + + @Test + public void givenSnakeCaseJson_whenParseWithJsonNamingAnnotation_thenGetExpectedObject() throws Exception { + ObjectMapper objectMapper = new ObjectMapper(); + UserWithSnakeStrategy user = objectMapper.readValue(JSON, UserWithSnakeStrategy.class); + assertEquals("Jackie", user.getFirstName()); + assertEquals("Chan", user.getLastName()); + } + + @Test + public void givenSnakeCaseJson_whenParseWithCustomMapper_thenGetExpectedObject() throws Exception { + ObjectMapper objectMapper = new ObjectMapper().setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE); + User user = objectMapper.readValue(JSON, User.class); + assertEquals("Jackie", user.getFirstName()); + assertEquals("Chan", user.getLastName()); + } + +} diff --git a/jackson-modules/pom.xml b/jackson-modules/pom.xml index 1bb684af0a..14e34a41bf 100644 --- a/jackson-modules/pom.xml +++ b/jackson-modules/pom.xml @@ -35,18 +35,6 @@ jackson-dataformat-xml ${jackson.version} - - org.junit.jupiter - junit-jupiter - ${junit-jupiter.version} - test - - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - \ No newline at end of file diff --git a/jackson-simple/pom.xml b/jackson-simple/pom.xml index 72e31ee5e3..ae8e380b33 100644 --- a/jackson-simple/pom.xml +++ b/jackson-simple/pom.xml @@ -22,18 +22,6 @@ ${jackson.version} - - org.junit.jupiter - junit-jupiter - ${junit-jupiter.version} - test - - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - org.assertj assertj-core diff --git a/java-collections-conversions-2/pom.xml b/java-collections-conversions-2/pom.xml index 55dc6e30b6..cd4366e87c 100644 --- a/java-collections-conversions-2/pom.xml +++ b/java-collections-conversions-2/pom.xml @@ -32,12 +32,6 @@ modelmapper ${modelmapper.version} - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - org.hamcrest hamcrest diff --git a/jhipster-5/bookstore-monolith/pom.xml b/jhipster-5/bookstore-monolith/pom.xml index 8403c2d1d4..411de0e712 100644 --- a/jhipster-5/bookstore-monolith/pom.xml +++ b/jhipster-5/bookstore-monolith/pom.xml @@ -1136,7 +1136,7 @@ 3.0.0-M2 2.2.1 3.1.0 - 2.22.1 + 2.22.2 3.2.2 0.9.11 1.6 diff --git a/jhipster/jhipster-uaa/gateway/pom.xml b/jhipster/jhipster-uaa/gateway/pom.xml index bc3c9bdef2..536b847237 100644 --- a/jhipster/jhipster-uaa/gateway/pom.xml +++ b/jhipster/jhipster-uaa/gateway/pom.xml @@ -1054,7 +1054,6 @@ 2.10 3.0.0-M2 3.1.0 - 2.22.0 3.2.2 0.9.11 1.6 diff --git a/jhipster/jhipster-uaa/quotes/pom.xml b/jhipster/jhipster-uaa/quotes/pom.xml index 7e4252b309..d922be10c2 100644 --- a/jhipster/jhipster-uaa/quotes/pom.xml +++ b/jhipster/jhipster-uaa/quotes/pom.xml @@ -874,7 +874,6 @@ 2.10 3.0.0-M2 3.1.0 - 2.22.0 3.2.2 0.9.11 0.8.2 diff --git a/jhipster/jhipster-uaa/uaa/pom.xml b/jhipster/jhipster-uaa/uaa/pom.xml index ec4dc1b484..a43da9c366 100644 --- a/jhipster/jhipster-uaa/uaa/pom.xml +++ b/jhipster/jhipster-uaa/uaa/pom.xml @@ -875,7 +875,6 @@ 2.10 3.0.0-M2 3.1.0 - 2.22.0 3.2.2 0.9.11 0.8.2 diff --git a/json-2/pom.xml b/json-2/pom.xml index 53d67320ba..b4301c41e5 100644 --- a/json-2/pom.xml +++ b/json-2/pom.xml @@ -24,12 +24,6 @@ jsoniter ${jsoniter.version} - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - org.assertj assertj-core diff --git a/junit5/README.md b/junit5/README.md new file mode 100644 index 0000000000..ad16ad164d --- /dev/null +++ b/junit5/README.md @@ -0,0 +1,6 @@ +## JUnit5 + +This module contains articles about the JUnit 5 + +### Relevant Articles: + diff --git a/junit5/pom.xml b/junit5/pom.xml new file mode 100644 index 0000000000..00b04ea292 --- /dev/null +++ b/junit5/pom.xml @@ -0,0 +1,21 @@ + + + + 4.0.0 + junit5 + junit5 + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + + + 8 + 8 + + + \ No newline at end of file diff --git a/junit5/src/test/java/com/baeldung/junit5/A_UnitTest.java b/junit5/src/test/java/com/baeldung/junit5/A_UnitTest.java new file mode 100644 index 0000000000..e4ba59b22d --- /dev/null +++ b/junit5/src/test/java/com/baeldung/junit5/A_UnitTest.java @@ -0,0 +1,21 @@ +package com.baeldung.junit5; + +import org.junit.jupiter.api.Test; + +public class A_UnitTest { + + @Test + public void first() throws Exception{ + System.out.println("Test A first() start => " + Thread.currentThread().getName()); + Thread.sleep(500); + System.out.println("Test A first() end => " + Thread.currentThread().getName()); + } + + @Test + public void second() throws Exception{ + System.out.println("Test A second() start => " + Thread.currentThread().getName()); + Thread.sleep(500); + System.out.println("Test A second() end => " + Thread.currentThread().getName()); + } + +} diff --git a/junit5/src/test/java/com/baeldung/junit5/B_UnitTest.java b/junit5/src/test/java/com/baeldung/junit5/B_UnitTest.java new file mode 100644 index 0000000000..2b195d2551 --- /dev/null +++ b/junit5/src/test/java/com/baeldung/junit5/B_UnitTest.java @@ -0,0 +1,23 @@ +package com.baeldung.junit5; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.parallel.Execution; +import org.junit.jupiter.api.parallel.ExecutionMode; + +public class B_UnitTest { + + @Test + public void first() throws Exception{ + System.out.println("Test B first() start => " + Thread.currentThread().getName()); + Thread.sleep(500); + System.out.println("Test B first() end => " + Thread.currentThread().getName()); + } + + @Test + public void second() throws Exception{ + System.out.println("Test B second() start => " + Thread.currentThread().getName()); + Thread.sleep(500); + System.out.println("Test B second() end => " + Thread.currentThread().getName()); + } + +} diff --git a/junit5/src/test/java/com/baeldung/junit5/C_UnitTest.java b/junit5/src/test/java/com/baeldung/junit5/C_UnitTest.java new file mode 100644 index 0000000000..ce545f6bee --- /dev/null +++ b/junit5/src/test/java/com/baeldung/junit5/C_UnitTest.java @@ -0,0 +1,45 @@ +package com.baeldung.junit5; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.parallel.ResourceLock; + +import java.util.ArrayList; +import java.util.List; + +public class C_UnitTest { + + private List resources; + + @BeforeEach + void before() { + resources = new ArrayList<>(); + resources.add("test"); + } + + @AfterEach + void after() { + resources.clear(); + } + + @Test + @ResourceLock(value = "resources") + public void first() throws Exception { + System.out.println("Test C first() start => " + Thread.currentThread().getName()); + resources.add("first"); + System.out.println(resources); + Thread.sleep(500); + System.out.println("Test C first() end => " + Thread.currentThread().getName()); + } + + @Test + @ResourceLock(value = "resources") + public void second() throws Exception { + System.out.println("Test C second() start => " + Thread.currentThread().getName()); + resources.add("second"); + System.out.println(resources); + Thread.sleep(500); + System.out.println("Test C second() end => " + Thread.currentThread().getName()); + } +} diff --git a/junit5/src/test/resources/junit-platform.properties b/junit5/src/test/resources/junit-platform.properties new file mode 100644 index 0000000000..42100f85da --- /dev/null +++ b/junit5/src/test/resources/junit-platform.properties @@ -0,0 +1,4 @@ +junit.jupiter.execution.parallel.enabled = true +junit.jupiter.execution.parallel.config.strategy=dynamic +junit.jupiter.execution.parallel.mode.default = concurrent +junit.jupiter.execution.parallel.mode.classes.default = concurrent diff --git a/libraries-data/pom.xml b/libraries-data/pom.xml index 3db34709e7..dd48453a8c 100644 --- a/libraries-data/pom.xml +++ b/libraries-data/pom.xml @@ -14,12 +14,6 @@ - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - org.apache.kafka kafka-streams @@ -92,6 +86,10 @@ commons-codec commons-codec + + junit + junit + @@ -104,6 +102,12 @@ flink-test-utils_2.11 ${flink.version} test + + + junit + junit + + org.slf4j diff --git a/libraries-security/pom.xml b/libraries-security/pom.xml index 001ecc54a0..6d3bbcd26c 100644 --- a/libraries-security/pom.xml +++ b/libraries-security/pom.xml @@ -48,11 +48,6 @@ bcpkix-jdk15on ${bouncycastle.version} - - org.junit.vintage - junit-vintage-engine - test - org.passay passay diff --git a/libraries-server/pom.xml b/libraries-server/pom.xml index a9c340b319..954f666785 100644 --- a/libraries-server/pom.xml +++ b/libraries-server/pom.xml @@ -61,12 +61,6 @@ netty-all ${netty.version} - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - org.apache.tomcat diff --git a/libraries/pom.xml b/libraries/pom.xml index 4ecf82aa87..b2e429ff65 100644 --- a/libraries/pom.xml +++ b/libraries/pom.xml @@ -146,12 +146,6 @@ jmh-core ${jmh-core.version} - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - info.debatty java-lsh diff --git a/maven-modules/maven-integration-test/pom.xml b/maven-modules/maven-integration-test/pom.xml index 4283baf63b..01be0ad1a4 100644 --- a/maven-modules/maven-integration-test/pom.xml +++ b/maven-modules/maven-integration-test/pom.xml @@ -26,12 +26,6 @@ jersey-hk2 ${jersey.version} - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - diff --git a/maven-modules/maven-properties/pom.xml b/maven-modules/maven-properties/pom.xml index b3169a7fb0..88e13a0fb8 100644 --- a/maven-modules/maven-properties/pom.xml +++ b/maven-modules/maven-properties/pom.xml @@ -14,15 +14,6 @@ ../.. - - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - - - diff --git a/micronaut/pom.xml b/micronaut/pom.xml index f36f565a94..019bd6ab29 100644 --- a/micronaut/pom.xml +++ b/micronaut/pom.xml @@ -64,12 +64,6 @@ ${logback.version} runtime - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - io.projectreactor reactor-core diff --git a/parent-boot-2/pom.xml b/parent-boot-2/pom.xml index 8e8dbba54d..42081fa115 100644 --- a/parent-boot-2/pom.xml +++ b/parent-boot-2/pom.xml @@ -58,11 +58,6 @@ - - org.apache.maven.plugins - maven-surefire-plugin - ${maven-surefire-plugin.version} - @@ -97,7 +92,6 @@ 1.9.1 3.4.0 - 2.22.2 \ No newline at end of file diff --git a/parent-java/pom.xml b/parent-java/pom.xml index 103b5f179c..4e5081393c 100644 --- a/parent-java/pom.xml +++ b/parent-java/pom.xml @@ -1,7 +1,7 @@ + xmlns="http://maven.apache.org/POM/4.0.0" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 parent-java 0.0.1-SNAPSHOT diff --git a/parent-spring-4/pom.xml b/parent-spring-4/pom.xml index e0e91cec9a..a36e1060ed 100644 --- a/parent-spring-4/pom.xml +++ b/parent-spring-4/pom.xml @@ -21,12 +21,6 @@ spring-core ${spring.version} - - org.junit.jupiter - junit-jupiter-engine - ${junit-jupiter.version} - test - diff --git a/parent-spring-5/pom.xml b/parent-spring-5/pom.xml index c4446ddda8..1263a56e2b 100644 --- a/parent-spring-5/pom.xml +++ b/parent-spring-5/pom.xml @@ -21,12 +21,6 @@ spring-core ${spring.version} - - org.junit.jupiter - junit-jupiter-engine - ${junit-jupiter.version} - test - diff --git a/patterns/clean-architecture/pom.xml b/patterns/clean-architecture/pom.xml index 71f50907fd..7b244e4a5e 100644 --- a/patterns/clean-architecture/pom.xml +++ b/patterns/clean-architecture/pom.xml @@ -29,11 +29,6 @@ org.springframework.boot spring-boot-starter-data-jpa - - org.junit.jupiter - junit-jupiter-engine - test - org.springframework.boot spring-boot-starter-test @@ -54,14 +49,6 @@ org.junit.platform junit-platform-engine - - org.junit.jupiter - junit-jupiter-engine - - - org.junit.jupiter - junit-jupiter-api - org.junit.platform junit-platform-runner diff --git a/persistence-modules/apache-derby/README.md b/persistence-modules/apache-derby/README.md new file mode 100644 index 0000000000..502115da5e --- /dev/null +++ b/persistence-modules/apache-derby/README.md @@ -0,0 +1,3 @@ +### Relevant Articles: + +- [Getting Started With Apache Derby](https://www.baeldung.com/java-apache-derby) diff --git a/persistence-modules/java-jpa-3/pom.xml b/persistence-modules/java-jpa-3/pom.xml index ec507c4fca..0eb4b8075d 100644 --- a/persistence-modules/java-jpa-3/pom.xml +++ b/persistence-modules/java-jpa-3/pom.xml @@ -69,9 +69,9 @@ test - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} + org.testcontainers + postgresql + 1.16.0 test diff --git a/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/postgresql_schema/Product.java b/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/postgresql_schema/Product.java new file mode 100644 index 0000000000..cf74e8bb6d --- /dev/null +++ b/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/postgresql_schema/Product.java @@ -0,0 +1,30 @@ +package com.baeldung.jpa.postgresql_schema; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "product", schema = "store") +public class Product { + + @Id + private int id; + private String 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; + } +} diff --git a/persistence-modules/java-jpa-3/src/main/resources/META-INF/persistence.xml b/persistence-modules/java-jpa-3/src/main/resources/META-INF/persistence.xml index 1166aaca71..ef1c4fb3d3 100644 --- a/persistence-modules/java-jpa-3/src/main/resources/META-INF/persistence.xml +++ b/persistence-modules/java-jpa-3/src/main/resources/META-INF/persistence.xml @@ -149,4 +149,15 @@ + + org.hibernate.jpa.HibernatePersistenceProvider + com.baeldung.jpa.postgresql_schema.Product + true + + + + + + + diff --git a/persistence-modules/java-jpa-3/src/test/java/com/baeldung/jpa/postgresql_schema/PostgresqlSchemaLiveTest.java b/persistence-modules/java-jpa-3/src/test/java/com/baeldung/jpa/postgresql_schema/PostgresqlSchemaLiveTest.java new file mode 100644 index 0000000000..e46ea2892c --- /dev/null +++ b/persistence-modules/java-jpa-3/src/test/java/com/baeldung/jpa/postgresql_schema/PostgresqlSchemaLiveTest.java @@ -0,0 +1,85 @@ +package com.baeldung.jpa.postgresql_schema; + +import org.junit.BeforeClass; +import org.junit.ClassRule; +import org.junit.Test; +import org.postgresql.ds.PGSimpleDataSource; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +public class PostgresqlSchemaLiveTest { + //This tests require running Docker application with working internet connection to fetch + //Postgres image if the image is not available locally. + + @ClassRule + public static PostgresqlTestContainer container = PostgresqlTestContainer.getInstance(); + + + @BeforeClass + public static void setup() throws Exception { + Properties properties = new Properties(); + properties.setProperty("user", container.getUsername()); + properties.setProperty("password", container.getPassword()); + Connection connection = DriverManager.getConnection(container.getJdbcUrl(), properties); + connection.createStatement().execute("CREATE SCHEMA store"); + connection.createStatement().execute("CREATE TABLE store.product(id SERIAL PRIMARY KEY, name VARCHAR(20))"); + connection.createStatement().execute("INSERT INTO store.product VALUES(1, 'test product')"); + } + + @Test + public void settingUpSchemaUsingJdbcURL() throws Exception { + Properties properties = new Properties(); + properties.setProperty("user", container.getUsername()); + properties.setProperty("password", container.getPassword()); + Connection connection = DriverManager.getConnection(container.getJdbcUrl().concat("¤tSchema=store"), properties); + + ResultSet resultSet = connection.createStatement().executeQuery("SELECT * FROM product"); + resultSet.next(); + + assertThat(resultSet.getInt(1), equalTo(1)); + assertThat(resultSet.getString(2), equalTo("test product")); + } + + @Test + public void settingUpSchemaUsingPGSimpleDataSource() throws Exception { + int port = Integer.parseInt(container.getJdbcUrl().substring(container.getJdbcUrl().lastIndexOf(":") + 1, container.getJdbcUrl().lastIndexOf("/"))); + PGSimpleDataSource ds = new PGSimpleDataSource(); + ds.setServerNames(new String[]{container.getHost()}); + ds.setPortNumbers(new int[]{port}); + ds.setUser(container.getUsername()); + ds.setPassword(container.getPassword()); + ds.setDatabaseName("test"); + ds.setCurrentSchema("store"); + + ResultSet resultSet = ds.getConnection().createStatement().executeQuery("SELECT * FROM product"); + resultSet.next(); + + assertThat(resultSet.getInt(1), equalTo(1)); + assertThat(resultSet.getString(2), equalTo("test product")); + } + + @Test + public void settingUpSchemaUsingTableAnnotation() { + Map props = new HashMap<>(); + props.put("hibernate.connection.url", container.getJdbcUrl()); + props.put("hibernate.connection.user", container.getUsername()); + props.put("hibernate.connection.password", container.getPassword()); + EntityManagerFactory emf = Persistence.createEntityManagerFactory("postgresql_schema_unit", props); + EntityManager entityManager = emf.createEntityManager(); + + Product product = entityManager.find(Product.class, 1); + + assertThat(product.getName(), equalTo("test product")); + } +} diff --git a/persistence-modules/java-jpa-3/src/test/java/com/baeldung/jpa/postgresql_schema/PostgresqlTestContainer.java b/persistence-modules/java-jpa-3/src/test/java/com/baeldung/jpa/postgresql_schema/PostgresqlTestContainer.java new file mode 100644 index 0000000000..edc84845c6 --- /dev/null +++ b/persistence-modules/java-jpa-3/src/test/java/com/baeldung/jpa/postgresql_schema/PostgresqlTestContainer.java @@ -0,0 +1,22 @@ +package com.baeldung.jpa.postgresql_schema; + +import org.testcontainers.containers.PostgreSQLContainer; + +public class PostgresqlTestContainer extends PostgreSQLContainer { + + private static final String IMAGE_VERSION = "postgres"; + + private static PostgresqlTestContainer container; + + + private PostgresqlTestContainer() { + super(IMAGE_VERSION); + } + + public static PostgresqlTestContainer getInstance() { + if (container == null) { + container = new PostgresqlTestContainer(); + } + return container; + } +} diff --git a/persistence-modules/pom.xml b/persistence-modules/pom.xml index c3df8866b1..4d42ff54cd 100644 --- a/persistence-modules/pom.xml +++ b/persistence-modules/pom.xml @@ -99,9 +99,6 @@ 5.2.17.Final 42.2.20 - - - 2.22.2 \ No newline at end of file diff --git a/persistence-modules/spring-boot-persistence/src/test/resources/dsrouting-db.sql b/persistence-modules/spring-boot-persistence/src/test/resources/dsrouting-db.sql index c9ca52907a..7449b23307 100644 --- a/persistence-modules/spring-boot-persistence/src/test/resources/dsrouting-db.sql +++ b/persistence-modules/spring-boot-persistence/src/test/resources/dsrouting-db.sql @@ -1,3 +1,5 @@ +drop table if exists client; + create table client ( id numeric, name varchar(50), diff --git a/persistence-modules/spring-data-redis/pom.xml b/persistence-modules/spring-data-redis/pom.xml index 5e17f27c06..330f0d975a 100644 --- a/persistence-modules/spring-data-redis/pom.xml +++ b/persistence-modules/spring-data-redis/pom.xml @@ -42,10 +42,6 @@ spring-boot-starter-test test - - org.junit.jupiter - junit-jupiter-api - org.junit.platform junit-platform-runner @@ -78,7 +74,6 @@ org.apache.maven.plugins maven-surefire-plugin - ${maven-surefire-plugin.version} true false diff --git a/persistence-modules/spring-jooq/pom.xml b/persistence-modules/spring-jooq/pom.xml index 4c195a6c92..c842922fe5 100644 --- a/persistence-modules/spring-jooq/pom.xml +++ b/persistence-modules/spring-jooq/pom.xml @@ -76,7 +76,6 @@ org.apache.maven.plugins maven-surefire-plugin - ${maven-surefire-plugin.version} 0 diff --git a/persistence-modules/spring-jpa/README.md b/persistence-modules/spring-jpa/README.md index e849ec4a83..202f5b0293 100644 --- a/persistence-modules/spring-jpa/README.md +++ b/persistence-modules/spring-jpa/README.md @@ -7,6 +7,7 @@ - [Self-Contained Testing Using an In-Memory Database](https://www.baeldung.com/spring-jpa-test-in-memory-database) - [Obtaining Auto-generated Keys in Spring JDBC](https://www.baeldung.com/spring-jdbc-autogenerated-keys) - [Spring Data Annotations](http://www.baeldung.com/spring-data-annotations) +- [A Guide to Spring AbstractRoutingDatasource](https://www.baeldung.com/spring-abstract-routing-data-source) - More articles: [[next -->]](/spring-jpa-2) ### Eclipse Config diff --git a/pom.xml b/pom.xml index 220e417869..01b55d48f9 100644 --- a/pom.xml +++ b/pom.xml @@ -113,11 +113,6 @@ - - org.junit.platform - junit-platform-surefire-provider - ${junit-platform-surefire-provider.version} - org.junit.jupiter junit-jupiter-engine @@ -472,6 +467,7 @@ json-path jsoup jta + junit5 kubernetes ksqldb @@ -1397,8 +1393,7 @@ 1.2.6 - - 2.21.0 + 2.22.2 3.8.1 3.0.0 1.8 diff --git a/restx/pom.xml b/restx/pom.xml index ea9f927563..57736f60cd 100644 --- a/restx/pom.xml +++ b/restx/pom.xml @@ -113,12 +113,6 @@ - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - diff --git a/spring-boot-modules/pom.xml b/spring-boot-modules/pom.xml index 9f179dd97f..0e4c2fe60b 100644 --- a/spring-boot-modules/pom.xml +++ b/spring-boot-modules/pom.xml @@ -46,7 +46,7 @@ spring-boot-groovy spring-boot-jasypt - spring-boot-keycloak + spring-boot-libraries spring-boot-libraries-2 spring-boot-logging-log4j2 @@ -95,19 +95,4 @@ - - - org.junit.jupiter - junit-jupiter - - - org.junit.vintage - junit-vintage-engine - - - - - 2.22.2 - - \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-actuator/src/main/java/com/baeldung/startup/ResourceInitializer.java b/spring-boot-modules/spring-boot-actuator/src/main/java/com/baeldung/startup/ResourceInitializer.java new file mode 100644 index 0000000000..e50816821c --- /dev/null +++ b/spring-boot-modules/spring-boot-actuator/src/main/java/com/baeldung/startup/ResourceInitializer.java @@ -0,0 +1,17 @@ +package com.baeldung.startup; + +import org.springframework.stereotype.Component; + +import java.util.concurrent.ThreadLocalRandom; +import java.util.concurrent.TimeUnit; + +@Component +public class ResourceInitializer { + + ResourceInitializer() throws Exception { + // simulate resource init with random delay of a few seconds + int randomDelay = ThreadLocalRandom.current().nextInt(5, 9); + TimeUnit.SECONDS.sleep(randomDelay); + } + +} diff --git a/spring-boot-modules/spring-boot-actuator/src/main/java/com/baeldung/startup/StartupTrackingApplication.java b/spring-boot-modules/spring-boot-actuator/src/main/java/com/baeldung/startup/StartupTrackingApplication.java new file mode 100644 index 0000000000..a3762cb98e --- /dev/null +++ b/spring-boot-modules/spring-boot-actuator/src/main/java/com/baeldung/startup/StartupTrackingApplication.java @@ -0,0 +1,38 @@ +package com.baeldung.startup; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; +import org.springframework.boot.context.metrics.buffering.BufferingApplicationStartup; + +import static java.lang.Boolean.FALSE; + +@SpringBootApplication(exclude = { + SecurityAutoConfiguration.class, + ManagementWebSecurityAutoConfiguration.class} +) +public class StartupTrackingApplication { + + public static void main(String[] args) { + // only load properties for this application + System.setProperty("spring.config.location", "classpath:application-startup.properties"); + + SpringApplication app = new SpringApplication(StartupTrackingApplication.class); + BufferingApplicationStartup startup = new BufferingApplicationStartup(2048); + + if (shouldFilterSteps()) { + startup.addFilter(startupStep -> startupStep.getName().matches("spring.beans.instantiate")); + } + + app.setApplicationStartup(startup); + app.run(args); + } + + private static boolean shouldFilterSteps() { + return Boolean.parseBoolean( + System.getProperty("startup.steps.filter", FALSE.toString()) + ); + } + +} diff --git a/spring-boot-modules/spring-boot-actuator/src/main/resources/application-startup.properties b/spring-boot-modules/spring-boot-actuator/src/main/resources/application-startup.properties new file mode 100644 index 0000000000..4cb5f2a94d --- /dev/null +++ b/spring-boot-modules/spring-boot-actuator/src/main/resources/application-startup.properties @@ -0,0 +1,6 @@ +management.endpoints.web.exposure.include=startup + +# JPA is not required for startup actuator endpoint +spring.autoconfigure.exclude= org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration, \ + org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration, \ + org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration diff --git a/spring-boot-modules/spring-boot-environment/pom.xml b/spring-boot-modules/spring-boot-environment/pom.xml index 504a0e2539..2cda396a9b 100644 --- a/spring-boot-modules/spring-boot-environment/pom.xml +++ b/spring-boot-modules/spring-boot-environment/pom.xml @@ -29,17 +29,6 @@ spring-boot-starter-test test - - org.junit.vintage - junit-vintage-engine - test - - - org.hamcrest - hamcrest-core - - - org.springframework.boot spring-boot-starter-data-jpa diff --git a/spring-boot-modules/spring-boot-flowable/pom.xml b/spring-boot-modules/spring-boot-flowable/pom.xml index 9d8daa022d..50500c3de6 100644 --- a/spring-boot-modules/spring-boot-flowable/pom.xml +++ b/spring-boot-modules/spring-boot-flowable/pom.xml @@ -39,11 +39,6 @@ spring-boot-starter-test test - - org.junit.jupiter - junit-jupiter-engine - test - diff --git a/spring-boot-modules/spring-boot-keycloak/.gitignore b/spring-boot-modules/spring-boot-keycloak/.gitignore deleted file mode 100644 index 2af7cefb0a..0000000000 --- a/spring-boot-modules/spring-boot-keycloak/.gitignore +++ /dev/null @@ -1,24 +0,0 @@ -target/ -!.mvn/wrapper/maven-wrapper.jar - -### STS ### -.apt_generated -.classpath -.factorypath -.project -.settings -.springBeans - -### IntelliJ IDEA ### -.idea -*.iws -*.iml -*.ipr - -### NetBeans ### -nbproject/private/ -build/ -nbbuild/ -dist/ -nbdist/ -.nb-gradle/ \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-keycloak/.mvn/wrapper/maven-wrapper.jar b/spring-boot-modules/spring-boot-keycloak/.mvn/wrapper/maven-wrapper.jar deleted file mode 100644 index 9cc84ea9b4..0000000000 Binary files a/spring-boot-modules/spring-boot-keycloak/.mvn/wrapper/maven-wrapper.jar and /dev/null differ diff --git a/spring-boot-modules/spring-boot-keycloak/.mvn/wrapper/maven-wrapper.properties b/spring-boot-modules/spring-boot-keycloak/.mvn/wrapper/maven-wrapper.properties deleted file mode 100644 index 9dda3b659b..0000000000 --- a/spring-boot-modules/spring-boot-keycloak/.mvn/wrapper/maven-wrapper.properties +++ /dev/null @@ -1 +0,0 @@ -distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.2/apache-maven-3.5.2-bin.zip diff --git a/spring-boot-modules/spring-boot-keycloak/README.md b/spring-boot-modules/spring-boot-keycloak/README.md index 2aff4664a6..7a1323d10e 100644 --- a/spring-boot-modules/spring-boot-keycloak/README.md +++ b/spring-boot-modules/spring-boot-keycloak/README.md @@ -8,4 +8,4 @@ This module contains articles about Keycloak in Spring Boot projects. - [Customizing the Login Page for Keycloak](https://www.baeldung.com/keycloak-custom-login-page) - [Keycloak User Self-Registration](https://www.baeldung.com/keycloak-user-registration) - [Customizing Themes for Keycloak](https://www.baeldung.com/spring-keycloak-custom-themes) - +- [Securing SOAP Web Services With Keycloak](https://www.baeldung.com/soap-keycloak) diff --git a/spring-boot-modules/spring-boot-keycloak/mvnw b/spring-boot-modules/spring-boot-keycloak/mvnw deleted file mode 100755 index 5bf251c077..0000000000 --- a/spring-boot-modules/spring-boot-keycloak/mvnw +++ /dev/null @@ -1,225 +0,0 @@ -#!/bin/sh -# ---------------------------------------------------------------------------- -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# ---------------------------------------------------------------------------- - -# ---------------------------------------------------------------------------- -# Maven2 Start Up Batch script -# -# Required ENV vars: -# ------------------ -# JAVA_HOME - location of a JDK home dir -# -# Optional ENV vars -# ----------------- -# M2_HOME - location of maven2's installed home dir -# MAVEN_OPTS - parameters passed to the Java VM when running Maven -# e.g. to debug Maven itself, use -# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -# MAVEN_SKIP_RC - flag to disable loading of mavenrc files -# ---------------------------------------------------------------------------- - -if [ -z "$MAVEN_SKIP_RC" ] ; then - - if [ -f /etc/mavenrc ] ; then - . /etc/mavenrc - fi - - if [ -f "$HOME/.mavenrc" ] ; then - . "$HOME/.mavenrc" - fi - -fi - -# OS specific support. $var _must_ be set to either true or false. -cygwin=false; -darwin=false; -mingw=false -case "`uname`" in - CYGWIN*) cygwin=true ;; - MINGW*) mingw=true;; - Darwin*) darwin=true - # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home - # See https://developer.apple.com/library/mac/qa/qa1170/_index.html - if [ -z "$JAVA_HOME" ]; then - if [ -x "/usr/libexec/java_home" ]; then - export JAVA_HOME="`/usr/libexec/java_home`" - else - export JAVA_HOME="/Library/Java/Home" - fi - fi - ;; -esac - -if [ -z "$JAVA_HOME" ] ; then - if [ -r /etc/gentoo-release ] ; then - JAVA_HOME=`java-config --jre-home` - fi -fi - -if [ -z "$M2_HOME" ] ; then - ## resolve links - $0 may be a link to maven's home - PRG="$0" - - # need this for relative symlinks - while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG="`dirname "$PRG"`/$link" - fi - done - - saveddir=`pwd` - - M2_HOME=`dirname "$PRG"`/.. - - # make it fully qualified - M2_HOME=`cd "$M2_HOME" && pwd` - - cd "$saveddir" - # echo Using m2 at $M2_HOME -fi - -# For Cygwin, ensure paths are in UNIX format before anything is touched -if $cygwin ; then - [ -n "$M2_HOME" ] && - M2_HOME=`cygpath --unix "$M2_HOME"` - [ -n "$JAVA_HOME" ] && - JAVA_HOME=`cygpath --unix "$JAVA_HOME"` - [ -n "$CLASSPATH" ] && - CLASSPATH=`cygpath --path --unix "$CLASSPATH"` -fi - -# For Migwn, ensure paths are in UNIX format before anything is touched -if $mingw ; then - [ -n "$M2_HOME" ] && - M2_HOME="`(cd "$M2_HOME"; pwd)`" - [ -n "$JAVA_HOME" ] && - JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" - # TODO classpath? -fi - -if [ -z "$JAVA_HOME" ]; then - javaExecutable="`which javac`" - if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then - # readlink(1) is not available as standard on Solaris 10. - readLink=`which readlink` - if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then - if $darwin ; then - javaHome="`dirname \"$javaExecutable\"`" - javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" - else - javaExecutable="`readlink -f \"$javaExecutable\"`" - fi - javaHome="`dirname \"$javaExecutable\"`" - javaHome=`expr "$javaHome" : '\(.*\)/bin'` - JAVA_HOME="$javaHome" - export JAVA_HOME - fi - fi -fi - -if [ -z "$JAVACMD" ] ; then - if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - else - JAVACMD="`which java`" - fi -fi - -if [ ! -x "$JAVACMD" ] ; then - echo "Error: JAVA_HOME is not defined correctly." >&2 - echo " We cannot execute $JAVACMD" >&2 - exit 1 -fi - -if [ -z "$JAVA_HOME" ] ; then - echo "Warning: JAVA_HOME environment variable is not set." -fi - -CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher - -# traverses directory structure from process work directory to filesystem root -# first directory with .mvn subdirectory is considered project base directory -find_maven_basedir() { - - if [ -z "$1" ] - then - echo "Path not specified to find_maven_basedir" - return 1 - fi - - basedir="$1" - wdir="$1" - while [ "$wdir" != '/' ] ; do - if [ -d "$wdir"/.mvn ] ; then - basedir=$wdir - break - fi - # workaround for JBEAP-8937 (on Solaris 10/Sparc) - if [ -d "${wdir}" ]; then - wdir=`cd "$wdir/.."; pwd` - fi - # end of workaround - done - echo "${basedir}" -} - -# concatenates all lines of a file -concat_lines() { - if [ -f "$1" ]; then - echo "$(tr -s '\n' ' ' < "$1")" - fi -} - -BASE_DIR=`find_maven_basedir "$(pwd)"` -if [ -z "$BASE_DIR" ]; then - exit 1; -fi - -export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} -echo $MAVEN_PROJECTBASEDIR -MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" - -# For Cygwin, switch paths to Windows format before running java -if $cygwin; then - [ -n "$M2_HOME" ] && - M2_HOME=`cygpath --path --windows "$M2_HOME"` - [ -n "$JAVA_HOME" ] && - JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` - [ -n "$CLASSPATH" ] && - CLASSPATH=`cygpath --path --windows "$CLASSPATH"` - [ -n "$MAVEN_PROJECTBASEDIR" ] && - MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` -fi - -WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain - -exec "$JAVACMD" \ - $MAVEN_OPTS \ - -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ - "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ - ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/spring-boot-modules/spring-boot-keycloak/mvnw.cmd b/spring-boot-modules/spring-boot-keycloak/mvnw.cmd deleted file mode 100644 index 019bd74d76..0000000000 --- a/spring-boot-modules/spring-boot-keycloak/mvnw.cmd +++ /dev/null @@ -1,143 +0,0 @@ -@REM ---------------------------------------------------------------------------- -@REM Licensed to the Apache Software Foundation (ASF) under one -@REM or more contributor license agreements. See the NOTICE file -@REM distributed with this work for additional information -@REM regarding copyright ownership. The ASF licenses this file -@REM to you under the Apache License, Version 2.0 (the -@REM "License"); you may not use this file except in compliance -@REM with the License. You may obtain a copy of the License at -@REM -@REM http://www.apache.org/licenses/LICENSE-2.0 -@REM -@REM Unless required by applicable law or agreed to in writing, -@REM software distributed under the License is distributed on an -@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -@REM KIND, either express or implied. See the License for the -@REM specific language governing permissions and limitations -@REM under the License. -@REM ---------------------------------------------------------------------------- - -@REM ---------------------------------------------------------------------------- -@REM Maven2 Start Up Batch script -@REM -@REM Required ENV vars: -@REM JAVA_HOME - location of a JDK home dir -@REM -@REM Optional ENV vars -@REM M2_HOME - location of maven2's installed home dir -@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands -@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending -@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven -@REM e.g. to debug Maven itself, use -@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files -@REM ---------------------------------------------------------------------------- - -@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' -@echo off -@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' -@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% - -@REM set %HOME% to equivalent of $HOME -if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") - -@REM Execute a user defined script before this one -if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre -@REM check for pre script, once with legacy .bat ending and once with .cmd ending -if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" -if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" -:skipRcPre - -@setlocal - -set ERROR_CODE=0 - -@REM To isolate internal variables from possible post scripts, we use another setlocal -@setlocal - -@REM ==== START VALIDATION ==== -if not "%JAVA_HOME%" == "" goto OkJHome - -echo. -echo Error: JAVA_HOME not found in your environment. >&2 -echo Please set the JAVA_HOME variable in your environment to match the >&2 -echo location of your Java installation. >&2 -echo. -goto error - -:OkJHome -if exist "%JAVA_HOME%\bin\java.exe" goto init - -echo. -echo Error: JAVA_HOME is set to an invalid directory. >&2 -echo JAVA_HOME = "%JAVA_HOME%" >&2 -echo Please set the JAVA_HOME variable in your environment to match the >&2 -echo location of your Java installation. >&2 -echo. -goto error - -@REM ==== END VALIDATION ==== - -:init - -@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". -@REM Fallback to current working directory if not found. - -set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% -IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir - -set EXEC_DIR=%CD% -set WDIR=%EXEC_DIR% -:findBaseDir -IF EXIST "%WDIR%"\.mvn goto baseDirFound -cd .. -IF "%WDIR%"=="%CD%" goto baseDirNotFound -set WDIR=%CD% -goto findBaseDir - -:baseDirFound -set MAVEN_PROJECTBASEDIR=%WDIR% -cd "%EXEC_DIR%" -goto endDetectBaseDir - -:baseDirNotFound -set MAVEN_PROJECTBASEDIR=%EXEC_DIR% -cd "%EXEC_DIR%" - -:endDetectBaseDir - -IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig - -@setlocal EnableExtensions EnableDelayedExpansion -for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a -@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% - -:endReadAdditionalConfig - -SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" - -set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" -set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain - -%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* -if ERRORLEVEL 1 goto error -goto end - -:error -set ERROR_CODE=1 - -:end -@endlocal & set ERROR_CODE=%ERROR_CODE% - -if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost -@REM check for post script, once with legacy .bat ending and once with .cmd ending -if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" -if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" -:skipRcPost - -@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' -if "%MAVEN_BATCH_PAUSE%" == "on" pause - -if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% - -exit /B %ERROR_CODE% diff --git a/spring-boot-modules/spring-boot-keycloak/pom.xml b/spring-boot-modules/spring-boot-keycloak/pom.xml index b80dbfa191..adad6bb2d2 100644 --- a/spring-boot-modules/spring-boot-keycloak/pom.xml +++ b/spring-boot-modules/spring-boot-keycloak/pom.xml @@ -64,6 +64,28 @@ org.springframework.boot spring-boot-starter-thymeleaf + + wsdl4j + wsdl4j + 1.6.3 + + + org.springframework.boot + spring-boot-starter-web-services + + + + org.springframework.security + spring-security-test + test + + + org.assertj + assertj-core + 3.21.0 + test + + @@ -72,11 +94,31 @@ org.springframework.boot spring-boot-maven-plugin + + org.codehaus.mojo + jaxb2-maven-plugin + 2.5.0 + + + xjc + + xjc + + + + + com.baeldung + + src/main/resources/products.xsd + + + + - 13.0.1 + 15.0.2 \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloaksoap/KeycloakSecurityConfig.java b/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloaksoap/KeycloakSecurityConfig.java new file mode 100644 index 0000000000..66a17f4967 --- /dev/null +++ b/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloaksoap/KeycloakSecurityConfig.java @@ -0,0 +1,54 @@ +package com.baeldung.keycloaksoap; + +import org.keycloak.adapters.KeycloakConfigResolver; +import org.keycloak.adapters.springboot.KeycloakSpringBootConfigResolver; +import org.keycloak.adapters.springsecurity.KeycloakConfiguration; +import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationProvider; +import org.keycloak.adapters.springsecurity.config.KeycloakWebSecurityConfigurerAdapter; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.core.authority.mapping.SimpleAuthorityMapper; +import org.springframework.security.core.session.SessionRegistryImpl; +import org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy; +import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy; + +@KeycloakConfiguration +@ConditionalOnProperty(name = "keycloak.enabled", havingValue = "true") +@EnableGlobalMethodSecurity(jsr250Enabled = true) +public class KeycloakSecurityConfig extends KeycloakWebSecurityConfigurerAdapter { + @Override + protected void configure(HttpSecurity http) throws Exception { + super.configure(http); + //@formatter:off + http + .csrf() + .disable() + .authorizeRequests() + .anyRequest() + .permitAll(); + //@formatter:on + } + + @Autowired + public void configureGlobal(AuthenticationManagerBuilder auth) { + KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider(); + keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper()); + auth.authenticationProvider(keycloakAuthenticationProvider); + } + + @Bean + @Override + protected SessionAuthenticationStrategy sessionAuthenticationStrategy() { + return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl()); + } + + @Bean + public KeycloakConfigResolver keycloakSpringBootConfigResolver() { + return new KeycloakSpringBootConfigResolver(); + } + +} diff --git a/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloaksoap/KeycloakSoapServicesApplication.java b/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloaksoap/KeycloakSoapServicesApplication.java new file mode 100644 index 0000000000..4cf60a804a --- /dev/null +++ b/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloaksoap/KeycloakSoapServicesApplication.java @@ -0,0 +1,15 @@ +package com.baeldung.keycloaksoap; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class KeycloakSoapServicesApplication { + + public static void main(String[] args) { + SpringApplication application = new SpringApplication(KeycloakSoapServicesApplication.class); + application.setAdditionalProfiles("keycloak"); + application.run(args); + } + +} diff --git a/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloaksoap/ProductsEndpoint.java b/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloaksoap/ProductsEndpoint.java new file mode 100644 index 0000000000..58f7739af0 --- /dev/null +++ b/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloaksoap/ProductsEndpoint.java @@ -0,0 +1,42 @@ +package com.baeldung.keycloaksoap; + +import com.baeldung.DeleteProductRequest; +import com.baeldung.DeleteProductResponse; +import com.baeldung.GetProductDetailsRequest; +import com.baeldung.GetProductDetailsResponse; +import com.baeldung.Product; +import org.springframework.ws.server.endpoint.annotation.Endpoint; +import org.springframework.ws.server.endpoint.annotation.PayloadRoot; +import org.springframework.ws.server.endpoint.annotation.RequestPayload; +import org.springframework.ws.server.endpoint.annotation.ResponsePayload; + +import javax.annotation.security.RolesAllowed; +import java.util.Map; + +@Endpoint +public class ProductsEndpoint { + + private final Map productMap; + + public ProductsEndpoint(Map productMap) { + this.productMap = productMap; + } + + @RolesAllowed("user") + @PayloadRoot(namespace = "http://www.baeldung.com/springbootsoap/keycloak", localPart = "getProductDetailsRequest") + @ResponsePayload + public GetProductDetailsResponse getProductDetails(@RequestPayload GetProductDetailsRequest request) { + GetProductDetailsResponse response = new GetProductDetailsResponse(); + response.setProduct(productMap.get(request.getId())); + return response; + } + + @RolesAllowed("admin") + @PayloadRoot(namespace = "http://www.baeldung.com/springbootsoap/keycloak", localPart = "deleteProductRequest") + @ResponsePayload + public DeleteProductResponse deleteProduct(@RequestPayload DeleteProductRequest request) { + DeleteProductResponse response = new DeleteProductResponse(); + response.setMessage("Success! Deleted the product with the id - "+request.getId()); + return response; + } +} diff --git a/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloaksoap/WebServiceConfig.java b/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloaksoap/WebServiceConfig.java new file mode 100644 index 0000000000..00d128fa12 --- /dev/null +++ b/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloaksoap/WebServiceConfig.java @@ -0,0 +1,75 @@ +package com.baeldung.keycloaksoap; + +import com.baeldung.Product; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.web.servlet.ServletRegistrationBean; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.ClassPathResource; +import org.springframework.ws.config.annotation.EnableWs; +import org.springframework.ws.config.annotation.WsConfigurerAdapter; +import org.springframework.ws.transport.http.MessageDispatcherServlet; +import org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition; +import org.springframework.xml.xsd.SimpleXsdSchema; +import org.springframework.xml.xsd.XsdSchema; + +import java.util.HashMap; +import java.util.Map; + +@EnableWs +@Configuration +public class WebServiceConfig extends WsConfigurerAdapter { + + @Value("${ws.api.path:/ws/api/v1/*}") + private String webserviceApiPath; + @Value("${ws.port.type.name:ProductsPort}") + private String webservicePortTypeName; + @Value("${ws.target.namespace:http://www.baeldung.com/springbootsoap/keycloak}") + private String webserviceTargetNamespace; + @Value("${ws.location.uri:http://localhost:18080/ws/api/v1/}") + private String locationUri; + + @Bean + public ServletRegistrationBean messageDispatcherServlet(ApplicationContext applicationContext) { + MessageDispatcherServlet servlet = new MessageDispatcherServlet(); + servlet.setApplicationContext(applicationContext); + servlet.setTransformWsdlLocations(true); + return new ServletRegistrationBean<>(servlet, webserviceApiPath); + } + + @Bean(name = "products") + public DefaultWsdl11Definition defaultWsdl11Definition(XsdSchema productsSchema) { + DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition(); + wsdl11Definition.setPortTypeName(webservicePortTypeName); + wsdl11Definition.setTargetNamespace(webserviceTargetNamespace); + wsdl11Definition.setLocationUri(locationUri); + wsdl11Definition.setSchema(productsSchema); + return wsdl11Definition; + } + + @Bean + public XsdSchema productsSchema() { + return new SimpleXsdSchema(new ClassPathResource("products.xsd")); + } + + @Bean + public Map getProducts() + { + Map map = new HashMap<>(); + Product foldsack= new Product(); + foldsack.setId("1"); + foldsack.setName("Fjallraven - Foldsack No. 1 Backpack, Fits 15 Laptops"); + foldsack.setDescription("Your perfect pack for everyday use and walks in the forest. "); + + Product shirt= new Product(); + shirt.setId("2"); + shirt.setName("Mens Casual Premium Slim Fit T-Shirts"); + shirt.setDescription("Slim-fitting style, contrast raglan long sleeve, three-button henley placket."); + + map.put("1", foldsack); + map.put("2", shirt); + return map; + } + +} diff --git a/spring-boot-modules/spring-boot-keycloak/src/main/resources/application-keycloak.properties b/spring-boot-modules/spring-boot-keycloak/src/main/resources/application-keycloak.properties new file mode 100644 index 0000000000..0a28b7ac48 --- /dev/null +++ b/spring-boot-modules/spring-boot-keycloak/src/main/resources/application-keycloak.properties @@ -0,0 +1,17 @@ +server.port=18080 + +keycloak.enabled=true +keycloak.realm=baeldung-soap-services +keycloak.auth-server-url=http://localhost:8080/auth +keycloak.bearer-only=true +keycloak.credentials.secret=14da6f9e-261f-489a-9bf0-1441e4a9ddc4 +keycloak.ssl-required=external +keycloak.resource=baeldung-soap-services +keycloak.use-resource-role-mappings=true + + +# Custom properties begin here +ws.api.path=/ws/api/v1/* +ws.port.type.name=ProductsPort +ws.target.namespace=http://www.baeldung.com/springbootsoap/keycloak +ws.location.uri=http://localhost:18080/ws/api/v1/ \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-keycloak/src/main/resources/products.xsd b/spring-boot-modules/spring-boot-keycloak/src/main/resources/products.xsd new file mode 100644 index 0000000000..b147118e96 --- /dev/null +++ b/spring-boot-modules/spring-boot-keycloak/src/main/resources/products.xsd @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-keycloak/src/test/java/com/baeldung/keycloaksoap/KeycloakSoapIntegrationTest.java b/spring-boot-modules/spring-boot-keycloak/src/test/java/com/baeldung/keycloaksoap/KeycloakSoapIntegrationTest.java new file mode 100644 index 0000000000..e0de897044 --- /dev/null +++ b/spring-boot-modules/spring-boot-keycloak/src/test/java/com/baeldung/keycloaksoap/KeycloakSoapIntegrationTest.java @@ -0,0 +1,153 @@ +package com.baeldung.keycloaksoap; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; + +import java.util.Objects; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * The class contains Live/Integration tests. + * These tests expect that the Keycloak server is up and running on port 8080. + * The tests may fail without a Keycloak server. + */ +@DisplayName("Keycloak SOAP Webservice Unit Tests") +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@ActiveProfiles("test") +@AutoConfigureMockMvc +class KeycloakSoapIntegrationTest { + + private static final Logger logger = LoggerFactory.getLogger(KeycloakSoapIntegrationTest.class); + @LocalServerPort + private int port; + @Autowired + private TestRestTemplate restTemplate; + @Autowired + private ObjectMapper objectMapper; + @Value("${grant.type}") + private String grantType; + @Value("${client.id}") + private String clientId; + @Value("${client.secret}") + private String clientSecret; + @Value("${url}") + private String keycloakUrl; + + /** + * Test a happy flow. Test the janedoe user. + * This user should be configured in Keycloak server with a role user + */ + @Test + @DisplayName("Get Products With Access Token") + void givenAccessToken_whenGetProducts_thenReturnProduct() { + + HttpHeaders headers = new HttpHeaders(); + headers.set("content-type", "text/xml"); + headers.set("Authorization", "Bearer " + generateToken("janedoe", "password")); + HttpEntity request = new HttpEntity<>(Utility.getGetProductDetailsRequest(), headers); + ResponseEntity responseEntity = restTemplate.postForEntity("http://localhost:" + port + "/ws/api/v1/", request, String.class); + + assertThat(responseEntity).isNotNull(); + assertThat(responseEntity.getStatusCodeValue()).isEqualTo(HttpStatus.OK.value()); + assertThat(responseEntity.getBody()).isNotBlank(); + assertThat(responseEntity.getBody()).containsIgnoringCase(":id>1janeadoe user. + * Keycloak returns Unauthorized. Assert 401 status and empty body. + */ + @Test + @DisplayName("Get Products With Wrong Access Token") + void givenWrongAccessToken_whenGetProducts_thenReturnError() { + + HttpHeaders headers = new HttpHeaders(); + headers.set("content-type", "text/xml"); + headers.set("Authorization", "Bearer " + generateToken("janeadoe", "password")); + HttpEntity request = new HttpEntity<>(Utility.getGetProductDetailsRequest(), headers); + ResponseEntity responseEntity = restTemplate.postForEntity("http://localhost:" + port + "/ws/api/v1/", request, String.class); + assertThat(responseEntity).isNotNull(); + assertThat(responseEntity.getStatusCodeValue()).isEqualTo(HttpStatus.UNAUTHORIZED.value()); + assertThat(responseEntity.getBody()).isBlank(); + } + + /** + * Happy flow to test deleteProduct operation. Test the jhondoe user. + * This user should be configured in Keycloak server with a role user + */ + @Test + @DisplayName("Delete Product With Access Token") + void givenAccessToken_whenDeleteProduct_thenReturnSuccess() { + HttpHeaders headers = new HttpHeaders(); + headers.set("content-type", "text/xml"); + headers.set("Authorization", "Bearer " + generateToken("jhondoe", "password")); + HttpEntity request = new HttpEntity<>(Utility.getDeleteProductsRequest(), headers); + ResponseEntity responseEntity = restTemplate.postForEntity("http://localhost:" + port + "/ws/api/v1/", request, String.class); + + assertThat(responseEntity).isNotNull(); + assertThat(responseEntity.getStatusCodeValue()).isEqualTo(HttpStatus.OK.value()); + assertThat(responseEntity.getBody()).isNotBlank(); + assertThat(responseEntity.getBody()).containsIgnoringCase("Deleted the product with the id"); + } + + /** + * Negative flow to test . Test the janedoe user. + * Obtain the access token of janedoe and access the admin operation deleteProduct + * Assume janedoe has restricted access to deleteProduct operation + */ + @Test + @DisplayName("Delete Products With Unauthorized Access Token") + void givenUnauthorizedAccessToken_whenDeleteProduct_thenReturnUnauthorized() { + HttpHeaders headers = new HttpHeaders(); + headers.set("content-type", "text/xml"); + headers.set("Authorization", "Bearer " + generateToken("janedoe", "password")); + HttpEntity request = new HttpEntity<>(Utility.getDeleteProductsRequest(), headers); + ResponseEntity responseEntity = restTemplate.postForEntity("http://localhost:" + port + "/ws/api/v1/", request, String.class); + + assertThat(responseEntity).isNotNull(); + assertThat(responseEntity.getStatusCodeValue()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR.value()); + assertThat(responseEntity.getBody()).isNotBlank(); + assertThat(responseEntity.getBody()).containsIgnoringCase("Access is denied"); + } + + private String generateToken(String username, String password) { + + try { + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); + MultiValueMap map = new LinkedMultiValueMap<>(); + map.add("grant_type", grantType); + map.add("client_id", clientId); + map.add("client_secret", clientSecret); + map.add("username", username); + map.add("password", password); + HttpEntity> entity = new HttpEntity<>(map, headers); + ResponseEntity response = restTemplate.exchange(keycloakUrl, HttpMethod.POST, entity, String.class); + return Objects.requireNonNull(response.getBody()).contains("access_token") ? objectMapper.readTree(response.getBody()).get("access_token").asText() : ""; + } catch (Exception ex) { + logger.error("There is an internal server error. Returning an empty access token", ex); + return ""; + } + + } + +} diff --git a/spring-boot-modules/spring-boot-keycloak/src/test/java/com/baeldung/keycloaksoap/Utility.java b/spring-boot-modules/spring-boot-keycloak/src/test/java/com/baeldung/keycloaksoap/Utility.java new file mode 100644 index 0000000000..1535d9f171 --- /dev/null +++ b/spring-boot-modules/spring-boot-keycloak/src/test/java/com/baeldung/keycloaksoap/Utility.java @@ -0,0 +1,12 @@ +package com.baeldung.keycloaksoap; + +public class Utility { + public static String getGetProductDetailsRequest() { + return "\n" + " \n" + " \n" + " \n" + + " 1\n" + " \n" + " \n" + ""; + } + public static String getDeleteProductsRequest() { + return "\n" + " \n" + " \n" + " \n" + + " 1\n" + " \n" + " \n" + ""; + } +} diff --git a/spring-boot-modules/spring-boot-keycloak/src/test/resources/application-test.properties b/spring-boot-modules/spring-boot-keycloak/src/test/resources/application-test.properties new file mode 100644 index 0000000000..a818b5be7a --- /dev/null +++ b/spring-boot-modules/spring-boot-keycloak/src/test/resources/application-test.properties @@ -0,0 +1,4 @@ +grant.type=password +client.id=baeldung-soap-services +client.secret=d2ba7af8-f7d2-4c97-b4a5-3c88b59920ae +url=http://localhost:8080/auth/realms/baeldung-soap-services/protocol/openid-connect/token diff --git a/spring-boot-modules/spring-boot-testing/pom.xml b/spring-boot-modules/spring-boot-testing/pom.xml index 2f33c44d60..658eb7728e 100644 --- a/spring-boot-modules/spring-boot-testing/pom.xml +++ b/spring-boot-modules/spring-boot-testing/pom.xml @@ -48,17 +48,6 @@ spring-boot-starter-test test - - org.junit.vintage - junit-vintage-engine - test - - - org.hamcrest - hamcrest-core - - - it.ozimov diff --git a/spring-boot-modules/spring-boot/pom.xml b/spring-boot-modules/spring-boot/pom.xml index 58c4e39043..49effa3700 100644 --- a/spring-boot-modules/spring-boot/pom.xml +++ b/spring-boot-modules/spring-boot/pom.xml @@ -53,17 +53,6 @@ spring-boot-starter-test test - - org.junit.vintage - junit-vintage-engine - test - - - org.hamcrest - hamcrest-core - - - io.dropwizard.metrics metrics-core diff --git a/spring-cloud/spring-cloud-config/client/pom.xml b/spring-cloud/spring-cloud-config/client/pom.xml index 55c6e77a72..0f463b6d6d 100644 --- a/spring-cloud/spring-cloud-config/client/pom.xml +++ b/spring-cloud/spring-cloud-config/client/pom.xml @@ -26,17 +26,6 @@ spring-boot-starter-test test - - org.junit.vintage - junit-vintage-engine - test - - - org.hamcrest - hamcrest-core - - - diff --git a/spring-cloud/spring-cloud-config/server/pom.xml b/spring-cloud/spring-cloud-config/server/pom.xml index 36d1b5b3aa..b41277113f 100644 --- a/spring-cloud/spring-cloud-config/server/pom.xml +++ b/spring-cloud/spring-cloud-config/server/pom.xml @@ -30,17 +30,6 @@ spring-boot-starter-test test - - org.junit.vintage - junit-vintage-engine - test - - - org.hamcrest - hamcrest-core - - - diff --git a/spring-cloud/spring-cloud-docker/docker-message-server/pom.xml b/spring-cloud/spring-cloud-docker/docker-message-server/pom.xml index 1c8c58c762..91cd587ff3 100644 --- a/spring-cloud/spring-cloud-docker/docker-message-server/pom.xml +++ b/spring-cloud/spring-cloud-docker/docker-message-server/pom.xml @@ -23,17 +23,6 @@ spring-boot-starter-test test - - org.junit.vintage - junit-vintage-engine - test - - - org.hamcrest - hamcrest-core - - - diff --git a/spring-cloud/spring-cloud-docker/docker-product-server/pom.xml b/spring-cloud/spring-cloud-docker/docker-product-server/pom.xml index cfea512399..ba4cf63ad8 100644 --- a/spring-cloud/spring-cloud-docker/docker-product-server/pom.xml +++ b/spring-cloud/spring-cloud-docker/docker-product-server/pom.xml @@ -23,17 +23,6 @@ spring-boot-starter-test test - - org.junit.vintage - junit-vintage-engine - test - - - org.hamcrest - hamcrest-core - - - diff --git a/spring-cloud/spring-cloud-ribbon-retry/pom.xml b/spring-cloud/spring-cloud-ribbon-retry/pom.xml index e0075b4f41..02fc103533 100644 --- a/spring-cloud/spring-cloud-ribbon-retry/pom.xml +++ b/spring-cloud/spring-cloud-ribbon-retry/pom.xml @@ -45,7 +45,6 @@ org.apache.maven.plugins maven-surefire-plugin - ${maven-surefire-plugin.version} 0 diff --git a/spring-core-3/pom.xml b/spring-core-3/pom.xml index 50d2e7ac5e..9e777a4a03 100644 --- a/spring-core-3/pom.xml +++ b/spring-core-3/pom.xml @@ -55,18 +55,6 @@ ${spring.version} test - - org.junit.jupiter - junit-jupiter-engine - ${junit-jupiter.version} - test - - - org.junit.jupiter - junit-jupiter-api - ${junit-jupiter.version} - test - diff --git a/spring-core-4/pom.xml b/spring-core-4/pom.xml index 5706b2ee75..f9665a672b 100644 --- a/spring-core-4/pom.xml +++ b/spring-core-4/pom.xml @@ -55,18 +55,6 @@ ${spring.version} test - - org.junit.jupiter - junit-jupiter-engine - ${junit-jupiter.version} - test - - - org.junit.jupiter - junit-jupiter-api - ${junit-jupiter.version} - test - org.awaitility awaitility diff --git a/spring-ejb/ejb-beans/pom.xml b/spring-ejb/ejb-beans/pom.xml index 10bc6d3104..6f20d949b0 100644 --- a/spring-ejb/ejb-beans/pom.xml +++ b/spring-ejb/ejb-beans/pom.xml @@ -80,12 +80,6 @@ arquillian-junit-container test - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - joda-time @@ -141,7 +135,6 @@ org.apache.maven.plugins maven-surefire-plugin - ${maven-surefire-plugin.version} always diff --git a/spring-jenkins-pipeline/pom.xml b/spring-jenkins-pipeline/pom.xml index 6f00dd5820..4e84bb8c70 100644 --- a/spring-jenkins-pipeline/pom.xml +++ b/spring-jenkins-pipeline/pom.xml @@ -62,6 +62,7 @@ + org.apache.maven.plugins maven-surefire-plugin diff --git a/spring-security-modules/spring-ldap/pom.xml b/spring-security-modules/spring-ldap/pom.xml index 44f754673f..086be2df5a 100644 --- a/spring-security-modules/spring-ldap/pom.xml +++ b/spring-security-modules/spring-ldap/pom.xml @@ -106,7 +106,6 @@ org.apache.maven.plugins maven-surefire-plugin - ${maven-surefire-plugin.version} integration-test diff --git a/spring-security-modules/spring-security-web-react/src/main/java/com/baeldung/spring/MvcConfig.java b/spring-security-modules/spring-security-web-react/src/main/java/com/baeldung/spring/MvcConfig.java index f8acdfe2ac..226459db75 100644 --- a/spring-security-modules/spring-security-web-react/src/main/java/com/baeldung/spring/MvcConfig.java +++ b/spring-security-modules/spring-security-web-react/src/main/java/com/baeldung/spring/MvcConfig.java @@ -1,18 +1,20 @@ package com.baeldung.spring; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.ViewResolver; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; 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 MvcConfig extends WebMvcConfigurerAdapter { +@ComponentScan(basePackages = { "com.baeldung.spring" }) +public class MvcConfig implements WebMvcConfigurer { public MvcConfig() { super(); @@ -22,8 +24,6 @@ public class MvcConfig extends WebMvcConfigurerAdapter { @Override public void addViewControllers(final ViewControllerRegistry registry) { - super.addViewControllers(registry); - registry.addViewController("/anonymous.html"); registry.addViewController("/login.html"); @@ -35,7 +35,7 @@ public class MvcConfig extends WebMvcConfigurerAdapter { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/static/**").addResourceLocations("/WEB-INF/view/react/build/static/"); - + registry.addResourceHandler("/*.js").addResourceLocations("/WEB-INF/view/react/build/"); registry.addResourceHandler("/*.json").addResourceLocations("/WEB-INF/view/react/build/"); registry.addResourceHandler("/*.ico").addResourceLocations("/WEB-INF/view/react/build/"); diff --git a/spring-security-modules/spring-security-web-react/src/main/java/com/baeldung/spring/RestController.java b/spring-security-modules/spring-security-web-react/src/main/java/com/baeldung/spring/RestController.java new file mode 100644 index 0000000000..4084df9698 --- /dev/null +++ b/spring-security-modules/spring-security-web-react/src/main/java/com/baeldung/spring/RestController.java @@ -0,0 +1,31 @@ +package com.baeldung.spring; +import javax.servlet.http.HttpServletRequest; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.ResponseEntity; +import org.springframework.security.web.csrf.CsrfToken; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; + +@Controller +@RequestMapping("/rest") +public class RestController { + + private static final Logger LOGGER = LoggerFactory.getLogger(RestController.class); + + @GetMapping + public ResponseEntity get(HttpServletRequest request) { + CsrfToken token = (CsrfToken) request.getAttribute("_csrf"); + LOGGER.info("{}={}", token.getHeaderName(), token.getToken()); + return ResponseEntity.ok().build(); + } + + @PostMapping + public ResponseEntity post(HttpServletRequest request) { + // Same impl as GET for testing purpose + return this.get(request); + } +} diff --git a/spring-security-modules/spring-security-web-react/src/main/java/com/baeldung/spring/SecSecurityConfig.java b/spring-security-modules/spring-security-web-react/src/main/java/com/baeldung/spring/SecSecurityConfig.java index 7b67028647..d560589cce 100644 --- a/spring-security-modules/spring-security-web-react/src/main/java/com/baeldung/spring/SecSecurityConfig.java +++ b/spring-security-modules/spring-security-web-react/src/main/java/com/baeldung/spring/SecSecurityConfig.java @@ -7,6 +7,7 @@ import org.springframework.security.config.annotation.authentication.builders.Au import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.web.csrf.CookieCsrfTokenRepository; @Configuration @EnableWebSecurity @@ -21,11 +22,11 @@ public class SecSecurityConfig extends WebSecurityConfigurerAdapter { protected void configure(final AuthenticationManagerBuilder auth) throws Exception { // @formatter:off auth.inMemoryAuthentication() - .withUser("user1").password("user1Pass").roles("USER") + .withUser("user1").password("{noop}user1Pass").roles("USER") .and() - .withUser("user2").password("user2Pass").roles("USER") + .withUser("user2").password("{noop}user2Pass").roles("USER") .and() - .withUser("admin").password("admin0Pass").roles("ADMIN"); + .withUser("admin").password("{noop}admin0Pass").roles("ADMIN"); // @formatter:on } @@ -33,11 +34,11 @@ public class SecSecurityConfig extends WebSecurityConfigurerAdapter { protected void configure(final HttpSecurity http) throws Exception { // @formatter:off http - .csrf().disable() + .csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()).and() .authorizeRequests() .antMatchers("/admin/**").hasRole("ADMIN") .antMatchers("/anonymous*").anonymous() - .antMatchers(HttpMethod.GET, "/index*", "/static/**", "/*.js", "/*.json", "/*.ico").permitAll() + .antMatchers(HttpMethod.GET, "/index*", "/static/**", "/*.js", "/*.json", "/*.ico", "/rest").permitAll() .anyRequest().authenticated() .and() .formLogin() diff --git a/spring-security-modules/spring-security-web-react/src/main/resources/logback.xml b/spring-security-modules/spring-security-web-react/src/main/resources/logback.xml index 25f3f36d1a..2cc702de59 100644 --- a/spring-security-modules/spring-security-web-react/src/main/resources/logback.xml +++ b/spring-security-modules/spring-security-web-react/src/main/resources/logback.xml @@ -12,7 +12,7 @@ - + diff --git a/spring-security-modules/spring-security-web-react/src/main/webapp/WEB-INF/view/homepage.jsp b/spring-security-modules/spring-security-web-react/src/main/webapp/WEB-INF/view/homepage.jsp index c9d88cbc9b..d64f80a5cb 100644 --- a/spring-security-modules/spring-security-web-react/src/main/webapp/WEB-INF/view/homepage.jsp +++ b/spring-security-modules/spring-security-web-react/src/main/webapp/WEB-INF/view/homepage.jsp @@ -1,11 +1,30 @@ <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <%@ taglib prefix="security" uri="http://www.springframework.org/security/tags" %> - + + +

This is the body of the sample view

+
+

CSRF Testing

+
+ CSRF Token: + + +
+
+
+   + +
+
+
Request Result:

+
+ +

Roles

This text is only visible to a user

@@ -22,5 +41,26 @@ ">Logout + \ No newline at end of file diff --git a/spring-security-modules/spring-security-web-react/src/main/webapp/WEB-INF/view/react/public/csrf.js b/spring-security-modules/spring-security-web-react/src/main/webapp/WEB-INF/view/react/public/csrf.js new file mode 100644 index 0000000000..657cc31f41 --- /dev/null +++ b/spring-security-modules/spring-security-web-react/src/main/webapp/WEB-INF/view/react/public/csrf.js @@ -0,0 +1,3 @@ +window.getCsrfToken = () => { + return document.cookie.replace(/(?:(?:^|.*;\s*)XSRF-TOKEN\s*\=\s*([^;]*).*$)|^.*$/, '$1'); +} diff --git a/spring-security-modules/spring-security-web-react/src/main/webapp/WEB-INF/view/react/public/index.html b/spring-security-modules/spring-security-web-react/src/main/webapp/WEB-INF/view/react/public/index.html index 0c3f78d7b3..6d4894da42 100644 --- a/spring-security-modules/spring-security-web-react/src/main/webapp/WEB-INF/view/react/public/index.html +++ b/spring-security-modules/spring-security-web-react/src/main/webapp/WEB-INF/view/react/public/index.html @@ -6,6 +6,7 @@ + - - org.junit.vintage - junit-vintage-engine - test - org.hamcrest hamcrest diff --git a/spring-web-modules/spring-resttemplate/pom.xml b/spring-web-modules/spring-resttemplate/pom.xml index 1379e40d23..3066a82242 100644 --- a/spring-web-modules/spring-resttemplate/pom.xml +++ b/spring-web-modules/spring-resttemplate/pom.xml @@ -108,11 +108,6 @@ ${com.squareup.okhttp3.version} - - - org.junit.vintage - junit-vintage-engine - org.hamcrest hamcrest diff --git a/tensorflow-java/pom.xml b/tensorflow-java/pom.xml index 2ac4d28a37..4dd86d45e3 100644 --- a/tensorflow-java/pom.xml +++ b/tensorflow-java/pom.xml @@ -21,18 +21,6 @@ tensorflow ${tensorflow.version} - - org.junit.jupiter - junit-jupiter-api - ${junit-jupiter.version} - test - - - org.junit.jupiter - junit-jupiter-engine - ${junit-jupiter.version} - test - diff --git a/testing-modules/assertion-libraries/pom.xml b/testing-modules/assertion-libraries/pom.xml index 57d38746ab..42dead6ee2 100644 --- a/testing-modules/assertion-libraries/pom.xml +++ b/testing-modules/assertion-libraries/pom.xml @@ -11,6 +11,7 @@ com.baeldung testing-modules 1.0.0-SNAPSHOT + ../ diff --git a/testing-modules/easy-random/pom.xml b/testing-modules/easy-random/pom.xml index 1ea6fbc387..f338519df3 100644 --- a/testing-modules/easy-random/pom.xml +++ b/testing-modules/easy-random/pom.xml @@ -8,9 +8,9 @@ com.baeldung - parent-modules + testing-modules 1.0.0-SNAPSHOT - ../../ + ../ diff --git a/testing-modules/easymock/pom.xml b/testing-modules/easymock/pom.xml index a8e37da8eb..fd7db5dbb1 100644 --- a/testing-modules/easymock/pom.xml +++ b/testing-modules/easymock/pom.xml @@ -11,6 +11,7 @@ com.baeldung testing-modules 1.0.0-SNAPSHOT + ../ diff --git a/testing-modules/gatling/pom.xml b/testing-modules/gatling/pom.xml index 281c74d6b3..c702b576c5 100644 --- a/testing-modules/gatling/pom.xml +++ b/testing-modules/gatling/pom.xml @@ -10,9 +10,9 @@ com.baeldung - parent-modules + testing-modules 1.0.0-SNAPSHOT - ../../ + ../ diff --git a/testing-modules/groovy-spock/pom.xml b/testing-modules/groovy-spock/pom.xml index 3c1f00abdf..65db332acb 100644 --- a/testing-modules/groovy-spock/pom.xml +++ b/testing-modules/groovy-spock/pom.xml @@ -11,9 +11,9 @@ com.baeldung - parent-modules + testing-modules 1.0.0-SNAPSHOT - ../../ + ../ diff --git a/testing-modules/junit-4/pom.xml b/testing-modules/junit-4/pom.xml index 0ae6b71f82..f58d1709d3 100644 --- a/testing-modules/junit-4/pom.xml +++ b/testing-modules/junit-4/pom.xml @@ -10,9 +10,9 @@ com.baeldung - parent-modules + testing-modules 1.0.0-SNAPSHOT - ../../ + ../ diff --git a/testing-modules/junit-5-advanced/pom.xml b/testing-modules/junit-5-advanced/pom.xml index 3f11c215ff..f37a41690b 100644 --- a/testing-modules/junit-5-advanced/pom.xml +++ b/testing-modules/junit-5-advanced/pom.xml @@ -10,29 +10,9 @@ com.baeldung - parent-modules + testing-modules 1.0.0-SNAPSHOT - ../../ + ../ - - - org.junit.jupiter - junit-jupiter - ${junit-jupiter.version} - test - - - org.junit.jupiter - junit-jupiter-engine - ${junit-jupiter.version} - - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - - - \ No newline at end of file diff --git a/testing-modules/junit-5-basics/pom.xml b/testing-modules/junit-5-basics/pom.xml index d92ee55682..62dc4321a8 100644 --- a/testing-modules/junit-5-basics/pom.xml +++ b/testing-modules/junit-5-basics/pom.xml @@ -10,9 +10,9 @@ com.baeldung - parent-modules + testing-modules 1.0.0-SNAPSHOT - ../../ + ../ @@ -22,36 +22,12 @@ ${junit-platform.version} test
- - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - org.junit.jupiter junit-jupiter-migrationsupport ${junit-jupiter.version} test - - org.junit.jupiter - junit-jupiter-engine - ${junit-jupiter.version} - test - - - org.junit.jupiter - junit-jupiter-params - ${junit-jupiter.version} - test - - - org.junit.jupiter - junit-jupiter-api - ${junit-jupiter.version} - test - com.h2database h2 @@ -97,8 +73,8 @@ + org.apache.maven.surefire maven-surefire-plugin - ${maven-surefire-plugin.version} **/*IntegrationTest.java @@ -116,8 +92,8 @@ + org.apache.maven.surefire maven-surefire-plugin - ${maven-surefire-plugin.version} com.baeldung.categories.UnitTest com.baeldung.categories.IntegrationTest @@ -134,8 +110,8 @@ + org.apache.maven.surefire maven-surefire-plugin - ${maven-surefire-plugin.version} UnitTest IntegrationTest diff --git a/testing-modules/junit-5/pom.xml b/testing-modules/junit-5/pom.xml index 148abecb0f..ef6e92faa4 100644 --- a/testing-modules/junit-5/pom.xml +++ b/testing-modules/junit-5/pom.xml @@ -11,9 +11,9 @@ com.baeldung - parent-modules + testing-modules 1.0.0-SNAPSHOT - ../../ + ../ @@ -22,16 +22,6 @@ junit-platform-engine ${junit-platform.version} - - org.junit.jupiter - junit-jupiter-engine - ${junit-jupiter.version} - - - org.junit.jupiter - junit-jupiter-api - ${junit-jupiter.version} - org.junit.platform junit-platform-runner @@ -45,13 +35,6 @@ ${junit-platform.version} test - - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - org.junit.jupiter junit-jupiter-migrationsupport @@ -140,7 +123,6 @@ 2.23.0 2.8.2 2.0.0 - 2.22.0 5.0.1.RELEASE 3.0.0-M3
diff --git a/testing-modules/junit5-annotations/pom.xml b/testing-modules/junit5-annotations/pom.xml index 79600eb589..86e71110c8 100644 --- a/testing-modules/junit5-annotations/pom.xml +++ b/testing-modules/junit5-annotations/pom.xml @@ -10,9 +10,9 @@ com.baeldung - parent-modules + testing-modules 1.0.0-SNAPSHOT - ../../ + ../ @@ -21,16 +21,6 @@ junit-platform-engine ${junit-platform.version} - - org.junit.jupiter - junit-jupiter-engine - ${junit-jupiter.version} - - - org.junit.jupiter - junit-jupiter-params - ${junit-jupiter.version} - org.junit.jupiter junit-jupiter-api diff --git a/testing-modules/junit5-migration/pom.xml b/testing-modules/junit5-migration/pom.xml index 07f11e2b3a..3e34c1dee5 100644 --- a/testing-modules/junit5-migration/pom.xml +++ b/testing-modules/junit5-migration/pom.xml @@ -10,9 +10,9 @@ com.baeldung - parent-modules + testing-modules 1.0.0-SNAPSHOT - ../../ + ../ @@ -27,12 +27,6 @@ ${junit-platform.version} test - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - org.junit.jupiter junit-jupiter-migrationsupport @@ -50,8 +44,4 @@
- - 2.21.0 - - \ No newline at end of file diff --git a/testing-modules/mockito-2/pom.xml b/testing-modules/mockito-2/pom.xml index 558ac59d08..cff7598edc 100644 --- a/testing-modules/mockito-2/pom.xml +++ b/testing-modules/mockito-2/pom.xml @@ -10,9 +10,9 @@ com.baeldung - parent-modules + testing-modules 1.0.0-SNAPSHOT - ../../ + ../ diff --git a/testing-modules/mockito-3/pom.xml b/testing-modules/mockito-3/pom.xml index 5a150ccbf9..5a79d81080 100644 --- a/testing-modules/mockito-3/pom.xml +++ b/testing-modules/mockito-3/pom.xml @@ -10,9 +10,9 @@ com.baeldung - parent-modules + testing-modules 1.0.0-SNAPSHOT - ../../ + ../ diff --git a/testing-modules/mocks/pom.xml b/testing-modules/mocks/pom.xml index 17700a835e..3fabde037c 100644 --- a/testing-modules/mocks/pom.xml +++ b/testing-modules/mocks/pom.xml @@ -8,9 +8,9 @@ com.baeldung - parent-modules + testing-modules 1.0.0-SNAPSHOT - ../../ + ../ diff --git a/testing-modules/mockserver/pom.xml b/testing-modules/mockserver/pom.xml index c039d6a0ab..3495ddb09d 100644 --- a/testing-modules/mockserver/pom.xml +++ b/testing-modules/mockserver/pom.xml @@ -9,9 +9,9 @@ com.baeldung - parent-modules + testing-modules 1.0.0-SNAPSHOT - ../../ + ../ diff --git a/testing-modules/parallel-tests-junit/math-test-functions/pom.xml b/testing-modules/parallel-tests-junit/math-test-functions/pom.xml index eae1bf61e7..7ead2051e2 100644 --- a/testing-modules/parallel-tests-junit/math-test-functions/pom.xml +++ b/testing-modules/parallel-tests-junit/math-test-functions/pom.xml @@ -13,21 +13,11 @@ 0.0.1-SNAPSHOT - - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - - - org.apache.maven.plugins maven-surefire-plugin - ${maven-surefire-plugin.version} all 10 @@ -45,8 +35,4 @@ - - 2.22.0 - - \ No newline at end of file diff --git a/testing-modules/parallel-tests-junit/string-test-functions/pom.xml b/testing-modules/parallel-tests-junit/string-test-functions/pom.xml index c838558fc2..86b4078eb3 100644 --- a/testing-modules/parallel-tests-junit/string-test-functions/pom.xml +++ b/testing-modules/parallel-tests-junit/string-test-functions/pom.xml @@ -13,21 +13,11 @@ 0.0.1-SNAPSHOT - - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - - - org.apache.maven.plugins maven-surefire-plugin - ${maven-surefire-plugin.version} all true @@ -37,8 +27,4 @@ - - 2.22.0 - - \ No newline at end of file diff --git a/testing-modules/powermock/pom.xml b/testing-modules/powermock/pom.xml index 7179f3ffbe..fad338bb9b 100644 --- a/testing-modules/powermock/pom.xml +++ b/testing-modules/powermock/pom.xml @@ -6,9 +6,10 @@ powermock - testing-modules com.baeldung + testing-modules 1.0.0-SNAPSHOT + ../ diff --git a/testing-modules/selenium-junit-testng/pom.xml b/testing-modules/selenium-junit-testng/pom.xml index ee4dcf8335..0bf6f0726d 100644 --- a/testing-modules/selenium-junit-testng/pom.xml +++ b/testing-modules/selenium-junit-testng/pom.xml @@ -9,9 +9,9 @@ com.baeldung - parent-modules + testing-modules 1.0.0-SNAPSHOT - ../../ + ../ @@ -31,12 +31,6 @@ testng ${testng.version} - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - org.hamcrest hamcrest-all diff --git a/testing-modules/spring-testing-2/pom.xml b/testing-modules/spring-testing-2/pom.xml index 419b8d512a..f3e4f098b4 100644 --- a/testing-modules/spring-testing-2/pom.xml +++ b/testing-modules/spring-testing-2/pom.xml @@ -55,7 +55,6 @@ org.apache.maven.plugins maven-surefire-plugin - ${maven-surefire-plugin.version} methods true diff --git a/testing-modules/spring-testing/pom.xml b/testing-modules/spring-testing/pom.xml index e687f8d6fd..08b56c9a1a 100644 --- a/testing-modules/spring-testing/pom.xml +++ b/testing-modules/spring-testing/pom.xml @@ -36,17 +36,6 @@ spring-boot-starter-test test - - org.junit.vintage - junit-vintage-engine - test - - - org.hamcrest - hamcrest-core - - - org.springframework spring-core @@ -71,28 +60,6 @@ org.springframework.data spring-data-jpa - - org.junit.jupiter - junit-jupiter - ${junit-jupiter.version} - test - - - org.junit.jupiter - junit-jupiter-engine - ${junit-jupiter.version} - - - org.junit.jupiter - junit-jupiter-api - ${junit-jupiter.version} - test - - - org.junit.platform - junit-platform-commons - ${junit-platform.version} - org.awaitility awaitility diff --git a/testing-modules/test-containers/pom.xml b/testing-modules/test-containers/pom.xml index 24f686d741..687bc418ad 100644 --- a/testing-modules/test-containers/pom.xml +++ b/testing-modules/test-containers/pom.xml @@ -11,9 +11,9 @@ com.baeldung - parent-modules + testing-modules 1.0.0-SNAPSHOT - ../../ + ../ @@ -23,18 +23,6 @@ ${junit-platform.version} test - - org.junit.platform - junit-platform-commons - ${junit-platform.version} - test - - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - org.apache.logging.log4j log4j-core @@ -87,7 +75,6 @@ 1.11.4 42.2.6 3.141.59 - 2.22.2 \ No newline at end of file diff --git a/testing-modules/testing-assertions/pom.xml b/testing-modules/testing-assertions/pom.xml index d5c5981b33..f9cd35c5e5 100644 --- a/testing-modules/testing-assertions/pom.xml +++ b/testing-modules/testing-assertions/pom.xml @@ -18,18 +18,6 @@ logback-classic ${logback.version} - - org.junit.jupiter - junit-jupiter-engine - ${junit-jupiter.version} - test - - - org.junit.jupiter - junit-jupiter-api - ${junit-jupiter.version} - test - org.assertj assertj-core diff --git a/testing-modules/testing-libraries-2/pom.xml b/testing-modules/testing-libraries-2/pom.xml index 82e4bbfdf0..2e8a1b4ed2 100644 --- a/testing-modules/testing-libraries-2/pom.xml +++ b/testing-modules/testing-libraries-2/pom.xml @@ -60,31 +60,6 @@ ${system-stubs.version} test - - - org.junit.jupiter - junit-jupiter - ${junit-jupiter.version} - test - - - org.junit.jupiter - junit-jupiter-engine - ${junit-jupiter.version} - test - - - org.junit.jupiter - junit-jupiter-params - ${junit-jupiter.version} - test - - - org.junit.jupiter - junit-jupiter-api - ${junit-jupiter.version} - test - diff --git a/testing-modules/testing-libraries/pom.xml b/testing-modules/testing-libraries/pom.xml index f9443fa792..8c0fca775b 100644 --- a/testing-modules/testing-libraries/pom.xml +++ b/testing-modules/testing-libraries/pom.xml @@ -10,6 +10,7 @@ com.baeldung testing-modules 1.0.0-SNAPSHOT + ../ diff --git a/testing-modules/testng/pom.xml b/testing-modules/testng/pom.xml index 8b6a46a694..99af6be5b4 100644 --- a/testing-modules/testng/pom.xml +++ b/testing-modules/testng/pom.xml @@ -10,9 +10,9 @@ com.baeldung - parent-modules + testing-modules 1.0.0-SNAPSHOT - ../../ + ../ diff --git a/testing-modules/xmlunit-2/pom.xml b/testing-modules/xmlunit-2/pom.xml index 07153ab042..a35d9c2b87 100644 --- a/testing-modules/xmlunit-2/pom.xml +++ b/testing-modules/xmlunit-2/pom.xml @@ -8,9 +8,9 @@ com.baeldung - parent-modules + testing-modules 1.0.0-SNAPSHOT - ../../ + ../ diff --git a/testing-modules/zerocode/pom.xml b/testing-modules/zerocode/pom.xml index 48030166b5..ea12385a26 100644 --- a/testing-modules/zerocode/pom.xml +++ b/testing-modules/zerocode/pom.xml @@ -7,9 +7,10 @@ 1.0-SNAPSHOT - testing-modules com.baeldung + testing-modules 1.0.0-SNAPSHOT + ../ diff --git a/xml/pom.xml b/xml/pom.xml index 6bae312452..f88f0f89b0 100644 --- a/xml/pom.xml +++ b/xml/pom.xml @@ -107,18 +107,6 @@ commons-lang ${commons-lang.version} - - org.junit.jupiter - junit-jupiter - ${junit-jupiter.version} - test - - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - org.assertj assertj-core