diff --git a/apache-poi-2/src/test/java/com/baeldung/poi/excel/lastrow/LastRowUnitTest.java b/apache-poi-2/src/test/java/com/baeldung/poi/excel/lastrow/LastRowUnitTest.java
new file mode 100644
index 0000000000..ea838be4ce
--- /dev/null
+++ b/apache-poi-2/src/test/java/com/baeldung/poi/excel/lastrow/LastRowUnitTest.java
@@ -0,0 +1,67 @@
+package com.baeldung.poi.excel.lastrow;
+
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.nio.file.Paths;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+public class LastRowUnitTest {
+ private static final String FILE_NAME = "lastRowTest.xlsx";
+ private String fileLocation;
+
+ @Before
+ public void setup() throws URISyntaxException {
+ fileLocation = Paths.get(ClassLoader.getSystemResource(FILE_NAME).toURI()).toString();
+ }
+
+ @Test
+ public void givenExampleGrid_whenGetRow_thenReturnRowObjectIfModified() throws IOException {
+ Workbook workbook = new XSSFWorkbook(fileLocation);
+ Sheet sheet = workbook.getSheetAt(0);
+
+ assertEquals(7, sheet.getLastRowNum());
+ assertEquals(6, sheet.getPhysicalNumberOfRows());
+
+ assertNotNull(sheet.getRow(0));
+ assertNotNull(sheet.getRow(1));
+ assertNotNull(sheet.getRow(2));
+ assertNotNull(sheet.getRow(3));
+ assertNull(sheet.getRow(4));
+ assertNull(sheet.getRow(5));
+ assertNotNull(sheet.getRow(6));
+ assertNotNull(sheet.getRow(7));
+ assertNull(sheet.getRow(8));
+
+ assertSame(sheet.getRow(7), getLastRowFromSheet(sheet));
+ }
+
+ @Test
+ public void givenEmptySheet_whenGetRow_thenReturnNull() throws IOException {
+ Workbook workbook = new XSSFWorkbook(fileLocation);
+ Sheet sheet = workbook.getSheetAt(1);
+
+ assertEquals(-1, sheet.getLastRowNum());
+ assertEquals(0, sheet.getPhysicalNumberOfRows());
+
+ assertNull(sheet.getRow(0));
+
+ assertSame(sheet.getRow(0), getLastRowFromSheet(sheet));
+ }
+
+ public static Row getLastRowFromSheet(Sheet sheet) {
+ Row lastRow = null;
+ int lastRowNum = sheet.getLastRowNum();
+ if (lastRowNum >= 0) {
+ lastRow = sheet.getRow(lastRowNum);
+ }
+ return lastRow;
+ }
+}
diff --git a/apache-poi-2/src/test/resources/lastRowTest.xlsx b/apache-poi-2/src/test/resources/lastRowTest.xlsx
new file mode 100644
index 0000000000..3980ceb1f2
Binary files /dev/null and b/apache-poi-2/src/test/resources/lastRowTest.xlsx differ
diff --git a/core-java-modules/core-java-collections-maps-4/README.md b/core-java-modules/core-java-collections-maps-4/README.md
index 795f0df702..92da12fbf9 100644
--- a/core-java-modules/core-java-collections-maps-4/README.md
+++ b/core-java-modules/core-java-collections-maps-4/README.md
@@ -6,3 +6,5 @@ This module contains articles about Map data structures in Java.
- [Using a Custom Class as a Key in a Java HashMap](https://www.baeldung.com/java-custom-class-map-key)
- [Nested HashMaps Examples in Java](https://www.baeldung.com/java-nested-hashmaps)
- [Java HashMap With Different Value Types](https://www.baeldung.com/java-hashmap-different-value-types)
+- [Difference Between Map and HashMap in Java](https://www.baeldung.com/java-map-vs-hashmap)
+- [How to Create a New Entry in a Map](https://www.baeldung.com/java-map-new-entry)
diff --git a/core-java-modules/core-java-concurrency-advanced-4/README.md b/core-java-modules/core-java-concurrency-advanced-4/README.md
index 446a553b88..ba838dbc72 100644
--- a/core-java-modules/core-java-concurrency-advanced-4/README.md
+++ b/core-java-modules/core-java-concurrency-advanced-4/README.md
@@ -4,3 +4,4 @@
- [Bad Practices With Synchronization](https://www.baeldung.com/java-synchronization-bad-practices)
- [Start Two Threads at the Exact Same Time in Java](https://www.baeldung.com/java-start-two-threads-at-same-time)
- [Volatile Variables and Thread Safety](https://www.baeldung.com/java-volatile-variables-thread-safety)
+- [Producer-Consumer Problem With Example in Java](https://www.baeldung.com/java-producer-consumer-problem)
diff --git a/core-java-modules/core-java-exceptions-4/README.md b/core-java-modules/core-java-exceptions-4/README.md
index 259feb685c..e77787a8a3 100644
--- a/core-java-modules/core-java-exceptions-4/README.md
+++ b/core-java-modules/core-java-exceptions-4/README.md
@@ -1,3 +1,4 @@
### Relevant Articles:
- [Java ArrayIndexOutOfBoundsException](https://www.baeldung.com/java-arrayindexoutofboundsexception)
+- [Java Missing Return Statement](https://www.baeldung.com/java-missing-return-statement)
diff --git a/core-java-modules/core-java-exceptions-4/src/main/java/com/baeldung/exception/variablemightnothavebeeninitialized/VariableMightNotHaveBeenInitialized.java b/core-java-modules/core-java-exceptions-4/src/main/java/com/baeldung/exception/variablemightnothavebeeninitialized/VariableMightNotHaveBeenInitialized.java
deleted file mode 100644
index 64118e6307..0000000000
--- a/core-java-modules/core-java-exceptions-4/src/main/java/com/baeldung/exception/variablemightnothavebeeninitialized/VariableMightNotHaveBeenInitialized.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package com.baeldung.exception.variablemightnothavebeeninitialized;
-
-public class VariableMightNotHaveBeenInitialized {
-
- private static int instanceVariableCount;
-
- /**
- * Method would not compile if lines 14 and 18 are uncommented.
- */
- public static void countEven() {
- //uninstantiated
- int count;
- int[] arr = new int[]{23, 56, 89, 12, 23};
- for (int i = 0; i < arr.length; i++) {
- if ((arr[i] % 2) == 0) {
- // count++;
- }
-
- }
- // System.out.println("Total Even Numbers : " + count);
- }
-
- public static int countEvenUsingInstanceVariable(int[] arr) {
-
- for (int i = 0; i < arr.length; i++) {
- if ((arr[i] % 2) == 0) {
- instanceVariableCount++;
- }
-
- }
- return instanceVariableCount;
- }
-
- public static int countEvenUsingIfElse(int[] arr, int args) {
- int count;
- count = args > 0 ? args : 0;
- for (int i = 0; i < arr.length; i++) {
- if ((arr[i] % 2) == 0) {
- count++;
- }
-
- }
- return count;
- }
-}
diff --git a/core-java-modules/core-java-exceptions-4/src/test/java/com/baeldung/exception/variablemightnothavebeeninitialized/VariableMightNotHaveBeenInitializedUnitTest.java b/core-java-modules/core-java-exceptions-4/src/test/java/com/baeldung/exception/variablemightnothavebeeninitialized/VariableMightNotHaveBeenInitializedUnitTest.java
deleted file mode 100644
index c4773d6442..0000000000
--- a/core-java-modules/core-java-exceptions-4/src/test/java/com/baeldung/exception/variablemightnothavebeeninitialized/VariableMightNotHaveBeenInitializedUnitTest.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package com.baeldung.exception.variablemightnothavebeeninitialized;
-
-import org.junit.Test;
-
-import static org.junit.Assert.assertEquals;
-
-public class VariableMightNotHaveBeenInitializedUnitTest {
-
- @Test
- public void usingInstanceVariable_returnCount() {
- int[] arr = new int[]{1, 2, 3, 4, 5, 6};
- int value = VariableMightNotHaveBeenInitialized.countEvenUsingInstanceVariable(arr);
-
- assertEquals(3, value);
- }
-
- @Test
- public void usingArgumentsAndIfElse_returnCount() {
- int[] arr = new int[]{1, 2, 3, 4, 5, 6};
- int value = VariableMightNotHaveBeenInitialized.countEvenUsingIfElse(arr, 2);
-
- assertEquals(5, value);
- }
-}
diff --git a/core-java-modules/core-java-io-4/src/main/java/com/baeldung/filetomap/FileToHashMap.java b/core-java-modules/core-java-io-4/src/main/java/com/baeldung/filetomap/FileToHashMap.java
new file mode 100644
index 0000000000..f88404a1a4
--- /dev/null
+++ b/core-java-modules/core-java-io-4/src/main/java/com/baeldung/filetomap/FileToHashMap.java
@@ -0,0 +1,83 @@
+package com.baeldung.filetomap;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+public class FileToHashMap {
+
+ enum DupKeyOption {
+ OVERWRITE, DISCARD
+ }
+
+ public static Map byBufferedReader(String filePath, DupKeyOption dupKeyOption) {
+ HashMap map = new HashMap<>();
+ String line;
+ try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
+ while ((line = reader.readLine()) != null) {
+ String[] keyValuePair = line.split(":", 2);
+ if (keyValuePair.length > 1) {
+ String key = keyValuePair[0];
+ String value = keyValuePair[1];
+ if (DupKeyOption.OVERWRITE == dupKeyOption) {
+ map.put(key, value);
+ } else if (DupKeyOption.DISCARD == dupKeyOption) {
+ map.putIfAbsent(key, value);
+ }
+ } else {
+ System.out.println("No Key:Value found in line, ignoring: " + line);
+ }
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return map;
+ }
+
+ public static Map byStream(String filePath, DupKeyOption dupKeyOption) {
+ Map map = new HashMap<>();
+ try (Stream lines = Files.lines(Paths.get(filePath))) {
+ lines.filter(line -> line.contains(":"))
+ .forEach(line -> {
+ String[] keyValuePair = line.split(":", 2);
+ String key = keyValuePair[0];
+ String value = keyValuePair[1];
+ if (DupKeyOption.OVERWRITE == dupKeyOption) {
+ map.put(key, value);
+ } else if (DupKeyOption.DISCARD == dupKeyOption) {
+ map.putIfAbsent(key, value);
+ }
+ });
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return map;
+ }
+
+ public static Map> aggregateByKeys(String filePath) {
+ Map> map = new HashMap<>();
+ try (Stream lines = Files.lines(Paths.get(filePath))) {
+ lines.filter(line -> line.contains(":"))
+ .forEach(line -> {
+ String[] keyValuePair = line.split(":", 2);
+ String key = keyValuePair[0];
+ String value = keyValuePair[1];
+ if (map.containsKey(key)) {
+ map.get(key).add(value);
+ } else {
+ map.put(key, Stream.of(value).collect(Collectors.toList()));
+ }
+ });
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return map;
+ }
+}
diff --git a/core-java-modules/core-java-io-4/src/test/java/com/baeldung/filetomap/FileToHashMapUnitTest.java b/core-java-modules/core-java-io-4/src/test/java/com/baeldung/filetomap/FileToHashMapUnitTest.java
new file mode 100644
index 0000000000..c89f26de69
--- /dev/null
+++ b/core-java-modules/core-java-io-4/src/test/java/com/baeldung/filetomap/FileToHashMapUnitTest.java
@@ -0,0 +1,66 @@
+package com.baeldung.filetomap;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.net.URISyntaxException;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class FileToHashMapUnitTest {
+
+ private String filePath;
+
+ private static final Map EXPECTED_MAP_DISCARD = Stream.of(new String[][]{
+ {"title", "The Lord of the Rings: The Return of the King"},
+ {"director", "Peter Jackson"},
+ {"actor", "Sean Astin"}
+ }).collect(Collectors.toMap(data -> data[0], data -> data[1]));
+
+ private static final Map EXPECTED_MAP_OVERWRITE = Stream.of(new String[][]{
+ {"title", "The Lord of the Rings: The Return of the King"},
+ {"director", "Peter Jackson"},
+ {"actor", "Ian McKellen"}
+ }).collect(Collectors.toMap(data -> data[0], data -> data[1]));
+
+ private static final Map> EXPECTED_MAP_AGGREGATE = Stream.of(new String[][]{
+ {"title", "The Lord of the Rings: The Return of the King"},
+ {"director", "Peter Jackson"},
+ {"actor", "Sean Astin", "Ian McKellen"}
+ }).collect(Collectors.toMap(arr -> arr[0], arr -> Arrays.asList(Arrays.copyOfRange(arr, 1, arr.length))));
+
+ @Before
+ public void setPath() throws URISyntaxException {
+ if (filePath == null) {
+ filePath = Paths.get(ClassLoader.getSystemResource("filetomap/theLordOfRings.txt").toURI()).toString();
+ }
+ }
+
+ @Test
+ public void givenInputFile_whenInvokeByBufferedReaderPriorToJava8_shouldGetExpectedMap() {
+ Map mapOverwrite = FileToHashMap.byBufferedReader(filePath, FileToHashMap.DupKeyOption.OVERWRITE);
+ Map mapDiscard = FileToHashMap.byBufferedReader(filePath, FileToHashMap.DupKeyOption.DISCARD);
+ assertThat(mapOverwrite).isEqualTo(EXPECTED_MAP_OVERWRITE);
+ assertThat(mapDiscard).isEqualTo(EXPECTED_MAP_DISCARD);
+ }
+
+ @Test
+ public void givenInputFile_whenInvokeByStream_shouldGetExpectedMap() {
+ Map mapOverwrite = FileToHashMap.byStream(filePath, FileToHashMap.DupKeyOption.OVERWRITE);
+ Map mapDiscard = FileToHashMap.byStream(filePath, FileToHashMap.DupKeyOption.DISCARD);
+ assertThat(mapOverwrite).isEqualTo(EXPECTED_MAP_OVERWRITE);
+ assertThat(mapDiscard).isEqualTo(EXPECTED_MAP_DISCARD);
+ }
+
+ @Test
+ public void givenInputFile_whenInvokeAggregateByKeys_shouldGetExpectedMap() {
+ Map> mapAgg = FileToHashMap.aggregateByKeys(filePath);
+ assertThat(mapAgg).isEqualTo(EXPECTED_MAP_AGGREGATE);
+ }
+}
diff --git a/core-java-modules/core-java-io-4/src/test/resources/filetomap/theLordOfRings.txt b/core-java-modules/core-java-io-4/src/test/resources/filetomap/theLordOfRings.txt
new file mode 100644
index 0000000000..1ab069e533
--- /dev/null
+++ b/core-java-modules/core-java-io-4/src/test/resources/filetomap/theLordOfRings.txt
@@ -0,0 +1,6 @@
+title:The Lord of the Rings: The Return of the King
+director:Peter Jackson
+actor:Sean Astin
+actor:Ian McKellen
+Gandalf and Aragorn lead the World of Men against Sauron's
+army to draw his gaze from Frodo and Sam as they approach Mount Doom with the One Ring.
\ No newline at end of file
diff --git a/docker/README.md b/docker/README.md
index 0adf1c9b51..b2ae5d56c9 100644
--- a/docker/README.md
+++ b/docker/README.md
@@ -7,3 +7,4 @@
- [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)
+- [Caching Maven Dependencies with Docker](https://www.baeldung.com/ops/docker-cache-maven-dependencies)
diff --git a/graphql/graphql-java/pom.xml b/graphql/graphql-java/pom.xml
index 4e2444c1fb..f2733bf671 100644
--- a/graphql/graphql-java/pom.xml
+++ b/graphql/graphql-java/pom.xml
@@ -12,8 +12,24 @@
com.baeldung
parent-modules
1.0.0-SNAPSHOT
+ ../../
+
+
+ jitpack.io
+ https://jitpack.io
+
+
+
+ false
+
+ central
+ Central Repository
+ https://repo.maven.apache.org/maven2
+
+
+
com.graphql-java
@@ -25,11 +41,114 @@
ratpack-core
${ratpack-core.version}
+
+ com.github.americanexpress.nodes
+ nodes
+ 0.5.0
+
+
+ com.graphql-java
+ graphql-java
+ 9.2
+
+
+ com.graphql-java
+ graphql-java-tools
+ 5.2.4
+
+
+ com.graphql-java
+ graphql-java-servlet
+ 6.1.3
+
+
+ javax.servlet
+ javax.servlet-api
+ 3.0.1
+ provided
+
+
+ org.apache.commons
+ commons-lang3
+ 3.12.0
+
+
+ org.mock-server
+ mockserver-netty
+ 5.11.2
+
+
+ org.mock-server
+ mockserver-client-java
+ 5.11.2
+
+
+ com.graphql-java-generator
+ graphql-java-runtime
+ ${graphql.java.generator.version}
+
+
+ org.junit.jupiter
+ junit-jupiter-engine
+ 5.8.2
+ test
+
+
+ org.assertj
+ assertj-core
+ 3.22.0
+ test
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ ${maven-compiler-plugin.version}
+
+ ${maven.compiler.source}
+ ${maven.compiler.target}
+
+
+
+ org.eclipse.jetty
+ jetty-maven-plugin
+ 10.0.7
+
+
+ maven-war-plugin
+ 3.1.0
+
+
+ com.graphql-java-generator
+ graphql-maven-plugin
+ ${graphql.java.generator.version}
+
+
+
+ generateClientCode
+
+
+
+
+ com.baeldung.graphql.generated
+ false
+ false
+ true
+
+
+
+
+
3.0.3
1.4.6
+ 3.1
+ 1.8
+ 1.8
+ 1.18
\ No newline at end of file
diff --git a/graphql/graphql-java/src/main/java/com/baeldung/graphql/clients/AmericanExpressNodes.java b/graphql/graphql-java/src/main/java/com/baeldung/graphql/clients/AmericanExpressNodes.java
new file mode 100644
index 0000000000..446dbd416e
--- /dev/null
+++ b/graphql/graphql-java/src/main/java/com/baeldung/graphql/clients/AmericanExpressNodes.java
@@ -0,0 +1,24 @@
+package com.baeldung.graphql.clients;
+
+import com.baeldung.graphql.data.Data;
+import io.aexp.nodes.graphql.GraphQLRequestEntity;
+import io.aexp.nodes.graphql.GraphQLResponseEntity;
+import io.aexp.nodes.graphql.GraphQLTemplate;
+import org.apache.commons.lang3.StringUtils;
+
+import java.io.IOException;
+
+public class AmericanExpressNodes {
+
+ public static GraphQLResponseEntity callGraphQLService(String url, String query) throws IOException {
+ GraphQLTemplate graphQLTemplate = new GraphQLTemplate();
+
+ GraphQLRequestEntity requestEntity = GraphQLRequestEntity.Builder()
+ .url(StringUtils.join(url, "?query=", query))
+ .request(Data.class)
+ .build();
+
+ return graphQLTemplate.query(requestEntity, Data.class);
+ }
+
+}
diff --git a/graphql/graphql-java/src/main/java/com/baeldung/graphql/clients/ApacheHttpClient.java b/graphql/graphql-java/src/main/java/com/baeldung/graphql/clients/ApacheHttpClient.java
new file mode 100644
index 0000000000..d4f88e62f5
--- /dev/null
+++ b/graphql/graphql-java/src/main/java/com/baeldung/graphql/clients/ApacheHttpClient.java
@@ -0,0 +1,25 @@
+package com.baeldung.graphql.clients;
+
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.utils.URIBuilder;
+import org.apache.http.impl.client.HttpClientBuilder;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+
+public class ApacheHttpClient {
+
+ public static HttpResponse callGraphQLService(String url, String query) throws URISyntaxException, IOException {
+ HttpClient client = HttpClientBuilder.create().build();
+ HttpGet request = new HttpGet(url);
+ URI uri = new URIBuilder(request.getURI())
+ .addParameter("query", query)
+ .build();
+ request.setURI(uri);
+ return client.execute(request);
+ }
+
+}
diff --git a/graphql/graphql-java/src/main/java/com/baeldung/graphql/data/Author.java b/graphql/graphql-java/src/main/java/com/baeldung/graphql/data/Author.java
new file mode 100644
index 0000000000..876df27769
--- /dev/null
+++ b/graphql/graphql-java/src/main/java/com/baeldung/graphql/data/Author.java
@@ -0,0 +1,31 @@
+package com.baeldung.graphql.data;
+
+import org.apache.commons.lang3.StringUtils;
+
+public class Author {
+
+ private String name;
+ private String surname;
+
+ public Author() {
+
+ }
+
+ public Author(String name, String surname) {
+ this.name = name;
+ this.surname = surname;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getSurname() {
+ return surname;
+ }
+
+ public String getFullName() {
+ return StringUtils.join(getName(), " ", getSurname());
+ }
+
+}
diff --git a/graphql/graphql-java/src/main/java/com/baeldung/graphql/data/Book.java b/graphql/graphql-java/src/main/java/com/baeldung/graphql/data/Book.java
new file mode 100644
index 0000000000..6e6188368b
--- /dev/null
+++ b/graphql/graphql-java/src/main/java/com/baeldung/graphql/data/Book.java
@@ -0,0 +1,25 @@
+package com.baeldung.graphql.data;
+
+public class Book {
+
+ private String title;
+ private Author author;
+
+ public Book() {
+
+ }
+
+ public Book(String title, Author author) {
+ this.title = title;
+ this.author = author;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public Author getAuthor() {
+ return author;
+ }
+
+}
diff --git a/graphql/graphql-java/src/main/java/com/baeldung/graphql/data/BookRepository.java b/graphql/graphql-java/src/main/java/com/baeldung/graphql/data/BookRepository.java
new file mode 100644
index 0000000000..f812ed088d
--- /dev/null
+++ b/graphql/graphql-java/src/main/java/com/baeldung/graphql/data/BookRepository.java
@@ -0,0 +1,19 @@
+package com.baeldung.graphql.data;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+public class BookRepository {
+
+ private static final List books = Stream.of(
+ new Book("Title 1", new Author("Pero", "Peric")),
+ new Book("Title 2", new Author("Marko", "Maric"))
+ ).collect(Collectors.toList());
+
+ public List getAllBooks() {
+ return Collections.unmodifiableList(books);
+ }
+
+}
diff --git a/graphql/graphql-java/src/main/java/com/baeldung/graphql/data/Data.java b/graphql/graphql-java/src/main/java/com/baeldung/graphql/data/Data.java
new file mode 100644
index 0000000000..63263a496b
--- /dev/null
+++ b/graphql/graphql-java/src/main/java/com/baeldung/graphql/data/Data.java
@@ -0,0 +1,22 @@
+package com.baeldung.graphql.data;
+
+import java.util.Collections;
+import java.util.List;
+
+public class Data {
+
+ private List allBooks;
+
+ public Data() {
+
+ }
+
+ public Data(List allBooks) {
+ this.allBooks = allBooks;
+ }
+
+ public List getAllBooks() {
+ return Collections.unmodifiableList(allBooks);
+ }
+
+}
diff --git a/graphql/graphql-java/src/main/java/com/baeldung/graphql/data/Response.java b/graphql/graphql-java/src/main/java/com/baeldung/graphql/data/Response.java
new file mode 100644
index 0000000000..eedd13e04e
--- /dev/null
+++ b/graphql/graphql-java/src/main/java/com/baeldung/graphql/data/Response.java
@@ -0,0 +1,19 @@
+package com.baeldung.graphql.data;
+
+public class Response {
+
+ private Data data;
+
+ public Response() {
+
+ }
+
+ public Response(Data data) {
+ this.data = data;
+ }
+
+ public Data getData() {
+ return data;
+ }
+
+}
diff --git a/graphql/graphql-java/src/main/java/com/baeldung/graphql/server/GraphQLEndpoint.java b/graphql/graphql-java/src/main/java/com/baeldung/graphql/server/GraphQLEndpoint.java
new file mode 100644
index 0000000000..c69144c9f5
--- /dev/null
+++ b/graphql/graphql-java/src/main/java/com/baeldung/graphql/server/GraphQLEndpoint.java
@@ -0,0 +1,36 @@
+package com.baeldung.graphql.server;
+
+import com.baeldung.graphql.data.BookRepository;
+import com.coxautodev.graphql.tools.SchemaParser;
+import graphql.schema.GraphQLSchema;
+import graphql.servlet.SimpleGraphQLHttpServlet;
+
+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 java.io.IOException;
+
+@WebServlet(urlPatterns = "/graphql")
+public class GraphQLEndpoint extends HttpServlet {
+
+ private SimpleGraphQLHttpServlet graphQLServlet;
+
+ @Override
+ protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ graphQLServlet.service(req, resp);
+ }
+
+ @Override
+ public void init() {
+ GraphQLSchema schema = SchemaParser.newParser()
+ .resolvers(new GraphQLQuery(new BookRepository()))
+ .file("schema.graphqls")
+ .build()
+ .makeExecutableSchema();
+ graphQLServlet = SimpleGraphQLHttpServlet
+ .newBuilder(schema)
+ .build();
+ }
+}
diff --git a/graphql/graphql-java/src/main/java/com/baeldung/graphql/server/GraphQLQuery.java b/graphql/graphql-java/src/main/java/com/baeldung/graphql/server/GraphQLQuery.java
new file mode 100644
index 0000000000..8ba9fa25c5
--- /dev/null
+++ b/graphql/graphql-java/src/main/java/com/baeldung/graphql/server/GraphQLQuery.java
@@ -0,0 +1,21 @@
+package com.baeldung.graphql.server;
+
+import com.baeldung.graphql.data.Book;
+import com.baeldung.graphql.data.BookRepository;
+import com.coxautodev.graphql.tools.GraphQLQueryResolver;
+
+import java.util.List;
+
+public class GraphQLQuery implements GraphQLQueryResolver {
+
+ private final BookRepository repository;
+
+ public GraphQLQuery(BookRepository repository) {
+ this.repository = repository;
+ }
+
+ public List allBooks() {
+ return repository.getAllBooks();
+ }
+
+}
diff --git a/graphql/graphql-java/src/main/resources/schema.graphqls b/graphql/graphql-java/src/main/resources/schema.graphqls
new file mode 100644
index 0000000000..b0834e04b7
--- /dev/null
+++ b/graphql/graphql-java/src/main/resources/schema.graphqls
@@ -0,0 +1,17 @@
+type Book {
+ title: String!
+ author: Author
+}
+
+type Author {
+ name: String!
+ surname: String!
+}
+
+type Query {
+ allBooks: [Book]
+}
+
+schema {
+ query: Query
+}
\ No newline at end of file
diff --git a/graphql/graphql-java/src/test/java/com/baeldung/graphql/GraphQLMockServer.java b/graphql/graphql-java/src/test/java/com/baeldung/graphql/GraphQLMockServer.java
new file mode 100644
index 0000000000..fb5a789428
--- /dev/null
+++ b/graphql/graphql-java/src/test/java/com/baeldung/graphql/GraphQLMockServer.java
@@ -0,0 +1,85 @@
+package com.baeldung.graphql;
+
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.mockserver.client.MockServerClient;
+import org.mockserver.integration.ClientAndServer;
+import org.mockserver.model.HttpStatusCode;
+
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.net.URISyntaxException;
+
+import static org.mockserver.integration.ClientAndServer.startClientAndServer;
+import static org.mockserver.matchers.Times.exactly;
+import static org.mockserver.model.HttpRequest.request;
+import static org.mockserver.model.HttpResponse.response;
+
+public class GraphQLMockServer {
+
+ public static ClientAndServer mockServer;
+ public static String serviceUrl;
+
+ private static int serverPort;
+
+ public static final String SERVER_ADDRESS = "127.0.0.1";
+ public static final String HTTP_GET_POST = "GET";
+ public static final String PATH = "/graphql";
+
+ @BeforeAll
+ static void startServer() throws IOException, URISyntaxException {
+ serverPort = getFreePort();
+ serviceUrl = "http://" + SERVER_ADDRESS + ":" + serverPort + PATH;
+ mockServer = startClientAndServer(serverPort);
+ mockAllBooksTitleRequest();
+ mockAllBooksTitleAuthorRequest();
+ }
+
+ @AfterAll
+ static void stopServer() {
+ mockServer.stop();
+ }
+
+ private static void mockAllBooksTitleAuthorRequest() {
+ String requestQuery = "{allBooks{title,author{name,surname}}}";
+ String responseJson = "{\"data\":{\"allBooks\":[{\"title\":\"Title 1\",\"author\":{\"name\":\"Pero\",\"surname\":\"Peric\"}},{\"title\":\"Title 2\",\"author\":{\"name\":\"Marko\",\"surname\":\"Maric\"}}]}}";
+
+ new MockServerClient(SERVER_ADDRESS, serverPort)
+ .when(
+ request()
+ .withPath(PATH)
+ .withQueryStringParameter("query", requestQuery),
+ exactly(1)
+ )
+ .respond(
+ response()
+ .withStatusCode(HttpStatusCode.OK_200.code())
+ .withBody(responseJson)
+ );
+ }
+
+ private static void mockAllBooksTitleRequest() {
+ String requestQuery = "{allBooks{title}}";
+ String responseJson = "{\"data\":{\"allBooks\":[{\"title\":\"Title 1\"},{\"title\":\"Title 2\"}]}}";
+
+ new MockServerClient(SERVER_ADDRESS, serverPort)
+ .when(
+ request()
+ .withPath(PATH)
+ .withQueryStringParameter("query", requestQuery),
+ exactly(1)
+ )
+ .respond(
+ response()
+ .withStatusCode(HttpStatusCode.OK_200.code())
+ .withBody(responseJson)
+ );
+ }
+
+ private static int getFreePort () throws IOException {
+ try (ServerSocket serverSocket = new ServerSocket(0)) {
+ return serverSocket.getLocalPort();
+ }
+ }
+
+}
diff --git a/graphql/graphql-java/src/test/java/com/baeldung/graphql/clients/AmericanExpressNodesUnitTest.java b/graphql/graphql-java/src/test/java/com/baeldung/graphql/clients/AmericanExpressNodesUnitTest.java
new file mode 100644
index 0000000000..8466cdee76
--- /dev/null
+++ b/graphql/graphql-java/src/test/java/com/baeldung/graphql/clients/AmericanExpressNodesUnitTest.java
@@ -0,0 +1,39 @@
+package com.baeldung.graphql.clients;
+
+import com.baeldung.graphql.GraphQLMockServer;
+import com.baeldung.graphql.data.Data;
+import io.aexp.nodes.graphql.GraphQLResponseEntity;
+import org.junit.jupiter.api.Test;
+
+import java.io.IOException;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertAll;
+
+class AmericanExpressNodesUnitTest extends GraphQLMockServer {
+
+ @Test
+ void givenGraphQLEndpoint_whenRequestingAllBooksWithTitle_thenExpectedJsonIsReturned() throws IOException {
+ GraphQLResponseEntity responseEntity = AmericanExpressNodes.callGraphQLService(serviceUrl, "{allBooks{title}}");
+
+ assertAll(
+ () -> assertThat(responseEntity.getResponse().getAllBooks()).hasSize(2),
+ () -> assertThat(responseEntity.getResponse().getAllBooks().get(0).getTitle()).isEqualTo("Title 1"),
+ () -> assertThat(responseEntity.getResponse().getAllBooks().get(1).getTitle()).isEqualTo("Title 2")
+ );
+ }
+
+ @Test
+ void givenGraphQLEndpoint_whenRequestingAllBooksWithTitleAndAuthor_thenExpectedJsonIsReturned() throws IOException {
+ GraphQLResponseEntity responseEntity = AmericanExpressNodes.callGraphQLService(serviceUrl, "{allBooks{title,author{name,surname}}}");
+
+ assertAll(
+ () -> assertThat(responseEntity.getResponse().getAllBooks()).hasSize(2),
+ () -> assertThat(responseEntity.getResponse().getAllBooks().get(0).getTitle()).isEqualTo("Title 1"),
+ () -> assertThat(responseEntity.getResponse().getAllBooks().get(0).getAuthor().getFullName()).isEqualTo("Pero Peric"),
+ () -> assertThat(responseEntity.getResponse().getAllBooks().get(1).getTitle()).isEqualTo("Title 2"),
+ () -> assertThat(responseEntity.getResponse().getAllBooks().get(1).getAuthor().getFullName()).isEqualTo("Marko Maric")
+ );
+ }
+
+}
diff --git a/graphql/graphql-java/src/test/java/com/baeldung/graphql/clients/ApacheHttpClientUnitTest.java b/graphql/graphql-java/src/test/java/com/baeldung/graphql/clients/ApacheHttpClientUnitTest.java
new file mode 100644
index 0000000000..17d97e0d14
--- /dev/null
+++ b/graphql/graphql-java/src/test/java/com/baeldung/graphql/clients/ApacheHttpClientUnitTest.java
@@ -0,0 +1,49 @@
+package com.baeldung.graphql.clients;
+
+import com.baeldung.graphql.GraphQLMockServer;
+import com.baeldung.graphql.data.Response;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.apache.commons.io.IOUtils;
+import org.apache.http.HttpResponse;
+import org.junit.jupiter.api.Test;
+
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.nio.charset.StandardCharsets;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertAll;
+
+class ApacheHttpClientUnitTest extends GraphQLMockServer {
+
+ private static final ObjectMapper objectMapper = new ObjectMapper();
+
+ @Test
+ void givenGraphQLEndpoint_whenRequestingAllBooksWithTitle_thenExpectedJsonIsReturned() throws IOException, URISyntaxException {
+ HttpResponse httpResponse = ApacheHttpClient.callGraphQLService(serviceUrl, "{allBooks{title}}");
+ String actualResponse = IOUtils.toString(httpResponse.getEntity().getContent(), StandardCharsets.UTF_8.name());
+ Response parsedResponse = objectMapper.readValue(actualResponse, Response.class);
+
+ assertAll(
+ () -> assertThat(parsedResponse.getData().getAllBooks()).hasSize(2),
+ () -> assertThat(parsedResponse.getData().getAllBooks().get(0).getTitle()).isEqualTo("Title 1"),
+ () -> assertThat(parsedResponse.getData().getAllBooks().get(1).getTitle()).isEqualTo("Title 2")
+ );
+ }
+
+ @Test
+ void givenGraphQLEndpoint_whenRequestingAllBooksWithTitleAndAuthor_thenExpectedJsonIsReturned() throws IOException, URISyntaxException {
+ HttpResponse httpResponse = ApacheHttpClient.callGraphQLService(serviceUrl, "{allBooks{title,author{name,surname}}}");
+ String actualResponse = IOUtils.toString(httpResponse.getEntity().getContent(), StandardCharsets.UTF_8.name());
+ Response parsedResponse = objectMapper.readValue(actualResponse, Response.class);
+
+ assertAll(
+ () -> assertThat(parsedResponse.getData().getAllBooks()).hasSize(2),
+ () -> assertThat(parsedResponse.getData().getAllBooks().get(0).getTitle()).isEqualTo("Title 1"),
+ () -> assertThat(parsedResponse.getData().getAllBooks().get(0).getAuthor().getFullName()).isEqualTo("Pero Peric"),
+ () -> assertThat(parsedResponse.getData().getAllBooks().get(1).getTitle()).isEqualTo("Title 2"),
+ () -> assertThat(parsedResponse.getData().getAllBooks().get(1).getAuthor().getFullName()).isEqualTo("Marko Maric")
+ );
+ }
+
+}
diff --git a/javax-servlets-2/README.md b/javax-servlets-2/README.md
index f126f17297..9a7ad02d39 100644
--- a/javax-servlets-2/README.md
+++ b/javax-servlets-2/README.md
@@ -3,3 +3,4 @@
This module contains articles about Servlets.
### Relevant Articles:
+- [Check if a User Is Logged-in With Servlets and JSP](https://www.baeldung.com/servlets-jsp-check-user-login)
diff --git a/javax-servlets/src/main/webapp/sample.txt b/javax-servlets/src/main/webapp/WEB-INF/sample.txt
similarity index 100%
rename from javax-servlets/src/main/webapp/sample.txt
rename to javax-servlets/src/main/webapp/WEB-INF/sample.txt
diff --git a/lombok-2/src/main/java/com/baeldung/lombok/tostring/Account.java b/lombok-2/src/main/java/com/baeldung/lombok/tostring/Account.java
new file mode 100644
index 0000000000..641ad1e1a3
--- /dev/null
+++ b/lombok-2/src/main/java/com/baeldung/lombok/tostring/Account.java
@@ -0,0 +1,56 @@
+package com.baeldung.lombok.tostring;
+
+import lombok.ToString;
+
+@ToString
+public class Account {
+
+ private String name;
+
+ // render this field before any others (the highest ranked)
+ @ToString.Include(rank = 1)
+ private String id;
+
+ @ToString.Exclude
+ private String accountNumber;
+
+ // automatically excluded
+ private String $ignored;
+
+ @ToString.Include
+ String description() {
+ return "Account description";
+ }
+
+ public String getAccountNumber() {
+ return accountNumber;
+ }
+
+ public void setAccountNumber(String accountNumber) {
+ this.accountNumber = accountNumber;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String get$ignored() {
+ return $ignored;
+ }
+
+ public void set$ignored(String value) {
+ this.$ignored = value;
+ }
+}
diff --git a/lombok-2/src/main/java/com/baeldung/lombok/tostring/AccountType.java b/lombok-2/src/main/java/com/baeldung/lombok/tostring/AccountType.java
new file mode 100644
index 0000000000..7f99b5ca35
--- /dev/null
+++ b/lombok-2/src/main/java/com/baeldung/lombok/tostring/AccountType.java
@@ -0,0 +1,9 @@
+package com.baeldung.lombok.tostring;
+
+import lombok.ToString;
+
+@ToString
+public enum AccountType {
+ CHECKING,
+ SAVING
+}
diff --git a/lombok-2/src/main/java/com/baeldung/lombok/tostring/RewardAccount.java b/lombok-2/src/main/java/com/baeldung/lombok/tostring/RewardAccount.java
new file mode 100644
index 0000000000..9ac9c6afa6
--- /dev/null
+++ b/lombok-2/src/main/java/com/baeldung/lombok/tostring/RewardAccount.java
@@ -0,0 +1,27 @@
+package com.baeldung.lombok.tostring;
+
+import lombok.ToString;
+
+@ToString
+public class RewardAccount extends Account {
+
+ private String rewardAccountId;
+
+ private Object[] relatedAccounts;
+
+ public String getRewardAccountId() {
+ return rewardAccountId;
+ }
+
+ public void setRewardAccountId(String rewardAccountId) {
+ this.rewardAccountId = rewardAccountId;
+ }
+
+ public Object[] getRelatedAccounts() {
+ return relatedAccounts;
+ }
+
+ public void setRelatedAccounts(Object[] relatedAccounts) {
+ this.relatedAccounts = relatedAccounts;
+ }
+}
diff --git a/lombok-2/src/main/java/com/baeldung/lombok/tostring/SavingAccount.java b/lombok-2/src/main/java/com/baeldung/lombok/tostring/SavingAccount.java
new file mode 100644
index 0000000000..dfba31cf27
--- /dev/null
+++ b/lombok-2/src/main/java/com/baeldung/lombok/tostring/SavingAccount.java
@@ -0,0 +1,17 @@
+package com.baeldung.lombok.tostring;
+
+import lombok.ToString;
+
+@ToString(callSuper = true)
+public class SavingAccount extends Account {
+
+ private String savingAccountId;
+
+ public String getSavingAccountId() {
+ return savingAccountId;
+ }
+
+ public void setSavingAccountId(String savingAccountId) {
+ this.savingAccountId = savingAccountId;
+ }
+}
diff --git a/lombok-2/src/test/java/com/baeldung/lombok/tostring/ToStringUnitTest.java b/lombok-2/src/test/java/com/baeldung/lombok/tostring/ToStringUnitTest.java
new file mode 100644
index 0000000000..cb56ad912d
--- /dev/null
+++ b/lombok-2/src/test/java/com/baeldung/lombok/tostring/ToStringUnitTest.java
@@ -0,0 +1,66 @@
+package com.baeldung.lombok.tostring;
+
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class ToStringUnitTest {
+
+ @Test
+ void whenPrintObject_thenOutputIsCorrect() {
+ Account account = new Account();
+ account.setId("12345");
+ account.setName("An account");
+ account.setAccountNumber("11111"); // should not be present in output
+ account.set$ignored("ignored value"); // should not be present in output
+
+ assertThat(account.toString())
+ .isEqualTo("Account(id=12345, name=An account, description=Account description)");
+ }
+
+ @Test
+ void whenPrintSubclassWithSuper_thenOutputIsCorrect() {
+ SavingAccount savingAccount = new SavingAccount();
+ savingAccount.setSavingAccountId("5678");
+ savingAccount.setId("12345");
+ savingAccount.setName("An account");
+
+ assertThat(savingAccount.toString())
+ .isEqualTo("SavingAccount(super=Account(id=12345, name=An account, description=Account description), savingAccountId=5678)");
+ }
+
+@Test
+void whenPrintArrays_thenOutputIsCorrect() {
+ RewardAccount account = new RewardAccount();
+ account.setRewardAccountId("12345");
+
+ // circular ref, just for demonstration
+ Object[] relatedAccounts = new Object[2];
+ relatedAccounts[0] = "54321";
+ relatedAccounts[1] = relatedAccounts;
+
+ account.setRelatedAccounts(relatedAccounts);
+
+ assertThat(account.toString())
+ .isEqualTo("RewardAccount(rewardAccountId=12345, relatedAccounts=[54321, [...]])");
+}
+
+ @Test
+ void whenPrintSubclassWithoutSuper_thenOutputIsCorrect() {
+ RewardAccount rewardAccount = new RewardAccount();
+ rewardAccount.setRewardAccountId("12345");
+
+ assertThat(rewardAccount.toString())
+ .isEqualTo("RewardAccount(rewardAccountId=12345, relatedAccounts=null)");
+ }
+
+ @Test
+ void whenPrintEnum_thenOutputIsCorrect() {
+ assertThat(AccountType.CHECKING.toString())
+ .isEqualTo("AccountType.CHECKING");
+
+ assertThat(AccountType.SAVING.toString())
+ .isEqualTo("AccountType.SAVING");
+ }
+
+}
diff --git a/maven-modules/maven-classifier/README.md b/maven-modules/maven-classifier/README.md
new file mode 100644
index 0000000000..ab8a7f914f
--- /dev/null
+++ b/maven-modules/maven-classifier/README.md
@@ -0,0 +1,3 @@
+### Relevant Articles:
+
+- [A Guide to Maven Artifact Classifiers](https://www.baeldung.com/maven-artifact-classifiers)
diff --git a/maven-modules/maven-simple/maven-profiles/pom.xml b/maven-modules/maven-simple/maven-profiles/pom.xml
index 322dada104..ba915038ad 100644
--- a/maven-modules/maven-simple/maven-profiles/pom.xml
+++ b/maven-modules/maven-simple/maven-profiles/pom.xml
@@ -5,7 +5,7 @@
4.0.0
com.baeldung
maven-profiles
- 0.0.1-SNAPSHOT
+ 1.0.0-SNAPSHOT
maven-profiles
diff --git a/maven-modules/maven-simple/parent-project/core/pom.xml b/maven-modules/maven-simple/parent-project/core/pom.xml
index ec25c9ace5..8f7371639f 100644
--- a/maven-modules/maven-simple/parent-project/core/pom.xml
+++ b/maven-modules/maven-simple/parent-project/core/pom.xml
@@ -10,7 +10,7 @@
parent-project
com.baeldung
- 1.0-SNAPSHOT
+ 1.0.0-SNAPSHOT
diff --git a/maven-modules/maven-simple/parent-project/pom.xml b/maven-modules/maven-simple/parent-project/pom.xml
index a68f8e63bc..fce9aa3f72 100644
--- a/maven-modules/maven-simple/parent-project/pom.xml
+++ b/maven-modules/maven-simple/parent-project/pom.xml
@@ -4,14 +4,13 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
parent-project
- 1.0-SNAPSHOT
parent-project
pom
com.baeldung
maven-simple
- 0.0.1-SNAPSHOT
+ 1.0.0-SNAPSHOT
diff --git a/maven-modules/maven-simple/parent-project/service/pom.xml b/maven-modules/maven-simple/parent-project/service/pom.xml
index 1953ec8638..39945af248 100644
--- a/maven-modules/maven-simple/parent-project/service/pom.xml
+++ b/maven-modules/maven-simple/parent-project/service/pom.xml
@@ -10,7 +10,7 @@
parent-project
com.baeldung
- 1.0-SNAPSHOT
+ 1.0.0-SNAPSHOT
diff --git a/maven-modules/maven-simple/parent-project/webapp/pom.xml b/maven-modules/maven-simple/parent-project/webapp/pom.xml
index bd13c5aeb8..1ab1321b20 100644
--- a/maven-modules/maven-simple/parent-project/webapp/pom.xml
+++ b/maven-modules/maven-simple/parent-project/webapp/pom.xml
@@ -10,7 +10,7 @@
parent-project
com.baeldung
- 1.0-SNAPSHOT
+ 1.0.0-SNAPSHOT
diff --git a/maven-modules/maven-simple/plugin-management/pom.xml b/maven-modules/maven-simple/plugin-management/pom.xml
index 2fb2d5ed41..3c4bd886ac 100644
--- a/maven-modules/maven-simple/plugin-management/pom.xml
+++ b/maven-modules/maven-simple/plugin-management/pom.xml
@@ -9,7 +9,7 @@
maven-simple
com.baeldung
- 0.0.1-SNAPSHOT
+ 1.0.0-SNAPSHOT
@@ -56,8 +56,8 @@
- 3.8.1
- 3.2.0
+ 3.10.0
+ 3.3.0
\ No newline at end of file
diff --git a/maven-modules/maven-simple/plugin-management/submodule-1/pom.xml b/maven-modules/maven-simple/plugin-management/submodule-1/pom.xml
index c36e092254..ff08dec9a6 100644
--- a/maven-modules/maven-simple/plugin-management/submodule-1/pom.xml
+++ b/maven-modules/maven-simple/plugin-management/submodule-1/pom.xml
@@ -8,7 +8,7 @@
plugin-management
com.baeldung
- 0.0.1-SNAPSHOT
+ 1.0.0-SNAPSHOT
diff --git a/maven-modules/maven-simple/plugin-management/submodule-2/pom.xml b/maven-modules/maven-simple/plugin-management/submodule-2/pom.xml
index e50d3cc26d..5db76cebdb 100644
--- a/maven-modules/maven-simple/plugin-management/submodule-2/pom.xml
+++ b/maven-modules/maven-simple/plugin-management/submodule-2/pom.xml
@@ -8,7 +8,7 @@
plugin-management
com.baeldung
- 0.0.1-SNAPSHOT
+ 1.0.0-SNAPSHOT
\ No newline at end of file
diff --git a/maven-modules/maven-simple/pom.xml b/maven-modules/maven-simple/pom.xml
index 938e2240f8..fe59259758 100644
--- a/maven-modules/maven-simple/pom.xml
+++ b/maven-modules/maven-simple/pom.xml
@@ -5,6 +5,7 @@
4.0.0
maven-simple
maven-simple
+ 1.0.0-SNAPSHOT
pom
diff --git a/muleesb/pom.xml b/muleesb/pom.xml
index f6cfa7d5d1..d78cebada2 100644
--- a/muleesb/pom.xml
+++ b/muleesb/pom.xml
@@ -108,7 +108,7 @@
org.mule.tools.maven
mule-maven-plugin
- 2.2.1
+ ${mule-maven-plugin.version}
standalone
${mule.version}
@@ -203,7 +203,7 @@
mulesoft-release
mulesoft release repository
default
- https://repository.mulesoft.org/releases/
+ https://repository.mulesoft.org/nexus/content/repositories/public/
false
@@ -212,9 +212,10 @@
3.9.0
- 1.2
+ 1.8
1.3.6
- 1.7
+ 1.10
+ 2.2.1
diff --git a/persistence-modules/java-cassandra/pom.xml b/persistence-modules/java-cassandra/pom.xml
index 6df75edc56..b0b98b040a 100644
--- a/persistence-modules/java-cassandra/pom.xml
+++ b/persistence-modules/java-cassandra/pom.xml
@@ -50,6 +50,25 @@
+
+
+ integration-lite-first
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+ 1
+ true
+
+
+
+
+
+
+
3.1.2
diff --git a/persistence-modules/java-mongodb/src/main/java/com/baeldung/mongo/update/MultipleFieldsExample.java b/persistence-modules/java-mongodb/src/main/java/com/baeldung/mongo/update/MultipleFieldsExample.java
index b2fcddeafb..ebc56cbfd0 100644
--- a/persistence-modules/java-mongodb/src/main/java/com/baeldung/mongo/update/MultipleFieldsExample.java
+++ b/persistence-modules/java-mongodb/src/main/java/com/baeldung/mongo/update/MultipleFieldsExample.java
@@ -10,35 +10,35 @@ import com.mongodb.client.result.UpdateResult;
public class MultipleFieldsExample {
- public static void main(String[] args) {
+ public static void main(String[] args) {
- //
- // Connect to cluster (default is localhost:27017)
- //
+ //
+ // Connect to cluster (default is localhost:27017)
+ //
- MongoClient mongoClient = new MongoClient("localhost", 27017);
- MongoDatabase database = mongoClient.getDatabase("baeldung");
- MongoCollection collection = database.getCollection("employee");
+ MongoClient mongoClient = new MongoClient("localhost", 27017);
+ MongoDatabase database = mongoClient.getDatabase("baeldung");
+ MongoCollection collection = database.getCollection("employee");
- //
- // Filter on the basis of employee_id
- //
+ //
+ // Filter on the basis of employee_id
+ //
- BasicDBObject searchQuery = new BasicDBObject("employee_id", 794875);
+ BasicDBObject searchQuery = new BasicDBObject("employee_id", 794875);
- //
- // Update the fields in Document
- //
+ //
+ // Update the fields in Document
+ //
- BasicDBObject updateFields = new BasicDBObject();
- updateFields.append("department_id", 3);
- updateFields.append("job", "Sales Manager");
- BasicDBObject setQuery = new BasicDBObject();
- setQuery.append("$set", updateFields);
- UpdateResult updateResult = collection.updateMany(searchQuery, setQuery);
+ BasicDBObject updateFields = new BasicDBObject();
+ updateFields.append("department_id", 3);
+ updateFields.append("job", "Sales Manager");
+ BasicDBObject setQuery = new BasicDBObject();
+ setQuery.append("$set", updateFields);
+ UpdateResult updateResult = collection.updateMany(searchQuery, setQuery);
- System.out.println("updateResult:- " + updateResult);
- System.out.println("updateResult:- " + updateResult.getModifiedCount());
+ System.out.println("updateResult:- " + updateResult);
+ System.out.println("updateResult:- " + updateResult.getModifiedCount());
- }
+ }
}
diff --git a/persistence-modules/java-mongodb/src/main/java/com/baeldung/mongo/update/UpdateMultipleFields.java b/persistence-modules/java-mongodb/src/main/java/com/baeldung/mongo/update/UpdateMultipleFields.java
index 20af6d99cb..96dd086ed7 100644
--- a/persistence-modules/java-mongodb/src/main/java/com/baeldung/mongo/update/UpdateMultipleFields.java
+++ b/persistence-modules/java-mongodb/src/main/java/com/baeldung/mongo/update/UpdateMultipleFields.java
@@ -11,26 +11,25 @@ import com.mongodb.client.result.UpdateResult;
public class UpdateMultipleFields {
- public static void main(String[] args) {
+ public static void main(String[] args) {
- //
- // Connect to cluster
- //
+ //
+ // Connect to cluster
+ //
- MongoClient mongoClient = new MongoClient("localhost", 27007);
- MongoDatabase database = mongoClient.getDatabase("baeldung");
- MongoCollection collection = database.getCollection("employee");
+ MongoClient mongoClient = new MongoClient("localhost", 27007);
+ MongoDatabase database = mongoClient.getDatabase("baeldung");
+ MongoCollection collection = database.getCollection("employee");
- //
- // Update query
- //
+ //
+ // Update query
+ //
- UpdateResult updateResult = collection.updateMany(Filters.eq("employee_id", 794875),
- Updates.combine(Updates.set("department_id", 4), Updates.set("job", "Sales Manager")));
+ UpdateResult updateResult = collection.updateMany(Filters.eq("employee_id", 794875), Updates.combine(Updates.set("department_id", 4), Updates.set("job", "Sales Manager")));
- System.out.println("updateResult:- " + updateResult);
- System.out.println("updateResult:- " + updateResult.getModifiedCount());
+ System.out.println("updateResult:- " + updateResult);
+ System.out.println("updateResult:- " + updateResult.getModifiedCount());
- }
+ }
-}
\ No newline at end of file
+}
diff --git a/persistence-modules/java-mongodb/src/test/java/com/baeldung/update/UpdateMultipleFieldsLiveTest.java b/persistence-modules/java-mongodb/src/test/java/com/baeldung/update/UpdateMultipleFieldsLiveTest.java
index d1538d5312..d06de23423 100644
--- a/persistence-modules/java-mongodb/src/test/java/com/baeldung/update/UpdateMultipleFieldsLiveTest.java
+++ b/persistence-modules/java-mongodb/src/test/java/com/baeldung/update/UpdateMultipleFieldsLiveTest.java
@@ -2,8 +2,6 @@ package com.baeldung.update;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertSame;
import org.bson.Document;
import org.junit.Before;
@@ -15,7 +13,6 @@ import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.model.Filters;
import com.mongodb.client.model.Updates;
-import com.mongodb.client.result.UpdateResult;
public class UpdateMultipleFieldsLiveTest {
@@ -30,8 +27,7 @@ public class UpdateMultipleFieldsLiveTest {
db = mongoClient.getDatabase("baeldung");
collection = db.getCollection("employee");
- collection.insertOne(Document.parse(
- "{'employee_id':794875,'employee_name': 'David smith','job': 'Sales Representative','department_id': 2,'salary': 20000,'hire_date': NumberLong(\"1643969311817\")}"));
+ collection.insertOne(Document.parse("{'employee_id':794875,'employee_name': 'David Smith','job': 'Sales Representative','department_id': 2,'salary': 20000,'hire_date': NumberLong(\"1643969311817\")}"));
}
}
@@ -47,7 +43,8 @@ public class UpdateMultipleFieldsLiveTest {
collection.updateMany(searchQuery, setQuery);
- Document nameDoc = collection.find(Filters.eq("employee_id", 794875)).first();
+ Document nameDoc = collection.find(Filters.eq("employee_id", 794875))
+ .first();
assertNotNull(nameDoc);
assertFalse(nameDoc.isEmpty());
@@ -62,10 +59,10 @@ public class UpdateMultipleFieldsLiveTest {
@Test
public void updateMultipleFieldsUsingDocument() {
- collection.updateMany(Filters.eq("employee_id", 794875),
- Updates.combine(Updates.set("department_id", 4), Updates.set("job", "Sales Manager")));
+ collection.updateMany(Filters.eq("employee_id", 794875), Updates.combine(Updates.set("department_id", 4), Updates.set("job", "Sales Manager")));
- Document nameDoc = collection.find(Filters.eq("employee_id", 794875)).first();
+ Document nameDoc = collection.find(Filters.eq("employee_id", 794875))
+ .first();
assertNotNull(nameDoc);
assertFalse(nameDoc.isEmpty());
@@ -78,3 +75,4 @@ public class UpdateMultipleFieldsLiveTest {
}
}
+
diff --git a/pom.xml b/pom.xml
index edc5302390..1243eb4522 100644
--- a/pom.xml
+++ b/pom.xml
@@ -518,7 +518,7 @@
micronaut
microprofile
msf4j
-
+ muleesb
mustache
mybatis
@@ -1001,7 +1001,7 @@
micronaut
microprofile
msf4j
-
+ muleesb
mustache
mybatis
diff --git a/spring-cloud/spring-cloud-gateway/README.md b/spring-cloud/spring-cloud-gateway/README.md
index 6b199977e3..808536ce80 100644
--- a/spring-cloud/spring-cloud-gateway/README.md
+++ b/spring-cloud/spring-cloud-gateway/README.md
@@ -9,3 +9,4 @@ This module contains articles about Spring Cloud Gateway
- [Spring Cloud Gateway Routing Predicate Factories](https://www.baeldung.com/spring-cloud-gateway-routing-predicate-factories)
- [Spring Cloud Gateway WebFilter Factories](https://www.baeldung.com/spring-cloud-gateway-webfilter-factories)
- [Using Spring Cloud Gateway with OAuth 2.0 Patterns](https://www.baeldung.com/spring-cloud-gateway-oauth2)
+- [URL Rewriting With Spring Cloud Gateway](https://www.baeldung.com/spring-cloud-gateway-url-rewriting)
diff --git a/spring-security-modules/spring-5-security-oauth/src/main/java/com/baeldung/oauth2resttemplate/AppController.java b/spring-security-modules/spring-5-security-oauth/src/main/java/com/baeldung/oauth2resttemplate/AppController.java
new file mode 100644
index 0000000000..3c3efd950f
--- /dev/null
+++ b/spring-security-modules/spring-5-security-oauth/src/main/java/com/baeldung/oauth2resttemplate/AppController.java
@@ -0,0 +1,32 @@
+package com.baeldung.oauth2resttemplate;
+
+import org.springframework.security.oauth2.client.OAuth2RestTemplate;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.GetMapping;
+
+import java.security.Principal;
+import java.util.Collection;
+
+@Controller
+public class AppController {
+
+ OAuth2RestTemplate restTemplate;
+
+ public AppController(OAuth2RestTemplate restTemplate) {
+ this.restTemplate = restTemplate;
+ }
+
+ @GetMapping("/home")
+ public String welcome(Model model, Principal principal) {
+ model.addAttribute("name", principal.getName());
+ return "home";
+ }
+
+ @GetMapping("/repos")
+ public String repos(Model model) {
+ Collection repos = restTemplate.getForObject("https://api.github.com/user/repos", Collection.class);
+ model.addAttribute("repos", repos);
+ return "repositories";
+ }
+}
diff --git a/spring-security-modules/spring-5-security-oauth/src/main/java/com/baeldung/oauth2resttemplate/GithubRepo.java b/spring-security-modules/spring-5-security-oauth/src/main/java/com/baeldung/oauth2resttemplate/GithubRepo.java
new file mode 100644
index 0000000000..48cc05c1de
--- /dev/null
+++ b/spring-security-modules/spring-5-security-oauth/src/main/java/com/baeldung/oauth2resttemplate/GithubRepo.java
@@ -0,0 +1,22 @@
+package com.baeldung.oauth2resttemplate;
+
+public class GithubRepo {
+ Long id;
+ String name;
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
diff --git a/spring-security-modules/spring-5-security-oauth/src/main/java/com/baeldung/oauth2resttemplate/SecurityConfig.java b/spring-security-modules/spring-5-security-oauth/src/main/java/com/baeldung/oauth2resttemplate/SecurityConfig.java
new file mode 100644
index 0000000000..fa274d1c9b
--- /dev/null
+++ b/spring-security-modules/spring-5-security-oauth/src/main/java/com/baeldung/oauth2resttemplate/SecurityConfig.java
@@ -0,0 +1,73 @@
+package com.baeldung.oauth2resttemplate;
+
+import org.springframework.boot.autoconfigure.security.oauth2.resource.ResourceServerProperties;
+import org.springframework.boot.autoconfigure.security.oauth2.resource.UserInfoTokenServices;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.web.servlet.FilterRegistrationBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.Ordered;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.oauth2.client.OAuth2ClientContext;
+import org.springframework.security.oauth2.client.OAuth2RestTemplate;
+import org.springframework.security.oauth2.client.filter.OAuth2ClientAuthenticationProcessingFilter;
+import org.springframework.security.oauth2.client.filter.OAuth2ClientContextFilter;
+import org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeResourceDetails;
+import org.springframework.security.oauth2.config.annotation.web.configuration.EnableOAuth2Client;
+import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
+
+import javax.servlet.Filter;
+
+@Configuration
+@EnableOAuth2Client
+public class SecurityConfig extends WebSecurityConfigurerAdapter {
+ OAuth2ClientContext oauth2ClientContext;
+
+ public SecurityConfig(OAuth2ClientContext oauth2ClientContext) {
+ this.oauth2ClientContext = oauth2ClientContext;
+ }
+
+ @Override
+ protected void configure(HttpSecurity http) throws Exception {
+ http.authorizeRequests().antMatchers("/", "/login**", "/error**")
+ .permitAll().anyRequest().authenticated()
+ .and().logout().logoutUrl("/logout").logoutSuccessUrl("/")
+ .and().addFilterBefore(oauth2ClientFilter(), BasicAuthenticationFilter.class);
+ }
+
+ @Bean
+ public FilterRegistrationBean oauth2ClientFilterRegistration(OAuth2ClientContextFilter filter) {
+ FilterRegistrationBean registration = new FilterRegistrationBean<>();
+ registration.setFilter(filter);
+ registration.setOrder(Ordered.HIGHEST_PRECEDENCE + 1);
+ return registration;
+ }
+
+ @Bean
+ public OAuth2RestTemplate restTemplate() {
+ return new OAuth2RestTemplate(githubClient(), oauth2ClientContext);
+ }
+
+ @Bean
+ @ConfigurationProperties("github.client")
+ public AuthorizationCodeResourceDetails githubClient() {
+ return new AuthorizationCodeResourceDetails();
+ }
+
+ private Filter oauth2ClientFilter() {
+ OAuth2ClientAuthenticationProcessingFilter oauth2ClientFilter = new OAuth2ClientAuthenticationProcessingFilter("/login/github");
+ OAuth2RestTemplate restTemplate = restTemplate();
+ oauth2ClientFilter.setRestTemplate(restTemplate);
+ UserInfoTokenServices tokenServices = new UserInfoTokenServices(githubResource().getUserInfoUri(), githubClient().getClientId());
+ tokenServices.setRestTemplate(restTemplate);
+ oauth2ClientFilter.setTokenServices(tokenServices);
+ return oauth2ClientFilter;
+ }
+
+ @Bean
+ @ConfigurationProperties("github.resource")
+ public ResourceServerProperties githubResource() {
+ return new ResourceServerProperties();
+ }
+}
diff --git a/spring-security-modules/spring-5-security-oauth/src/main/java/com/baeldung/oauth2resttemplate/SpringSecurityOauth2ClientApplication.java b/spring-security-modules/spring-5-security-oauth/src/main/java/com/baeldung/oauth2resttemplate/SpringSecurityOauth2ClientApplication.java
new file mode 100644
index 0000000000..846169e5bf
--- /dev/null
+++ b/spring-security-modules/spring-5-security-oauth/src/main/java/com/baeldung/oauth2resttemplate/SpringSecurityOauth2ClientApplication.java
@@ -0,0 +1,15 @@
+package com.baeldung.oauth2resttemplate;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.PropertySource;
+
+@SpringBootApplication
+@PropertySource("classpath:application-oauth2-rest-template.properties")
+public class SpringSecurityOauth2ClientApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(SpringSecurityOauth2ClientApplication.class, args);
+ }
+
+}
diff --git a/spring-security-modules/spring-5-security-oauth/src/main/resources/application-oauth2-rest-template.properties b/spring-security-modules/spring-5-security-oauth/src/main/resources/application-oauth2-rest-template.properties
new file mode 100644
index 0000000000..15d34b76be
--- /dev/null
+++ b/spring-security-modules/spring-5-security-oauth/src/main/resources/application-oauth2-rest-template.properties
@@ -0,0 +1,9 @@
+github.client.clientId=[CLIENT_ID]
+github.client.clientSecret=[CLIENT_SECRET]
+github.client.userAuthorizationUri=https://github.com/login/oauth/authorize
+github.client.accessTokenUri=https://github.com/login/oauth/access_token
+github.client.clientAuthenticationScheme=form
+
+github.resource.userInfoUri=https://api.github.com/user
+
+spring.thymeleaf.prefix=classpath:/templates/oauth2resttemplate/
\ No newline at end of file
diff --git a/spring-security-modules/spring-5-security-oauth/src/main/resources/templates/oauth2resttemplate/error.html b/spring-security-modules/spring-5-security-oauth/src/main/resources/templates/oauth2resttemplate/error.html
new file mode 100644
index 0000000000..45bcddf654
--- /dev/null
+++ b/spring-security-modules/spring-5-security-oauth/src/main/resources/templates/oauth2resttemplate/error.html
@@ -0,0 +1,9 @@
+
+
+
+ Error
+
+
+ An error occurred.
+
+
\ No newline at end of file
diff --git a/spring-security-modules/spring-5-security-oauth/src/main/resources/templates/oauth2resttemplate/home.html b/spring-security-modules/spring-5-security-oauth/src/main/resources/templates/oauth2resttemplate/home.html
new file mode 100644
index 0000000000..3eba3615d6
--- /dev/null
+++ b/spring-security-modules/spring-5-security-oauth/src/main/resources/templates/oauth2resttemplate/home.html
@@ -0,0 +1,18 @@
+
+
+
+ Home
+
+
+
+ Welcome [[${name}]]
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-security-modules/spring-5-security-oauth/src/main/resources/templates/oauth2resttemplate/index.html b/spring-security-modules/spring-5-security-oauth/src/main/resources/templates/oauth2resttemplate/index.html
new file mode 100644
index 0000000000..4db3b78d23
--- /dev/null
+++ b/spring-security-modules/spring-5-security-oauth/src/main/resources/templates/oauth2resttemplate/index.html
@@ -0,0 +1,16 @@
+
+
+
+ OAuth2Client
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-security-modules/spring-5-security-oauth/src/main/resources/templates/oauth2resttemplate/repositories.html b/spring-security-modules/spring-5-security-oauth/src/main/resources/templates/oauth2resttemplate/repositories.html
new file mode 100644
index 0000000000..1eabf2270f
--- /dev/null
+++ b/spring-security-modules/spring-5-security-oauth/src/main/resources/templates/oauth2resttemplate/repositories.html
@@ -0,0 +1,14 @@
+
+
+
+ Repositories
+
+
+
+
Repos
+
+
+
+
\ No newline at end of file
diff --git a/spring-security-modules/spring-security-web-boot-3/README.md b/spring-security-modules/spring-security-web-boot-3/README.md
index 45fede7a4c..2f98e0f4a0 100644
--- a/spring-security-modules/spring-security-web-boot-3/README.md
+++ b/spring-security-modules/spring-security-web-boot-3/README.md
@@ -12,4 +12,5 @@ The "REST With Spring" Classes: http://github.learnspringsecurity.com
- [Spring Security – Cache Control Headers](https://www.baeldung.com/spring-security-cache-control-headers)
- [Fixing 401s with CORS Preflights and Spring Security](https://www.baeldung.com/spring-security-cors-preflight)
- [Content Security Policy with Spring Security](https://www.baeldung.com/spring-security-csp)
+- [Enable Logging for Spring Security](https://www.baeldung.com/spring-security-enable-logging)
- More articles: [[<-- prev]](/spring-security-modules/spring-security-web-boot-2)
diff --git a/spring-sleuth/pom.xml b/spring-sleuth/pom.xml
index 5fd109e968..a6fba5ea56 100644
--- a/spring-sleuth/pom.xml
+++ b/spring-sleuth/pom.xml
@@ -39,7 +39,7 @@
- 2.0.2.RELEASE
+ 3.1.0
\ No newline at end of file
diff --git a/spring-sleuth/src/main/java/com/baeldung/sleuth/traceid/SleuthCurrentTraceIdApp.java b/spring-sleuth/src/main/java/com/baeldung/sleuth/traceid/SleuthCurrentTraceIdApp.java
new file mode 100644
index 0000000000..bae1d310a2
--- /dev/null
+++ b/spring-sleuth/src/main/java/com/baeldung/sleuth/traceid/SleuthCurrentTraceIdApp.java
@@ -0,0 +1,11 @@
+package com.baeldung.sleuth.traceid;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class SleuthCurrentTraceIdApp {
+ public static void main(String[] args) {
+ SpringApplication.run(SleuthCurrentTraceIdApp.class, args);
+ }
+}
diff --git a/spring-sleuth/src/main/java/com/baeldung/sleuth/traceid/SleuthTraceIdController.java b/spring-sleuth/src/main/java/com/baeldung/sleuth/traceid/SleuthTraceIdController.java
new file mode 100644
index 0000000000..07dca487d0
--- /dev/null
+++ b/spring-sleuth/src/main/java/com/baeldung/sleuth/traceid/SleuthTraceIdController.java
@@ -0,0 +1,32 @@
+package com.baeldung.sleuth.traceid;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import brave.Span;
+import brave.Tracer;
+
+@RestController
+public class SleuthTraceIdController {
+
+ private static final Logger logger = LoggerFactory.getLogger(SleuthTraceIdController.class);
+
+ @Autowired
+ private Tracer tracer;
+
+ @GetMapping("/traceid")
+ public String getSleuthTraceId() {
+ logger.info("Hello with Sleuth");
+ Span span = tracer.currentSpan();
+ if (span != null) {
+ logger.info("Span ID hex {}", span.context().spanIdString());
+ logger.info("Span ID decimal {}", span.context().spanId());
+ logger.info("Trace ID hex {}", span.context().traceIdString());
+ logger.info("Trace ID decimal {}", span.context().traceId());
+ }
+ return "Hello from Sleuth";
+ }
+}