diff --git a/core-java-modules/core-java-8-2/README.md b/core-java-modules/core-java-8-2/README.md index 7f2245ccc0..12a060ccfe 100644 --- a/core-java-modules/core-java-8-2/README.md +++ b/core-java-modules/core-java-8-2/README.md @@ -8,4 +8,5 @@ This module contains articles about Java 8 core features - [Java 8 Stream skip() vs limit()](https://www.baeldung.com/java-stream-skip-vs-limit) - [Guide to Java BiFunction Interface](https://www.baeldung.com/java-bifunction-interface) - [Interface With Default Methods vs Abstract Class](https://www.baeldung.com/java-interface-default-method-vs-abstract-class) +- [Convert Between Byte Array and UUID in Java](https://www.baeldung.com/java-byte-array-to-uuid) - [[<-- Prev]](/core-java-modules/core-java-8) diff --git a/core-java-modules/core-java-8-2/src/main/java/com/baeldung/game/RockPaperScissorsGame.java b/core-java-modules/core-java-8-2/src/main/java/com/baeldung/game/RockPaperScissorsGame.java index fc9299f12d..17f0f02698 100644 --- a/core-java-modules/core-java-8-2/src/main/java/com/baeldung/game/RockPaperScissorsGame.java +++ b/core-java-modules/core-java-8-2/src/main/java/com/baeldung/game/RockPaperScissorsGame.java @@ -1,17 +1,24 @@ package com.baeldung.game; -import java.util.HashMap; -import java.util.Map; -import java.util.Random; -import java.util.Scanner; +import java.util.*; class RockPaperScissorsGame { - private static Map movesMap = new HashMap() {{ - put(0, "rock"); - put(1, "paper"); - put(2, "scissors"); - }}; + enum Move { + ROCK("rock"), + PAPER("paper"), + SCISSORS("scissors"); + + private String value; + + Move(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + } public static void main(String[] args) { Scanner scanner = new Scanner(System.in); @@ -31,7 +38,7 @@ class RockPaperScissorsGame { break; } - if (!movesMap.containsValue(playerMove)) { + if (Arrays.stream(Move.values()).noneMatch(x -> x.getValue().equals(playerMove))) { System.out.println("Your move isn't valid!"); continue; } @@ -51,15 +58,15 @@ class RockPaperScissorsGame { } private static boolean isPlayerWin(String playerMove, String computerMove) { - return playerMove.equals("rock") && computerMove.equals("scissors") - || (playerMove.equals("scissors") && computerMove.equals("paper")) - || (playerMove.equals("paper") && computerMove.equals("rock")); + return playerMove.equals(Move.ROCK.value) && computerMove.equals(Move.SCISSORS.value) + || (playerMove.equals(Move.SCISSORS.value) && computerMove.equals(Move.PAPER.value)) + || (playerMove.equals(Move.PAPER.value) && computerMove.equals(Move.ROCK.value)); } private static String getComputerMove() { Random random = new Random(); int randomNumber = random.nextInt(3); - String computerMove = movesMap.get(randomNumber); + String computerMove = Move.values()[randomNumber].getValue(); System.out.println("Computer move: " + computerMove); return computerMove; } diff --git a/core-java-modules/core-java-collections-4/README.md b/core-java-modules/core-java-collections-4/README.md index 0e14f407c4..cbca44d372 100644 --- a/core-java-modules/core-java-collections-4/README.md +++ b/core-java-modules/core-java-collections-4/README.md @@ -7,3 +7,4 @@ - [ArrayList vs. LinkedList vs. HashMap in Java](https://www.baeldung.com/java-arraylist-vs-linkedlist-vs-hashmap) - [Java Deque vs. Stack](https://www.baeldung.com/java-deque-vs-stack) - [Collection.toArray(new T[0]) or .toArray(new T[size])](https://www.baeldung.com/java-collection-toarray-methods) +- [Create an Empty Map in Java](https://www.baeldung.com/java-create-empty-map) diff --git a/core-java-modules/core-java-collections-4/src/main/java/com/baeldung/maps/initialize/EmptyMapInitializer.java b/core-java-modules/core-java-collections-4/src/main/java/com/baeldung/maps/initialize/EmptyMapInitializer.java new file mode 100644 index 0000000000..3dc644f1af --- /dev/null +++ b/core-java-modules/core-java-collections-4/src/main/java/com/baeldung/maps/initialize/EmptyMapInitializer.java @@ -0,0 +1,56 @@ +package com.baeldung.maps.initialize; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Maps; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.NavigableMap; +import java.util.SortedMap; +import java.util.TreeMap; + +public class EmptyMapInitializer { + + public static Map articleMap; + static { + articleMap = new HashMap<>(); + } + + public static Map createEmptyMap() { + return Collections.emptyMap(); + } + + public void createMapUsingConstructors() { + Map hashMap = new HashMap(); + Map linkedHashMap = new LinkedHashMap(); + Map treeMap = new TreeMap(); + } + + public Map createEmptyMapUsingMapsObject() { + Map emptyMap = Maps.newHashMap(); + return emptyMap; + } + + public Map createGenericEmptyMapUsingMapsObject() { + Map genericEmptyMap = Maps.newHashMap(); + return genericEmptyMap; + } + + public static Map createMapUsingGuava() { + Map emptyMapUsingGuava = + Maps.newHashMap(ImmutableMap.of()); + return emptyMapUsingGuava; + } + + public SortedMap createEmptySortedMap() { + SortedMap sortedMap = Collections.emptySortedMap(); + return sortedMap; + } + + public NavigableMap createEmptyNavigableMap() { + NavigableMap navigableMap = Collections.emptyNavigableMap(); + return navigableMap; + } + +} diff --git a/core-java-modules/core-java-collections-4/src/test/java/com/baeldung/maps/initialize/EmptyMapInitializerUnitTest.java b/core-java-modules/core-java-collections-4/src/test/java/com/baeldung/maps/initialize/EmptyMapInitializerUnitTest.java new file mode 100644 index 0000000000..cc25205ba7 --- /dev/null +++ b/core-java-modules/core-java-collections-4/src/test/java/com/baeldung/maps/initialize/EmptyMapInitializerUnitTest.java @@ -0,0 +1,31 @@ +package com.baeldung.maps.initialize; + +import java.util.Map; +import org.junit.Test; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class EmptyMapInitializerUnitTest { + + @Test(expected=UnsupportedOperationException.class) + public void givenEmptyMap_whenAddingEntries_throwsException() { + Map map = EmptyMapInitializer.createEmptyMap(); + map.put("key", "value"); + } + + @Test + public void givenEmptyMap_whenChecked_returnsTrue() { + assertTrue(EmptyMapInitializer.articleMap.isEmpty()); + } + + @Test + public void givenEmptyMap_whenCreatedUsingGuava_returnsEmptyOrNot() { + Map emptyMapUsingGuava = + EmptyMapInitializer.createMapUsingGuava(); + assertTrue(emptyMapUsingGuava.isEmpty()); + emptyMapUsingGuava.put("key", "value"); + assertFalse(emptyMapUsingGuava.isEmpty()); + } + +} diff --git a/core-java-modules/core-java-nio-2/src/test/java/com/baeldung/bytebuffer/ByteBufferUnitTest.java b/core-java-modules/core-java-nio-2/src/test/java/com/baeldung/bytebuffer/ByteBufferUnitTest.java new file mode 100644 index 0000000000..5d108ba14a --- /dev/null +++ b/core-java-modules/core-java-nio-2/src/test/java/com/baeldung/bytebuffer/ByteBufferUnitTest.java @@ -0,0 +1,339 @@ +package com.baeldung.bytebuffer; + +import org.junit.Test; + +import java.lang.reflect.Field; +import java.nio.*; +import java.nio.charset.StandardCharsets; + +import static org.junit.Assert.*; + +public class ByteBufferUnitTest { + @Test + public void givenBufferCreation_whenUsingAllocate_thenSuccess() { + ByteBuffer buffer = ByteBuffer.allocate(10); + assertNotNull(buffer); + } + + @Test + public void givenBufferCreation_whenUsingAllocateDirect_thenSuccess() { + ByteBuffer buffer = ByteBuffer.allocateDirect(10); + assertNotNull(buffer); + } + + @Test + public void givenBufferCreation_whenUsingWrap_thenSuccess() { + byte[] bytes = new byte[10]; + ByteBuffer buffer = ByteBuffer.wrap(bytes); + assertNotNull(buffer); + } + + @Test + public void givenBufferIndex_whenUsingAllocate_thenInitialIndices() { + // create instance using allocate + ByteBuffer buffer = ByteBuffer.allocate(10); + + // get index + int position = buffer.position(); + int limit = buffer.limit(); + int capacity = buffer.capacity(); + + // assert + assertEquals(0, position); + assertEquals(10, limit); + assertEquals(10, capacity); + } + + @Test + public void givenBufferIndex_whenChangingPositionAndLimit_thenSuccess() { + // create instance + ByteBuffer buffer = ByteBuffer.allocate(10); + + // change index + buffer.position(2); + buffer.limit(5); + + // assert + assertIndex(buffer, -1, 2, 5, 10); + } + + @Test + public void givenBufferIndex_whenUsingWrap_thenInitialIndices() { + // create instance + byte[] bytes = new byte[10]; + ByteBuffer buffer = ByteBuffer.wrap(bytes); + + // assert + assertIndex(buffer, -1, 0, 10, 10); + } + + @Test + public void givenBufferIndex_whenUsingWrapWithOffsetAndLength_thenInitialIndices() { + // create instance + byte[] bytes = new byte[10]; + ByteBuffer buffer = ByteBuffer.wrap(bytes, 2, 6); + + // assert + assertIndex(buffer, -1, 2, 8, 10); + } + + @Test + public void givenBufferIndex_whenUsingMarkAndReset_thenOK() { + ByteBuffer buffer = ByteBuffer.allocate(10); + assertIndex(buffer, -1, 0, 10, 10); + + buffer.position(2); + assertIndex(buffer, -1, 2, 10, 10); + + buffer.mark(); + assertIndex(buffer, 2, 2, 10, 10); + + buffer.position(5); + assertIndex(buffer, 2, 5, 10, 10); + + buffer.reset(); + assertIndex(buffer, 2, 2, 10, 10); + } + + @Test + public void givenBufferIndex_whenUsingClear_thenOK() { + // create instance + ByteBuffer buffer = ByteBuffer.allocate(10); + assertIndex(buffer, -1, 0, 10, 10); + + // change index + buffer.position(2); + buffer.mark(); + buffer.position(5); + buffer.limit(8); + assertIndex(buffer, 2, 5, 8, 10); + + // clear + buffer.clear(); + assertIndex(buffer, -1, 0, 10, 10); + } + + @Test + public void givenBufferIndex_whenUsingFlip_thenOK() { + // create instance + ByteBuffer buffer = ByteBuffer.allocate(10); + assertIndex(buffer, -1, 0, 10, 10); + + // change index + buffer.position(2); + buffer.mark(); + buffer.position(5); + buffer.limit(8); + assertIndex(buffer, 2, 5, 8, 10); + + // flip + buffer.flip(); + assertIndex(buffer, -1, 0, 5, 10); + } + + @Test + public void givenBufferIndex_whenUsingRewind_thenOK() { + // create instance + ByteBuffer buffer = ByteBuffer.allocate(10); + assertIndex(buffer, -1, 0, 10, 10); + + // change index + buffer.position(2); + buffer.mark(); + buffer.position(5); + buffer.limit(8); + assertIndex(buffer, 2, 5, 8, 10); + + // rewind + buffer.rewind(); + assertIndex(buffer, -1, 0, 8, 10); + } + + @Test + public void givenBufferIndex_whenUsingCompact_thenOK() { + // create instance + ByteBuffer buffer = ByteBuffer.allocate(10); + assertIndex(buffer, -1, 0, 10, 10); + + // change index + buffer.position(2); + buffer.mark(); + buffer.position(5); + buffer.limit(8); + assertIndex(buffer, 2, 5, 8, 10); + + // compact + buffer.compact(); + assertIndex(buffer, -1, 3, 10, 10); + } + + @Test + public void givenBufferIndex_whenUsingRemain_thenOK() { + // create instance + ByteBuffer buffer = ByteBuffer.allocate(10); + + // change index + buffer.position(2); + buffer.limit(8); + + // remain + boolean flag = buffer.hasRemaining(); + int remaining = buffer.remaining(); + + // assert + assertTrue(flag); + assertEquals(6, remaining); + } + + @Test(expected = BufferUnderflowException.class) + public void givenNotEnoughRemaining_WhenCallingGetInt_thenBufferUnderflowException() { + ByteBuffer buffer = ByteBuffer.allocate(2); + buffer.getInt(); + } + + @Test(expected = BufferOverflowException.class) + public void givenNotEnoughRemaining_WhenCallingPutInt_thenBufferOverflowException() { + ByteBuffer buffer = ByteBuffer.allocate(2); + buffer.putInt(10); + } + + @Test + public void givenBufferView_whenUsingDuplicate_thenOK() { + // create instance + ByteBuffer buffer = ByteBuffer.allocate(10); + assertIndex(buffer, -1, 0, 10, 10); + + // change index + buffer.position(2); + buffer.mark(); + buffer.position(5); + buffer.limit(8); + assertIndex(buffer, 2, 5, 8, 10); + + // view + ByteBuffer view = buffer.duplicate(); + assertIndex(view, 2, 5, 8, 10); + } + + @Test + public void givenBufferView_whenUsingSlice_thenOK() { + // create instance + ByteBuffer buffer = ByteBuffer.allocate(10); + assertIndex(buffer, -1, 0, 10, 10); + + // change index + buffer.position(2); + buffer.mark(); + buffer.position(5); + buffer.limit(8); + assertIndex(buffer, 2, 5, 8, 10); + + // view + ByteBuffer view = buffer.slice(); + assertIndex(view, -1, 0, 3, 3); + } + + @Test + public void givenBufferView_whenUsingAsReaOnlyBuffer_thenOK() { + // create instance + ByteBuffer buffer = ByteBuffer.allocate(10); + assertIndex(buffer, -1, 0, 10, 10); + + // change index + buffer.position(2); + buffer.mark(); + buffer.position(5); + buffer.limit(8); + assertIndex(buffer, 2, 5, 8, 10); + + // view + ByteBuffer view = buffer.asReadOnlyBuffer(); + assertIndex(view, 2, 5, 8, 10); + } + + @Test + public void givenBufferView_whenUsingAsIntBuffer_thenOK() { + // create instance + byte[] bytes = new byte[]{ + (byte) 0xCA, (byte) 0xFE, (byte) 0xBA, (byte) 0xBE, // CAFEBABE ---> cafebabe + (byte) 0xF0, (byte) 0x07, (byte) 0xBA, (byte) 0x11, // F007BA11 ---> football + (byte) 0x0F, (byte) 0xF1, (byte) 0xCE // 0FF1CE ---> office + }; + ByteBuffer buffer = ByteBuffer.wrap(bytes); + assertIndex(buffer, -1, 0, 11, 11); + + // view + IntBuffer intBuffer = buffer.asIntBuffer(); + int capacity = intBuffer.capacity(); + assertEquals(2, capacity); + assertIndex(intBuffer, -1, 0, 2, 2); + } + + @Test + public void givenByteOrder_whenUsingBigEndian_thenOK() { + // create instance + byte[] bytes = new byte[]{(byte) 0xCA, (byte) 0xFE, (byte) 0xBA, (byte) 0xBE}; + ByteBuffer buffer = ByteBuffer.wrap(bytes); + + // change byte order + buffer.order(ByteOrder.BIG_ENDIAN); + int val = buffer.getInt(); + + // assert + assertEquals(0xCAFEBABE, val); + } + + @Test + public void givenByteOrder_whenUsingLittleEndian_thenOK() { + // create instance + byte[] bytes = new byte[]{(byte) 0xCA, (byte) 0xFE, (byte) 0xBA, (byte) 0xBE}; + ByteBuffer buffer = ByteBuffer.wrap(bytes); + + // change byte order + buffer.order(ByteOrder.LITTLE_ENDIAN); + int val = buffer.getInt(); + + // assert + assertEquals(0xBEBAFECA, val); + } + + @Test + public void givenComparing_whenUsingEqualsAndCompareTo_thenOK() { + // create instance + byte[] bytes1 = "World".getBytes(StandardCharsets.UTF_8); + byte[] bytes2 = "HelloWorld".getBytes(StandardCharsets.UTF_8); + ByteBuffer buffer1 = ByteBuffer.wrap(bytes1); + ByteBuffer buffer2 = ByteBuffer.wrap(bytes2); + + // change index + buffer2.position(5); + + // equals and compareTo + boolean equal = buffer1.equals(buffer2); + int result = buffer1.compareTo(buffer2); + + // assert + assertTrue(equal); + assertEquals(0, result); + } + + private void assertIndex(Buffer buffer, int mark, int position, int limit, int capacity) { + assertEquals(mark, getMark(buffer)); + assertEquals(position, buffer.position()); + assertEquals(limit, buffer.limit()); + assertEquals(capacity, buffer.capacity()); + } + + private int getMark(Buffer buffer) { + try { + Class clazz = Buffer.class; + Field f = clazz.getDeclaredField("mark"); + f.setAccessible(true); + Object result = f.get(buffer); + return (int) result; + } catch (NoSuchFieldException | IllegalAccessException e) { + e.printStackTrace(); + } + return -1; + } +} diff --git a/core-java-modules/core-java-security-3/README.md b/core-java-modules/core-java-security-3/README.md index 31969cd270..9d82e829e2 100644 --- a/core-java-modules/core-java-security-3/README.md +++ b/core-java-modules/core-java-security-3/README.md @@ -10,4 +10,5 @@ This module contains articles about core Java Security - [HMAC in Java](https://www.baeldung.com/java-hmac) - [Generating a Secure AES Key in Java](https://www.baeldung.com/java-secure-aes-key) - [Computing an X509 Certificate’s Thumbprint in Java](https://www.baeldung.com/java-x509-certificate-thumbprint) +- [Error: “trustAnchors parameter must be non-empty”](https://www.baeldung.com/java-trustanchors-parameter-must-be-non-empty) - More articles: [[<-- prev]](/core-java-modules/core-java-security-2) diff --git a/docker/README.md b/docker/README.md index 0de3694215..0adf1c9b51 100644 --- a/docker/README.md +++ b/docker/README.md @@ -6,3 +6,4 @@ - [How To Configure Java Heap Size Inside a Docker Container](https://www.baeldung.com/ops/docker-jvm-heap-size) - [Dockerfile Strategies for Git](https://www.baeldung.com/ops/dockerfile-git-strategies) - [How to Get Docker-Compose to Always Use the Latest Image](https://www.baeldung.com/ops/docker-compose-latest-image) +- [How to Include Files Outside of Docker’s Build Context](https://www.baeldung.com/ops/docker-include-files-outside-build-context) diff --git a/docker/docker-include-outside-build-context/projects/config/Dockerfile b/docker/docker-include-outside-build-context/projects/config/Dockerfile new file mode 100644 index 0000000000..754f9f9be3 --- /dev/null +++ b/docker/docker-include-outside-build-context/projects/config/Dockerfile @@ -0,0 +1,2 @@ +FROM nginx:latest +COPY nginx.conf /etc/nginx/nginx.conf diff --git a/docker/docker-include-outside-build-context/projects/config/nginx.conf b/docker/docker-include-outside-build-context/projects/config/nginx.conf new file mode 100644 index 0000000000..944da2f112 --- /dev/null +++ b/docker/docker-include-outside-build-context/projects/config/nginx.conf @@ -0,0 +1,8 @@ +events {} + +http { + server { + listen 80; + index index.html; + } +} diff --git a/docker/docker-include-outside-build-context/projects/sample-site/docker/Dockerfile b/docker/docker-include-outside-build-context/projects/sample-site/docker/Dockerfile new file mode 100644 index 0000000000..bda0bbe257 --- /dev/null +++ b/docker/docker-include-outside-build-context/projects/sample-site/docker/Dockerfile @@ -0,0 +1,3 @@ +FROM nginx:latest +COPY sample-site/html/* /etc/nginx/html/ +COPY config/nginx.conf /etc/nginx/nginx.conf diff --git a/docker/docker-include-outside-build-context/projects/sample-site/docker/Dockerfile-from-base b/docker/docker-include-outside-build-context/projects/sample-site/docker/Dockerfile-from-base new file mode 100644 index 0000000000..1b72414bc0 --- /dev/null +++ b/docker/docker-include-outside-build-context/projects/sample-site/docker/Dockerfile-from-base @@ -0,0 +1,2 @@ +FROM sample-site-base:latest +COPY html/* /etc/nginx/html/ diff --git a/docker/docker-include-outside-build-context/projects/sample-site/docker/Dockerfile-script b/docker/docker-include-outside-build-context/projects/sample-site/docker/Dockerfile-script new file mode 100644 index 0000000000..572028f19f --- /dev/null +++ b/docker/docker-include-outside-build-context/projects/sample-site/docker/Dockerfile-script @@ -0,0 +1,3 @@ +FROM nginx:latest +COPY html/* /etc/nginx/html/ +COPY config/nginx.conf /etc/nginx/nginx.conf diff --git a/docker/docker-include-outside-build-context/projects/sample-site/docker/build-docker.sh b/docker/docker-include-outside-build-context/projects/sample-site/docker/build-docker.sh new file mode 100755 index 0000000000..e84687b7b7 --- /dev/null +++ b/docker/docker-include-outside-build-context/projects/sample-site/docker/build-docker.sh @@ -0,0 +1,6 @@ +mkdir tmp-context +cp -R ../html tmp-context/ +cp -R ../../config tmp-context/ +cp Dockerfile-script tmp-context/Dockerfile +docker build -t sample-site:latest tmp-context +rm -rf tmp-context diff --git a/docker/docker-include-outside-build-context/projects/sample-site/html/index.html b/docker/docker-include-outside-build-context/projects/sample-site/html/index.html new file mode 100644 index 0000000000..85f287fad7 --- /dev/null +++ b/docker/docker-include-outside-build-context/projects/sample-site/html/index.html @@ -0,0 +1,10 @@ + + + + + Sample Site + + +

Welcome to the first page of the site

+ + diff --git a/gradle/gradle-source-vs-target-compatibility/README.md b/gradle/gradle-source-vs-target-compatibility/README.md new file mode 100644 index 0000000000..cc3157fde3 --- /dev/null +++ b/gradle/gradle-source-vs-target-compatibility/README.md @@ -0,0 +1,3 @@ +### Relevant Articles: + +- [Gradle: sourceCompatiblity vs targetCompatibility](https://www.baeldung.com/gradle-sourcecompatiblity-vs-targetcompatibility) diff --git a/java-collections-maps-3/README.md b/java-collections-maps-3/README.md index 75842c85a4..e2e0a56489 100644 --- a/java-collections-maps-3/README.md +++ b/java-collections-maps-3/README.md @@ -7,3 +7,4 @@ - [Update the Value Associated With a Key in a HashMap](https://www.baeldung.com/java-hashmap-update-value-by-key) - [Java Map – keySet() vs. entrySet() vs. values() Methods](https://www.baeldung.com/java-map-entries-methods) - [Java IdentityHashMap Class and Its Use Cases](https://www.baeldung.com/java-identityhashmap) +- [How to Invert a Map in Java](https://www.baeldung.com/java-invert-map) diff --git a/java-collections-maps-3/src/main/java/com/baeldung/map/invert/InvertHashMapExample.java b/java-collections-maps-3/src/main/java/com/baeldung/map/invert/InvertHashMapExample.java new file mode 100644 index 0000000000..a203fd17c4 --- /dev/null +++ b/java-collections-maps-3/src/main/java/com/baeldung/map/invert/InvertHashMapExample.java @@ -0,0 +1,59 @@ +package com.baeldung.map.invert; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.stream.Collectors; + +public class InvertHashMapExample { + + public static void main(String[] args) { + + Map map = new HashMap<>(); + map.put("first", 1); + map.put("second", 2); + System.out.println(map); + + invertMapUsingForLoop(map); + invertMapUsingStreams(map); + invertMapUsingMapper(map); + + map.put("two", 2); + invertMapUsingGroupingBy(map); + } + + public static Map invertMapUsingForLoop(Map map) { + Map inversedMap = new HashMap(); + for (Entry entry : map.entrySet()) { + inversedMap.put(entry.getValue(), entry.getKey()); + } + System.out.println(inversedMap); + return inversedMap; + } + + public static Map invertMapUsingStreams(Map map) { + Map inversedMap = map.entrySet() + .stream() + .collect(Collectors.toMap(Entry::getValue, Entry::getKey)); + System.out.println(inversedMap); + return inversedMap; + } + + public static Map invertMapUsingMapper(Map sourceMap) { + Map inversedMap = sourceMap.entrySet() + .stream() + .collect(Collectors.toMap(Entry::getValue, Entry::getKey, (oldValue, newValue) -> oldValue)); + System.out.println(inversedMap); + return inversedMap; + } + + public static Map> invertMapUsingGroupingBy(Map map) { + Map> inversedMap = map.entrySet() + .stream() + .collect(Collectors.groupingBy(Map.Entry::getValue, Collectors.mapping(Map.Entry::getKey, Collectors.toList()))); + System.out.println(inversedMap); + return inversedMap; + } + +} diff --git a/java-collections-maps-3/src/test/java/com/baeldung/map/invert/InvertHashMapUnitTest.java b/java-collections-maps-3/src/test/java/com/baeldung/map/invert/InvertHashMapUnitTest.java new file mode 100644 index 0000000000..6870cdef23 --- /dev/null +++ b/java-collections-maps-3/src/test/java/com/baeldung/map/invert/InvertHashMapUnitTest.java @@ -0,0 +1,72 @@ +package com.baeldung.map.invert; + +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +public class InvertHashMapUnitTest { + + Map sourceMap; + + @BeforeEach + void setup() { + sourceMap = new HashMap<>(); + sourceMap.put("Sunday", 0); + sourceMap.put("Monday", 1); + sourceMap.put("Tuesday", 2); + sourceMap.put("Wednesday", 3); + sourceMap.put("Thursday", 4); + sourceMap.put("Friday", 5); + sourceMap.put("Saturday", 6); + } + + @Test + void givenSourceMap_whenUsingForLoop_returnsInvertedMap() { + Map inversedMap = InvertHashMapExample.invertMapUsingForLoop(sourceMap); + + assertNotNull(inversedMap); + assertEquals(sourceMap.size(), inversedMap.size()); + assertEquals("Monday", inversedMap.get(1)); + } + + @Test + void givenSourceMap_whenUsingStreams_returnsInvertedMap() { + Map inversedMap = InvertHashMapExample.invertMapUsingStreams(sourceMap); + + assertNotNull(inversedMap); + assertEquals(sourceMap.size(), inversedMap.size()); + assertEquals("Monday", inversedMap.get(1)); + } + + @Test + void givenSourceMap_whenUsingMapper_returnsInvertedMap() { + Map inversedMap = InvertHashMapExample.invertMapUsingMapper(sourceMap); + + assertNotNull(inversedMap); + assertEquals(sourceMap.size(), inversedMap.size()); + assertEquals("Monday", inversedMap.get(1)); + } + + @Test + void givenSourceMapWithDuplicateValues_whenUsingGroupBy_returnsInvertedMap() { + sourceMap.put("MONDAY", 1); + Map> inversedMap = InvertHashMapExample.invertMapUsingGroupingBy(sourceMap); + + assertNotNull(inversedMap); + assertNotEquals(sourceMap.size(), inversedMap.size()); // duplicate keys are merged now + assertEquals(2, inversedMap.get(1).size()); + assertTrue(inversedMap.get(1).contains("Monday")); + assertTrue(inversedMap.get(1).contains("MONDAY")); + } + +} diff --git a/java-native/README.md b/java-native/README.md index 4f85342a38..2aa02c03d5 100644 --- a/java-native/README.md +++ b/java-native/README.md @@ -7,3 +7,4 @@ This module contains articles about the Java Native Interface (JNI). - [Guide to JNI (Java Native Interface)](https://www.baeldung.com/jni) - [Using JNA to Access Native Dynamic Libraries](https://www.baeldung.com/java-jna-dynamic-libraries) - [Check if a Java Program Is Running in 64-Bit or 32-Bit JVM](https://www.baeldung.com/java-detect-jvm-64-or-32-bit) +- [How to use JNI’s RegisterNatives() method?](https://www.baeldung.com/jni-registernatives) diff --git a/javax-servlets-2/README.md b/javax-servlets-2/README.md new file mode 100644 index 0000000000..f126f17297 --- /dev/null +++ b/javax-servlets-2/README.md @@ -0,0 +1,5 @@ +## Servlets + +This module contains articles about Servlets. + +### Relevant Articles: diff --git a/javax-servlets-2/pom.xml b/javax-servlets-2/pom.xml new file mode 100644 index 0000000000..34c00c3d05 --- /dev/null +++ b/javax-servlets-2/pom.xml @@ -0,0 +1,60 @@ + + + 4.0.0 + com.baeldung.javax-servlets + javax-servlets-2 + 1.0-SNAPSHOT + javax-servlets-2 + war + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + + + + + commons-fileupload + commons-fileupload + ${commons-fileupload.version} + + + + javax.servlet + javax.servlet-api + ${javax.servlet-api.version} + + + javax.servlet.jsp + javax.servlet.jsp-api + ${javax.servlet.jsp-api.version} + provided + + + javax.servlet + jstl + ${jstl.version} + + + org.apache.httpcomponents + httpclient + ${org.apache.httpcomponents.version} + test + + + commons-logging + commons-logging + + + + + + + 4.5.13 + 4.0.1 + + diff --git a/javax-servlets-2/src/main/java/com/baeldung/user/check/User.java b/javax-servlets-2/src/main/java/com/baeldung/user/check/User.java new file mode 100644 index 0000000000..f61c0490bc --- /dev/null +++ b/javax-servlets-2/src/main/java/com/baeldung/user/check/User.java @@ -0,0 +1,80 @@ +package com.baeldung.user.check; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; + +/** + * @since 6 de fev de 2022 + * @author ulisses + */ +public class User implements Serializable { + private static final long serialVersionUID = 1L; + + protected static final HashMap DB = new HashMap<>(); + static { + DB.put("admin", new User("admin", "password")); + DB.put("user", new User("user", "pass")); + } + + private String name; + private String password; + + private List logins = new ArrayList(); + + public User(String name, String password) { + this.name = name; + this.password = password; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public List getLogins() { + return logins; + } + + public void setLogins(List logins) { + this.logins = logins; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((name == null) ? 0 : name.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + User other = (User) obj; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + return true; + } +} diff --git a/javax-servlets-2/src/main/java/com/baeldung/user/check/UserCheckFilter.java b/javax-servlets-2/src/main/java/com/baeldung/user/check/UserCheckFilter.java new file mode 100644 index 0000000000..2a370afe85 --- /dev/null +++ b/javax-servlets-2/src/main/java/com/baeldung/user/check/UserCheckFilter.java @@ -0,0 +1,46 @@ +package com.baeldung.user.check; + +import java.io.IOException; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.annotation.WebFilter; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +@WebFilter("/user-check/*") +public class UserCheckFilter implements Filter { + public static void forward(HttpServletRequest request, HttpServletResponse response, String page) throws ServletException, IOException { + request.getRequestDispatcher("/WEB-INF/user.check" + page) + .forward(request, response); + } + + @Override + public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { + if (!(req instanceof HttpServletRequest)) { + throw new ServletException("Can only process HttpServletRequest"); + } + + if (!(res instanceof HttpServletResponse)) { + throw new ServletException("Can only process HttpServletResponse"); + } + + HttpServletRequest request = (HttpServletRequest) req; + HttpServletResponse response = (HttpServletResponse) res; + + request.setAttribute("origin", request.getRequestURI()); + + if (!request.getRequestURI() + .contains("login") && request.getSession(false) == null) { + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + forward(request, response, "/login.jsp"); + // we return here so the original servlet is not processed + return; + } + + chain.doFilter(request, response); + } +} diff --git a/javax-servlets-2/src/main/java/com/baeldung/user/check/UserCheckLoginServlet.java b/javax-servlets-2/src/main/java/com/baeldung/user/check/UserCheckLoginServlet.java new file mode 100644 index 0000000000..e1a38fc7b8 --- /dev/null +++ b/javax-servlets-2/src/main/java/com/baeldung/user/check/UserCheckLoginServlet.java @@ -0,0 +1,56 @@ +package com.baeldung.user.check; + +import java.io.IOException; +import java.util.Date; + +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +@WebServlet("/user-check/login") +public class UserCheckLoginServlet extends HttpServlet { + private static final long serialVersionUID = 1L; + + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + if (request.getSession(false) != null) { + response.sendRedirect(request.getContextPath() + "/user-check/home"); + return; + } + + String referer = (String) request.getAttribute("origin"); + request.setAttribute("origin", referer); + UserCheckFilter.forward(request, response, "/login.jsp"); + } + + @Override + protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + String key = request.getParameter("name"); + String pass = request.getParameter("password"); + + User user = User.DB.get(key); + if (user == null || !user.getPassword() + .equals(pass)) { + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + request.setAttribute("origin", request.getParameter("origin")); + request.setAttribute("error", "invalid login"); + UserCheckFilter.forward(request, response, "/login.jsp"); + return; + } + + user.getLogins() + .add(new Date()); + + HttpSession session = request.getSession(); + session.setAttribute("user", user); + + String origin = request.getParameter("origin"); + if (origin == null || origin.contains("login")) + origin = "./"; + + response.sendRedirect(origin); + } +} diff --git a/javax-servlets-2/src/main/java/com/baeldung/user/check/UserCheckLogoutServlet.java b/javax-servlets-2/src/main/java/com/baeldung/user/check/UserCheckLogoutServlet.java new file mode 100644 index 0000000000..42c0bb87ab --- /dev/null +++ b/javax-servlets-2/src/main/java/com/baeldung/user/check/UserCheckLogoutServlet.java @@ -0,0 +1,26 @@ +package com.baeldung.user.check; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +@WebServlet("/user-check/logout") +public class UserCheckLogoutServlet extends HttpServlet { + private static final long serialVersionUID = 1L; + + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + HttpSession session = request.getSession(false); + if (session != null) { + session.invalidate(); + } + + request.setAttribute("loggedOut", true); + response.sendRedirect("./"); + } +} diff --git a/javax-servlets-2/src/main/java/com/baeldung/user/check/UserCheckServlet.java b/javax-servlets-2/src/main/java/com/baeldung/user/check/UserCheckServlet.java new file mode 100644 index 0000000000..d7d5d1e762 --- /dev/null +++ b/javax-servlets-2/src/main/java/com/baeldung/user/check/UserCheckServlet.java @@ -0,0 +1,28 @@ +package com.baeldung.user.check; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +@WebServlet(name = "home", urlPatterns = { "/user-check/", "/user-check", "/user-check/home" }) +public class UserCheckServlet extends HttpServlet { + private static final long serialVersionUID = 1L; + + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + HttpSession session = request.getSession(false); + if (session == null || session.getAttribute("user") == null) { + throw new IllegalStateException("user not logged in"); + } + + User user = (User) session.getAttribute("user"); + request.setAttribute("user", user); + + UserCheckFilter.forward(request, response, "/home.jsp"); + } +} diff --git a/javax-servlets-2/src/main/resources/logback.xml b/javax-servlets-2/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/javax-servlets-2/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/javax-servlets-2/src/main/webapp/WEB-INF/user.check/home.jsp b/javax-servlets-2/src/main/webapp/WEB-INF/user.check/home.jsp new file mode 100644 index 0000000000..4e17763552 --- /dev/null +++ b/javax-servlets-2/src/main/webapp/WEB-INF/user.check/home.jsp @@ -0,0 +1,31 @@ +<%@ page contentType="text/html;charset=UTF-8" session="false"%> +<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c"%> + + + + login success - current session info + + +
+

user info

+
+ name: ${user.name} +
+ +
+ logins: +
    + +
  • ${login}
  • +
    +
+
+ + +
+ + diff --git a/javax-servlets-2/src/main/webapp/WEB-INF/user.check/login.jsp b/javax-servlets-2/src/main/webapp/WEB-INF/user.check/login.jsp new file mode 100644 index 0000000000..19a857585d --- /dev/null +++ b/javax-servlets-2/src/main/webapp/WEB-INF/user.check/login.jsp @@ -0,0 +1,33 @@ +<%@ page contentType="text/html;charset=UTF-8" session="false"%> +<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c"%> + + + + login + + +
+ + +
* redirected to login from: ${origin}
+
+ + +
* error: ${error}
+
+ +
+ credentials + + + + + + + + +
+
+ + diff --git a/javax-servlets-2/src/test/java/com/baeldung/user/check/UserCheckServletLiveTest.java b/javax-servlets-2/src/test/java/com/baeldung/user/check/UserCheckServletLiveTest.java new file mode 100644 index 0000000000..42858d61e7 --- /dev/null +++ b/javax-servlets-2/src/test/java/com/baeldung/user/check/UserCheckServletLiveTest.java @@ -0,0 +1,98 @@ +package com.baeldung.user.check; + +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.List; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.client.LaxRedirectStrategy; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.util.EntityUtils; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class UserCheckServletLiveTest { + private static final String BASE_URL = "http://localhost:8080/javax-servlets-2/user-check"; + + @Mock + HttpServletRequest request; + + @Mock + HttpServletResponse response; + + private CloseableHttpClient buildClient() { + return HttpClientBuilder.create() + .setRedirectStrategy(new LaxRedirectStrategy()) + .build(); + } + + @Test + public void whenCorrectCredentials_thenLoginSucceeds() throws Exception { + try (CloseableHttpClient client = buildClient()) { + HttpPost post = new HttpPost(BASE_URL + "/login"); + + List form = new ArrayList<>(); + form.add(new BasicNameValuePair("name", "admin")); + form.add(new BasicNameValuePair("password", "password")); + + post.setEntity(new UrlEncodedFormEntity(form)); + try (CloseableHttpResponse response = client.execute(post)) { + String body = EntityUtils.toString(response.getEntity()); + + assertTrue(response.getStatusLine() + .getStatusCode() == 200); + + assertTrue(body.contains("login success")); + } + } + } + + @Test + public void whenIncorrectCredentials_thenLoginFails() throws Exception { + try (CloseableHttpClient client = buildClient()) { + HttpPost post = new HttpPost(BASE_URL + "/login"); + + List form = new ArrayList<>(); + form.add(new BasicNameValuePair("name", "admin")); + form.add(new BasicNameValuePair("password", "invalid")); + + post.setEntity(new UrlEncodedFormEntity(form)); + try (CloseableHttpResponse response = client.execute(post)) { + String body = EntityUtils.toString(response.getEntity()); + + assertTrue(response.getStatusLine() + .getStatusCode() == 401); + + assertTrue(body.contains("invalid login")); + } + } + } + + @Test + public void whenNotLoggedIn_thenRedirectedToLoginPage() throws Exception { + try (CloseableHttpClient client = buildClient()) { + HttpGet get = new HttpGet(BASE_URL + "/home"); + + try (CloseableHttpResponse response = client.execute(get)) { + String body = EntityUtils.toString(response.getEntity()); + + assertTrue(response.getStatusLine() + .getStatusCode() == 401); + + assertTrue(body.contains("redirected to login")); + } + } + } +} diff --git a/jta/pom.xml b/jta/pom.xml index e9f9364646..e62c480c81 100644 --- a/jta/pom.xml +++ b/jta/pom.xml @@ -15,6 +15,18 @@ 0.0.1-SNAPSHOT ../parent-boot-2 + + + + + org.apache.logging.log4j + log4j-bom + ${log4j2.version} + import + pom + + + @@ -37,6 +49,7 @@ 2.4.7 + 2.17.1 \ No newline at end of file diff --git a/maven-modules/maven-generate-war/pom.xml b/maven-modules/maven-generate-war/pom.xml index 56256f58ea..b388cfdadd 100644 --- a/maven-modules/maven-generate-war/pom.xml +++ b/maven-modules/maven-generate-war/pom.xml @@ -63,6 +63,7 @@ 11 + 2.17.1 \ No newline at end of file diff --git a/parent-spring-5/pom.xml b/parent-spring-5/pom.xml index 175e8d58f9..b2d581c9c1 100644 --- a/parent-spring-5/pom.xml +++ b/parent-spring-5/pom.xml @@ -24,7 +24,7 @@ - 5.3.13 + 5.3.16 5.6.0 1.5.10.RELEASE diff --git a/patterns/enterprise-patterns/pom.xml b/patterns/enterprise-patterns/pom.xml index 10c07d6d05..999b359170 100644 --- a/patterns/enterprise-patterns/pom.xml +++ b/patterns/enterprise-patterns/pom.xml @@ -48,6 +48,13 @@ pom import + + org.apache.logging.log4j + log4j-bom + ${log4j2.version} + import + pom + @@ -63,6 +70,7 @@ 3.7.4 2.2.2.RELEASE + 2.17.1 \ No newline at end of file diff --git a/persistence-modules/hibernate-queries/README.md b/persistence-modules/hibernate-queries/README.md index 61d94e32de..58ca74cd24 100644 --- a/persistence-modules/hibernate-queries/README.md +++ b/persistence-modules/hibernate-queries/README.md @@ -7,4 +7,5 @@ This module contains articles about use of Queries in Hibernate. - [Criteria Queries Using JPA Metamodel](https://www.baeldung.com/hibernate-criteria-queries-metamodel) - [Get All Data from a Table with Hibernate](https://www.baeldung.com/hibernate-select-all) - [Hibernate Named Query](https://www.baeldung.com/hibernate-named-query) -- [Hibernate Query Plan Cache](https://www.baeldung.com/hibernate-query-plan-cache) \ No newline at end of file +- [Hibernate Query Plan Cache](https://www.baeldung.com/hibernate-query-plan-cache) +- [Hibernate’s addScalar() Method](https://www.baeldung.com/hibernate-addscalar) diff --git a/persistence-modules/spring-data-dynamodb/pom.xml b/persistence-modules/spring-data-dynamodb/pom.xml index 148215b68a..0e990c69f3 100644 --- a/persistence-modules/spring-data-dynamodb/pom.xml +++ b/persistence-modules/spring-data-dynamodb/pom.xml @@ -24,6 +24,13 @@ pom import + + org.apache.logging.log4j + log4j-bom + ${log4j2.version} + import + pom + @@ -184,6 +191,7 @@ https://s3-us-west-2.amazonaws.com/dynamodb-local/release 3.1.1 2.4.7 + 2.17.1 \ No newline at end of file diff --git a/pom.xml b/pom.xml index f5378f9961..cab9a34f02 100644 --- a/pom.xml +++ b/pom.xml @@ -459,6 +459,7 @@ java-vavr-stream java-websocket javax-servlets + javax-servlets-2 javaxval jaxb jee-7 @@ -943,6 +944,7 @@ java-vavr-stream java-websocket javax-servlets + javax-servlets-2 javaxval jaxb jee-7 @@ -1343,7 +1345,8 @@ persistence-modules/spring-data-cassandra-2 quarkus-vs-springboot quarkus-jandex - spring-boot-modules/spring-boot-cassandre + spring-boot-modules/spring-boot-cassandre + spring-boot-modules/spring-boot-camel testing-modules/testing-assertions @@ -1400,7 +1403,8 @@ persistence-modules/spring-data-cassandra-2 quarkus-vs-springboot quarkus-jandex - spring-boot-modules/spring-boot-cassandre + spring-boot-modules/spring-boot-cassandre + spring-boot-modules/spring-boot-camel testing-modules/testing-assertions diff --git a/quarkus-vs-springboot/spring-project/pom.xml b/quarkus-vs-springboot/spring-project/pom.xml index bf524cd550..7f0fa4c8c6 100644 --- a/quarkus-vs-springboot/spring-project/pom.xml +++ b/quarkus-vs-springboot/spring-project/pom.xml @@ -187,6 +187,7 @@ 11 0.11.0-RC1 + 2.17.1 \ No newline at end of file diff --git a/spring-5-autowiring-beans/README.md b/spring-5-autowiring-beans/README.md new file mode 100644 index 0000000000..dc8751325e --- /dev/null +++ b/spring-5-autowiring-beans/README.md @@ -0,0 +1,3 @@ +### Relevant Articles: + +- [Spring @Autowired Field Null – Common Causes and Solutions](https://www.baeldung.com/spring-autowired-field-null) diff --git a/spring-5-data-reactive/pom.xml b/spring-5-data-reactive/pom.xml index c145992737..023eda856b 100644 --- a/spring-5-data-reactive/pom.xml +++ b/spring-5-data-reactive/pom.xml @@ -13,6 +13,18 @@ 0.0.1-SNAPSHOT ../parent-boot-2 + + + + + org.apache.logging.log4j + log4j-bom + ${log4j2.version} + import + pom + + + @@ -138,6 +150,7 @@ 3.3.1.RELEASE 2.2.6.RELEASE + 2.17.1 \ No newline at end of file diff --git a/spring-activiti/pom.xml b/spring-activiti/pom.xml index c685207cc4..2ede13a152 100644 --- a/spring-activiti/pom.xml +++ b/spring-activiti/pom.xml @@ -16,6 +16,18 @@ 0.0.1-SNAPSHOT ../parent-boot-1 + + + + + org.apache.logging.log4j + log4j-bom + ${log4j2.version} + import + pom + + + @@ -59,6 +71,7 @@ 6.0.0 + 2.17.1 \ No newline at end of file diff --git a/spring-boot-modules/pom.xml b/spring-boot-modules/pom.xml index 4925530a35..fabd54aa92 100644 --- a/spring-boot-modules/pom.xml +++ b/spring-boot-modules/pom.xml @@ -36,7 +36,6 @@ spring-boot-deployment spring-boot-di spring-boot-disable-logging - spring-boot-camel spring-boot-ci-cd spring-boot-custom-starter @@ -51,6 +50,7 @@ spring-boot-libraries spring-boot-libraries-2 + spring-boot-libraries-comparison spring-boot-logging-log4j2 spring-boot-multiple-datasources spring-boot-mvc diff --git a/spring-boot-modules/spring-boot-2/pom.xml b/spring-boot-modules/spring-boot-2/pom.xml index 08dc517fa0..0da07eaf00 100644 --- a/spring-boot-modules/spring-boot-2/pom.xml +++ b/spring-boot-modules/spring-boot-2/pom.xml @@ -62,7 +62,7 @@ - 2.14.1 + 2.17.1 5.3.15 11 11 diff --git a/spring-boot-modules/spring-boot-camel/pom.xml b/spring-boot-modules/spring-boot-camel/pom.xml index 5d5e2ce6bd..5bda1b2351 100644 --- a/spring-boot-modules/spring-boot-camel/pom.xml +++ b/spring-boot-modules/spring-boot-camel/pom.xml @@ -16,22 +16,22 @@ - org.apache.camel + org.apache.camel.springboot camel-servlet-starter ${camel.version} - org.apache.camel + org.apache.camel.springboot camel-jackson-starter ${camel.version} - org.apache.camel + org.apache.camel.springboot camel-swagger-java-starter ${camel.version} - org.apache.camel + org.apache.camel.springboot camel-spring-boot-starter ${camel.version} @@ -64,7 +64,8 @@ - 3.0.0-M4 + 11 + 3.15.0 \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-libraries-comparison/README.md b/spring-boot-modules/spring-boot-libraries-comparison/README.md new file mode 100644 index 0000000000..d373f91b3b --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries-comparison/README.md @@ -0,0 +1,7 @@ +## Spring Boot Libraries + +This module contains articles about various Spring Boot libraries Comparison + +### Relevant Articles: + +- [GraphQL vs REST](https://www.baeldung.com/graphql-vs-rest) diff --git a/spring-boot-modules/spring-boot-libraries-comparison/pom.xml b/spring-boot-modules/spring-boot-libraries-comparison/pom.xml new file mode 100644 index 0000000000..59d0e75be3 --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries-comparison/pom.xml @@ -0,0 +1,46 @@ + + + 4.0.0 + spring-boot-libraries-comparison + + + com.baeldung.spring-boot-modules + spring-boot-modules + 1.0.0-SNAPSHOT + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.data + spring-data-jpa + + + com.graphql-java + graphql-spring-boot-starter + ${graphql-spring-boot-starter.version} + + + com.graphql-java + graphql-java-tools + ${graphql-java-tools.version} + + + com.graphql-java + graphiql-spring-boot-starter + ${graphql-spring-boot-starter.version} + + + + + + 5.0.2 + 5.2.4 + + + \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-libraries-comparison/src/main/java/com/baeldung/graphqlvsrest/GraphqlVsRestApplication.java b/spring-boot-modules/spring-boot-libraries-comparison/src/main/java/com/baeldung/graphqlvsrest/GraphqlVsRestApplication.java new file mode 100644 index 0000000000..29a3ef1e0f --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries-comparison/src/main/java/com/baeldung/graphqlvsrest/GraphqlVsRestApplication.java @@ -0,0 +1,19 @@ +package com.baeldung.graphqlvsrest; + +import com.baeldung.graphqlvsrest.configuration.GraphqlConfiguration; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; +import org.springframework.context.annotation.Import; + +@SpringBootApplication +@Import(GraphqlConfiguration.class) +@EnableAutoConfiguration(exclude = {SecurityAutoConfiguration.class}) +public class GraphqlVsRestApplication { + + public static void main(String[] args) { + SpringApplication.run(GraphqlVsRestApplication.class, args); + } + +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-libraries-comparison/src/main/java/com/baeldung/graphqlvsrest/configuration/GraphqlConfiguration.java b/spring-boot-modules/spring-boot-libraries-comparison/src/main/java/com/baeldung/graphqlvsrest/configuration/GraphqlConfiguration.java new file mode 100644 index 0000000000..c100a03143 --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries-comparison/src/main/java/com/baeldung/graphqlvsrest/configuration/GraphqlConfiguration.java @@ -0,0 +1,35 @@ +package com.baeldung.graphqlvsrest.configuration; + +import com.baeldung.graphqlvsrest.repository.OrderRepository; +import com.baeldung.graphqlvsrest.resolver.Mutation; +import com.baeldung.graphqlvsrest.resolver.ProductResolver; +import com.baeldung.graphqlvsrest.resolver.Query; +import com.baeldung.graphqlvsrest.repository.ProductRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class GraphqlConfiguration { + + @Autowired + ProductRepository productRepository; + + @Autowired + OrderRepository orderRepository; + + @Bean + public Query query() { + return new Query(productRepository); + } + + @Bean + public ProductResolver productResolver(){ + return new ProductResolver(orderRepository); + } + + @Bean + public Mutation mutation() { + return new Mutation(productRepository); + } +} diff --git a/spring-boot-modules/spring-boot-libraries-comparison/src/main/java/com/baeldung/graphqlvsrest/controller/OrderController.java b/spring-boot-modules/spring-boot-libraries-comparison/src/main/java/com/baeldung/graphqlvsrest/controller/OrderController.java new file mode 100644 index 0000000000..14f0468bbd --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries-comparison/src/main/java/com/baeldung/graphqlvsrest/controller/OrderController.java @@ -0,0 +1,25 @@ +package com.baeldung.graphqlvsrest.controller; + +import com.baeldung.graphqlvsrest.entity.Order; +import com.baeldung.graphqlvsrest.entity.Product; +import com.baeldung.graphqlvsrest.model.ProductModel; +import com.baeldung.graphqlvsrest.repository.OrderRepository; +import com.baeldung.graphqlvsrest.repository.ProductRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Pageable; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController +@RequestMapping("order") +public class OrderController { + + @Autowired + OrderRepository orderRepository; + + @GetMapping() + public List getOrders(@RequestParam("product-id") Integer productId){ + return orderRepository.getOrdersByProduct(productId); + } +} diff --git a/spring-boot-modules/spring-boot-libraries-comparison/src/main/java/com/baeldung/graphqlvsrest/controller/ProductController.java b/spring-boot-modules/spring-boot-libraries-comparison/src/main/java/com/baeldung/graphqlvsrest/controller/ProductController.java new file mode 100644 index 0000000000..2fdee8765a --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries-comparison/src/main/java/com/baeldung/graphqlvsrest/controller/ProductController.java @@ -0,0 +1,38 @@ +package com.baeldung.graphqlvsrest.controller; + +import com.baeldung.graphqlvsrest.entity.Product; +import com.baeldung.graphqlvsrest.model.ProductModel; +import com.baeldung.graphqlvsrest.repository.ProductRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Pageable; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController +@RequestMapping("product") +public class ProductController { + + @Autowired + ProductRepository productRepository; + + @GetMapping + public List getProducts(Pageable pageable){ + return productRepository.getProducts(pageable.getPageSize(), pageable.getPageNumber()); + } + + @GetMapping("/{product-id}") + public Product getProducts(@PathVariable("product-id") Integer productId){ + return productRepository.getProduct(productId); + } + + @PostMapping + public Product save(@RequestBody ProductModel productModel){ + return productRepository.save(productModel); + } + + @PutMapping("/{product-id}") + public Product update(@PathVariable("product-id") Integer productId, @RequestBody ProductModel productModel){ + return productRepository.update(productId, productModel); + } +} diff --git a/spring-boot-modules/spring-boot-libraries-comparison/src/main/java/com/baeldung/graphqlvsrest/entity/Order.java b/spring-boot-modules/spring-boot-libraries-comparison/src/main/java/com/baeldung/graphqlvsrest/entity/Order.java new file mode 100644 index 0000000000..89606e9897 --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries-comparison/src/main/java/com/baeldung/graphqlvsrest/entity/Order.java @@ -0,0 +1,58 @@ +package com.baeldung.graphqlvsrest.entity; + +public class Order { + private Integer id; + private Integer product_id; + private String customer_uuid; + private String status; + private String address; + private String creation_date; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public Integer getProduct_id() { + return product_id; + } + + public void setProduct_id(Integer product_id) { + this.product_id = product_id; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getCustomer_uuid() { + return customer_uuid; + } + + public void setCustomer_uuid(String customer_uuid) { + this.customer_uuid = customer_uuid; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public String getCreation_date() { + return creation_date; + } + + public void setCreation_date(String creation_date) { + this.creation_date = creation_date; + } +} diff --git a/spring-boot-modules/spring-boot-libraries-comparison/src/main/java/com/baeldung/graphqlvsrest/entity/Product.java b/spring-boot-modules/spring-boot-libraries-comparison/src/main/java/com/baeldung/graphqlvsrest/entity/Product.java new file mode 100644 index 0000000000..2da9244c92 --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries-comparison/src/main/java/com/baeldung/graphqlvsrest/entity/Product.java @@ -0,0 +1,115 @@ +package com.baeldung.graphqlvsrest.entity; + +import com.baeldung.graphqlvsrest.model.ProductModel; + +import java.util.List; + +public class Product { + private Integer id; + private String name; + private String description; + private String status; + private String currency; + private Double price; + private List image_url; + private List video_url; + private Integer stock; + private Float average_rating; + + public Product(Integer id, ProductModel productModel) { + this.id = id; + this.name = productModel.getName(); + this.description = productModel.getDescription(); + this.currency = productModel.getCurrency(); + this.price = productModel.getPrice(); + this.stock = productModel.getStock(); + this.image_url = productModel.getImage_url(); + this.video_url = productModel.getVideo_url(); + this.average_rating = 0F; + this.status = productModel.getStatus(); + } + + public Product(){ + + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getCurrency() { + return currency; + } + + public void setCurrency(String currency) { + this.currency = currency; + } + + public Double getPrice() { + return price; + } + + public void setPrice(Double price) { + this.price = price; + } + + public List getImage_url() { + return image_url; + } + + public void setImage_url(List image_url) { + this.image_url = image_url; + } + + public List getVideo_url() { + return video_url; + } + + public void setVideo_url(List video_url) { + this.video_url = video_url; + } + + public Integer getStock() { + return stock; + } + + public void setStock(Integer stock) { + this.stock = stock; + } + + public Float getAverage_rating() { + return average_rating; + } + + public void setAverage_rating(Float average_rating) { + this.average_rating = average_rating; + } +} diff --git a/spring-boot-modules/spring-boot-libraries-comparison/src/main/java/com/baeldung/graphqlvsrest/model/ProductModel.java b/spring-boot-modules/spring-boot-libraries-comparison/src/main/java/com/baeldung/graphqlvsrest/model/ProductModel.java new file mode 100644 index 0000000000..db7a3ba54e --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries-comparison/src/main/java/com/baeldung/graphqlvsrest/model/ProductModel.java @@ -0,0 +1,92 @@ +package com.baeldung.graphqlvsrest.model; + +import java.util.List; + +public class ProductModel { + private String name; + private String description; + private String status; + private String currency; + private Double price; + private List image_url; + private List video_url; + private Integer stock; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getCurrency() { + return currency; + } + + public void setCurrency(String currency) { + this.currency = currency; + } + + public Double getPrice() { + return price; + } + + public void setPrice(Double price) { + this.price = price; + } + + public List getImage_url() { + return image_url; + } + + public void setImage_url(List image_url) { + this.image_url = image_url; + } + + public List getVideo_url() { + return video_url; + } + + public void setVideo_url(List video_url) { + this.video_url = video_url; + } + + public Integer getStock() { + return stock; + } + + public void setStock(Integer stock) { + this.stock = stock; + } + + @Override + public String toString() { + return "ProductModel{" + + "name='" + name + '\'' + + ", description='" + description + '\'' + + ", status='" + status + '\'' + + ", currency='" + currency + '\'' + + ", price=" + price + + ", image_url=" + image_url + + ", video_url=" + video_url + + ", stock=" + stock + + '}'; + } +} diff --git a/spring-boot-modules/spring-boot-libraries-comparison/src/main/java/com/baeldung/graphqlvsrest/repository/OrderRepository.java b/spring-boot-modules/spring-boot-libraries-comparison/src/main/java/com/baeldung/graphqlvsrest/repository/OrderRepository.java new file mode 100644 index 0000000000..92cc288426 --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries-comparison/src/main/java/com/baeldung/graphqlvsrest/repository/OrderRepository.java @@ -0,0 +1,11 @@ +package com.baeldung.graphqlvsrest.repository; + +import com.baeldung.graphqlvsrest.entity.Order; +import com.baeldung.graphqlvsrest.entity.Product; +import com.baeldung.graphqlvsrest.model.ProductModel; + +import java.util.List; + +public interface OrderRepository { + List getOrdersByProduct(Integer productId); +} diff --git a/spring-boot-modules/spring-boot-libraries-comparison/src/main/java/com/baeldung/graphqlvsrest/repository/ProductRepository.java b/spring-boot-modules/spring-boot-libraries-comparison/src/main/java/com/baeldung/graphqlvsrest/repository/ProductRepository.java new file mode 100644 index 0000000000..c0fb12327f --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries-comparison/src/main/java/com/baeldung/graphqlvsrest/repository/ProductRepository.java @@ -0,0 +1,14 @@ +package com.baeldung.graphqlvsrest.repository; + +import com.baeldung.graphqlvsrest.entity.Product; +import com.baeldung.graphqlvsrest.model.ProductModel; + +import java.util.List; + +public interface ProductRepository { + List getProducts(Integer pageSize, Integer pageNumber); + Product getProduct(Integer id); + Product save(ProductModel productModel); + Product update(Integer productId, ProductModel productModel); + +} diff --git a/spring-boot-modules/spring-boot-libraries-comparison/src/main/java/com/baeldung/graphqlvsrest/repository/impl/OrderRepositoryImpl.java b/spring-boot-modules/spring-boot-libraries-comparison/src/main/java/com/baeldung/graphqlvsrest/repository/impl/OrderRepositoryImpl.java new file mode 100644 index 0000000000..e4f316c865 --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries-comparison/src/main/java/com/baeldung/graphqlvsrest/repository/impl/OrderRepositoryImpl.java @@ -0,0 +1,36 @@ +package com.baeldung.graphqlvsrest.repository.impl; + +import com.baeldung.graphqlvsrest.entity.Order; +import com.baeldung.graphqlvsrest.repository.OrderRepository; +import org.springframework.stereotype.Repository; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.UUID; +import java.util.stream.Collectors; + +@Repository +public class OrderRepositoryImpl implements OrderRepository { + + private static List orderList = new ArrayList<>(); + + public OrderRepositoryImpl() { + for (int i = 1; i <= 100; i++){ + Order order = new Order(); + order.setId(i); + order.setProduct_id(i%10); + order.setAddress(UUID.randomUUID().toString()); + order.setCustomer_uuid(UUID.randomUUID().toString()); + order.setCreation_date(new Date(System.currentTimeMillis()).toString()); + order.setStatus("Delivered"); + orderList.add(order); + } + } + + + @Override + public List getOrdersByProduct(Integer productId) { + return orderList.stream().filter(order -> order.getProduct_id().equals(productId)).collect(Collectors.toList()); + } +} diff --git a/spring-boot-modules/spring-boot-libraries-comparison/src/main/java/com/baeldung/graphqlvsrest/repository/impl/ProductRepositoryImpl.java b/spring-boot-modules/spring-boot-libraries-comparison/src/main/java/com/baeldung/graphqlvsrest/repository/impl/ProductRepositoryImpl.java new file mode 100644 index 0000000000..845472faea --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries-comparison/src/main/java/com/baeldung/graphqlvsrest/repository/impl/ProductRepositoryImpl.java @@ -0,0 +1,74 @@ +package com.baeldung.graphqlvsrest.repository.impl; + +import com.baeldung.graphqlvsrest.entity.Product; +import com.baeldung.graphqlvsrest.model.ProductModel; +import com.baeldung.graphqlvsrest.repository.ProductRepository; +import org.springframework.stereotype.Repository; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +@Repository +public class ProductRepositoryImpl implements ProductRepository { + + private static List productList = new ArrayList<>(); + + public ProductRepositoryImpl() { + for (int i = 1; i <= 10; i++){ + Product product = new Product(); + product.setId(i); + product.setName(String.format("Product %d", i)); + product.setDescription(String.format("Product %d description", i)); + product.setCurrency(String.format("Product %d currency", i)); + product.setPrice(Double.valueOf(i^2)); + product.setStock(10); + product.setAverage_rating(0F); + product.setImage_url(Arrays.asList(String.format("www.baeldung.com/imageurl/%d", i))); + product.setVideo_url(Arrays.asList(String.format("www.baeldung.com/videourl/%d", i))); + productList.add(product); + } + } + + @Override + public List getProducts(Integer pageSize, Integer pageNumber) { + return productList.stream().skip(pageSize*pageNumber).limit(pageSize).collect(Collectors.toList()); + } + + @Override + public Product getProduct(Integer id) { + return productList.stream().filter(product -> product.getId().equals(id)).findFirst().orElse(null); + } + + @Override + public Product save(ProductModel productModel) { + Product product = new Product(productList.size()+1, productModel); + productList.add(product); + return product; + } + + @Override + public Product update(Integer productId, ProductModel productModel) { + Product product = getProduct(productId); + if (product != null){ + update(product, productModel); + } + return product; + } + + private void update(Product product, ProductModel productModel){ + if (productModel != null) { + System.out.println(productModel.toString()); + Optional.ofNullable(productModel.getName()).ifPresent(product::setName); + Optional.ofNullable(productModel.getDescription()).ifPresent(product::setDescription); + Optional.ofNullable(productModel.getCurrency()).ifPresent(product::setCurrency); + Optional.ofNullable(productModel.getImage_url()).ifPresent(product::setImage_url); + Optional.ofNullable(productModel.getStock()).ifPresent(product::setStock); + Optional.ofNullable(productModel.getStatus()).ifPresent(product::setStatus); + Optional.ofNullable(productModel.getVideo_url()).ifPresent(product::setVideo_url); + Optional.ofNullable(productModel.getPrice()).ifPresent(product::setPrice); + } + } +} diff --git a/spring-boot-modules/spring-boot-libraries-comparison/src/main/java/com/baeldung/graphqlvsrest/resolver/Mutation.java b/spring-boot-modules/spring-boot-libraries-comparison/src/main/java/com/baeldung/graphqlvsrest/resolver/Mutation.java new file mode 100644 index 0000000000..3d643f97e6 --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries-comparison/src/main/java/com/baeldung/graphqlvsrest/resolver/Mutation.java @@ -0,0 +1,22 @@ +package com.baeldung.graphqlvsrest.resolver; + +import com.baeldung.graphqlvsrest.entity.Product; +import com.baeldung.graphqlvsrest.model.ProductModel; +import com.baeldung.graphqlvsrest.repository.ProductRepository; +import com.coxautodev.graphql.tools.GraphQLMutationResolver; + +public class Mutation implements GraphQLMutationResolver { + + private ProductRepository productRepository; + public Mutation(ProductRepository productRepository){ + this.productRepository = productRepository; + } + + public Product saveProduct(ProductModel productModel) { + return productRepository.save(productModel); + } + + public Product updateProduct(Integer productId, ProductModel productModel) { + return productRepository.update(productId, productModel); + } +} diff --git a/spring-boot-modules/spring-boot-libraries-comparison/src/main/java/com/baeldung/graphqlvsrest/resolver/ProductResolver.java b/spring-boot-modules/spring-boot-libraries-comparison/src/main/java/com/baeldung/graphqlvsrest/resolver/ProductResolver.java new file mode 100644 index 0000000000..f20b8d5920 --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries-comparison/src/main/java/com/baeldung/graphqlvsrest/resolver/ProductResolver.java @@ -0,0 +1,18 @@ +package com.baeldung.graphqlvsrest.resolver; + +import com.baeldung.graphqlvsrest.entity.Order; +import com.baeldung.graphqlvsrest.entity.Product; +import com.baeldung.graphqlvsrest.repository.OrderRepository; +import com.coxautodev.graphql.tools.GraphQLResolver; + +import java.util.List; + +public class ProductResolver implements GraphQLResolver { + private OrderRepository orderRepository; + public ProductResolver(OrderRepository orderRepository){ + this.orderRepository = orderRepository; + } + public List getOrders(Product product){ + return orderRepository.getOrdersByProduct(product.getId()); + } +} diff --git a/spring-boot-modules/spring-boot-libraries-comparison/src/main/java/com/baeldung/graphqlvsrest/resolver/Query.java b/spring-boot-modules/spring-boot-libraries-comparison/src/main/java/com/baeldung/graphqlvsrest/resolver/Query.java new file mode 100644 index 0000000000..0d218261b2 --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries-comparison/src/main/java/com/baeldung/graphqlvsrest/resolver/Query.java @@ -0,0 +1,27 @@ +package com.baeldung.graphqlvsrest.resolver; + +import com.baeldung.graphqlvsrest.entity.Order; +import com.baeldung.graphqlvsrest.entity.Product; +import com.baeldung.graphqlvsrest.repository.OrderRepository; +import com.baeldung.graphqlvsrest.repository.ProductRepository; +import com.coxautodev.graphql.tools.GraphQLQueryResolver; + +import java.util.List; + +public class Query implements GraphQLQueryResolver { + + private ProductRepository productRepository; + public Query(ProductRepository productRepository){ + this.productRepository = productRepository; + } + + public List getProducts(int pageSize, int pageNumber) { + return productRepository.getProducts(pageSize, pageNumber); + } + + public Product getProduct(int id) { + return productRepository.getProduct(id); + } + + +} diff --git a/spring-boot-modules/spring-boot-libraries-comparison/src/main/resources/application.properties b/spring-boot-modules/spring-boot-libraries-comparison/src/main/resources/application.properties new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spring-boot-modules/spring-boot-libraries-comparison/src/main/resources/graphql/schema.graphqls b/spring-boot-modules/spring-boot-libraries-comparison/src/main/resources/graphql/schema.graphqls new file mode 100644 index 0000000000..2709510d72 --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries-comparison/src/main/resources/graphql/schema.graphqls @@ -0,0 +1,57 @@ +type Product { + id: ID + name: String! + description: String + status: String + currency: String! + price: Float + image_url: [String] + video_url: [String] + stock: Int + average_rating: Float + orders:[Order] +} + +type Order{ + id:ID + product_id:Int + customer_uuid:String + address:String + status:String + creation_date:String +} + +input ProductModel { + name: String! + description: String + status: String + currency: String! + price: Float + image_url: [String] + video_url: [String] + stock: Int +} + +input ProductUpdateModel { + name: String + description: String + status: String + currency: String + price: Float + image_url: [String] + video_url: [String] + stock: Int +} + + +# The Root Query for the application +type Query { + products(size: Int, page: Int): [Product]! + product(id: Int): Product! +} + +# The Root Mutation for the application +type Mutation { + saveProduct(product: ProductModel) : Product! + updateProduct(id: Int, product: ProductUpdateModel) : Product! +} diff --git a/spring-boot-modules/spring-boot-logging-log4j2/pom.xml b/spring-boot-modules/spring-boot-logging-log4j2/pom.xml index 8cf052deb3..036df19887 100644 --- a/spring-boot-modules/spring-boot-logging-log4j2/pom.xml +++ b/spring-boot-modules/spring-boot-logging-log4j2/pom.xml @@ -102,6 +102,7 @@ 4.13.2 5.8.1 + 2.17.1 \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-mvc-birt/pom.xml b/spring-boot-modules/spring-boot-mvc-birt/pom.xml index 16b07000f8..8f1c770bbe 100644 --- a/spring-boot-modules/spring-boot-mvc-birt/pom.xml +++ b/spring-boot-modules/spring-boot-mvc-birt/pom.xml @@ -70,6 +70,7 @@ 1.8 4.8.0 1.2.17 + 2.17.1 \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-react/pom.xml b/spring-boot-modules/spring-boot-react/pom.xml index d515aed6ce..dc0c6914c9 100644 --- a/spring-boot-modules/spring-boot-react/pom.xml +++ b/spring-boot-modules/spring-boot-react/pom.xml @@ -11,6 +11,18 @@ 1.0.0-SNAPSHOT + + + + org.apache.logging.log4j + log4j-bom + ${log4j2.version} + import + pom + + + + org.springframework.boot @@ -128,6 +140,7 @@ v1.12.1 2.4.4 1.0.2 + 2.17.1 \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-security/README.md b/spring-boot-modules/spring-boot-security/README.md index b9966709cb..d848f798ba 100644 --- a/spring-boot-modules/spring-boot-security/README.md +++ b/spring-boot-modules/spring-boot-security/README.md @@ -10,6 +10,7 @@ This module contains articles about Spring Boot Security - [Guide to @CurrentSecurityContext in Spring Security](https://www.baeldung.com/spring-currentsecuritycontext) - [Disable Security for a Profile in Spring Boot](https://www.baeldung.com/spring-security-disable-profile) - [Spring @EnableWebSecurity vs. @EnableGlobalMethodSecurity](https://www.baeldung.com/spring-enablewebsecurity-vs-enableglobalmethodsecurity) +- [Spring Security – Configuring Different URLs](https://www.baeldung.com/spring-security-configuring-urls) ### Spring Boot Security Auto-Configuration diff --git a/spring-boot-modules/spring-boot-swagger-keycloak/pom.xml b/spring-boot-modules/spring-boot-swagger-keycloak/pom.xml index 82e1951b8e..a7f3e01014 100644 --- a/spring-boot-modules/spring-boot-swagger-keycloak/pom.xml +++ b/spring-boot-modules/spring-boot-swagger-keycloak/pom.xml @@ -24,6 +24,13 @@ pom import + + org.apache.logging.log4j + log4j-bom + ${log4j2.version} + import + pom + @@ -62,6 +69,7 @@ 2.4.5 3.0.0 15.0.2 + 2.17.1 diff --git a/spring-boot-modules/spring-boot-swagger/README.md b/spring-boot-modules/spring-boot-swagger/README.md index 174bfe626d..a09df23a80 100644 --- a/spring-boot-modules/spring-boot-swagger/README.md +++ b/spring-boot-modules/spring-boot-swagger/README.md @@ -5,3 +5,4 @@ - [Generate PDF from Swagger API Documentation](https://www.baeldung.com/swagger-generate-pdf) - [Remove Basic Error Controller In SpringFox Swagger-UI](https://www.baeldung.com/spring-swagger-remove-error-controller) - [Setting Example and Description with Swagger](https://www.baeldung.com/swagger-set-example-description) +- [Document Enum in Swagger](https://www.baeldung.com/swagger-enum) diff --git a/spring-boot-modules/spring-boot-testing/pom.xml b/spring-boot-modules/spring-boot-testing/pom.xml index 658eb7728e..fcfc2364ba 100644 --- a/spring-boot-modules/spring-boot-testing/pom.xml +++ b/spring-boot-modules/spring-boot-testing/pom.xml @@ -14,6 +14,18 @@ 1.0.0-SNAPSHOT + + + + org.apache.logging.log4j + log4j-bom + ${log4j2.version} + import + pom + + + + org.springframework.boot @@ -131,6 +143,7 @@ 1.6 0.7.2 2.5.0 + 2.17.1 \ No newline at end of file diff --git a/spring-cloud/spring-cloud-contract/pom.xml b/spring-cloud/spring-cloud-contract/pom.xml index 8546e76586..6e8b130ed1 100644 --- a/spring-cloud/spring-cloud-contract/pom.xml +++ b/spring-cloud/spring-cloud-contract/pom.xml @@ -21,6 +21,13 @@ + + org.apache.logging.log4j + log4j-bom + ${log4j2.version} + import + pom + org.springframework.boot spring-boot-starter-web @@ -55,6 +62,7 @@ 2.1.1.RELEASE 2.1.4.RELEASE + 2.17.1 \ No newline at end of file diff --git a/spring-cloud/spring-cloud-eureka-self-preservation/pom.xml b/spring-cloud/spring-cloud-eureka-self-preservation/pom.xml index 0b7da2ce4a..e22ad6b7c9 100644 --- a/spring-cloud/spring-cloud-eureka-self-preservation/pom.xml +++ b/spring-cloud/spring-cloud-eureka-self-preservation/pom.xml @@ -14,6 +14,18 @@ spring-cloud 1.0.0-SNAPSHOT + + + + + org.apache.logging.log4j + log4j-bom + ${log4j2.version} + import + pom + + + spring-cloud-eureka-server @@ -32,6 +44,7 @@ 2.1.3.RELEASE Greenwich.SR3 + 2.17.1 \ No newline at end of file diff --git a/spring-cloud/spring-cloud-eureka/pom.xml b/spring-cloud/spring-cloud-eureka/pom.xml index e5327d4530..795eab7d6e 100644 --- a/spring-cloud/spring-cloud-eureka/pom.xml +++ b/spring-cloud/spring-cloud-eureka/pom.xml @@ -14,6 +14,18 @@ spring-cloud 1.0.0-SNAPSHOT + + + + + org.apache.logging.log4j + log4j-bom + ${log4j2.version} + import + pom + + + spring-cloud-eureka-server @@ -34,6 +46,7 @@ 2.1.2.RELEASE Greenwich.RELEASE + 2.17.1 \ No newline at end of file diff --git a/spring-cloud/spring-cloud-load-balancer/pom.xml b/spring-cloud/spring-cloud-load-balancer/pom.xml index 9c650565ed..65cf83de09 100644 --- a/spring-cloud/spring-cloud-load-balancer/pom.xml +++ b/spring-cloud/spring-cloud-load-balancer/pom.xml @@ -19,6 +19,18 @@ spring-cloud-loadbalancer-server spring-cloud-loadbalancer-client + + + + + org.apache.logging.log4j + log4j-bom + ${log4j2.version} + import + pom + + + @@ -32,6 +44,7 @@ 2.6.1 2021.0.0 + 2.17.1 diff --git a/spring-cloud/spring-cloud-openfeign/README.md b/spring-cloud/spring-cloud-openfeign/README.md index 5d3dc060c7..44f4d15b16 100644 --- a/spring-cloud/spring-cloud-openfeign/README.md +++ b/spring-cloud/spring-cloud-openfeign/README.md @@ -4,3 +4,4 @@ - [Differences Between Netflix Feign and OpenFeign](https://www.baeldung.com/netflix-feign-vs-openfeign) - [File Upload With Open Feign](https://www.baeldung.com/java-feign-file-upload) - [Feign Logging Configuration](https://www.baeldung.com/java-feign-logging) +- [Provide an OAuth2 Token to a Feign Client](https://www.baeldung.com/spring-cloud-feign-oauth-token) diff --git a/spring-cloud/spring-cloud-stream-starters/twitterhdfs/pom.xml b/spring-cloud/spring-cloud-stream-starters/twitterhdfs/pom.xml index 1c8fa4e694..73d6e62d37 100644 --- a/spring-cloud/spring-cloud-stream-starters/twitterhdfs/pom.xml +++ b/spring-cloud/spring-cloud-stream-starters/twitterhdfs/pom.xml @@ -78,6 +78,7 @@ 4.13.2 5.8.1 + 2.17.1 \ No newline at end of file diff --git a/spring-cloud/spring-cloud-zuul-eureka-integration/eureka-client/pom.xml b/spring-cloud/spring-cloud-zuul-eureka-integration/eureka-client/pom.xml index 3514924198..b2cb66744b 100644 --- a/spring-cloud/spring-cloud-zuul-eureka-integration/eureka-client/pom.xml +++ b/spring-cloud/spring-cloud-zuul-eureka-integration/eureka-client/pom.xml @@ -17,6 +17,13 @@ + + org.apache.logging.log4j + log4j-bom + ${log4j2.version} + import + pom + org.springframework.cloud spring-cloud-starter-parent @@ -45,5 +52,9 @@ test + + + 2.17.1 + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-zuul-eureka-integration/eureka-server/pom.xml b/spring-cloud/spring-cloud-zuul-eureka-integration/eureka-server/pom.xml index dcd912df07..466291650c 100644 --- a/spring-cloud/spring-cloud-zuul-eureka-integration/eureka-server/pom.xml +++ b/spring-cloud/spring-cloud-zuul-eureka-integration/eureka-server/pom.xml @@ -17,6 +17,13 @@ + + org.apache.logging.log4j + log4j-bom + ${log4j2.version} + import + pom + org.springframework.cloud spring-cloud-starter-parent @@ -45,5 +52,9 @@ test + + + 2.17.1 + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-zuul-eureka-integration/zuul-server/pom.xml b/spring-cloud/spring-cloud-zuul-eureka-integration/zuul-server/pom.xml index bb38ec1351..27afc3eb69 100644 --- a/spring-cloud/spring-cloud-zuul-eureka-integration/zuul-server/pom.xml +++ b/spring-cloud/spring-cloud-zuul-eureka-integration/zuul-server/pom.xml @@ -14,6 +14,13 @@ + + org.apache.logging.log4j + log4j-bom + ${log4j2.version} + import + pom + org.springframework.cloud spring-cloud-starter-parent @@ -53,5 +60,9 @@ test + + + 2.17.1 + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-zuul/spring-zuul-rate-limiting/pom.xml b/spring-cloud/spring-cloud-zuul/spring-zuul-rate-limiting/pom.xml index 2969b5eed9..4727859ea2 100644 --- a/spring-cloud/spring-cloud-zuul/spring-zuul-rate-limiting/pom.xml +++ b/spring-cloud/spring-cloud-zuul/spring-zuul-rate-limiting/pom.xml @@ -13,6 +13,18 @@ spring-cloud-zuul 0.0.1-SNAPSHOT + + + + + org.apache.logging.log4j + log4j-bom + ${log4j2.version} + import + pom + + + @@ -44,6 +56,7 @@ 2.2.0.RELEASE 2.4.7 2020.0.4 + 2.17.1 \ No newline at end of file diff --git a/spring-di-2/pom.xml b/spring-di-2/pom.xml index d3be846424..1207506d17 100644 --- a/spring-di-2/pom.xml +++ b/spring-di-2/pom.xml @@ -16,6 +16,13 @@ + + org.apache.logging.log4j + log4j-bom + ${log4j2.version} + import + pom + org.springframework.boot spring-boot-dependencies @@ -80,6 +87,7 @@ 2.6.1 1.11 1 + 2.17.1 \ No newline at end of file diff --git a/spring-di-3/README.md b/spring-di-3/README.md index 9ab7789f37..4246069616 100644 --- a/spring-di-3/README.md +++ b/spring-di-3/README.md @@ -5,4 +5,5 @@ This module contains articles about dependency injection with Spring ### Relevant Articles - [@Lookup Annotation in Spring](https://www.baeldung.com/spring-lookup) +- [Spring @Autowired Field Null – Common Causes and Solutions](https://www.baeldung.com/spring-autowired-field-null) - More articles: [[<-- prev]](../spring-di-2) diff --git a/spring-di-3/pom.xml b/spring-di-3/pom.xml index 0d4bbd01af..c6a2687606 100644 --- a/spring-di-3/pom.xml +++ b/spring-di-3/pom.xml @@ -16,6 +16,13 @@ + + org.apache.logging.log4j + log4j-bom + ${log4j2.version} + import + pom + org.springframework.boot spring-boot-dependencies @@ -40,6 +47,7 @@ 2.6.1 + 2.17.1 \ No newline at end of file diff --git a/spring-native/pom.xml b/spring-native/pom.xml index 4455e050f2..f54d7b5308 100644 --- a/spring-native/pom.xml +++ b/spring-native/pom.xml @@ -75,6 +75,7 @@ 1.8 1.8 1.8 + 2.17.1 \ No newline at end of file diff --git a/spring-roo/pom.xml b/spring-roo/pom.xml index b55a334256..ea42095d92 100644 --- a/spring-roo/pom.xml +++ b/spring-roo/pom.xml @@ -625,6 +625,7 @@ 1.0.3 2.0.0.RELEASE 1.2.0 + 2.17.1 \ No newline at end of file diff --git a/spring-security-modules/spring-5-security-oauth/pom.xml b/spring-security-modules/spring-5-security-oauth/pom.xml index aa4958ae47..706cdb3082 100644 --- a/spring-security-modules/spring-5-security-oauth/pom.xml +++ b/spring-security-modules/spring-5-security-oauth/pom.xml @@ -15,6 +15,19 @@ 0.0.1-SNAPSHOT ../../parent-boot-2 + + + + + org.apache.logging.log4j + log4j-bom + ${log4j2.version} + import + pom + + + + @@ -72,6 +85,7 @@ is available --> 2.5.2 com.baeldung.oauth2.SpringOAuthApplication + 2.17.1 \ No newline at end of file diff --git a/spring-security-modules/spring-security-legacy-oidc/pom.xml b/spring-security-modules/spring-security-legacy-oidc/pom.xml index ca54a6765d..9dd898f9dd 100644 --- a/spring-security-modules/spring-security-legacy-oidc/pom.xml +++ b/spring-security-modules/spring-security-legacy-oidc/pom.xml @@ -14,6 +14,18 @@ 0.0.1-SNAPSHOT ../../parent-boot-2 + + + + + org.apache.logging.log4j + log4j-bom + ${log4j2.version} + import + pom + + + @@ -50,6 +62,7 @@ 1.0.9.RELEASE 0.3.0 2.4.7 + 2.17.1 \ No newline at end of file diff --git a/spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/logging/LoggingController.java b/spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/logging/LoggingController.java new file mode 100644 index 0000000000..c2d47fe6d6 --- /dev/null +++ b/spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/logging/LoggingController.java @@ -0,0 +1,16 @@ +package com.baeldung.logging; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; + +@Controller +public class LoggingController { + + @GetMapping("/logging") + public ResponseEntity logging() { + return new ResponseEntity<>("logging/baeldung", HttpStatus.OK); + } + +} diff --git a/spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/logging/SecurityConfig.java b/spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/logging/SecurityConfig.java new file mode 100644 index 0000000000..f48f817dd2 --- /dev/null +++ b/spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/logging/SecurityConfig.java @@ -0,0 +1,26 @@ +package com.baeldung.logging; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.builders.WebSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; + +@EnableWebSecurity +public class SecurityConfig extends WebSecurityConfigurerAdapter { + + @Value("${spring.websecurity.debug:false}") + boolean webSecurityDebug; + + @Override + public void configure(WebSecurity web) { + web.debug(webSecurityDebug); + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + http.authorizeRequests() + .antMatchers("/**") + .permitAll(); + } +} diff --git a/spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/logging/SecurityLoggingApplication.java b/spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/logging/SecurityLoggingApplication.java new file mode 100644 index 0000000000..2fadf1cc26 --- /dev/null +++ b/spring-security-modules/spring-security-web-boot-3/src/main/java/com/baeldung/logging/SecurityLoggingApplication.java @@ -0,0 +1,14 @@ +package com.baeldung.logging; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class SecurityLoggingApplication { + + public static void main(String... args) { + SpringApplication application = new SpringApplication(SecurityLoggingApplication.class); + application.setAdditionalProfiles("logging"); + application.run(args); + } +} diff --git a/spring-security-modules/spring-security-web-boot-3/src/main/resources/application-logging.properties b/spring-security-modules/spring-security-web-boot-3/src/main/resources/application-logging.properties new file mode 100644 index 0000000000..4f0c3450a3 --- /dev/null +++ b/spring-security-modules/spring-security-web-boot-3/src/main/resources/application-logging.properties @@ -0,0 +1,4 @@ + +logging.level.org.springframework.security=DEBUG + +spring.websecurity.debug=true \ No newline at end of file diff --git a/spring-swagger-codegen/custom-validations-opeanpi-codegen/pom.xml b/spring-swagger-codegen/custom-validations-opeanpi-codegen/pom.xml index 336cb0da74..9add9ae494 100644 --- a/spring-swagger-codegen/custom-validations-opeanpi-codegen/pom.xml +++ b/spring-swagger-codegen/custom-validations-opeanpi-codegen/pom.xml @@ -100,6 +100,7 @@ 11 3.0.0 + 2.17.1 \ No newline at end of file diff --git a/spring-web-modules/spring-boot-jsp/pom.xml b/spring-web-modules/spring-boot-jsp/pom.xml index b9b4a97e6b..d2a363bafa 100644 --- a/spring-web-modules/spring-boot-jsp/pom.xml +++ b/spring-web-modules/spring-boot-jsp/pom.xml @@ -23,6 +23,13 @@ pom import + + org.apache.logging.log4j + log4j-bom + ${log4j2.version} + import + pom + org.springframework.boot spring-boot-dependencies @@ -92,6 +99,7 @@ 1.2 2.4.4 + 2.17.1 \ No newline at end of file