Merge branch 'eugenp:master' into JAVA-18167
This commit is contained in:
@@ -7,7 +7,7 @@ import org.junit.Test;
|
||||
|
||||
import com.baeldung.apache.beam.intro.WordCount;
|
||||
|
||||
public class WordCountUnitTest {
|
||||
public class WordCountIntegrationTest {
|
||||
|
||||
@Test
|
||||
public void givenInputFile_whenWordCountRuns_thenJobFinishWithoutError() {
|
||||
@@ -24,4 +24,12 @@
|
||||
</resources>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>javax.annotation</groupId>
|
||||
<artifactId>javax.annotation-api</artifactId>
|
||||
<version>1.3.2</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -9,6 +9,7 @@ import java.util.Collection;
|
||||
*/
|
||||
public class UserList {
|
||||
|
||||
public UserList() {}
|
||||
private Collection<User> users;
|
||||
|
||||
public Collection<User> getUsers() {
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.baeldung.java_8_features.Person;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.NoSuchElementException;
|
||||
@@ -71,4 +72,17 @@ public class Java8MaxMinUnitTest {
|
||||
|
||||
assertEquals(bugatti, maxBySpeed);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenIntegerList_whenGetMinAndIndex_thenSuccess() {
|
||||
final List<Integer> listOfIntegers = Arrays.asList(11, 13, 9, 20, 7, 3, 30);
|
||||
final Integer expectedMinValue = 3;
|
||||
final Integer expectedMinIndex = 5;
|
||||
|
||||
Integer minValue = Collections.min(listOfIntegers);
|
||||
Integer minIndex = listOfIntegers.indexOf(minValue);
|
||||
|
||||
assertEquals(minValue, expectedMinValue);
|
||||
assertEquals(minIndex, expectedMinIndex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,8 @@ package com.baeldung.concurrent.prioritytaskexecution;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class PriorityJobSchedulerUnitTest {
|
||||
//Converted to ManualTest due to thread sleep
|
||||
public class PriorityJobSchedulerManualTest {
|
||||
private static final int POOL_SIZE = 1;
|
||||
private static final int QUEUE_SIZE = 10;
|
||||
|
||||
@@ -5,4 +5,5 @@ This module contains articles about date operations in Java.
|
||||
|
||||
- [Create Date From Unix Timestamp in Java](https://www.baeldung.com/java-date-unix-timestamp)
|
||||
- [Convert java.util.Date to java.sql.Date](https://www.baeldung.com/java-convert-util-date-to-sql)
|
||||
- [How to Determine Date of the First Day of the Week Using LocalDate in Java](https://www.baeldung.com/java-first-day-of-the-week)
|
||||
- [[<-- Prev]](/core-java-modules/core-java-date-operations-2)
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
Hello, world!
|
||||
@@ -27,9 +27,30 @@
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>${maven-compiler-plugin.version}</version>
|
||||
<configuration>
|
||||
<source>${maven.compiler.source}</source>
|
||||
<target>${maven.compiler.target}</target>
|
||||
<compilerArgs>
|
||||
<arg>--add-exports=java.base/jdk.internal.vm.annotation=ALL-UNNAMED</arg>
|
||||
</compilerArgs>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<jol-core.version>0.10</jol-core.version>
|
||||
<reflections.version>0.10.2</reflections.version>
|
||||
|
||||
<maven.compiler.source>11</maven.compiler.source>
|
||||
<maven.compiler.target>11</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
|
||||
</project>
|
||||
@@ -3,7 +3,8 @@ package com.baeldung.memlayout;
|
||||
import org.junit.Test;
|
||||
import org.openjdk.jol.info.ClassLayout;
|
||||
import org.openjdk.jol.vm.VM;
|
||||
import sun.misc.Contended;
|
||||
|
||||
import jdk.internal.vm.annotation.Contended;
|
||||
|
||||
public class MemoryLayoutUnitTest {
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>core-java-jvm</artifactId>
|
||||
<version>0.1.0-SNAPSHOT</version>
|
||||
@@ -30,13 +30,6 @@
|
||||
<artifactId>esapi</artifactId>
|
||||
<version>${esapi.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sun</groupId>
|
||||
<artifactId>tools</artifactId>
|
||||
<version>${sun.tools.version}</version>
|
||||
<scope>system</scope>
|
||||
<systemPath>${java.home}/../lib/tools.jar</systemPath>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.ow2.asm</groupId>
|
||||
<artifactId>asm</artifactId>
|
||||
@@ -176,9 +169,8 @@
|
||||
|
||||
<properties>
|
||||
<javaassist.version>3.27.0-GA</javaassist.version>
|
||||
<sun.tools.version>1.8.0</sun.tools.version>
|
||||
<jol-core.version>0.10</jol-core.version>
|
||||
<asm.version>8.0.1</asm.version>
|
||||
<asm.version>9.4</asm.version>
|
||||
<bcel.version>6.5.0</bcel.version>
|
||||
</properties>
|
||||
|
||||
|
||||
@@ -1,13 +1,5 @@
|
||||
package com.baeldung.classloader;
|
||||
|
||||
import com.sun.javafx.util.Logging;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class PrintClassLoader {
|
||||
@@ -15,7 +7,6 @@ public class PrintClassLoader {
|
||||
public void printClassLoaders() throws ClassNotFoundException {
|
||||
|
||||
System.out.println("Classloader of this class:" + PrintClassLoader.class.getClassLoader());
|
||||
System.out.println("Classloader of Logging:" + Logging.class.getClassLoader());
|
||||
System.out.println("Classloader of ArrayList:" + ArrayList.class.getClassLoader());
|
||||
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ public class ViewBytecodeUnitTest {
|
||||
JavaClass objectClazz = Repository.lookupClass("java.lang.Object");
|
||||
|
||||
assertEquals(objectClazz.getClassName(), "java.lang.Object");
|
||||
assertEquals(objectClazz.getMethods().length, 14);
|
||||
assertEquals(objectClazz.getMethods().length, 12);
|
||||
assertTrue(objectClazz.toString().contains("public class java.lang.Object"));
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ public class ViewBytecodeUnitTest {
|
||||
ClassFile cf = cp.get("java.lang.Object").getClassFile();
|
||||
|
||||
assertEquals(cf.getName(), "java.lang.Object");
|
||||
assertEquals(cf.getMethods().size(), 14);
|
||||
assertEquals(cf.getMethods().size(), 12);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,13 +3,12 @@ package com.baeldung.headlessmode;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
|
||||
import java.awt.Canvas;
|
||||
import java.awt.Font;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Frame;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.HeadlessException;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.image.ComponentColorModel;
|
||||
import java.awt.image.DataBuffer;
|
||||
import java.awt.image.WritableRaster;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@@ -58,7 +57,7 @@ public class HeadlessModeUnitTest {
|
||||
boolean result = false;
|
||||
try (InputStream inStream = HeadlessModeUnitTest.class.getResourceAsStream(IN_FILE); FileOutputStream outStream = new FileOutputStream(OUT_FILE)) {
|
||||
BufferedImage inputImage = ImageIO.read(inStream);
|
||||
result = ImageIO.write(inputImage, FORMAT, outStream);
|
||||
result = ImageIO.write(removeAlphaChannel(inputImage), FORMAT, outStream);
|
||||
}
|
||||
|
||||
assertThat(result).isTrue();
|
||||
@@ -84,4 +83,10 @@ public class HeadlessModeUnitTest {
|
||||
assertThat(FlexibleApp.iAmFlexible()).isEqualTo(FlexibleApp.HEADED);
|
||||
}
|
||||
|
||||
private BufferedImage removeAlphaChannel(BufferedImage inputImage) {
|
||||
final WritableRaster raster = inputImage.getRaster();
|
||||
final WritableRaster newRaster = raster.createWritableChild(0, 0, inputImage.getWidth(), inputImage.getHeight(), 0, 0, new int[]{0, 1, 2});
|
||||
ColorModel newCM = new ComponentColorModel(inputImage.getColorModel().getColorSpace(), false, false, Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
|
||||
return new BufferedImage(newCM, newRaster, false, null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ public class NumberOfLineFinder {
|
||||
int lines = 0;
|
||||
try (LineNumberReader reader = new LineNumberReader(new FileReader(fileName))) {
|
||||
reader.skip(Integer.MAX_VALUE);
|
||||
lines = reader.getLineNumber() + 1;
|
||||
lines = reader.getLineNumber();
|
||||
} catch (IOException ioe) {
|
||||
ioe.printStackTrace();
|
||||
}
|
||||
|
||||
@@ -21,9 +21,11 @@ public class CreationDateResolverUnitTest {
|
||||
|
||||
final Instant response = creationDateResolver.resolveCreationTimeWithBasicAttributes(path);
|
||||
|
||||
assertTrue(Instant
|
||||
.now()
|
||||
.isAfter(response));
|
||||
Optional.of(response).ifPresent((value) -> {
|
||||
assertTrue(Instant
|
||||
.now()
|
||||
.isAfter(value));
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -75,8 +75,8 @@ public class FormatNumberUnitTest {
|
||||
public void givenCurrency_whenFormatNumberCurrencyWithChosenLocalisation_thenGetExpectedResult() {
|
||||
double value = 23_500;
|
||||
assertThat(currencyWithChosenLocalisation(value, new Locale("en", "US"))).isEqualTo("$23,500.00");
|
||||
assertThat(currencyWithChosenLocalisation(value, new Locale("zh", "CN"))).isEqualTo("¥23,500.00");
|
||||
assertThat(currencyWithChosenLocalisation(value, new Locale("pl", "PL"))).isEqualTo("23 500 zł");
|
||||
assertThat(currencyWithChosenLocalisation(value, new Locale("zh", "CN"))).isEqualTo("¥23,500.00");
|
||||
assertThat(currencyWithChosenLocalisation(value, new Locale("pl", "PL"))).isEqualTo("23 500,00 zł");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>core-java-security</artifactId>
|
||||
<version>0.1.0-SNAPSHOT</version>
|
||||
|
||||
@@ -10,3 +10,4 @@
|
||||
- [Understanding the Difference Between Stream.of() and IntStream.range()](https://www.baeldung.com/java-stream-of-and-intstream-range)
|
||||
- [Check if Object Is an Array in Java](https://www.baeldung.com/java-check-if-object-is-an-array)
|
||||
- [Mapping an Array of Integers to Strings Using Java Streams](https://www.baeldung.com/java-stream-integer-array-to-strings)
|
||||
- [Difference Between parallelStream() and stream().parallel() in Java](https://www.baeldung.com/java-parallelstream-vs-stream-parallel)
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
|
||||
<properties>
|
||||
<icu4j.version>61.1</icu4j.version>
|
||||
<argLine>-Djava.locale.providers=COMPAT</argLine>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.baeldung.datetostring;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
@@ -14,7 +13,8 @@ import java.util.Date;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
public class DateToStringFormatterUnitTest {
|
||||
|
||||
|
||||
@@ -15,6 +15,11 @@
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>javax.xml.bind</groupId>
|
||||
<artifactId>jaxb-api</artifactId>
|
||||
<version>2.4.0-b180725.0427</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
|
||||
@@ -16,9 +16,21 @@
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
<module>core-java</module>
|
||||
<module>core-java-8</module>
|
||||
<module>core-java-8-2</module>
|
||||
<!--Won't be upgraded to JDK 17-->
|
||||
<!--<module>core-java</module>-->
|
||||
<!--<module>core-java-8</module>-->
|
||||
<!--<module>core-java-8-2</module>-->
|
||||
<!--<module>core-java-8-datetime</module>-->
|
||||
<!--<module>core-java-8-datetime-2</module>-->
|
||||
<!--<module>core-java-collections-conversions-2</module>-->
|
||||
<!--<module>core-java-lang</module>-->
|
||||
<!--<module>core-java-lang-math-3</module>-->
|
||||
<!--<module>core-java-nio-2</module>-->
|
||||
<!--<module>core-java-security</module>-->
|
||||
<!--<module>core-java-serialization</module>-->
|
||||
<!--<module>core-java-streams-2</module>-->
|
||||
<!--<module>core-java-sun</module>-->
|
||||
|
||||
<module>core-java-annotations</module>
|
||||
<module>core-java-arrays-sorting</module>
|
||||
<module>core-java-arrays-guides</module>
|
||||
@@ -33,7 +45,6 @@
|
||||
<module>core-java-collections-4</module>
|
||||
<module>core-java-collections-5</module>
|
||||
<module>core-java-collections-conversions</module>
|
||||
<module>core-java-collections-conversions-2</module>
|
||||
<module>core-java-collections-set-2</module>
|
||||
<module>core-java-collections-list</module>
|
||||
<module>core-java-collections-list-2</module>
|
||||
@@ -52,11 +63,9 @@
|
||||
<module>core-java-concurrency-collections</module>
|
||||
<module>core-java-concurrency-collections-2</module>
|
||||
<module>core-java-console</module>
|
||||
<module>core-java-8-datetime-2</module>
|
||||
<module>core-java-datetime-string-2</module>
|
||||
<module>core-java-date-operations-2</module>
|
||||
<module>core-java-date-operations-3</module>
|
||||
<module>core-java-8-datetime</module>
|
||||
<module>core-java-exceptions</module>
|
||||
<module>core-java-exceptions-2</module>
|
||||
<module>core-java-exceptions-3</module>
|
||||
@@ -77,14 +86,12 @@
|
||||
<module>core-java-jvm-2</module>
|
||||
<module>core-java-jvm-3</module>
|
||||
<module>core-java-lambdas</module>
|
||||
<module>core-java-lang</module>
|
||||
<module>core-java-lang-2</module>
|
||||
<module>core-java-lang-3</module>
|
||||
<module>core-java-lang-4</module>
|
||||
<module>core-java-lang-5</module>
|
||||
<module>core-java-lang-math</module>
|
||||
<module>core-java-lang-math-2</module>
|
||||
<module>core-java-lang-math-3</module>
|
||||
<module>core-java-lang-oop-constructors</module>
|
||||
<module>core-java-lang-oop-patterns</module>
|
||||
<module>core-java-lang-oop-generics</module>
|
||||
@@ -102,27 +109,20 @@
|
||||
<module>core-java-networking-2</module>
|
||||
<module>core-java-networking-4</module>
|
||||
<module>core-java-nio</module>
|
||||
<module>core-java-nio-2</module>
|
||||
<module>core-java-numbers</module>
|
||||
<module>core-java-numbers-2</module>
|
||||
<module>core-java-numbers-3</module>
|
||||
<module>core-java-numbers-4</module>
|
||||
<module>core-java-numbers-5</module>
|
||||
<module>core-java-numbers-conversions</module>
|
||||
<module>core-java-optional</module>
|
||||
<module>core-java-perf</module>
|
||||
<module>core-java-reflection</module>
|
||||
<module>core-java-reflection-2</module>
|
||||
<module>core-java-security</module>
|
||||
<module>core-java-security-2</module>
|
||||
<module>core-java-security-3</module>
|
||||
<module>core-java-serialization</module>
|
||||
<module>core-java-security-algorithms</module>
|
||||
<module>core-java-streams</module>
|
||||
<module>core-java-streams-2</module>
|
||||
<module>core-java-streams-3</module>
|
||||
<module>core-java-streams-maps</module>
|
||||
<module>core-java-streams-collect</module>
|
||||
<module>core-java-string-algorithms</module>
|
||||
<module>core-java-string-algorithms-2</module>
|
||||
<module>core-java-string-apis</module>
|
||||
@@ -131,7 +131,6 @@
|
||||
<module>core-java-string-conversions-2</module>
|
||||
<module>core-java-string-operations</module>
|
||||
<module>core-java-string-operations-2</module>
|
||||
<module>core-java-sun</module>
|
||||
<module>core-java-regex</module>
|
||||
<module>core-java-regex-2</module>
|
||||
<module>core-java-uuid</module>
|
||||
|
||||
@@ -15,6 +15,11 @@
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>javax.xml.bind</groupId>
|
||||
<artifactId>jaxb-api</artifactId>
|
||||
<version>2.4.0-b180725.0427</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
@@ -32,6 +37,9 @@
|
||||
<configuration>
|
||||
<source>${source.version}</source>
|
||||
<target>${target.version}</target>
|
||||
<compilerArgs>
|
||||
<arg>--add-exports=java.base/com.sun.crypto.provider=ALL-UNNAMED</arg>
|
||||
</compilerArgs>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
@@ -72,8 +80,8 @@
|
||||
<properties>
|
||||
<dependency.plugin.version>3.1.1</dependency.plugin.version>
|
||||
<compiler.plugin.version>3.8.0</compiler.plugin.version>
|
||||
<source.version>1.8</source.version>
|
||||
<target.version>1.8</target.version>
|
||||
<source.version>11</source.version>
|
||||
<target.version>11</target.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
@@ -1,19 +1,18 @@
|
||||
package com.baeldung.prejpms;
|
||||
|
||||
import java.io.StringWriter;
|
||||
import java.lang.StackWalker.Option;
|
||||
import java.lang.StackWalker.StackFrame;
|
||||
import com.sun.crypto.provider.SunJCE;
|
||||
import java.util.Base64;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import javax.xml.bind.JAXBContext;
|
||||
import javax.xml.bind.JAXBException;
|
||||
import javax.xml.bind.Marshaller;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.sun.crypto.provider.SunJCE;
|
||||
|
||||
import sun.misc.BASE64Encoder;
|
||||
import sun.reflect.Reflection;
|
||||
|
||||
public class App {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
|
||||
@@ -37,14 +36,14 @@ public class App {
|
||||
private static void getCallStackClassNames() {
|
||||
try {
|
||||
StringBuffer sbStack = new StringBuffer();
|
||||
int i = 0;
|
||||
Class<?> caller = Reflection.getCallerClass(i++);
|
||||
do {
|
||||
sbStack.append(i + ".")
|
||||
.append(caller.getName())
|
||||
.append("\n");
|
||||
caller = Reflection.getCallerClass(i++);
|
||||
} while (caller != null);
|
||||
AtomicInteger i = new AtomicInteger(0);
|
||||
StackWalker.getInstance((Option.RETAIN_CLASS_REFERENCE))
|
||||
.walk(s -> s.map(StackFrame::getDeclaringClass)
|
||||
.map(e -> {
|
||||
i.getAndIncrement();
|
||||
return e.getName();
|
||||
}))
|
||||
.forEach(name -> sbStack.append(String.format("%d. %s \n", i.get(), name)));
|
||||
LOGGER.info("2. Call Stack:\n{}", sbStack);
|
||||
} catch (Throwable e) {
|
||||
LOGGER.error(e.toString());
|
||||
@@ -54,7 +53,7 @@ public class App {
|
||||
private static void getXmlFromObject(Book book) {
|
||||
try {
|
||||
Marshaller marshallerObj = JAXBContext.newInstance(Book.class)
|
||||
.createMarshaller();
|
||||
.createMarshaller();
|
||||
marshallerObj.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
|
||||
|
||||
StringWriter sw = new StringWriter();
|
||||
@@ -68,7 +67,8 @@ public class App {
|
||||
|
||||
private static void getBase64EncodedString(String inputString) {
|
||||
try {
|
||||
String encodedString = new BASE64Encoder().encode(inputString.getBytes());
|
||||
String encodedString = new String(Base64.getEncoder()
|
||||
.encode(inputString.getBytes()));
|
||||
LOGGER.info("4. Base Encoded String: {}", encodedString);
|
||||
} catch (Throwable e) {
|
||||
LOGGER.error(e.toString());
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>core-java-exclusions</artifactId>
|
||||
<version>0.0.0-SNAPSHOT</version>
|
||||
<name>core-java-exclusions</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung.dependency-exclusion</groupId>
|
||||
<artifactId>dependency-exclusion</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>${surefire-version}</version>
|
||||
<configuration>
|
||||
<runOrder>alphabetical</runOrder>
|
||||
<threadCount>1</threadCount>
|
||||
<properties>
|
||||
<property>
|
||||
<name>junit</name>
|
||||
<value>false</value>
|
||||
</property>
|
||||
</properties>
|
||||
</configuration>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<!-- Deactivate JUnit 4.7 engine by overriding it with an empty dummy -->
|
||||
<groupId>org.apache.maven.surefire</groupId>
|
||||
<artifactId>surefire-junit47</artifactId>
|
||||
<version>dummy</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -1,12 +0,0 @@
|
||||
package com.sample.project.tests;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class ExcludeDirectDependencyUnitTest {
|
||||
@Test
|
||||
public void basicUnitTest() {
|
||||
assertTrue(true);
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.apache.maven.surefire</groupId>
|
||||
<artifactId>surefire-junit47</artifactId>
|
||||
<version>dummy</version>
|
||||
</project>
|
||||
@@ -1,71 +0,0 @@
|
||||
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.baeldung.dependency-exclusion</groupId>
|
||||
<artifactId>dependency-exclusion</artifactId>
|
||||
<name>dependency-exclusion</name>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-java</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../parent-java</relativePath>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<surefire-version>2.22.2</surefire-version>
|
||||
</properties>
|
||||
|
||||
<modules>
|
||||
<module>dummy-surefire-junit47</module>
|
||||
<module>core-java-exclusions</module>
|
||||
</modules>
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.7.0</version>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
<compilerArgs>
|
||||
<arg>-parameters</arg>
|
||||
</compilerArgs>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>${surefire-version}</version>
|
||||
<configuration>
|
||||
<threadCount>1</threadCount>
|
||||
</configuration>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven.surefire</groupId>
|
||||
<artifactId>surefire-junit-platform</artifactId>
|
||||
<version>${surefire-version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
</build>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.13</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
</project>
|
||||
@@ -14,3 +14,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring
|
||||
- [Inheritance with Jackson](https://www.baeldung.com/jackson-inheritance)
|
||||
- [Working with Tree Model Nodes in Jackson](https://www.baeldung.com/jackson-json-node-tree-model)
|
||||
- [Get all the Keys in a JSON String Using JsonNode](https://www.baeldung.com/java-jsonnode-get-keys)
|
||||
- [Difference Between asText() and toString() in JsonNode](https://www.baeldung.com/java-jsonnode-astext-vs-tostring)
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.baeldung.offsetdatetime;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import com.fasterxml.jackson.databind.module.SimpleModule;
|
||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||
|
||||
import java.time.OffsetDateTime;
|
||||
|
||||
public class Main {
|
||||
public static void main(String[] args) throws JsonProcessingException {
|
||||
System.out.println(serializeUser());
|
||||
System.out.println(customSerialize());
|
||||
System.out.println(customDeserialize());
|
||||
}
|
||||
|
||||
static String serializeUser() throws JsonProcessingException {
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
|
||||
objectMapper.registerModule(new JavaTimeModule());
|
||||
|
||||
User user = new User();
|
||||
user.setCreatedAt(OffsetDateTime.parse("2021-09-30T15:30:00+01:00"));
|
||||
|
||||
return objectMapper.writeValueAsString(user);
|
||||
}
|
||||
|
||||
static String customSerialize() throws JsonProcessingException {
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
objectMapper.registerModule(new SimpleModule().addSerializer(OffsetDateTime.class, new OffsetDateTimeSerializer()));
|
||||
|
||||
User user = new User();
|
||||
user.setCreatedAt(OffsetDateTime.parse("2021-09-30T15:30:00+01:00"));
|
||||
|
||||
return objectMapper.writeValueAsString(user);
|
||||
}
|
||||
|
||||
static String customDeserialize() throws JsonProcessingException {
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
objectMapper.registerModule(new SimpleModule().addDeserializer(OffsetDateTime.class, new OffsetDateTimeDeserializer()));
|
||||
|
||||
String jsonString = "{\"createdAt\":\"30-09-2021 15:30:00 +01:00\"}";
|
||||
User returnedUser = objectMapper.readValue(jsonString, User.class);
|
||||
|
||||
return returnedUser.getCreatedAt().toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.baeldung.offsetdatetime;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||
import com.fasterxml.jackson.databind.JsonDeserializer;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
public class OffsetDateTimeDeserializer extends JsonDeserializer<OffsetDateTime> {
|
||||
private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter
|
||||
.ofPattern("dd-MM-yyyy HH:mm:ss XXX");
|
||||
|
||||
@Override
|
||||
public OffsetDateTime deserialize(JsonParser jsonParser, DeserializationContext deserializationContext)
|
||||
throws IOException {
|
||||
String dateAsString = jsonParser.getText();
|
||||
if (dateAsString == null) {
|
||||
throw new IOException("OffsetDateTime argument is null.");
|
||||
}
|
||||
return OffsetDateTime.parse(dateAsString, DATE_TIME_FORMATTER);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.baeldung.offsetdatetime;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.databind.JsonSerializer;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
public class OffsetDateTimeSerializer extends JsonSerializer<OffsetDateTime> {
|
||||
private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter
|
||||
.ofPattern("dd-MM-yyyy HH:mm:ss XXX");
|
||||
|
||||
@Override
|
||||
public void serialize(OffsetDateTime value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider)
|
||||
throws IOException {
|
||||
if (value == null) {
|
||||
throw new IOException("OffsetDateTime argument is null.");
|
||||
}
|
||||
jsonGenerator.writeString(DATE_TIME_FORMATTER.format(value));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.baeldung.offsetdatetime;
|
||||
|
||||
import java.time.OffsetDateTime;
|
||||
|
||||
public class User {
|
||||
private OffsetDateTime createdAt;
|
||||
|
||||
public User() {
|
||||
}
|
||||
|
||||
public OffsetDateTime getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
public void setCreatedAt(OffsetDateTime createdAt) {
|
||||
this.createdAt = createdAt;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.baeldung.offsetdatetime;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class MainUnitTest {
|
||||
|
||||
@Test
|
||||
void givenUser_whenSerialized_thenCreatedDateIsSerialized() throws JsonProcessingException {
|
||||
Assertions.assertEquals("{\"createdAt\":\"2021-09-30T15:30:00+01:00\"}", Main.serializeUser());
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenUser_whenCustomSerialized_thenCreatedDateIsSerialized() throws JsonProcessingException {
|
||||
Assertions.assertEquals("{\"createdAt\":\"30-09-2021 15:30:00 +01:00\"}", Main.customSerialize());
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenUser_whenCustomDeserialized_thenCreatedDateIsDeserialized() throws JsonProcessingException {
|
||||
Assertions.assertEquals("2021-09-30T15:30+01:00", Main.customDeserialize());
|
||||
}
|
||||
}
|
||||
@@ -24,11 +24,6 @@
|
||||
</modules>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>${jackson.version}</version>
|
||||
</dependency>
|
||||
<!--jackson for xml -->
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.dataformat</groupId>
|
||||
|
||||
@@ -4,3 +4,4 @@
|
||||
- [Jenkins Pipeline – Change to Another Folder](https://www.baeldung.com/ops/jenkins-pipeline-change-to-another-folder)
|
||||
- [How to Stop a Zombie Job on Jenkins Without Restarting the Server?](https://www.baeldung.com/ops/stop-zombie-job-on-jenkins-without-restarting-the-server)
|
||||
- [Running Stages in Parallel With Jenkins Workflow / Pipeline](https://www.baeldung.com/ops/running-stages-in-parallel-jenkins-workflow-pipeline)
|
||||
- [Skip a Stage in a Jenkins Pipeline](https://www.baeldung.com/ops/jenkins-pipeline-skip-stage)
|
||||
|
||||
@@ -16,7 +16,7 @@ import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import jakarta.ws.rs.core.Application;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
|
||||
public class EchoHeadersUnitTest extends JerseyTest {
|
||||
public class EchoHeadersIntegrationTest extends JerseyTest {
|
||||
|
||||
private static final String SIMPLE_HEADER_KEY = "my-header-key";
|
||||
private static final String SIMPLE_HEADER_VALUE = "my-header-value";
|
||||
@@ -1,6 +1,8 @@
|
||||
# R2DBC Test configuration
|
||||
r2dbc:
|
||||
url: r2dbc:h2:mem://./testdb
|
||||
user: local
|
||||
password: local
|
||||
|
||||
server:
|
||||
port: 8080
|
||||
@@ -24,6 +26,7 @@ spring:
|
||||
user: local
|
||||
password: local
|
||||
locations: classpath:db/h2/migration
|
||||
|
||||
main:
|
||||
allow-bean-definition-overriding: true
|
||||
|
||||
|
||||
|
||||
@@ -7,4 +7,5 @@
|
||||
- [The DAO with Spring and Hibernate](https://www.baeldung.com/persistence-layer-with-spring-and-hibernate)
|
||||
- [Simplify the DAO with Spring and Java Generics](https://www.baeldung.com/simplifying-the-data-access-layer-with-spring-and-java-generics)
|
||||
- [Multitenancy With Spring Data JPA](https://www.baeldung.com/multitenancy-with-spring-data-jpa)
|
||||
- [Remove Entity with Many-to-Many Relationship in JPA](https://www.baeldung.com/jpa-remove-entity-many-to-many)
|
||||
- More articles: [[<-- prev]](/spring-jpa)
|
||||
|
||||
96
pom.xml
96
pom.xml
@@ -332,7 +332,21 @@
|
||||
|
||||
<module>checker-plugin</module>
|
||||
<!-- <module>clojure</module> --> <!-- Not a maven project -->
|
||||
<module>core-java-modules</module>
|
||||
|
||||
<module>core-java-modules/core-java</module>
|
||||
<module>core-java-modules/core-java-8</module>
|
||||
<module>core-java-modules/core-java-8-2</module>
|
||||
<module>core-java-modules/core-java-8-datetime</module>
|
||||
<module>core-java-modules/core-java-8-datetime-2</module>
|
||||
<module>core-java-modules/core-java-sun</module>
|
||||
<module>core-java-modules/core-java-security</module>
|
||||
<module>core-java-modules/core-java-nio-2</module>
|
||||
<module>core-java-modules/core-java-serialization</module>
|
||||
<module>core-java-modules/core-java-lang</module>
|
||||
<module>core-java-modules/core-java-lang-math-3</module>
|
||||
<module>core-java-modules/core-java-collections-conversions-2</module>
|
||||
<module>core-java-modules/core-java-streams-2</module>
|
||||
|
||||
<module>couchbase</module>
|
||||
<!-- <module>ethereum</module> --> <!-- JAVA-6001 -->
|
||||
<!-- <module>gradle-modules</module> --> <!-- Not a maven project -->
|
||||
@@ -521,7 +535,20 @@
|
||||
<module>checker-plugin</module>
|
||||
<!-- <module>clojure</module> --> <!-- Not a maven project -->
|
||||
|
||||
<module>core-java-modules</module>
|
||||
<module>core-java-modules/core-java</module>
|
||||
<module>core-java-modules/core-java-8</module>
|
||||
<module>core-java-modules/core-java-8-2</module>
|
||||
<module>core-java-modules/core-java-8-datetime</module>
|
||||
<module>core-java-modules/core-java-8-datetime-2</module>
|
||||
<module>core-java-modules/core-java-sun</module>
|
||||
<module>core-java-modules/core-java-security</module>
|
||||
<module>core-java-modules/core-java-nio-2</module>
|
||||
<module>core-java-modules/core-java-serialization</module>
|
||||
<module>core-java-modules/core-java-lang</module>
|
||||
<module>core-java-modules/core-java-lang-math-3</module>
|
||||
<module>core-java-modules/core-java-collections-conversions-2</module>
|
||||
<module>core-java-modules/core-java-streams-2</module>
|
||||
|
||||
<module>couchbase</module>
|
||||
<!-- <module>ethereum</module> --> <!-- JAVA-6001 -->
|
||||
<!-- <module>gradle-modules</module> --> <!-- Not a maven project -->
|
||||
@@ -778,15 +805,8 @@
|
||||
<module>couchbase</module>
|
||||
<module>core-groovy-modules</module>
|
||||
|
||||
<module>core-java-modules/core-java-9</module>
|
||||
<module>core-java-modules/core-java-9-improvements</module>
|
||||
<module>core-java-modules/core-java-9-jigsaw</module>
|
||||
<module>core-java-modules</module>
|
||||
<!-- <module>core-java-modules/core-java-9-new-features</module> --> <!-- uses preview features, to be decided how to handle -->
|
||||
<module>core-java-modules/core-java-9-streams</module>
|
||||
<module>core-java-modules/core-java-10</module>
|
||||
<module>core-java-modules/core-java-11</module>
|
||||
<module>core-java-modules/core-java-11-2</module>
|
||||
<module>core-java-modules/core-java-11-3</module>
|
||||
<!-- <module>core-java-modules/core-java-12</module> --> <!-- uses preview features, to be decided how to handle -->
|
||||
<!-- <module>core-java-modules/core-java-13</module> --> <!-- uses preview features, to be decided how to handle -->
|
||||
<!-- <module>core-java-modules/core-java-14</module> --> <!-- uses preview features, to be decided how to handle -->
|
||||
@@ -794,27 +814,6 @@
|
||||
<!-- <module>core-java-modules/core-java-16</module> --> <!-- uses preview features, to be decided how to handle -->
|
||||
<!-- <module>core-java-modules/core-java-17</module> --> <!-- uses preview features, to be decided how to handle -->
|
||||
<!-- <module>core-java-modules/core-java-19</module> --> <!-- uses preview features, to be decided how to handle -->
|
||||
<module>core-java-modules/core-java-collections-set</module>
|
||||
<module>core-java-modules/core-java-collections-list-4</module>
|
||||
<module>core-java-modules/core-java-collections-array-list</module>
|
||||
<module>core-java-modules/core-java-collections-maps-4</module>
|
||||
<module>core-java-modules/core-java-collections-maps-5</module>
|
||||
<module>core-java-modules/core-java-concurrency-simple</module>
|
||||
<module>core-java-modules/core-java-date-operations-1</module>
|
||||
<module>core-java-modules/core-java-datetime-conversion</module>
|
||||
<module>core-java-modules/core-java-datetime-string</module>
|
||||
<module>core-java-modules/core-java-io-conversions-2</module>
|
||||
<module>core-java-modules/core-java-jpms</module>
|
||||
<module>core-java-modules/core-java-os</module>
|
||||
<module>core-java-modules/core-java-streams-4</module>
|
||||
<module>core-java-modules/core-java-string-algorithms-3</module>
|
||||
<module>core-java-modules/core-java-string-operations-3</module>
|
||||
<module>core-java-modules/core-java-string-operations-4</module>
|
||||
<module>core-java-modules/core-java-string-operations-5</module>
|
||||
<module>core-java-modules/core-java-time-measurements</module>
|
||||
<module>core-java-modules/core-java-networking-3</module>
|
||||
<module>core-java-modules/core-java-strings</module>
|
||||
<module>core-java-modules/core-java-httpclient</module>
|
||||
<module>custom-pmd</module>
|
||||
<module>spring-core-6</module>
|
||||
<module>data-structures</module>
|
||||
@@ -956,7 +955,7 @@
|
||||
<module>xstream</module>
|
||||
<module>webrtc</module>
|
||||
<module>persistence-modules/java-mongodb</module>
|
||||
|
||||
|
||||
<module>messaging-modules</module>
|
||||
|
||||
<module>persistence-modules/questdb</module>
|
||||
@@ -1050,15 +1049,9 @@
|
||||
<module>couchbase</module>
|
||||
|
||||
<module>core-groovy-modules</module>
|
||||
<module>core-java-modules/core-java-9</module>
|
||||
<module>core-java-modules/core-java-9-improvements</module>
|
||||
<module>core-java-modules/core-java-9-jigsaw</module>
|
||||
|
||||
<module>core-java-modules</module>
|
||||
<!-- <module>core-java-modules/core-java-9-new-features</module> --> <!-- uses preview features, to be decided how to handle -->
|
||||
<module>core-java-modules/core-java-9-streams</module>
|
||||
<module>core-java-modules/core-java-10</module>
|
||||
<module>core-java-modules/core-java-11</module>
|
||||
<module>core-java-modules/core-java-11-2</module>
|
||||
<module>core-java-modules/core-java-11-3</module>
|
||||
<!-- <module>core-java-modules/core-java-12</module> --> <!-- uses preview features, to be decided how to handle -->
|
||||
<!-- <module>core-java-modules/core-java-13</module> --> <!-- uses preview features, to be decided how to handle -->
|
||||
<!-- <module>core-java-modules/core-java-14</module> --> <!-- uses preview features, to be decided how to handle -->
|
||||
@@ -1066,27 +1059,6 @@
|
||||
<!-- <module>core-java-modules/core-java-16</module> --> <!-- uses preview features, to be decided how to handle -->
|
||||
<!-- <module>core-java-modules/core-java-17</module> --> <!-- uses preview features, to be decided how to handle -->
|
||||
<!-- <module>core-java-modules/core-java-19</module> --> <!-- uses preview features, to be decided how to handle -->
|
||||
<module>core-java-modules/core-java-collections-set</module>
|
||||
<module>core-java-modules/core-java-collections-list-4</module>
|
||||
<module>core-java-modules/core-java-collections-array-list</module>
|
||||
<module>core-java-modules/core-java-collections-maps-4</module>
|
||||
<module>core-java-modules/core-java-collections-maps-5</module>
|
||||
<module>core-java-modules/core-java-concurrency-simple</module>
|
||||
<module>core-java-modules/core-java-date-operations-1</module>
|
||||
<module>core-java-modules/core-java-datetime-conversion</module>
|
||||
<module>core-java-modules/core-java-datetime-string</module>
|
||||
<module>core-java-modules/core-java-io-conversions-2</module>
|
||||
<module>core-java-modules/core-java-jpms</module>
|
||||
<module>core-java-modules/core-java-os</module>
|
||||
<module>core-java-modules/core-java-streams-4</module>
|
||||
<module>core-java-modules/core-java-string-algorithms-3</module>
|
||||
<module>core-java-modules/core-java-string-operations-3</module>
|
||||
<module>core-java-modules/core-java-string-operations-4</module>
|
||||
<module>core-java-modules/core-java-string-operations-5</module>
|
||||
<module>core-java-modules/core-java-time-measurements</module>
|
||||
<module>core-java-modules/core-java-networking-3</module>
|
||||
<module>core-java-modules/core-java-strings</module>
|
||||
<module>core-java-modules/core-java-httpclient</module>
|
||||
<module>spring-aop</module>
|
||||
<module>spring-aop-2</module>
|
||||
<module>custom-pmd</module>
|
||||
@@ -1232,7 +1204,7 @@
|
||||
<module>xstream</module>
|
||||
<module>webrtc</module>
|
||||
<module>persistence-modules/java-mongodb</module>
|
||||
<module>libraries-2</module>
|
||||
<module>libraries-2</module>
|
||||
<module>messaging-modules</module>
|
||||
|
||||
<module>persistence-modules/questdb</module>
|
||||
|
||||
@@ -5,3 +5,4 @@
|
||||
- [Singleton Design Pattern vs Singleton Beans in Spring Boot](https://www.baeldung.com/spring-boot-singleton-vs-beans)
|
||||
- [Migrate Application From Spring Boot 2 to Spring Boot 3](https://www.baeldung.com/spring-boot-3-migration)
|
||||
- [Using Java Records with JPA](https://www.baeldung.com/spring-jpa-java-records)
|
||||
- [HTTP Interface in Spring 6](https://www.baeldung.com/spring-6-http-interface)
|
||||
|
||||
@@ -32,6 +32,20 @@
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-webflux</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mock-server</groupId>
|
||||
<artifactId>mockserver-netty</artifactId>
|
||||
<version>${mockserver.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mock-server</groupId>
|
||||
<artifactId>mockserver-client-java</artifactId>
|
||||
<version>${mockserver.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
@@ -125,7 +139,7 @@
|
||||
<springdoc.version>2.0.0</springdoc.version>
|
||||
<maven-surefire-plugin.version>3.0.0-M7</maven-surefire-plugin.version>
|
||||
<start-class>com.baeldung.sample.TodoApplication</start-class>
|
||||
|
||||
<mockserver.version>5.14.0</mockserver.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
@@ -15,12 +15,12 @@ interface BooksService {
|
||||
List<Book> getBooks();
|
||||
|
||||
@GetExchange("/books/{id}")
|
||||
Book getBook(@PathVariable long id);
|
||||
Book getBook(@PathVariable("id") long id);
|
||||
|
||||
@PostExchange("/books")
|
||||
Book saveBook(@RequestBody Book book);
|
||||
|
||||
@DeleteExchange("/books/{id}")
|
||||
ResponseEntity<Void> deleteBook(@PathVariable long id);
|
||||
ResponseEntity<Void> deleteBook(@PathVariable("id") long id);
|
||||
|
||||
}
|
||||
@@ -7,3 +7,4 @@ This module contains articles about configuring the Spring Boot `Environment`
|
||||
- [Spring Properties File Outside jar](https://www.baeldung.com/spring-properties-file-outside-jar)
|
||||
- [Get the Running Port in Spring Boot](https://www.baeldung.com/spring-boot-running-port)
|
||||
- [Environment Variable Prefixes in Spring Boot 2.5](https://www.baeldung.com/spring-boot-env-variable-prefixes)
|
||||
- [Spring Profiles](http://www.baeldung.com/spring-profiles)
|
||||
|
||||
@@ -133,8 +133,23 @@
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>dev</id>
|
||||
<activation>
|
||||
<activeByDefault>true</activeByDefault>
|
||||
</activation>
|
||||
<properties>
|
||||
<spring.profiles.active>dev</spring.profiles.active>
|
||||
</properties>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>prod</id>
|
||||
<properties>
|
||||
<spring.profiles.active>prod</spring.profiles.active>
|
||||
</properties>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
|
||||
<properties>
|
||||
<jpa.version>2.2</jpa.version>
|
||||
<subethasmtp.version>3.1.7</subethasmtp.version>
|
||||
|
||||
@@ -4,4 +4,34 @@ management.metrics.enable.jvm=true
|
||||
management.endpoint.restart.enabled=true
|
||||
spring.datasource.tomcat.jmx-enabled=false
|
||||
management.endpoint.shutdown.enabled=true
|
||||
spring.config.import=file:./additional.properties,optional:file:/Users/home/config/jdbc.properties
|
||||
spring.config.import=file:./additional.properties,optional:file:/Users/home/config/jdbc.properties
|
||||
|
||||
#---
|
||||
spring.profiles.active=@spring.profiles.active@
|
||||
|
||||
my.prop=used-always-in-all-profiles
|
||||
|
||||
#---
|
||||
spring.config.activate.on-profile=dev
|
||||
#spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
|
||||
#spring.datasource.url=jdbc:mysql://localhost:3306/db
|
||||
#spring.datasource.username=root
|
||||
#spring.datasource.password=root
|
||||
|
||||
#---
|
||||
spring.config.activate.on-profile=production
|
||||
#spring.datasource.driver-class-name=org.h2.Driver
|
||||
#spring.datasource.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1
|
||||
#spring.datasource.username=sa
|
||||
#spring.datasource.password=sa
|
||||
|
||||
#---
|
||||
spring.profiles.group.production=proddb,prodquartz
|
||||
|
||||
#---
|
||||
spring.config.activate.on-profile=proddb
|
||||
db=url_to_production_db
|
||||
|
||||
#---
|
||||
spring.config.activate.on-profile=prodquartz
|
||||
quartz=url_to_quartz_scheduler
|
||||
@@ -10,3 +10,5 @@
|
||||
- [Load Spring Boot Properties From a JSON File](https://www.baeldung.com/spring-boot-json-properties)
|
||||
- [IntelliJ – Cannot Resolve Spring Boot Configuration Properties Error](https://www.baeldung.com/intellij-resolve-spring-boot-configuration-properties)
|
||||
- [Log Properties in a Spring Boot Application](https://www.baeldung.com/spring-boot-log-properties)
|
||||
- [Using Environment Variables in Spring Boot’s application.properties](https://www.baeldung.com/spring-boot-properties-env-variables)
|
||||
- More articles: [[<-- prev]](../spring-boot-properties-2)
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
package com.baeldung.envvariables.valueinjection;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@ConfigurationProperties(prefix = "baeldung")
|
||||
public class BaeldungProperties {
|
||||
|
||||
private String presentation;
|
||||
|
||||
public String getPresentation() {
|
||||
return presentation;
|
||||
}
|
||||
|
||||
public void setPresentation(String presentation) {
|
||||
this.presentation = presentation;
|
||||
}
|
||||
|
||||
}
|
||||
package com.baeldung.envvariables;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@ConfigurationProperties(prefix = "baeldung")
|
||||
public class BaeldungProperties {
|
||||
|
||||
private String presentation;
|
||||
|
||||
public String getPresentation() {
|
||||
return presentation;
|
||||
}
|
||||
|
||||
public void setPresentation(String presentation) {
|
||||
this.presentation = presentation;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,60 +1,60 @@
|
||||
package com.baeldung.envvariables.valueinjection;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
public class MyController {
|
||||
|
||||
@Value("${environment.name}")
|
||||
private String environmentName;
|
||||
|
||||
@Value("${java.home.and.environment}")
|
||||
private String javaHomeAndEnvironmentName;
|
||||
|
||||
@Value("${thispropertydoesnotexist}")
|
||||
private String nonExistentProperty;
|
||||
|
||||
@Value("${baeldung.presentation}")
|
||||
private String baeldungPresentation;
|
||||
|
||||
@Autowired
|
||||
private Environment environment;
|
||||
|
||||
@Autowired
|
||||
private BaeldungProperties baeldungProperties;
|
||||
|
||||
@GetMapping("/environment_name")
|
||||
String getEnvironmentName_FromEnvironmentVariables() {
|
||||
return environmentName;
|
||||
}
|
||||
|
||||
@GetMapping("/java_home_and_environment")
|
||||
String getJavaHomeAndEnvironmentName_FromEnvironmentVariables() {
|
||||
return javaHomeAndEnvironmentName;
|
||||
}
|
||||
|
||||
@GetMapping("non_existent_property")
|
||||
String getNonexistentProperty_FromEnvironmentVariables() {
|
||||
return nonExistentProperty;
|
||||
}
|
||||
|
||||
@GetMapping("baeldung_presentation_from_value")
|
||||
String getBaeldungPresentation_FromValue() {
|
||||
return baeldungPresentation;
|
||||
}
|
||||
|
||||
@GetMapping("baeldung_presentation_from_environment")
|
||||
String getBaeldungPresentation_FromEnvironment() {
|
||||
return environment.getProperty("baeldung.presentation");
|
||||
}
|
||||
|
||||
@GetMapping("baeldung_configuration_properties")
|
||||
String getBaeldungPresentation_FromConfigurationProperties() {
|
||||
return baeldungProperties.getPresentation();
|
||||
}
|
||||
|
||||
}
|
||||
package com.baeldung.envvariables;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
public class MyController {
|
||||
|
||||
@Value("${environment.name}")
|
||||
private String environmentName;
|
||||
|
||||
@Value("${java.home.and.environment}")
|
||||
private String javaHomeAndEnvironmentName;
|
||||
|
||||
@Value("${thispropertydoesnotexist}")
|
||||
private String nonExistentProperty;
|
||||
|
||||
@Value("${baeldung.presentation}")
|
||||
private String baeldungPresentation;
|
||||
|
||||
@Autowired
|
||||
private Environment environment;
|
||||
|
||||
@Autowired
|
||||
private BaeldungProperties baeldungProperties;
|
||||
|
||||
@GetMapping("/environment_name")
|
||||
String getEnvironmentName_FromEnvironmentVariables() {
|
||||
return environmentName;
|
||||
}
|
||||
|
||||
@GetMapping("/java_home_and_environment")
|
||||
String getJavaHomeAndEnvironmentName_FromEnvironmentVariables() {
|
||||
return javaHomeAndEnvironmentName;
|
||||
}
|
||||
|
||||
@GetMapping("non_existent_property")
|
||||
String getNonexistentProperty_FromEnvironmentVariables() {
|
||||
return nonExistentProperty;
|
||||
}
|
||||
|
||||
@GetMapping("baeldung_presentation_from_value")
|
||||
String getBaeldungPresentation_FromValue() {
|
||||
return baeldungPresentation;
|
||||
}
|
||||
|
||||
@GetMapping("baeldung_presentation_from_environment")
|
||||
String getBaeldungPresentation_FromEnvironment() {
|
||||
return environment.getProperty("baeldung.presentation");
|
||||
}
|
||||
|
||||
@GetMapping("baeldung_configuration_properties")
|
||||
String getBaeldungPresentation_FromConfigurationProperties() {
|
||||
return baeldungProperties.getPresentation();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -26,4 +26,9 @@ spring.config.activate.on-profile=multidocument-prod
|
||||
spring.datasource.password=password
|
||||
spring.datasource.url=jdbc:h2:prod
|
||||
spring.datasource.username=prodUser
|
||||
bael.property=prodValue
|
||||
bael.property=prodValue
|
||||
#---
|
||||
environment.name=${OS}
|
||||
java.home.and.environment=${JAVA_HOME}+${OS}
|
||||
not.existing.system.property=${thispropertydoesnotexist}
|
||||
baeldung.presentation=${HELLO_BAELDUNG}. Java is installed in the folder: ${JAVA_HOME}
|
||||
@@ -1,36 +1,36 @@
|
||||
package com.baeldung.envvariables.valueinjection;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
|
||||
@SpringBootTest(classes = MyController.class)
|
||||
@AutoConfigureMockMvc
|
||||
public class MyControllerIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
private MockMvc mockMvc;
|
||||
|
||||
/** NB : these tests are commented out because they are environment dependent
|
||||
* If you want to run one of them on your machine, follow the instruction above it
|
||||
*
|
||||
* expects the value of your system environment property 'OS' (it is already defined at least in Windows_NT)
|
||||
@Test void givenExistingSystemProperty_whenInjected_thenHasSystemPropertyValue() throws Exception {
|
||||
mockMvc.perform(get("/environment_name"))
|
||||
.andExpect(content().string(equalTo("Windows_NT")));
|
||||
}
|
||||
|
||||
* expects the value of the JAVA_HOME environment variable (you need to define it if you haven't yet), with a + and the 'OS' environment property in the end
|
||||
@Test void givenCombinationOfSystemPropertyAndEnvironmentVariable_whenInjected_thenHasExpectedValue() throws Exception {
|
||||
mockMvc.perform(get("/java_home_and_environment"))
|
||||
.andExpect(content().string(equalTo("C:\\Program Files\\Java\\jdk-11.0.14+Windows_NT")));
|
||||
}
|
||||
|
||||
* expects the content to be ${thispropertydoesnotexist} ; if you have defined an environment property called thispropertydoesnotexist, it would fail
|
||||
@Test void givenNonExistentProperty_whenInjected_thenKeepsTheStringValue() throws Exception {
|
||||
mockMvc.perform(get("/non_existent_property"))
|
||||
.andExpect(content().string(equalTo("${thispropertydoesnotexist}")));
|
||||
}
|
||||
*/
|
||||
}
|
||||
package com.baeldung.envvariables;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
|
||||
@SpringBootTest(classes = MyController.class)
|
||||
@AutoConfigureMockMvc
|
||||
public class MyControllerIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
private MockMvc mockMvc;
|
||||
|
||||
/** NB : these tests are commented out because they are environment dependent
|
||||
* If you want to run one of them on your machine, follow the instruction above it
|
||||
*
|
||||
* expects the value of your system environment property 'OS' (it is already defined at least in Windows_NT)
|
||||
@Test void givenExistingSystemProperty_whenInjected_thenHasSystemPropertyValue() throws Exception {
|
||||
mockMvc.perform(get("/environment_name"))
|
||||
.andExpect(content().string(equalTo("Windows_NT")));
|
||||
}
|
||||
|
||||
* expects the value of the JAVA_HOME environment variable (you need to define it if you haven't yet), with a + and the 'OS' environment property in the end
|
||||
@Test void givenCombinationOfSystemPropertyAndEnvironmentVariable_whenInjected_thenHasExpectedValue() throws Exception {
|
||||
mockMvc.perform(get("/java_home_and_environment"))
|
||||
.andExpect(content().string(equalTo("C:\\Program Files\\Java\\jdk-11.0.14+Windows_NT")));
|
||||
}
|
||||
|
||||
* expects the content to be ${thispropertydoesnotexist} ; if you have defined an environment property called thispropertydoesnotexist, it would fail
|
||||
@Test void givenNonExistentProperty_whenInjected_thenKeepsTheStringValue() throws Exception {
|
||||
mockMvc.perform(get("/non_existent_property"))
|
||||
.andExpect(content().string(equalTo("${thispropertydoesnotexist}")));
|
||||
}
|
||||
*/
|
||||
}
|
||||
@@ -2,3 +2,4 @@
|
||||
|
||||
- [Spring Validation in the Service Layer](https://www.baeldung.com/spring-service-layer-validation)
|
||||
- [Validation in Spring Boot](https://www.baeldung.com/spring-boot-bean-validation)
|
||||
- [Spring Null-Safety Annotations](https://www.baeldung.com/spring-null-safety-annotations)
|
||||
@@ -20,6 +20,12 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>tomcat-embed-el</artifactId>
|
||||
<groupId>org.apache.tomcat.embed</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.dataformat</groupId>
|
||||
@@ -42,37 +48,101 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>jakarta.xml.bind-api</artifactId>
|
||||
<groupId>jakarta.xml.bind</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>txw2</artifactId>
|
||||
<groupId>org.glassfish.jaxb</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-rest</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<!-- Spring HATEOAS -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-hateoas</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<!-- util -->
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>${guava.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>listenablefuture</artifactId>
|
||||
<groupId>com.google.guava</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>jsr305</artifactId>
|
||||
<groupId>com.google.code.findbugs</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>error_prone_annotations</artifactId>
|
||||
<groupId>com.google.errorprone</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>j2objc-annotations</artifactId>
|
||||
<groupId>com.google.j2objc</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>jakarta.xml.bind-api</artifactId>
|
||||
<groupId>jakarta.xml.bind</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.htmlunit</groupId>
|
||||
<artifactId>htmlunit</artifactId>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
<groupId>commons-logging</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.modelmapper</groupId>
|
||||
<artifactId>modelmapper</artifactId>
|
||||
<version>${modelmapper.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.rest-assured</groupId>
|
||||
<artifactId>rest-assured</artifactId>
|
||||
<version>3.3.0</version>
|
||||
<scope>provided</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>hamcrest-library</artifactId>
|
||||
<groupId>org.hamcrest</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
@@ -90,5 +160,4 @@
|
||||
<modelmapper.version>3.1.0</modelmapper.version>
|
||||
<maven-war-plugin.version>3.3.2</maven-war-plugin.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
</project>
|
||||
|
||||
@@ -6,7 +6,7 @@ import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||
|
||||
@RestControllerAdvice
|
||||
public class ProductControllerAdvice {
|
||||
public class PriceControllerAdvice {
|
||||
|
||||
@ExceptionHandler(PriceNotFoundException.class)
|
||||
public ResponseEntity<Object> handlePriceNotFoundException(PriceNotFoundException exception) {
|
||||
@@ -4,8 +4,6 @@ This module contains articles about core Spring functionality
|
||||
|
||||
## Relevant Articles:
|
||||
|
||||
- [Spring Profiles](http://www.baeldung.com/spring-profiles)
|
||||
- [Quick Guide to Spring Bean Scopes](http://www.baeldung.com/spring-bean-scopes)
|
||||
- [Spring Events](https://www.baeldung.com/spring-events)
|
||||
- [Spring Null-Safety Annotations](https://www.baeldung.com/spring-null-safety-annotations)
|
||||
- More articles: [[<-- prev]](/spring-core)[[next -->]](/spring-core-3)
|
||||
|
||||
@@ -162,24 +162,6 @@
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>dev</id>
|
||||
<activation>
|
||||
<activeByDefault>true</activeByDefault>
|
||||
</activation>
|
||||
<properties>
|
||||
<spring.profiles.active>dev</spring.profiles.active>
|
||||
</properties>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>prod</id>
|
||||
<properties>
|
||||
<spring.profiles.active>prod</spring.profiles.active>
|
||||
</properties>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
<properties>
|
||||
<start-class>com.baeldung.sample.App</start-class>
|
||||
<!-- Spring -->
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
spring.profiles.active=@spring.profiles.active@
|
||||
|
||||
my.prop=used-always-in-all-profiles
|
||||
|
||||
#---
|
||||
spring.config.activate.on-profile=dev
|
||||
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
|
||||
spring.datasource.url=jdbc:mysql://localhost:3306/db
|
||||
spring.datasource.username=root
|
||||
spring.datasource.password=root
|
||||
|
||||
#---
|
||||
spring.config.activate.on-profile=production
|
||||
spring.datasource.driver-class-name=org.h2.Driver
|
||||
spring.datasource.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1
|
||||
spring.datasource.username=sa
|
||||
spring.datasource.password=sa
|
||||
|
||||
#---
|
||||
spring.profiles.group.production=proddb,prodquartz
|
||||
|
||||
#---
|
||||
spring.config.activate.on-profile=proddb
|
||||
db=url_to_production_db
|
||||
|
||||
#---
|
||||
spring.config.activate.on-profile=prodquartz
|
||||
quartz=url_to_quartz_scheduler
|
||||
@@ -1,6 +1,5 @@
|
||||
|
||||
### Relevant Articles:
|
||||
- [Using Environment Variables in Spring Boot’s application.properties](https://www.baeldung.com/spring-boot-properties-env-variables)
|
||||
- [Reinitialize Singleton Bean in Spring Context](https://www.baeldung.com/spring-reinitialize-singleton-bean)
|
||||
- [HTTP Interface in Spring 6](https://www.baeldung.com/spring-6-http-interface)
|
||||
- [Getting the Current ApplicationContext in Spring](https://www.baeldung.com/spring-get-current-applicationcontext)
|
||||
- More articles: [[<-- prev]](../spring-core-5)
|
||||
@@ -21,20 +21,6 @@
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-webflux</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mock-server</groupId>
|
||||
<artifactId>mockserver-netty</artifactId>
|
||||
<version>${mockserver.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mock-server</groupId>
|
||||
<artifactId>mockserver-client-java</artifactId>
|
||||
<version>${mockserver.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
@@ -104,7 +90,6 @@
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
<mockserver.version>5.14.0</mockserver.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
@@ -1,5 +1 @@
|
||||
environment.name=${OS}
|
||||
java.home.and.environment=${JAVA_HOME}+${OS}
|
||||
not.existing.system.property=${thispropertydoesnotexist}
|
||||
baeldung.presentation=${HELLO_BAELDUNG}. Java is installed in the folder: ${JAVA_HOME}
|
||||
config.file.path=./spring-core-6/src/main/resources/config.properties
|
||||
@@ -1,217 +0,0 @@
|
||||
package com.baeldung.httpinterface;
|
||||
|
||||
import org.apache.http.HttpException;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockserver.client.MockServerClient;
|
||||
import org.mockserver.integration.ClientAndServer;
|
||||
import org.mockserver.configuration.Configuration;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.ServerSocket;
|
||||
import java.util.List;
|
||||
|
||||
import org.mockserver.model.HttpRequest;
|
||||
import org.mockserver.model.MediaType;
|
||||
import org.mockserver.verify.VerificationTimes;
|
||||
import org.slf4j.event.Level;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.HttpStatusCode;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
import org.springframework.web.reactive.function.client.WebClientResponseException;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
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;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
class BooksServiceMockServerTest {
|
||||
|
||||
private static final String SERVER_ADDRESS = "localhost";
|
||||
private static final String PATH = "/books";
|
||||
|
||||
private static int serverPort;
|
||||
private static ClientAndServer mockServer;
|
||||
private static String serviceUrl;
|
||||
|
||||
@BeforeAll
|
||||
static void startServer() throws IOException {
|
||||
serverPort = getFreePort();
|
||||
serviceUrl = "http://" + SERVER_ADDRESS + ":" + serverPort;
|
||||
|
||||
Configuration config = Configuration.configuration().logLevel(Level.WARN);
|
||||
mockServer = startClientAndServer(config, serverPort);
|
||||
|
||||
mockAllBooksRequest();
|
||||
mockBookByIdRequest();
|
||||
mockSaveBookRequest();
|
||||
mockDeleteBookRequest();
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
static void stopServer() {
|
||||
mockServer.stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenMockedGetResponse_whenGetBooksServiceMethodIsCalled_thenTwoBooksAreReturned() {
|
||||
BooksClient booksClient = new BooksClient(WebClient.builder().baseUrl(serviceUrl).build());
|
||||
BooksService booksService = booksClient.getBooksService();
|
||||
|
||||
List<Book> books = booksService.getBooks();
|
||||
assertEquals(2, books.size());
|
||||
|
||||
mockServer.verify(
|
||||
HttpRequest.request()
|
||||
.withMethod(HttpMethod.GET.name())
|
||||
.withPath(PATH),
|
||||
VerificationTimes.exactly(1)
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenMockedGetResponse_whenGetExistingBookServiceMethodIsCalled_thenCorrectBookIsReturned() {
|
||||
BooksClient booksClient = new BooksClient(WebClient.builder().baseUrl(serviceUrl).build());
|
||||
BooksService booksService = booksClient.getBooksService();
|
||||
|
||||
Book book = booksService.getBook(1);
|
||||
assertEquals("Book_1", book.title());
|
||||
|
||||
mockServer.verify(
|
||||
HttpRequest.request()
|
||||
.withMethod(HttpMethod.GET.name())
|
||||
.withPath(PATH + "/1"),
|
||||
VerificationTimes.exactly(1)
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenMockedGetResponse_whenGetNonExistingBookServiceMethodIsCalled_thenCorrectBookIsReturned() {
|
||||
BooksClient booksClient = new BooksClient(WebClient.builder().baseUrl(serviceUrl).build());
|
||||
BooksService booksService = booksClient.getBooksService();
|
||||
|
||||
assertThrows(WebClientResponseException.class, () -> booksService.getBook(9));
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenCustomErrorHandlerIsSet_whenGetNonExistingBookServiceMethodIsCalled_thenCustomExceptionIsThrown() {
|
||||
BooksClient booksClient = new BooksClient(WebClient.builder()
|
||||
.defaultStatusHandler(HttpStatusCode::isError, resp ->
|
||||
Mono.just(new MyServiceException("Custom exception")))
|
||||
.baseUrl(serviceUrl)
|
||||
.build());
|
||||
|
||||
BooksService booksService = booksClient.getBooksService();
|
||||
assertThrows(MyServiceException.class, () -> booksService.getBook(9));
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenMockedPostResponse_whenSaveBookServiceMethodIsCalled_thenCorrectBookIsReturned() {
|
||||
BooksClient booksClient = new BooksClient(WebClient.builder().baseUrl(serviceUrl).build());
|
||||
BooksService booksService = booksClient.getBooksService();
|
||||
|
||||
Book book = booksService.saveBook(new Book(3, "Book_3", "Author_3", 2000));
|
||||
assertEquals("Book_3", book.title());
|
||||
|
||||
mockServer.verify(
|
||||
HttpRequest.request()
|
||||
.withMethod(HttpMethod.POST.name())
|
||||
.withPath(PATH),
|
||||
VerificationTimes.exactly(1)
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenMockedDeleteResponse_whenDeleteBookServiceMethodIsCalled_thenCorrectCodeIsReturned() {
|
||||
BooksClient booksClient = new BooksClient(WebClient.builder().baseUrl(serviceUrl).build());
|
||||
BooksService booksService = booksClient.getBooksService();
|
||||
|
||||
ResponseEntity<Void> response = booksService.deleteBook(3);
|
||||
assertEquals(HttpStatusCode.valueOf(200), response.getStatusCode());
|
||||
|
||||
mockServer.verify(
|
||||
HttpRequest.request()
|
||||
.withMethod(HttpMethod.DELETE.name())
|
||||
.withPath(PATH + "/3"),
|
||||
VerificationTimes.exactly(1)
|
||||
);
|
||||
}
|
||||
|
||||
private static int getFreePort () throws IOException {
|
||||
try (ServerSocket serverSocket = new ServerSocket(0)) {
|
||||
return serverSocket.getLocalPort();
|
||||
}
|
||||
}
|
||||
|
||||
private static void mockAllBooksRequest() {
|
||||
new MockServerClient(SERVER_ADDRESS, serverPort)
|
||||
.when(
|
||||
request()
|
||||
.withPath(PATH)
|
||||
.withMethod(HttpMethod.GET.name()),
|
||||
exactly(1)
|
||||
)
|
||||
.respond(
|
||||
response()
|
||||
.withStatusCode(HttpStatus.SC_OK)
|
||||
.withContentType(MediaType.APPLICATION_JSON)
|
||||
.withBody("[{\"id\":1,\"title\":\"Book_1\",\"author\":\"Author_1\",\"year\":1998},{\"id\":2,\"title\":\"Book_2\",\"author\":\"Author_2\",\"year\":1999}]")
|
||||
);
|
||||
}
|
||||
|
||||
private static void mockBookByIdRequest() {
|
||||
new MockServerClient(SERVER_ADDRESS, serverPort)
|
||||
.when(
|
||||
request()
|
||||
.withPath(PATH + "/1")
|
||||
.withMethod(HttpMethod.GET.name()),
|
||||
exactly(1)
|
||||
)
|
||||
.respond(
|
||||
response()
|
||||
.withStatusCode(HttpStatus.SC_OK)
|
||||
.withContentType(MediaType.APPLICATION_JSON)
|
||||
.withBody("{\"id\":1,\"title\":\"Book_1\",\"author\":\"Author_1\",\"year\":1998}")
|
||||
);
|
||||
}
|
||||
|
||||
private static void mockSaveBookRequest() {
|
||||
new MockServerClient(SERVER_ADDRESS, serverPort)
|
||||
.when(
|
||||
request()
|
||||
.withPath(PATH)
|
||||
.withMethod(HttpMethod.POST.name())
|
||||
.withContentType(MediaType.APPLICATION_JSON)
|
||||
.withBody("{\"id\":3,\"title\":\"Book_3\",\"author\":\"Author_3\",\"year\":2000}"),
|
||||
exactly(1)
|
||||
)
|
||||
.respond(
|
||||
response()
|
||||
.withStatusCode(HttpStatus.SC_OK)
|
||||
.withContentType(MediaType.APPLICATION_JSON)
|
||||
.withBody("{\"id\":3,\"title\":\"Book_3\",\"author\":\"Author_3\",\"year\":2000}")
|
||||
);
|
||||
}
|
||||
|
||||
private static void mockDeleteBookRequest() {
|
||||
new MockServerClient(SERVER_ADDRESS, serverPort)
|
||||
.when(
|
||||
request()
|
||||
.withPath(PATH + "/3")
|
||||
.withMethod(HttpMethod.DELETE.name()),
|
||||
exactly(1)
|
||||
)
|
||||
.respond(
|
||||
response()
|
||||
.withStatusCode(HttpStatus.SC_OK)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
package com.baeldung.httpinterface;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Answers;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.springframework.core.ParameterizedTypeReference;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.HttpStatusCode;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import static org.mockito.BDDMockito.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class BooksServiceMockitoTest {
|
||||
|
||||
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||
private WebClient webClient;
|
||||
|
||||
@InjectMocks
|
||||
private BooksClient booksClient;
|
||||
|
||||
@Test
|
||||
void givenMockedWebClientReturnsTwoBooks_whenGetBooksServiceMethodIsCalled_thenListOfTwoBooksIsReturned() {
|
||||
given(webClient.method(HttpMethod.GET)
|
||||
.uri(anyString(), anyMap())
|
||||
.retrieve()
|
||||
.bodyToMono(new ParameterizedTypeReference<List<Book>>(){}))
|
||||
.willReturn(Mono.just(List.of(
|
||||
new Book(1,"Book_1", "Author_1", 1998),
|
||||
new Book(2, "Book_2", "Author_2", 1999)
|
||||
)));
|
||||
|
||||
BooksService booksService = booksClient.getBooksService();
|
||||
List<Book> books = booksService.getBooks();
|
||||
assertEquals(2, books.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenMockedWebClientReturnsBook_whenGetBookServiceMethodIsCalled_thenBookIsReturned() {
|
||||
given(webClient.method(HttpMethod.GET)
|
||||
.uri(anyString(), anyMap())
|
||||
.retrieve()
|
||||
.bodyToMono(new ParameterizedTypeReference<Book>(){}))
|
||||
.willReturn(Mono.just(new Book(1,"Book_1", "Author_1", 1998)));
|
||||
|
||||
BooksService booksService = booksClient.getBooksService();
|
||||
Book book = booksService.getBook(1);
|
||||
assertEquals("Book_1", book.title());
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenMockedWebClientReturnsBook_whenSaveBookServiceMethodIsCalled_thenBookIsReturned() {
|
||||
given(webClient.method(HttpMethod.POST)
|
||||
.uri(anyString(), anyMap())
|
||||
.retrieve()
|
||||
.bodyToMono(new ParameterizedTypeReference<Book>(){}))
|
||||
.willReturn(Mono.just(new Book(3, "Book_3", "Author_3", 2000)));
|
||||
|
||||
BooksService booksService = booksClient.getBooksService();
|
||||
Book book = booksService.saveBook(new Book(3, "Book_3", "Author_3", 2000));
|
||||
assertEquals("Book_3", book.title());
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenMockedWebClientReturnsOk_whenDeleteBookServiceMethodIsCalled_thenOkCodeIsReturned() {
|
||||
given(webClient.method(HttpMethod.DELETE)
|
||||
.uri(anyString(), anyMap())
|
||||
.retrieve()
|
||||
.toBodilessEntity()
|
||||
.block(any())
|
||||
.getStatusCode())
|
||||
.willReturn(HttpStatusCode.valueOf(200));
|
||||
|
||||
BooksService booksService = booksClient.getBooksService();
|
||||
ResponseEntity<Void> response = booksService.deleteBook(3);
|
||||
assertEquals(HttpStatusCode.valueOf(200), response.getStatusCode());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -23,6 +23,16 @@
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
<version>3.0.5</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.micrometer</groupId>
|
||||
<artifactId>micrometer-registry-prometheus</artifactId>
|
||||
<version>1.10.5</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.kafka</groupId>
|
||||
<artifactId>spring-kafka</artifactId>
|
||||
|
||||
@@ -10,6 +10,7 @@ public class LagAnalyzerApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(LagAnalyzerApplication.class, args);
|
||||
while (true) ;
|
||||
while (true)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.baeldung.monitoring.service;
|
||||
|
||||
import com.baeldung.monitoring.util.MonitoringUtil;
|
||||
|
||||
import org.apache.kafka.clients.admin.AdminClient;
|
||||
import org.apache.kafka.clients.admin.AdminClientConfig;
|
||||
import org.apache.kafka.clients.admin.ListConsumerGroupOffsetsResult;
|
||||
@@ -27,36 +28,38 @@ public class LagAnalyzerService {
|
||||
private final KafkaConsumer<String, String> consumer;
|
||||
|
||||
@Autowired
|
||||
public LagAnalyzerService(
|
||||
@Value("${monitor.kafka.bootstrap.config}") String bootstrapServerConfig) {
|
||||
public LagAnalyzerService(@Value("${monitor.kafka.bootstrap.config}") String bootstrapServerConfig) {
|
||||
adminClient = getAdminClient(bootstrapServerConfig);
|
||||
consumer = getKafkaConsumer(bootstrapServerConfig);
|
||||
}
|
||||
|
||||
public Map<TopicPartition, Long> analyzeLag(
|
||||
String groupId)
|
||||
throws ExecutionException, InterruptedException {
|
||||
public Map<TopicPartition, Long> analyzeLag(String groupId)
|
||||
throws ExecutionException, InterruptedException {
|
||||
Map<TopicPartition, Long> consumerGrpOffsets = getConsumerGrpOffsets(groupId);
|
||||
Map<TopicPartition, Long> producerOffsets = getProducerOffsets(consumerGrpOffsets);
|
||||
Map<TopicPartition, Long> lags = computeLags(consumerGrpOffsets, producerOffsets);
|
||||
for (Map.Entry<TopicPartition, Long> lagEntry : lags.entrySet()) {
|
||||
String topic = lagEntry.getKey().topic();
|
||||
int partition = lagEntry.getKey().partition();
|
||||
String topic = lagEntry.getKey()
|
||||
.topic();
|
||||
int partition = lagEntry.getKey()
|
||||
.partition();
|
||||
Long lag = lagEntry.getValue();
|
||||
LOGGER.info("Time={} | Lag for topic = {}, partition = {} is {}",
|
||||
MonitoringUtil.time(),
|
||||
topic,
|
||||
partition,
|
||||
lag);
|
||||
LOGGER.info("Time={} | Lag for topic = {}, partition = {}, groupId = {} is {}",
|
||||
MonitoringUtil.time(),
|
||||
topic,
|
||||
partition,
|
||||
groupId,
|
||||
lag);
|
||||
}
|
||||
return lags;
|
||||
}
|
||||
|
||||
public Map<TopicPartition, Long> getConsumerGrpOffsets(String groupId)
|
||||
throws ExecutionException, InterruptedException {
|
||||
throws ExecutionException, InterruptedException {
|
||||
ListConsumerGroupOffsetsResult info = adminClient.listConsumerGroupOffsets(groupId);
|
||||
Map<TopicPartition, OffsetAndMetadata> metadataMap
|
||||
= info.partitionsToOffsetAndMetadata().get();
|
||||
Map<TopicPartition, OffsetAndMetadata> metadataMap = info
|
||||
.partitionsToOffsetAndMetadata()
|
||||
.get();
|
||||
Map<TopicPartition, Long> groupOffset = new HashMap<>();
|
||||
for (Map.Entry<TopicPartition, OffsetAndMetadata> entry : metadataMap.entrySet()) {
|
||||
TopicPartition key = entry.getKey();
|
||||
@@ -66,8 +69,7 @@ public class LagAnalyzerService {
|
||||
return groupOffset;
|
||||
}
|
||||
|
||||
private Map<TopicPartition, Long> getProducerOffsets(
|
||||
Map<TopicPartition, Long> consumerGrpOffset) {
|
||||
private Map<TopicPartition, Long> getProducerOffsets(Map<TopicPartition, Long> consumerGrpOffset) {
|
||||
List<TopicPartition> topicPartitions = new LinkedList<>();
|
||||
for (Map.Entry<TopicPartition, Long> entry : consumerGrpOffset.entrySet()) {
|
||||
TopicPartition key = entry.getKey();
|
||||
@@ -77,9 +79,9 @@ public class LagAnalyzerService {
|
||||
}
|
||||
|
||||
public Map<TopicPartition, Long> computeLags(
|
||||
Map<TopicPartition, Long> consumerGrpOffsets,
|
||||
Map<TopicPartition, Long> producerOffsets) {
|
||||
Map<TopicPartition, Long> lags = new HashMap<>();
|
||||
Map<TopicPartition, Long> consumerGrpOffsets,
|
||||
Map<TopicPartition, Long> producerOffsets) {
|
||||
Map<TopicPartition, Long> lags = new HashMap<>();
|
||||
for (Map.Entry<TopicPartition, Long> entry : consumerGrpOffsets.entrySet()) {
|
||||
Long producerOffset = producerOffsets.get(entry.getKey());
|
||||
Long consumerOffset = consumerGrpOffsets.get(entry.getKey());
|
||||
@@ -91,15 +93,24 @@ public class LagAnalyzerService {
|
||||
|
||||
private AdminClient getAdminClient(String bootstrapServerConfig) {
|
||||
Properties config = new Properties();
|
||||
config.put(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServerConfig);
|
||||
config.put(
|
||||
AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG,
|
||||
bootstrapServerConfig);
|
||||
return AdminClient.create(config);
|
||||
}
|
||||
|
||||
private KafkaConsumer<String, String> getKafkaConsumer(String bootstrapServerConfig) {
|
||||
private KafkaConsumer<String, String> getKafkaConsumer(
|
||||
String bootstrapServerConfig) {
|
||||
Properties properties = new Properties();
|
||||
properties.setProperty(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServerConfig);
|
||||
properties.setProperty(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
|
||||
properties.setProperty(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
|
||||
properties.setProperty(
|
||||
ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG,
|
||||
bootstrapServerConfig);
|
||||
properties.setProperty(
|
||||
ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG,
|
||||
StringDeserializer.class.getName());
|
||||
properties.setProperty(
|
||||
ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG,
|
||||
StringDeserializer.class.getName());
|
||||
return new KafkaConsumer<>(properties);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,8 +15,8 @@ public class LiveLagAnalyzerService {
|
||||
|
||||
@Autowired
|
||||
public LiveLagAnalyzerService(
|
||||
LagAnalyzerService lagAnalyzerService,
|
||||
@Value(value = "${monitor.kafka.consumer.groupid}") String groupId) {
|
||||
LagAnalyzerService lagAnalyzerService,
|
||||
@Value(value = "${monitor.kafka.consumer.groupid}") String groupId) {
|
||||
this.lagAnalyzerService = lagAnalyzerService;
|
||||
this.groupId = groupId;
|
||||
}
|
||||
|
||||
@@ -7,10 +7,9 @@ import org.springframework.stereotype.Service;
|
||||
@Service
|
||||
public class ConsumerSimulator {
|
||||
|
||||
@KafkaListener(
|
||||
topics = "${monitor.topic.name}",
|
||||
containerFactory = "kafkaListenerContainerFactory",
|
||||
autoStartup = "${monitor.consumer.simulate}")
|
||||
@KafkaListener(topics = "${monitor.topic.name}",
|
||||
containerFactory = "kafkaListenerContainerFactory",
|
||||
autoStartup = "${monitor.consumer.simulate}")
|
||||
public void listenGroup(String message) throws InterruptedException {
|
||||
Thread.sleep(10L);
|
||||
}
|
||||
|
||||
@@ -2,53 +2,54 @@ package com.baeldung.monitoring.simulation;
|
||||
|
||||
import org.apache.kafka.clients.consumer.ConsumerConfig;
|
||||
import org.apache.kafka.common.serialization.StringDeserializer;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.PropertySource;
|
||||
import org.springframework.kafka.annotation.EnableKafka;
|
||||
import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory;
|
||||
import org.springframework.kafka.core.ConsumerFactory;
|
||||
import org.springframework.kafka.core.DefaultKafkaConsumerFactory;
|
||||
import org.springframework.kafka.core.MicrometerConsumerListener;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import io.micrometer.core.instrument.MeterRegistry;
|
||||
|
||||
@EnableKafka
|
||||
@Configuration
|
||||
@Component
|
||||
public class KafkaConsumerConfig {
|
||||
|
||||
@Value(value = "${monitor.kafka.bootstrap.config}")
|
||||
private String bootstrapAddress;
|
||||
@Value(value = "${monitor.kafka.consumer.groupid}")
|
||||
private String groupId;
|
||||
@Value(value = "${monitor.kafka.consumer.groupid.simulate}")
|
||||
private String simulateGroupId;
|
||||
@Value(value = "${monitor.producer.simulate}")
|
||||
private boolean enabled;
|
||||
|
||||
public ConsumerFactory<String, String> consumerFactory(String groupId) {
|
||||
@Autowired
|
||||
private MeterRegistry meterRegistry;
|
||||
|
||||
@Bean
|
||||
public ConsumerFactory<String, String> consumerFactory() {
|
||||
Map<String, Object> props = new HashMap<>();
|
||||
props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapAddress);
|
||||
if (enabled) {
|
||||
props.put(ConsumerConfig.GROUP_ID_CONFIG, groupId);
|
||||
} else {
|
||||
props.put(ConsumerConfig.GROUP_ID_CONFIG, simulateGroupId);
|
||||
}
|
||||
props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
|
||||
props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
|
||||
props.put(ConsumerConfig.AUTO_COMMIT_INTERVAL_MS_CONFIG, 0);
|
||||
return new DefaultKafkaConsumerFactory<>(props);
|
||||
props.put(ConsumerConfig.GROUP_ID_CONFIG, groupId);
|
||||
DefaultKafkaConsumerFactory<String, String> consumerFactory = new DefaultKafkaConsumerFactory<>(props);
|
||||
consumerFactory.addListener(new MicrometerConsumerListener<>(this.meterRegistry));
|
||||
return consumerFactory;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ConcurrentKafkaListenerContainerFactory<String, String> kafkaListenerContainerFactory() {
|
||||
ConcurrentKafkaListenerContainerFactory<String, String> factory = new ConcurrentKafkaListenerContainerFactory<>();
|
||||
if (enabled) {
|
||||
factory.setConsumerFactory(consumerFactory(groupId));
|
||||
} else {
|
||||
factory.setConsumerFactory(consumerFactory(simulateGroupId));
|
||||
}
|
||||
return factory;
|
||||
public ConcurrentKafkaListenerContainerFactory<String, String>
|
||||
kafkaListenerContainerFactory(@Qualifier("consumerFactory") ConsumerFactory<String,
|
||||
String> consumerFactory) {
|
||||
ConcurrentKafkaListenerContainerFactory<String, String> listenerContainerFactory =
|
||||
new ConcurrentKafkaListenerContainerFactory<>();
|
||||
listenerContainerFactory.setConsumerFactory(consumerFactory);
|
||||
return listenerContainerFactory;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,10 +23,9 @@ public class ProducerSimulator {
|
||||
private final boolean enabled;
|
||||
|
||||
@Autowired
|
||||
public ProducerSimulator(
|
||||
KafkaTemplate<String, String> kafkaTemplate,
|
||||
@Value(value = "${monitor.topic.name}") String topicName,
|
||||
@Value(value = "${monitor.producer.simulate}") String enabled) {
|
||||
public ProducerSimulator(KafkaTemplate<String, String> kafkaTemplate,
|
||||
@Value(value = "${monitor.topic.name}") String topicName,
|
||||
@Value(value = "${monitor.producer.simulate}") String enabled) {
|
||||
this.kafkaTemplate = kafkaTemplate;
|
||||
this.topicName = topicName;
|
||||
this.enabled = BooleanUtils.toBoolean(enabled);
|
||||
@@ -37,7 +36,9 @@ public class ProducerSimulator {
|
||||
if (enabled) {
|
||||
if (endTime.after(new Date())) {
|
||||
String message = "msg-" + time();
|
||||
SendResult<String, String> result = kafkaTemplate.send(topicName, message).get();
|
||||
SendResult<String, String> result = kafkaTemplate
|
||||
.send(topicName, message)
|
||||
.get();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
server.port=8081
|
||||
spring.kafka.bootstrap-servers=localhost:9092
|
||||
message.topic.name=baeldung
|
||||
long.message.topic.name=longMessage
|
||||
@@ -15,3 +16,12 @@ monitor.consumer.simulate=true
|
||||
monitor.kafka.consumer.groupid.simulate=baeldungGrpSimulate
|
||||
test.topic=testtopic1
|
||||
|
||||
|
||||
|
||||
management.endpoints.web.base-path=/actuator
|
||||
management.endpoints.web.exposure.include=*
|
||||
management.endpoint.health.show-details=always
|
||||
management.endpoint.metrics.enabled=true
|
||||
management.endpoint.prometheus.enabled=true
|
||||
|
||||
spring.jmx.enabled=false
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
### Relevant Articles:
|
||||
|
||||
- [A Guide to SAML with Spring Security](https://www.baeldung.com/spring-security-saml)
|
||||
- [SAML with Spring Boot and Spring Security](https://www.baeldung.com/spring-security-saml)
|
||||
|
||||
Reference in New Issue
Block a user