Merge branch 'eugenp:master' into master
This commit is contained in:
@@ -3,12 +3,17 @@
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>apache-tapestry</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>apache-tapestry</name>
|
||||
<packaging>war</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<!-- To set up an application with a database, change the artifactId below to tapestry-hibernate,
|
||||
and add a dependency on your JDBC driver. You'll also need to add Hibernate configuration files, such
|
||||
|
||||
@@ -8,6 +8,13 @@
|
||||
<name>ShippingFunction</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>aws-lambda</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<relativePath>../../</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.amazonaws</groupId>
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
This module contains articles about Java HttpClient
|
||||
|
||||
### Relevant articles
|
||||
- TODO
|
||||
- [Posting with Java HttpClient](https://www.baeldung.com/java-httpclient-post)
|
||||
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package com.baeldung.http;
|
||||
|
||||
import java.net.http.HttpClient;
|
||||
import java.time.Duration;
|
||||
|
||||
public class JavaHttpClientTimeout {
|
||||
static HttpClient getHttpClientWithTimeout(int seconds) {
|
||||
return HttpClient.newBuilder()
|
||||
.connectTimeout(Duration.ofSeconds(seconds))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
package com.baeldung.http;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.http.HttpClient;
|
||||
import java.net.http.HttpConnectTimeoutException;
|
||||
import java.net.http.HttpRequest;
|
||||
import java.net.http.HttpResponse;
|
||||
import java.time.Duration;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import static com.baeldung.http.JavaHttpClientTimeout.getHttpClientWithTimeout;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
class JavaHttpClientTimeoutIntegrationTest {
|
||||
|
||||
private HttpClient httpClient;
|
||||
private HttpRequest httpRequest;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
httpClient = getHttpClientWithTimeout(3);
|
||||
httpClient.connectTimeout().map(Duration::toSeconds)
|
||||
.ifPresent(sec -> System.out.println("Timeout in seconds: " + sec));
|
||||
|
||||
httpRequest = HttpRequest.newBuilder().uri(URI.create("http://10.255.255.1")).GET().build();
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldThrowExceptionWhenMakingSyncCall() {
|
||||
HttpConnectTimeoutException thrown = assertThrows(
|
||||
HttpConnectTimeoutException.class,
|
||||
() -> httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString()),
|
||||
"Expected doThing() to throw, but it didn't"
|
||||
);
|
||||
assertTrue(thrown.getMessage().contains("timed out"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldThrowExceptionWhenMakingASyncCall() throws ExecutionException, InterruptedException, TimeoutException {
|
||||
CompletableFuture<String> completableFuture =
|
||||
httpClient.sendAsync(httpRequest, HttpResponse.BodyHandlers.ofString())
|
||||
.thenApply(HttpResponse::body)
|
||||
.exceptionally(Throwable::getMessage);
|
||||
String response = completableFuture.get(5, TimeUnit.SECONDS);
|
||||
assertTrue(response.contains("timed out"));
|
||||
}
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
package com.baeldung.searchfilesbywildcards;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import java.nio.file.FileSystem;
|
||||
import java.nio.file.FileSystems;
|
||||
import java.nio.file.FileVisitResult;
|
||||
import java.nio.file.FileVisitor;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.PathMatcher;
|
||||
import java.nio.file.SimpleFileVisitor;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class SearchFileByWildcard {
|
||||
public static List<String> matchesList = new ArrayList<String>();
|
||||
public List<String> searchWithWc(Path rootDir, String pattern) throws IOException {
|
||||
matchesList.clear();
|
||||
FileVisitor<Path> matcherVisitor = new SimpleFileVisitor<Path>() {
|
||||
@Override
|
||||
public FileVisitResult visitFile(Path file, BasicFileAttributes attribs) throws IOException {
|
||||
FileSystem fs = FileSystems.getDefault();
|
||||
PathMatcher matcher = fs.getPathMatcher(pattern);
|
||||
Path name = file.getFileName();
|
||||
if (matcher.matches(name)) {
|
||||
matchesList.add(name.toString());
|
||||
}
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
};
|
||||
Files.walkFileTree(rootDir, matcherVisitor);
|
||||
return matchesList;
|
||||
}
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
package com.baeldung.searchfilesbywildcards;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class SearchFileByWildcardUnitTest {
|
||||
@Test
|
||||
public void whenFourFilenameMatch_thenListOfFour() throws IOException {
|
||||
SearchFileByWildcard sfbw = new SearchFileByWildcard();
|
||||
List<String> actual = sfbw.searchWithWc(Paths.get("src/test/resources/sfbw"), "glob:*.{txt,docx}");
|
||||
|
||||
assertEquals(new HashSet<>(Arrays.asList("six.txt", "three.txt", "two.docx", "one.txt")), new HashSet<>(actual));
|
||||
}
|
||||
@Test
|
||||
public void whenOneFilenameMatch_thenListOfOne() throws IOException {
|
||||
SearchFileByWildcard sfbw = new SearchFileByWildcard();
|
||||
List<String> actual = sfbw.searchWithWc(Paths.get("src/test/resources/sfbw"), "glob:????.{csv}");
|
||||
|
||||
assertEquals(new HashSet<>(Arrays.asList("five.csv")), new HashSet<>(actual));
|
||||
}
|
||||
}
|
||||
Binary file not shown.
+7
@@ -0,0 +1,7 @@
|
||||
package com.baeldung.reflection.proxy;
|
||||
|
||||
public interface AdvancedOperation {
|
||||
int multiply(int a, int b);
|
||||
|
||||
int divide(int a, int b);
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package com.baeldung.reflection.proxy;
|
||||
|
||||
public interface BasicOperation {
|
||||
int add(int a, int b);
|
||||
|
||||
int subtract(int a, int b);
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
package com.baeldung.reflection.proxy;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class DollarProxyUnitTest {
|
||||
@Test
|
||||
public void givenProxy_whenInvokingGetProxyClass_thenGeneratingProxyClass() {
|
||||
// Java 8: -Dsun.misc.ProxyGenerator.saveGeneratedFiles=true
|
||||
// Java 9 or later: -Djdk.proxy.ProxyGenerator.saveGeneratedFiles=true
|
||||
// Note: System.setProperty() doesn't work here
|
||||
// because ProxyGenerator.saveGeneratedFiles read its property only once.
|
||||
// The @Test annotation in this method will generate a $Proxy class.
|
||||
|
||||
ClassLoader classLoader = ClassLoader.getSystemClassLoader();
|
||||
Class<?>[] interfaces = {BasicOperation.class, AdvancedOperation.class};
|
||||
Class<?> proxyClass = Proxy.getProxyClass(classLoader, interfaces);
|
||||
|
||||
boolean isProxyClass = Proxy.isProxyClass(proxyClass);
|
||||
assertTrue(isProxyClass);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenReflection_whenReadingAnnotation_thenGeneratingProxyClass() {
|
||||
FunctionalInterface instance = Consumer.class.getDeclaredAnnotation(FunctionalInterface.class);
|
||||
Class<?> clazz = instance.getClass();
|
||||
|
||||
boolean isProxyClass = Proxy.isProxyClass(clazz);
|
||||
assertTrue(isProxyClass);
|
||||
}
|
||||
}
|
||||
@@ -30,6 +30,12 @@
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>${apache-commons-lang3.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
<artifactId>assertj-core</artifactId>
|
||||
<version>${assertj.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
package com.baeldung.checkvowels;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class CheckVowels {
|
||||
private static final String VOWELS = "aeiouAEIOU";
|
||||
private static final Pattern VOWELS_PATTERN = Pattern.compile("[aeiou]", Pattern.CASE_INSENSITIVE);
|
||||
|
||||
public static boolean isInVowelsString(char c) {
|
||||
return VOWELS.indexOf(c) != -1;
|
||||
}
|
||||
|
||||
public static boolean isInVowelsString(String c) {
|
||||
return VOWELS.contains(c);
|
||||
}
|
||||
|
||||
public static boolean isVowelBySwitch(char c) {
|
||||
switch (c) {
|
||||
case 'a':
|
||||
case 'e':
|
||||
case 'i':
|
||||
case 'o':
|
||||
case 'u':
|
||||
case 'A':
|
||||
case 'E':
|
||||
case 'I':
|
||||
case 'O':
|
||||
case 'U':
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isVowelByRegex(String c) {
|
||||
return VOWELS_PATTERN.matcher(c).matches();
|
||||
}
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
package com.baeldung.checkvowels;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static com.baeldung.checkvowels.CheckVowels.*;
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
class CheckVowelsUnitTest {
|
||||
|
||||
@Test
|
||||
void givenAVowelCharacter_thenInVowelString() {
|
||||
assertThat(isInVowelsString('e')).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenAConsonantCharacter_thenNotInVowelString() {
|
||||
assertThat(isInVowelsString('z')).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenAVowelString_thenInVowelString() {
|
||||
assertThat(isInVowelsString("e")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenAConsonantString_thenNotInVowelString() {
|
||||
assertThat(isInVowelsString("z")).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenAVowelCharacter_thenInVowelSwitch() {
|
||||
assertThat(isVowelBySwitch('e')).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenAConsonantCharacter_thenNotInVowelSwitch() {
|
||||
assertThat(isVowelBySwitch('z')).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenAVowelString_thenInVowelPattern() {
|
||||
assertThat(isVowelByRegex("e")).isTrue();
|
||||
assertThat(isVowelByRegex("E")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenAVowelCharacter_thenInVowelPattern() {
|
||||
assertThat(isVowelByRegex(Character.toString('e'))).isTrue();
|
||||
assertThat(isVowelByRegex("E")).isTrue();
|
||||
}
|
||||
}
|
||||
@@ -1,19 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>docker-push-to-private-repo</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>docker-push-to-private-repo</name>
|
||||
<description>Example application to showcase how to push a docker image to a private repository</description>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung.docker</groupId>
|
||||
<artifactId>docker</artifactId>
|
||||
<version>0.0.1</version>
|
||||
</parent>
|
||||
<artifactId>push-to-private-repo</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>push-to-private-repo</name>
|
||||
<description>Example application to showcase how to push a docker image to a private repository</description>
|
||||
<properties>
|
||||
<java.version>11</java.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
@@ -40,4 +40,8 @@
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
<properties>
|
||||
<java.version>11</java.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
@@ -8,3 +8,4 @@
|
||||
- [Convert Byte Size Into a Human-Readable Format in Java](https://www.baeldung.com/java-human-readable-byte-size)
|
||||
- [Convert boolean to int in Java](https://www.baeldung.com/java-boolean-to-int)
|
||||
- [Generate a Random Value From an Enum](https://www.baeldung.com/java-enum-random-value)
|
||||
- [Reverse a Number in Java](https://www.baeldung.com/java-reverse-number)
|
||||
|
||||
@@ -1090,6 +1090,66 @@
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>integration-lite-first</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>com.github.eirslett</groupId>
|
||||
<artifactId>frontend-maven-plugin</artifactId>
|
||||
|
||||
<executions>
|
||||
<execution>
|
||||
<id>install node and npm</id>
|
||||
<phase>none</phase>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>npm install</id>
|
||||
<phase>none</phase>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>webpack build dev</id>
|
||||
<phase>none</phase>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>webpack build test</id>
|
||||
<phase>none</phase>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>integration-lite-second</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>com.github.eirslett</groupId>
|
||||
<artifactId>frontend-maven-plugin</artifactId>
|
||||
|
||||
<executions>
|
||||
<execution>
|
||||
<id>install node and npm</id>
|
||||
<phase>none</phase>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>npm install</id>
|
||||
<phase>none</phase>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>webpack build dev</id>
|
||||
<phase>none</phase>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>webpack build test</id>
|
||||
<phase>none</phase>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
<properties>
|
||||
|
||||
@@ -174,7 +174,7 @@
|
||||
<gson.version>2.8.2</gson.version>
|
||||
<cache.version>1.1.1</cache.version>
|
||||
<flink.version>1.5.0</flink.version>
|
||||
<hazelcast.version>5.1.1</hazelcast.version>
|
||||
<hazelcast.version>3.8.4</hazelcast.version>
|
||||
<org.apache.crunch.crunch-core.version>0.15.0</org.apache.crunch.crunch-core.version>
|
||||
<org.apache.hadoop.hadoop-client>2.2.0</org.apache.hadoop.hadoop-client>
|
||||
<jmapper.version>1.6.0.1</jmapper.version>
|
||||
|
||||
@@ -8,6 +8,12 @@
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<name>libraries-primitive</name>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<!-- https://mvnrepository.com/artifact/it.unimi.dsi/fastutil -->
|
||||
<dependency>
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
# Lightrun Example Application - Tasks Management
|
||||
|
||||
This application exists as an example for the Lightrun series of articles.
|
||||
|
||||
## Building
|
||||
|
||||
This application requires [Apache Maven](https://maven.apache.org/) and [Java 17+](https://www.oracle.com/java/technologies/downloads/).
|
||||
|
||||
Building the code is done by executing:
|
||||
|
||||
```
|
||||
$ mvn install
|
||||
```
|
||||
|
||||
from the top level.
|
||||
|
||||
## Running
|
||||
|
||||
The application consists of three services:
|
||||
|
||||
* Tasks
|
||||
* Users
|
||||
* API
|
||||
|
||||
These are all Spring Boot applications.
|
||||
|
||||
The Tasks and Users services exist as microservices for managing one facet of data. Each uses a database, and utilise a JMS queue between them as well. For convenience this infrastructure is all embedded in the applications.
|
||||
|
||||
This does mean that the startup order is important. The JMS queue exists within the Tasks service and is connected to from the Users service. As such, the Tasks service must be started before the others.
|
||||
|
||||
Each service can be started either by executing `mvn spring-boot:run` from within the appropriate directory. Alternatively, as Spring Boot applications, the build will produce an executable JAR file within the `target` directory that can be executed as, for
|
||||
example:
|
||||
|
||||
```
|
||||
$ java -jar ./target/tasks-service-0.0.1-SNAPSHOT.jar
|
||||
```
|
||||
@@ -0,0 +1,33 @@
|
||||
HELP.md
|
||||
target/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
!**/src/main/**/target/
|
||||
!**/src/test/**/target/
|
||||
|
||||
### STS ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
build/
|
||||
!**/src/main/**/build/
|
||||
!**/src/test/**/build/
|
||||
|
||||
### VS Code ###
|
||||
.vscode/
|
||||
@@ -0,0 +1,45 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.6.7</version>
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>api-service</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>api-service</name>
|
||||
<description>Aggregator Service for LightRun Article</description>
|
||||
<properties>
|
||||
<java.version>17</java.version>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.baeldung.apiservice;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class ApiServiceApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(ApiServiceApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.baeldung.apiservice;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.slf4j.MDC;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.servlet.HandlerInterceptor;
|
||||
|
||||
@Component
|
||||
public class RequestIdGenerator implements HandlerInterceptor {
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
||||
String requestId = UUID.randomUUID()
|
||||
.toString();
|
||||
|
||||
MDC.put(RequestIdGenerator.class.getCanonicalName(), requestId);
|
||||
response.addHeader("X-Request-Id", requestId);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
|
||||
MDC.remove(RequestIdGenerator.class.getCanonicalName());
|
||||
}
|
||||
|
||||
public static String getRequestId() {
|
||||
return MDC.get(RequestIdGenerator.class.getCanonicalName());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.baeldung.apiservice;
|
||||
|
||||
import org.springframework.boot.web.client.RestTemplateBuilder;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
@Configuration
|
||||
public class RestTemplateConfig {
|
||||
@Bean
|
||||
public RestTemplate restTemplate(RestTemplateBuilder builder) {
|
||||
return builder.additionalInterceptors((request, body, execution) -> {
|
||||
request.getHeaders()
|
||||
.add("X-Request-Id", RequestIdGenerator.getRequestId());
|
||||
|
||||
return execution.execute(request, body);
|
||||
})
|
||||
.build();
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user