Merge branch 'master' into master
This commit is contained in:
commit
944f31de8e
|
@ -35,12 +35,12 @@
|
|||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.flink</groupId>
|
||||
<artifactId>flink-connector-kafka-0.11_2.11</artifactId>
|
||||
<artifactId>flink-connector-kafka</artifactId>
|
||||
<version>${flink.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.flink</groupId>
|
||||
<artifactId>flink-streaming-java_2.11</artifactId>
|
||||
<artifactId>flink-streaming-java</artifactId>
|
||||
<version>${flink.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
@ -67,7 +67,7 @@
|
|||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.flink</groupId>
|
||||
<artifactId>flink-test-utils_2.11</artifactId>
|
||||
<artifactId>flink-test-utils</artifactId>
|
||||
<version>${flink.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
@ -163,11 +163,29 @@
|
|||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<argLine>
|
||||
--add-opens java.base/java.time=ALL-UNNAMED
|
||||
--add-opens java.base/java.nio=ALL-UNNAMED
|
||||
--add-opens java.base/java.util=ALL-UNNAMED
|
||||
</argLine>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
||||
|
||||
<properties>
|
||||
<kafka.version>2.8.0</kafka.version>
|
||||
<kafka.version>3.4.0</kafka.version>
|
||||
<testcontainers-kafka.version>1.15.3</testcontainers-kafka.version>
|
||||
<testcontainers-jupiter.version>1.15.3</testcontainers-jupiter.version>
|
||||
<flink.version>1.5.0</flink.version>
|
||||
<flink.version>1.16.1</flink.version>
|
||||
<awaitility.version>3.0.0</awaitility.version>
|
||||
<org.apache.spark.spark-core.version>2.4.8</org.apache.spark.spark-core.version>
|
||||
<graphframes.version>0.8.1-spark3.0-s_2.12</graphframes.version>
|
||||
|
|
|
@ -9,8 +9,8 @@ import org.apache.flink.streaming.api.TimeCharacteristic;
|
|||
import org.apache.flink.streaming.api.datastream.DataStream;
|
||||
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
|
||||
import org.apache.flink.streaming.api.windowing.time.Time;
|
||||
import org.apache.flink.streaming.connectors.kafka.FlinkKafkaConsumer011;
|
||||
import org.apache.flink.streaming.connectors.kafka.FlinkKafkaProducer011;
|
||||
import org.apache.flink.streaming.connectors.kafka.FlinkKafkaConsumer;
|
||||
import org.apache.flink.streaming.connectors.kafka.FlinkKafkaProducer;
|
||||
|
||||
import static com.baeldung.flink.connector.Consumers.*;
|
||||
import static com.baeldung.flink.connector.Producers.*;
|
||||
|
@ -25,12 +25,12 @@ public class FlinkDataPipeline {
|
|||
|
||||
StreamExecutionEnvironment environment = StreamExecutionEnvironment.getExecutionEnvironment();
|
||||
|
||||
FlinkKafkaConsumer011<String> flinkKafkaConsumer = createStringConsumerForTopic(inputTopic, address, consumerGroup);
|
||||
FlinkKafkaConsumer<String> flinkKafkaConsumer = createStringConsumerForTopic(inputTopic, address, consumerGroup);
|
||||
flinkKafkaConsumer.setStartFromEarliest();
|
||||
|
||||
DataStream<String> stringInputStream = environment.addSource(flinkKafkaConsumer);
|
||||
|
||||
FlinkKafkaProducer011<String> flinkKafkaProducer = createStringProducer(outputTopic, address);
|
||||
FlinkKafkaProducer<String> flinkKafkaProducer = createStringProducer(outputTopic, address);
|
||||
|
||||
stringInputStream.map(new WordsCapitalizer())
|
||||
.addSink(flinkKafkaProducer);
|
||||
|
@ -48,11 +48,11 @@ public class FlinkDataPipeline {
|
|||
|
||||
environment.setStreamTimeCharacteristic(TimeCharacteristic.EventTime);
|
||||
|
||||
FlinkKafkaConsumer011<InputMessage> flinkKafkaConsumer = createInputMessageConsumer(inputTopic, kafkaAddress, consumerGroup);
|
||||
FlinkKafkaConsumer<InputMessage> flinkKafkaConsumer = createInputMessageConsumer(inputTopic, kafkaAddress, consumerGroup);
|
||||
flinkKafkaConsumer.setStartFromEarliest();
|
||||
|
||||
flinkKafkaConsumer.assignTimestampsAndWatermarks(new InputMessageTimestampAssigner());
|
||||
FlinkKafkaProducer011<Backup> flinkKafkaProducer = createBackupProducer(outputTopic, kafkaAddress);
|
||||
FlinkKafkaProducer<Backup> flinkKafkaProducer = createBackupProducer(outputTopic, kafkaAddress);
|
||||
|
||||
DataStream<InputMessage> inputMessagesStream = environment.addSource(flinkKafkaConsumer);
|
||||
|
||||
|
|
|
@ -3,26 +3,26 @@ package com.baeldung.flink.connector;
|
|||
import com.baeldung.flink.model.InputMessage;
|
||||
import com.baeldung.flink.schema.InputMessageDeserializationSchema;
|
||||
import org.apache.flink.api.common.serialization.SimpleStringSchema;
|
||||
import org.apache.flink.streaming.connectors.kafka.FlinkKafkaConsumer011;
|
||||
import org.apache.flink.streaming.connectors.kafka.FlinkKafkaConsumer;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
public class Consumers {
|
||||
|
||||
public static FlinkKafkaConsumer011<String> createStringConsumerForTopic(String topic, String kafkaAddress, String kafkaGroup) {
|
||||
public static FlinkKafkaConsumer<String> createStringConsumerForTopic(String topic, String kafkaAddress, String kafkaGroup) {
|
||||
Properties props = new Properties();
|
||||
props.setProperty("bootstrap.servers", kafkaAddress);
|
||||
props.setProperty("group.id", kafkaGroup);
|
||||
FlinkKafkaConsumer011<String> consumer = new FlinkKafkaConsumer011<>(topic, new SimpleStringSchema(), props);
|
||||
FlinkKafkaConsumer<String> consumer = new FlinkKafkaConsumer<>(topic, new SimpleStringSchema(), props);
|
||||
|
||||
return consumer;
|
||||
}
|
||||
|
||||
public static FlinkKafkaConsumer011<InputMessage> createInputMessageConsumer(String topic, String kafkaAddress, String kafkaGroup) {
|
||||
public static FlinkKafkaConsumer<InputMessage> createInputMessageConsumer(String topic, String kafkaAddress, String kafkaGroup) {
|
||||
Properties properties = new Properties();
|
||||
properties.setProperty("bootstrap.servers", kafkaAddress);
|
||||
properties.setProperty("group.id", kafkaGroup);
|
||||
FlinkKafkaConsumer011<InputMessage> consumer = new FlinkKafkaConsumer011<InputMessage>(topic, new InputMessageDeserializationSchema(), properties);
|
||||
FlinkKafkaConsumer<InputMessage> consumer = new FlinkKafkaConsumer<InputMessage>(topic, new InputMessageDeserializationSchema(), properties);
|
||||
|
||||
return consumer;
|
||||
}
|
||||
|
|
|
@ -3,15 +3,15 @@ package com.baeldung.flink.connector;
|
|||
import com.baeldung.flink.model.Backup;
|
||||
import com.baeldung.flink.schema.BackupSerializationSchema;
|
||||
import org.apache.flink.api.common.serialization.SimpleStringSchema;
|
||||
import org.apache.flink.streaming.connectors.kafka.FlinkKafkaProducer011;
|
||||
import org.apache.flink.streaming.connectors.kafka.FlinkKafkaProducer;
|
||||
|
||||
public class Producers {
|
||||
|
||||
public static FlinkKafkaProducer011<String> createStringProducer(String topic, String kafkaAddress) {
|
||||
return new FlinkKafkaProducer011<>(kafkaAddress, topic, new SimpleStringSchema());
|
||||
public static FlinkKafkaProducer<String> createStringProducer(String topic, String kafkaAddress) {
|
||||
return new FlinkKafkaProducer<>(kafkaAddress, topic, new SimpleStringSchema());
|
||||
}
|
||||
|
||||
public static FlinkKafkaProducer011<Backup> createBackupProducer(String topic, String kafkaAddress) {
|
||||
return new FlinkKafkaProducer011<Backup>(kafkaAddress, topic, new BackupSerializationSchema());
|
||||
public static FlinkKafkaProducer<Backup> createBackupProducer(String topic, String kafkaAddress) {
|
||||
return new FlinkKafkaProducer<Backup>(kafkaAddress, topic, new BackupSerializationSchema());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -122,6 +122,7 @@
|
|||
<docker.image.prefix>${azure.containerRegistry}.azurecr.io</docker.image.prefix>
|
||||
<docker-maven-plugin.version>1.1.0</docker-maven-plugin.version>
|
||||
<azure-webapp-maven-plugin.version>1.1.0</azure-webapp-maven-plugin.version>
|
||||
<maven-war-plugin.version>3.3.2</maven-war-plugin.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -0,0 +1 @@
|
|||
### Relevant Articles:
|
|
@ -0,0 +1,25 @@
|
|||
<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-conversions.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>core-java-numbers-conversions</artifactId>
|
||||
<name>core-java-numbers-conversions</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung.core-java-modules</groupId>
|
||||
<artifactId>core-java-modules</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<build>
|
||||
<finalName>core-java-numbers-conversions</finalName>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
</build>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,52 @@
|
|||
package com.baeldung.numtoletter;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
|
||||
public class ConvertNumberToLetterUnitTest {
|
||||
|
||||
static char numToLetterBySubstr(int i) {
|
||||
String LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
if (i > 0 && i <= 25) {
|
||||
return LETTERS.substring(i, i + 1).charAt(0);
|
||||
} else {
|
||||
return '?';
|
||||
}
|
||||
}
|
||||
|
||||
static char numToLetterByAsciiCode(int i) {
|
||||
if (i > 0 && i <= 25) {
|
||||
return (char) ('A' + i);
|
||||
} else {
|
||||
return '?';
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenANumber_whenConvertToLetterUsingSubstring_shouldGetExpectedResult() {
|
||||
char negativeInputResult = numToLetterBySubstr(-7);
|
||||
assertEquals('?', negativeInputResult);
|
||||
|
||||
char tooLargeInputResult = numToLetterBySubstr(42);
|
||||
assertEquals('?', tooLargeInputResult);
|
||||
|
||||
char result = numToLetterBySubstr(10);
|
||||
assertEquals('K', result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenANumber_whenConvertToLetterUsingAscii_shouldGetExpectedResult() {
|
||||
char negativeInputResult = numToLetterByAsciiCode(-7);
|
||||
assertEquals('?', negativeInputResult);
|
||||
|
||||
char tooLargeInputResult = numToLetterByAsciiCode(42);
|
||||
assertEquals('?', tooLargeInputResult);
|
||||
|
||||
char charResult = numToLetterByAsciiCode(10);
|
||||
assertEquals('K', charResult);
|
||||
|
||||
assertEquals("K", String.valueOf(charResult));
|
||||
}
|
||||
}
|
|
@ -40,6 +40,6 @@ public class CharacterEncodingExamples {
|
|||
charsetDecoder.onMalformedInput(codingErrorAction);
|
||||
return new BufferedReader(
|
||||
new InputStreamReader(
|
||||
new ByteArrayInputStream(input.getBytes()), charsetDecoder)).readLine();
|
||||
new ByteArrayInputStream(input.getBytes(charset)), charsetDecoder)).readLine();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75,7 +75,7 @@ public class CharacterEncodingExamplesUnitTest {
|
|||
|
||||
@Test
|
||||
public void givenUTF8String_whenDecodeByUS_ASCII_thenIgnoreMalformedInputSequence() throws IOException {
|
||||
Assertions.assertEquals("The faade pattern is a software design pattern.", CharacterEncodingExamples.decodeText("The façade pattern is a software design pattern.", StandardCharsets.US_ASCII, CodingErrorAction.IGNORE));
|
||||
Assertions.assertEquals("The fa?ade pattern is a software design pattern.", CharacterEncodingExamples.decodeText("The façade pattern is a software design pattern.", StandardCharsets.US_ASCII, CodingErrorAction.IGNORE));
|
||||
}
|
||||
|
||||
//@Test
|
||||
|
@ -89,7 +89,8 @@ public class CharacterEncodingExamplesUnitTest {
|
|||
CodingErrorAction.REPLACE));
|
||||
}
|
||||
|
||||
@Test
|
||||
//@Test
|
||||
// run this manually as it's dependent on platform encoding
|
||||
public void givenUTF8String_whenDecodeByUS_ASCII_thenReportMalformedInputSequence() {
|
||||
Assertions.assertThrows(
|
||||
MalformedInputException.class,
|
||||
|
|
|
@ -108,6 +108,7 @@
|
|||
<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>
|
||||
|
|
|
@ -103,7 +103,7 @@
|
|||
<configuration>
|
||||
<packageName>com.baeldung.feign.soap</packageName>
|
||||
<sources>
|
||||
<source>src/main/resources/users.xsd</source>
|
||||
<source>${project.basedir}/src/main/resources/users.xsd</source>
|
||||
</sources>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
<properties>
|
||||
<javax.websocket-api.version>1.1</javax.websocket-api.version>
|
||||
<gson.version>2.8.0</gson.version>
|
||||
<maven-war-plugin.version>3.3.2</maven-war-plugin.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,5 @@
|
|||
## Jetbrains
|
||||
|
||||
This module contains articles about Jetbrains' libraries.
|
||||
|
||||
### Relevant articles:
|
|
@ -0,0 +1,37 @@
|
|||
<?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/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetbrains</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<name>jetbrains</name>
|
||||
<packaging>jar</packaging>
|
||||
<url>http://maven.apache.org</url>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-java</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../parent-java</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>${apache.commons.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains</groupId>
|
||||
<artifactId>annotations</artifactId>
|
||||
<version>${jetbrains.annotations.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<apache.commons.version>3.12.0</apache.commons.version>
|
||||
<jetbrains.annotations.version>24.0.1</jetbrains.annotations.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,112 @@
|
|||
package com.baeldung.annotations;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
|
||||
public class Demo {
|
||||
|
||||
@Contract("_ -> new")
|
||||
Person fromName(String name) {
|
||||
return new Person().withName(name);
|
||||
}
|
||||
|
||||
@Contract(" -> fail")
|
||||
void alwaysFail() {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@Contract(" -> fail")
|
||||
void doNothingWithWrongContract() {
|
||||
|
||||
}
|
||||
|
||||
@Contract("_, null -> null; null, _ -> param2; _, !null -> !null")
|
||||
String concatenateOnlyIfSecondArgumentIsNotNull(String head, String tail) {
|
||||
if (tail == null) {
|
||||
return null;
|
||||
}
|
||||
if (head == null) {
|
||||
return tail;
|
||||
}
|
||||
return head + tail;
|
||||
}
|
||||
|
||||
void uselessNullCheck() {
|
||||
String head = "1234";
|
||||
String tail = "5678";
|
||||
String concatenation = concatenateOnlyIfSecondArgumentIsNotNull(head, tail);
|
||||
if (concatenation != null) {
|
||||
System.out.println(concatenation);
|
||||
}
|
||||
}
|
||||
|
||||
void uselessNullCheckOnInferredAnnotation() {
|
||||
if (StringUtils.isEmpty(null)) {
|
||||
System.out.println("baeldung");
|
||||
}
|
||||
}
|
||||
|
||||
@Contract(pure = true)
|
||||
String replace(String string, char oldChar, char newChar) {
|
||||
return string.replace(oldChar, newChar);
|
||||
}
|
||||
|
||||
@Contract(value = "true -> false; false -> true", pure = true)
|
||||
boolean not(boolean input) {
|
||||
return !input;
|
||||
}
|
||||
|
||||
@Contract("true -> new")
|
||||
void contractExpectsWrongParameterType(List<Integer> integers) {
|
||||
|
||||
}
|
||||
|
||||
@Contract("_, _ -> new")
|
||||
void contractExpectsMoreParametersThanMethodHas(String s) {
|
||||
|
||||
}
|
||||
|
||||
@Contract("_ -> _; null -> !null")
|
||||
String secondContractClauseNotReachable(String s) {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Contract("_ -> true")
|
||||
void contractExpectsWrongReturnType(String s) {
|
||||
|
||||
}
|
||||
|
||||
// NB: the following examples demonstrate how to use the mutates attribute of the annotation
|
||||
// This attribute is currently experimental and could be changed or removed in the future
|
||||
@Contract(mutates = "param")
|
||||
void incrementArrayFirstElement(Integer[] integers) {
|
||||
if (integers.length > 0) {
|
||||
integers[0] = integers[0] + 1;
|
||||
}
|
||||
}
|
||||
|
||||
@Contract(pure = true, mutates = "param")
|
||||
void impossibleToMutateParamInPureFunction(List<String> strings) {
|
||||
if (strings != null) {
|
||||
strings.forEach(System.out::println);
|
||||
}
|
||||
}
|
||||
|
||||
@Contract(mutates = "param3")
|
||||
void impossibleToMutateThirdParamWhenMethodHasOnlyTwoParams(int a, int b) {
|
||||
|
||||
}
|
||||
|
||||
@Contract(mutates = "param")
|
||||
void impossibleToMutableImmutableType(String s) {
|
||||
|
||||
}
|
||||
|
||||
@Contract(mutates = "this")
|
||||
static void impossibleToMutateThisInStaticMethod() {
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package com.baeldung.annotations;
|
||||
|
||||
import org.jetbrains.annotations.Contract;
|
||||
|
||||
public class Person {
|
||||
|
||||
String name;
|
||||
|
||||
@Contract("_ -> this")
|
||||
Person withName(String name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
|
@ -48,8 +48,15 @@
|
|||
<plugin>
|
||||
<groupId>com.lazerycode.jmeter</groupId>
|
||||
<artifactId>jmeter-maven-plugin</artifactId>
|
||||
<version>${jmeter.version}</version>
|
||||
<version>3.7.0</version>
|
||||
<executions>
|
||||
<!-- Generate JMeter configuration -->
|
||||
<execution>
|
||||
<id>configuration</id>
|
||||
<goals>
|
||||
<goal>configure</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>jmeter-tests</id>
|
||||
<goals>
|
||||
|
@ -66,7 +73,6 @@
|
|||
</build>
|
||||
|
||||
<properties>
|
||||
<jmeter.version>2.6.0</jmeter.version>
|
||||
</properties>
|
||||
|
||||
<profiles>
|
||||
|
|
|
@ -57,7 +57,7 @@
|
|||
<stringProp name="filename"></stringProp>
|
||||
<stringProp name="parameters"></stringProp>
|
||||
<boolProp name="resetInterpreter">false</boolProp>
|
||||
<stringProp name="script">FileWriter fWriter = new FileWriter("<path>/result.txt", true);
|
||||
<stringProp name="script">FileWriter fWriter = new FileWriter("<path>/result.txt", true);
|
||||
BufferedWriter buff = new BufferedWriter(fWriter);
|
||||
|
||||
buff.write("Response Code : " + ctx.getPreviousResult().getResponseCode());
|
||||
|
|
|
@ -47,7 +47,7 @@ public class JsoupParserIntegrationTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void examplesSelectors() {
|
||||
public void examplesSelectors() throws IOException {
|
||||
Elements links = doc.select("a");
|
||||
Elements logo = doc.select(".spring-logo--container");
|
||||
Elements pagination = doc.select("#pagination_control");
|
||||
|
@ -57,52 +57,46 @@ public class JsoupParserIntegrationTest {
|
|||
Element pag = doc.getElementById("pagination_control");
|
||||
Elements desktopOnly = doc.getElementsByClass("desktopOnly");
|
||||
|
||||
Elements sections = doc.select("section");
|
||||
Element firstSection = sections.first();
|
||||
Elements sectionParagraphs = firstSection.select(".paragraph");
|
||||
Elements articles = doc.select("article");
|
||||
Element firstArticle = articles.first();
|
||||
Elements sectionParagraphs = firstArticle.select(".paragraph");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void examplesTraversing() {
|
||||
Elements sections = doc.select("section");
|
||||
public void examplesTraversing() throws IOException {
|
||||
Elements articles = doc.select("article");
|
||||
|
||||
Element firstSection = sections.first();
|
||||
Element lastSection = sections.last();
|
||||
Element secondSection = sections.get(2);
|
||||
Elements allParents = firstSection.parents();
|
||||
Element parent = firstSection.parent();
|
||||
Elements children = firstSection.children();
|
||||
Elements siblings = firstSection.siblingElements();
|
||||
Element firstArticle = articles.first();
|
||||
Element lastSection = articles.last();
|
||||
Element secondSection = articles.get(2);
|
||||
Elements allParents = firstArticle.parents();
|
||||
Element parent = firstArticle.parent();
|
||||
Elements children = firstArticle.children();
|
||||
Elements siblings = firstArticle.siblingElements();
|
||||
|
||||
sections.forEach(el -> System.out.println("section: " + el));
|
||||
articles.forEach(el -> System.out.println("article: " + el));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void examplesExtracting() {
|
||||
public void examplesExtracting() throws IOException {
|
||||
Element firstArticle = doc.select("article")
|
||||
.first();
|
||||
Element timeElement = firstArticle.select("time")
|
||||
Element titleElement = firstArticle.select("h1 a")
|
||||
.first();
|
||||
String dateTimeOfFirstArticle = timeElement.attr("datetime");
|
||||
Element sectionDiv = firstArticle.select("section div")
|
||||
.first();
|
||||
String sectionDivText = sectionDiv.text();
|
||||
|
||||
String titleText = titleElement.text();
|
||||
String articleHtml = firstArticle.html();
|
||||
String outerHtml = firstArticle.outerHtml();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void examplesModifying() {
|
||||
public void examplesModifying() throws IOException {
|
||||
Element firstArticle = doc.select("article")
|
||||
.first();
|
||||
Element timeElement = firstArticle.select("time")
|
||||
.first();
|
||||
Element sectionDiv = firstArticle.select("section div")
|
||||
Element h1Element = firstArticle.select("h1")
|
||||
.first();
|
||||
|
||||
String dateTimeOfFirstArticle = timeElement.attr("datetime");
|
||||
timeElement.attr("datetime", "2016-12-16 15:19:54.3");
|
||||
sectionDiv.text("foo bar");
|
||||
h1Element.text("foo bar");
|
||||
firstArticle.select("h2")
|
||||
.html("<div><span></span></div>");
|
||||
|
||||
|
|
|
@ -15,8 +15,7 @@
|
|||
<modules>
|
||||
<module>k8s-intro</module>
|
||||
<module>k8s-admission-controller</module>
|
||||
<!-- <module>kubernetes-spring</module> --> <!-- JDK-11 Module -->
|
||||
<module>k8s-java-heap-dump</module>
|
||||
<module>kubernetes-spring</module>
|
||||
</modules>
|
||||
|
||||
</project>
|
|
@ -132,7 +132,7 @@
|
|||
<properties>
|
||||
<mapdb.version>3.0.8</mapdb.version>
|
||||
<classgraph.version>4.8.153</classgraph.version>
|
||||
<jbpm.version>7.1.0.Final</jbpm.version>
|
||||
<jbpm.version>7.20.0.Final</jbpm.version>
|
||||
<picocli.version>4.7.0</picocli.version>
|
||||
<chronicle.map.version>3.24ea1</chronicle.map.version>
|
||||
<crawler4j.version>4.4.0</crawler4j.version>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<process processType="Private" isExecutable="true" id="com.baeldung.bpmn.helloworld" name="HelloWorld Process" tns:packageName="com.baeldung.bpmn.process" >
|
||||
|
||||
<!-- nodes -->
|
||||
<scriptTask id="_jbpm-unique-1" name="HelloWorld" scriptFormat="http://www.java.com/java" >
|
||||
<scriptTask id="_jbpm-unique-1" name="HelloWorld">
|
||||
<script>System.out.println("Hello World");</script>
|
||||
</scriptTask>
|
||||
<endEvent id="_jbpm-unique-2" name="End" >
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
package com.baeldung.jbpm;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.jbpm.test.JbpmJUnitBaseTestCase;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
|
@ -47,6 +50,6 @@ public class WorkflowEngineIntegrationTest extends JbpmJUnitBaseTestCase {
|
|||
@Test
|
||||
public void givenProcessInstance_whenExecutionCompleted_thenVerifyProcessInstanceStatus() {
|
||||
assertProcessInstanceCompleted(processInstance.getId(), ksession);
|
||||
assertTrue("ProcessInstance completed with status 2", processInstance.getState() == 2);
|
||||
assertEquals("ProcessInstance completed with status 2", 2, processInstance.getState());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
<module>jgroups</module>
|
||||
<module>rabbitmq</module>
|
||||
<module>spring-amqp</module>
|
||||
<module>spring-apache-camel</module>
|
||||
<module>spring-jms</module>
|
||||
</modules>
|
||||
|
||||
|
|
|
@ -67,7 +67,6 @@
|
|||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-war-plugin</artifactId>
|
||||
<version>${maven-war-plugin.version}</version>
|
||||
<configuration>
|
||||
<warSourceDirectory>src/main/webapp</warSourceDirectory>
|
||||
<warName>spring-jms</warName>
|
||||
|
@ -83,6 +82,7 @@
|
|||
<springframework.version>4.3.4.RELEASE</springframework.version>
|
||||
<activemq.version>5.14.1</activemq.version>
|
||||
<spring-boot-test.version>1.5.10.RELEASE</spring-boot-test.version>
|
||||
<maven-war-plugin.version>3.3.2</maven-war-plugin.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,46 @@
|
|||
package com.baeldung.fluentinterface;
|
||||
|
||||
import static java.util.Arrays.stream;
|
||||
import static java.util.stream.Collectors.joining;
|
||||
|
||||
public class HtmlDocument {
|
||||
private final String content;
|
||||
|
||||
private HtmlDocument(String html) {
|
||||
this.content = html;
|
||||
}
|
||||
|
||||
public HtmlDocument() {
|
||||
this("");
|
||||
}
|
||||
|
||||
public String html() {
|
||||
return String.format("<html>%s</html>", content);
|
||||
}
|
||||
|
||||
public HtmlDocument header(String header) {
|
||||
return new HtmlDocument(String.format("%s <h1>%s</h1>", content, header));
|
||||
}
|
||||
|
||||
public HtmlDocument secondaryHeader(String header) {
|
||||
return new HtmlDocument(String.format("%s <h2>%s</h2>", content, header));
|
||||
}
|
||||
|
||||
public HtmlDocument paragraph(String paragraph) {
|
||||
return new HtmlDocument(String.format("%s <p>%s</p>", content, paragraph));
|
||||
}
|
||||
|
||||
public HtmlDocument horizontalLine() {
|
||||
return new HtmlDocument(String.format("%s <hr>", content));
|
||||
}
|
||||
|
||||
public HtmlDocument orderedList(String... items) {
|
||||
String listItems = stream(items).map(el -> String.format("<li>%s</li>", el)).collect(joining());
|
||||
return new HtmlDocument(String.format("%s <ol>%s</ol>", content, listItems));
|
||||
}
|
||||
|
||||
public HtmlDocument unorderedList(String... items) {
|
||||
String listItems = stream(items).map(el -> String.format("<li>%s</li>", el)).collect(joining());
|
||||
return new HtmlDocument(String.format("%s <ul>%s</ul>", content, listItems));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package com.baeldung.fluentinterface;
|
||||
|
||||
import com.baeldung.fluentinterface.components.HtmlElement;
|
||||
import com.baeldung.fluentinterface.components.HtmlHeader;
|
||||
import com.baeldung.fluentinterface.components.HtmlList;
|
||||
|
||||
import static java.lang.String.format;
|
||||
import static java.util.Arrays.stream;
|
||||
import static java.util.stream.Collectors.joining;
|
||||
|
||||
public class LargeHtmlDocument {
|
||||
private final String content;
|
||||
|
||||
private LargeHtmlDocument(String html) {
|
||||
this.content = html;
|
||||
}
|
||||
|
||||
public LargeHtmlDocument() {
|
||||
this("");
|
||||
}
|
||||
|
||||
public String html() {
|
||||
return format("<html>%s</html>", content);
|
||||
}
|
||||
|
||||
public LargeHtmlDocument head(HtmlElement head) {
|
||||
return new LargeHtmlDocument(format("%s <head>%s</head>", content, head.html()));
|
||||
}
|
||||
public LargeHtmlDocument body(HtmlElement body) {
|
||||
return new LargeHtmlDocument(format("%s <body>%s</body>", content, body.html()));
|
||||
}
|
||||
public LargeHtmlDocument footer(HtmlElement footer) {
|
||||
return new LargeHtmlDocument(format("%s <footer>%s</footer>", content, footer.html()));
|
||||
}
|
||||
|
||||
private LargeHtmlDocument append(String html) {
|
||||
return new LargeHtmlDocument(format("%s %s", content, html));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
package com.baeldung.fluentinterface;
|
||||
|
||||
public class User {
|
||||
private String firstName;
|
||||
private String lastName;
|
||||
private String email;
|
||||
private String username;
|
||||
private Long id;
|
||||
|
||||
public String name() {
|
||||
return firstName + " " + lastName;
|
||||
}
|
||||
|
||||
public User(String firstName, String lastName, String email, String username, Long id) {
|
||||
this.firstName = firstName;
|
||||
this.lastName = lastName;
|
||||
this.email = email;
|
||||
this.username = username;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private String firstName;
|
||||
private String lastName;
|
||||
private String email;
|
||||
private String username;
|
||||
private Long id;
|
||||
|
||||
private Builder() {
|
||||
}
|
||||
|
||||
public Builder firstName(String firstName) {
|
||||
this.firstName = firstName;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder lastName(String lastName) {
|
||||
this.lastName = lastName;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder email(String email) {
|
||||
this.email = email;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder username(String username) {
|
||||
this.username = username;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder id(Long id) {
|
||||
this.id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
public User build() {
|
||||
return new User(firstName, lastName, email, username, id);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package com.baeldung.fluentinterface.components;
|
||||
|
||||
public class HorizontalLine implements HtmlElement {
|
||||
@Override
|
||||
public String html() {
|
||||
return "<hr>";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package com.baeldung.fluentinterface.components;
|
||||
|
||||
public class HtmlDiv implements HtmlElement {
|
||||
|
||||
private final String content;
|
||||
|
||||
public HtmlDiv(String content) {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public HtmlDiv() {
|
||||
this.content = "";
|
||||
}
|
||||
|
||||
public HtmlDiv append(HtmlElement element) {
|
||||
return new HtmlDiv(content + element.html());
|
||||
}
|
||||
public HtmlDiv text(String text) {
|
||||
return new HtmlDiv(content + text);
|
||||
}
|
||||
public HtmlDiv paragraph(String text) {
|
||||
return new HtmlDiv(content + text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String html() {
|
||||
return String.format("<div>%s</div>", content);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
package com.baeldung.fluentinterface.components;
|
||||
|
||||
public interface HtmlElement {
|
||||
String html();
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package com.baeldung.fluentinterface.components;
|
||||
|
||||
public class HtmlHeader implements HtmlElement {
|
||||
|
||||
private final Type type;
|
||||
private final String value;
|
||||
|
||||
public HtmlHeader(Type type, String value) {
|
||||
this.type = type;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String html() {
|
||||
return String.format("<%s>%s</%s>", type.tag(), value, type.tag());
|
||||
}
|
||||
|
||||
public enum Type {
|
||||
PRIMARY("h1"),
|
||||
SECONDARY("h2"),
|
||||
THIRD("h3"),
|
||||
FOURTH("h4");
|
||||
|
||||
private final String tag;
|
||||
|
||||
Type(String tag) {
|
||||
this.tag = tag;
|
||||
}
|
||||
|
||||
public String tag() {
|
||||
return tag;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package com.baeldung.fluentinterface.components;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static java.lang.String.format;
|
||||
import static java.util.stream.Collectors.joining;
|
||||
|
||||
public class HtmlList implements HtmlElement {
|
||||
|
||||
private final Type type;
|
||||
private final List<String> items;
|
||||
|
||||
public HtmlList(Type type, String... items) {
|
||||
this.type = type;
|
||||
this.items = Arrays.asList(items);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String html() {
|
||||
String listItems = items.stream().map(el -> format("<li>%s</li>", el)).collect(joining());
|
||||
return String.format("<%s>%s</%s>", type.tag(), listItems, type.tag());
|
||||
}
|
||||
|
||||
public enum Type {
|
||||
ORDERED("ol"),
|
||||
UNORDERED("ul");
|
||||
|
||||
private final String tag;
|
||||
|
||||
Type(String tag) {
|
||||
this.tag = tag;
|
||||
}
|
||||
|
||||
public String tag() {
|
||||
return tag;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package com.baeldung.fluentinterface.components;
|
||||
|
||||
public class HtmlSpan implements HtmlElement {
|
||||
|
||||
private final String content;
|
||||
|
||||
public HtmlSpan(String content) {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public HtmlSpan() {
|
||||
this.content = "";
|
||||
}
|
||||
|
||||
public HtmlSpan append(HtmlElement element) {
|
||||
return new HtmlSpan(content + element.html());
|
||||
}
|
||||
|
||||
public HtmlSpan paragraph(String text) {
|
||||
return new HtmlSpan(content + text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String html() {
|
||||
return String.format("<span>%s</span>", content);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
package com.baeldung.fluentinterface;
|
||||
|
||||
import com.baeldung.fluentinterface.components.*;
|
||||
import com.baeldung.fluentinterface.components.HtmlHeader.Type;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static com.baeldung.fluentinterface.components.HtmlList.Type.ORDERED;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class FluentInterfaceUnitTest {
|
||||
|
||||
@Test
|
||||
void givenTenNumbers_thenStreamIsProcessedCorrectly() {
|
||||
Stream<Integer> numbers = Stream.of(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
|
||||
Stream<String> processedNumbers = numbers.distinct()
|
||||
.filter(nr -> nr % 2 == 0)
|
||||
.skip(1)
|
||||
.limit(4)
|
||||
.map(nr -> "#" + nr)
|
||||
.peek(nr -> System.out.println(nr));
|
||||
String result = processedNumbers.collect(Collectors.joining(", "));
|
||||
|
||||
assertThat(result).isEqualTo("#2, #4, #6, #8");
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenUserBuilder_thenCreateUserCorrectly() {
|
||||
User.Builder userBuilder = User.builder();
|
||||
userBuilder = userBuilder
|
||||
.firstName("John")
|
||||
.lastName("Doe")
|
||||
.email("jd@gmail.com")
|
||||
.username("jd_2000")
|
||||
.id(1234L);
|
||||
|
||||
User user = userBuilder.build();
|
||||
|
||||
assertThat(user.name()).isEqualTo("John Doe");
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenHtmlDocument_thenGenerateHtmlCorrectly() {
|
||||
HtmlDocument document = new HtmlDocument()
|
||||
.header("Principles of O.O.P.")
|
||||
.paragraph("OOP in Java.")
|
||||
.horizontalLine()
|
||||
.paragraph("The main pillars of OOP are:")
|
||||
.orderedList("Encapsulation", "Inheritance", "Abstraction", "Polymorphism");
|
||||
String html = document.html();
|
||||
|
||||
assertThat(html).isEqualToIgnoringWhitespace(
|
||||
"<html>"
|
||||
+ "<h1>Principles of O.O.P.</h1>"
|
||||
+ "<p>OOP in Java.</p>"
|
||||
+ "<hr>"
|
||||
+ "<p>The main pillars of OOP are:</p>"
|
||||
+ "<ol>"
|
||||
+ "<li>Encapsulation</li>"
|
||||
+ "<li>Inheritance</li>"
|
||||
+ "<li>Abstraction</li>"
|
||||
+ "<li>Polymorphism</li>"
|
||||
+ "</ol>"
|
||||
+ "</html>"
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenHtmlDocument_thenInstanceIsImmutable() {
|
||||
HtmlDocument document = new HtmlDocument()
|
||||
.header("Principles of O.O.P.");
|
||||
HtmlDocument updatedDocument = document
|
||||
.paragraph("OOP in Java.");
|
||||
|
||||
assertThat(document).isNotEqualTo(updatedDocument);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void givenLargeHtmlDocument_thenGenerateHtmlCorrectly() {
|
||||
String html = new LargeHtmlDocument()
|
||||
.head(new HtmlHeader(Type.PRIMARY, "title"))
|
||||
.body(new HtmlDiv()
|
||||
.append(new HtmlSpan()
|
||||
.paragraph("learning OOP from John Doe")
|
||||
.append(new HorizontalLine())
|
||||
.paragraph("The pillars of OOP:")
|
||||
)
|
||||
.append(new HtmlList(ORDERED, "Encapsulation", "Inheritance", "Abstraction", "Polymorphism"))
|
||||
)
|
||||
.footer(new HtmlDiv()
|
||||
.paragraph("trademark John Doe")
|
||||
)
|
||||
.html();
|
||||
|
||||
String expectedHtml = "<html> <head><h1>title</h1></head> <body><div><span>learning OOP from John Doe<hr>The pillars of OOP:</span><ol><li>Encapsulation</li><li>Inheritance</li><li>Abstraction</li><li>Polymorphism</li></ol></div></body> <footer><div>trademark John Doe</div></footer></html>";
|
||||
assertThat(html).isEqualToIgnoringWhitespace(expectedHtml);
|
||||
}
|
||||
}
|
|
@ -7,16 +7,7 @@
|
|||
<version>1.0</version>
|
||||
<name>idd</name>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>9</source>
|
||||
<target>9</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
|
||||
</build>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package com.baeldung.idd;
|
||||
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
|
|
@ -98,7 +98,8 @@
|
|||
<module>spring-data-mongodb-reactive</module>
|
||||
<module>spring-data-neo4j</module>
|
||||
<module>spring-data-redis</module>
|
||||
<module>spring-data-rest</module>
|
||||
<!-- Moved to JDK9+ profiles-->
|
||||
<!-- <module>spring-data-rest</module>-->
|
||||
<module>spring-data-rest-2</module>
|
||||
<module>spring-data-rest-querydsl</module>
|
||||
<module>spring-data-solr</module>
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
### Relevant Articles:
|
||||
- [Introduction to QuestDB](#)
|
|
@ -0,0 +1,29 @@
|
|||
<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">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.baeldung</groupId>
|
||||
<artifactId>questdb</artifactId>
|
||||
<name>questdb</name>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-java</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../../parent-java</relativePath>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<questdb.version>7.0.0</questdb.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.questdb</groupId>
|
||||
<artifactId>questdb</artifactId>
|
||||
<version>${questdb.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
|
@ -0,0 +1,29 @@
|
|||
package com.baeldung;
|
||||
|
||||
import io.questdb.client.Sender;
|
||||
|
||||
|
||||
public class InsertData {
|
||||
static final String SENSORS_TABLE_NAME = "sensors";
|
||||
|
||||
public static void main(String[] args) {
|
||||
try (Sender sender = Sender.builder().address("localhost:9009").build()) {
|
||||
sender.table(SENSORS_TABLE_NAME)
|
||||
.stringColumn("id", "KTC")
|
||||
.stringColumn("name", "Kitchen temperature (Celsius)")
|
||||
.doubleColumn("currentValue", 20)
|
||||
.atNow();
|
||||
sender.table(SENSORS_TABLE_NAME)
|
||||
.stringColumn("id", "SMT")
|
||||
.stringColumn("name", "Smart Garden temperature (Celsius)")
|
||||
.doubleColumn("currentValue", 28.5)
|
||||
.atNow();
|
||||
sender.table(SENSORS_TABLE_NAME)
|
||||
.stringColumn("id", "RM1")
|
||||
.stringColumn("name", "Room 1")
|
||||
.doubleColumn("currentValue", 19.5)
|
||||
.doubleColumn("idealValue", 18.5)
|
||||
.atNow();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -11,9 +11,9 @@
|
|||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-boot-2</artifactId>
|
||||
<artifactId>parent-boot-3</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../../parent-boot-2</relativePath>
|
||||
<relativePath>../../parent-boot-3</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
|
@ -42,6 +42,17 @@
|
|||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hibernate.orm</groupId>
|
||||
<artifactId>hibernate-community-dialects</artifactId>
|
||||
<version>${hibernate-community-dialects.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.rest-assured</groupId>
|
||||
<artifactId>rest-assured</artifactId>
|
||||
<version>3.3.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
|
@ -64,23 +75,6 @@
|
|||
<build>
|
||||
<finalName>${project.artifactId}</finalName>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>com.mysema.maven</groupId>
|
||||
<artifactId>maven-apt-plugin</artifactId>
|
||||
<version>${maven.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>generate-sources</phase>
|
||||
<goals>
|
||||
<goal>process</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<outputDirectory>target/generated-sources</outputDirectory>
|
||||
<processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
|
@ -91,6 +85,7 @@
|
|||
<properties>
|
||||
<start-class>com.baeldung.books.SpringDataRestApplication</start-class>
|
||||
<maven.version>1.0</maven.version>
|
||||
<hibernate-community-dialects.version>6.1.7.Final</hibernate-community-dialects.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -1,78 +0,0 @@
|
|||
package com.baeldung.books.dialect;
|
||||
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.dialect.identity.IdentityColumnSupport;
|
||||
|
||||
import java.sql.Types;
|
||||
|
||||
public class SQLiteDialect extends Dialect {
|
||||
|
||||
public SQLiteDialect() {
|
||||
registerColumnType(Types.BIT, "integer");
|
||||
registerColumnType(Types.TINYINT, "tinyint");
|
||||
registerColumnType(Types.SMALLINT, "smallint");
|
||||
registerColumnType(Types.INTEGER, "integer");
|
||||
registerColumnType(Types.BIGINT, "bigint");
|
||||
registerColumnType(Types.FLOAT, "float");
|
||||
registerColumnType(Types.REAL, "real");
|
||||
registerColumnType(Types.DOUBLE, "double");
|
||||
registerColumnType(Types.NUMERIC, "numeric");
|
||||
registerColumnType(Types.DECIMAL, "decimal");
|
||||
registerColumnType(Types.CHAR, "char");
|
||||
registerColumnType(Types.VARCHAR, "varchar");
|
||||
registerColumnType(Types.LONGVARCHAR, "longvarchar");
|
||||
registerColumnType(Types.DATE, "date");
|
||||
registerColumnType(Types.TIME, "time");
|
||||
registerColumnType(Types.TIMESTAMP, "timestamp");
|
||||
registerColumnType(Types.BINARY, "blob");
|
||||
registerColumnType(Types.VARBINARY, "blob");
|
||||
registerColumnType(Types.LONGVARBINARY, "blob");
|
||||
registerColumnType(Types.BLOB, "blob");
|
||||
registerColumnType(Types.CLOB, "clob");
|
||||
registerColumnType(Types.BOOLEAN, "integer");
|
||||
}
|
||||
|
||||
public IdentityColumnSupport getIdentityColumnSupport() {
|
||||
return new SQLiteIdentityColumnSupport();
|
||||
}
|
||||
|
||||
public boolean hasAlterTable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean dropConstraints() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getDropForeignKeyString() {
|
||||
return "";
|
||||
}
|
||||
|
||||
public String getAddForeignKeyConstraintString(String constraintName, String[] foreignKey, String referencedTable, String[] primaryKey, boolean referencesPrimaryKey) {
|
||||
return "";
|
||||
}
|
||||
|
||||
public String getAddPrimaryKeyConstraintString(String constraintName) {
|
||||
return "";
|
||||
}
|
||||
|
||||
public String getForUpdateString() {
|
||||
return "";
|
||||
}
|
||||
|
||||
public String getAddColumnString() {
|
||||
return "add column";
|
||||
}
|
||||
|
||||
public boolean supportsOuterJoinForUpdate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsIfExistsBeforeTableName() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean supportsCascadeDelete() {
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
package com.baeldung.books.dialect;
|
||||
|
||||
import org.hibernate.MappingException;
|
||||
import org.hibernate.dialect.identity.IdentityColumnSupportImpl;
|
||||
|
||||
public class SQLiteIdentityColumnSupport extends IdentityColumnSupportImpl {
|
||||
|
||||
@Override
|
||||
public boolean supportsIdentityColumns() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdentitySelectString(String table, String column, int type) throws MappingException {
|
||||
return "select last_insert_rowid()";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdentityColumnString(int type) throws MappingException {
|
||||
return "integer";
|
||||
}
|
||||
}
|
|
@ -1,11 +1,11 @@
|
|||
package com.baeldung.books.models;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.OneToOne;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.OneToOne;
|
||||
|
||||
@Entity
|
||||
public class Address {
|
||||
|
|
|
@ -2,15 +2,15 @@ package com.baeldung.books.models;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.JoinTable;
|
||||
import javax.persistence.ManyToMany;
|
||||
import jakarta.persistence.CascadeType;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.JoinTable;
|
||||
import jakarta.persistence.ManyToMany;
|
||||
|
||||
@Entity
|
||||
public class Author {
|
||||
|
|
|
@ -2,15 +2,15 @@ package com.baeldung.books.models;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.ManyToMany;
|
||||
import javax.persistence.ManyToOne;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.FetchType;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.ManyToMany;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
|
||||
@Entity
|
||||
public class Book {
|
||||
|
|
|
@ -2,14 +2,14 @@ package com.baeldung.books.models;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.OneToOne;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.OneToMany;
|
||||
import jakarta.persistence.OneToOne;
|
||||
|
||||
import org.springframework.data.rest.core.annotation.RestResource;
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
package com.baeldung.books.models;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
|
||||
@Entity
|
||||
public class Subject {
|
||||
|
|
|
@ -2,6 +2,6 @@ driverClassName=org.sqlite.JDBC
|
|||
url=jdbc:sqlite:memory:myDb?cache=shared
|
||||
username=sa
|
||||
password=sa
|
||||
hibernate.dialect=com.baeldung.dialect.SQLiteDialect
|
||||
spring.jpa.database-platform=org.hibernate.community.dialect.SQLiteDialect
|
||||
hibernate.hbm2ddl.auto=create-drop
|
||||
hibernate.show_sql=true
|
||||
|
|
108
pom.xml
108
pom.xml
|
@ -330,59 +330,35 @@
|
|||
<module>parent-spring-5</module>
|
||||
<module>parent-java</module>
|
||||
|
||||
|
||||
<module>azure</module>
|
||||
<module>checker-plugin</module>
|
||||
<!-- <module>clojure</module> --> <!-- Not a maven project -->
|
||||
|
||||
<module>core-java-modules</module>
|
||||
|
||||
<module>couchbase</module>
|
||||
|
||||
<!-- <module>ethereum</module> --> <!-- JAVA-6001 -->
|
||||
<!-- <module>gradle-modules</module> --> <!-- Not a maven project -->
|
||||
<module>gradle-modules/gradle/maven-to-gradle</module>
|
||||
<!-- <module>grails</module> --> <!-- Not a maven project -->
|
||||
|
||||
<!-- <module>guest</module> --> <!-- not to be built as its for guest articles -->
|
||||
|
||||
<module>apache-httpclient</module>
|
||||
<module>apache-httpclient4</module>
|
||||
|
||||
<module>java-jdi</module>
|
||||
<module>java-websocket</module>
|
||||
|
||||
<module>jetbrains</module>
|
||||
<module>jhipster-5</module>
|
||||
|
||||
<module>jmh</module>
|
||||
|
||||
<module>kubernetes-modules</module>
|
||||
|
||||
<!-- <module>lagom</module> --> <!-- Not a maven project -->
|
||||
<module>language-interop</module>
|
||||
<module>libraries-3</module>
|
||||
|
||||
<module>libraries-data-db</module>
|
||||
|
||||
<module>logging-modules</module>
|
||||
<module>lombok-modules</module>
|
||||
|
||||
<module>maven-modules</module>
|
||||
|
||||
<module>messaging-modules</module>
|
||||
|
||||
<module>microservices-modules</module>
|
||||
<module>muleesb</module>
|
||||
|
||||
|
||||
<module>netflix-modules</module>
|
||||
|
||||
<module>osgi</module>
|
||||
|
||||
|
||||
<module>persistence-modules</module>
|
||||
|
||||
<module>vavr-modules</module>
|
||||
<module>web-modules</module>
|
||||
</modules>
|
||||
|
||||
|
@ -428,7 +404,6 @@
|
|||
<module>parent-spring-5</module>
|
||||
<module>parent-java</module>
|
||||
|
||||
<module>spf4j</module>
|
||||
<module>spring-4</module>
|
||||
<module>spring-aop</module>
|
||||
|
||||
|
@ -436,14 +411,11 @@
|
|||
<module>spring-boot-modules</module>
|
||||
<module>spring-cloud-modules</module>
|
||||
<!-- <module>spring-cloud-cli</module> --> <!-- Not a maven project -->
|
||||
<module>spring-di</module>
|
||||
<module>spring-di-2</module>
|
||||
<module>spring-ejb-modules</module>
|
||||
|
||||
<module>spring-exceptions</module>
|
||||
<module>spring-integration</module>
|
||||
<module>spring-jenkins-pipeline</module>
|
||||
|
||||
<module>spring-jinq</module>
|
||||
<module>spring-katharsis</module>
|
||||
<module>spring-mobile</module>
|
||||
<module>spring-remoting-modules</module>
|
||||
|
@ -520,10 +492,9 @@
|
|||
<module>libraries-5</module>
|
||||
<module>libraries-6</module>
|
||||
<module>spring-boot-modules/spring-boot-react</module>
|
||||
<module>spring-ejb-modules/ejb-beans</module>
|
||||
|
||||
<module>vaadin</module>
|
||||
<module>vavr-modules</module>
|
||||
|
||||
</modules>
|
||||
</profile>
|
||||
|
||||
|
@ -559,8 +530,6 @@
|
|||
<module>parent-spring-5</module>
|
||||
<module>parent-java</module>
|
||||
|
||||
|
||||
<module>azure</module>
|
||||
<module>checker-plugin</module>
|
||||
<!-- <module>clojure</module> --> <!-- Not a maven project -->
|
||||
|
||||
|
@ -571,43 +540,24 @@
|
|||
<module>gradle-modules/gradle/maven-to-gradle</module>
|
||||
<!-- <module>grails</module> --> <!-- Not a maven project -->
|
||||
<!-- <module>guest</module> --> <!-- not to be built as its for guest articles -->
|
||||
|
||||
<module>apache-httpclient</module>
|
||||
<module>apache-httpclient4</module>
|
||||
|
||||
<module>java-jdi</module>
|
||||
<module>java-websocket</module>
|
||||
|
||||
<module>jhipster-5</module>
|
||||
<module>jmh</module>
|
||||
|
||||
<module>kubernetes-modules</module>
|
||||
|
||||
<!-- <module>lagom</module> --> <!-- Not a maven project -->
|
||||
<module>language-interop</module>
|
||||
<module>libraries-3</module>
|
||||
|
||||
<module>libraries-data-db</module>
|
||||
|
||||
<module>logging-modules</module>
|
||||
<module>lombok-modules</module>
|
||||
|
||||
<module>maven-modules</module>
|
||||
|
||||
<module>messaging-modules</module>
|
||||
|
||||
<module>microservices-modules</module>
|
||||
<module>muleesb</module>
|
||||
|
||||
<module>netflix-modules</module>
|
||||
|
||||
<module>osgi</module>
|
||||
|
||||
|
||||
|
||||
<module>persistence-modules</module>
|
||||
|
||||
<module>vavr-modules</module>
|
||||
<module>web-modules</module>
|
||||
</modules>
|
||||
|
||||
|
@ -645,21 +595,17 @@
|
|||
<module>parent-spring-5</module>
|
||||
<module>parent-java</module>
|
||||
|
||||
|
||||
<module>spf4j</module>
|
||||
<module>spring-4</module>
|
||||
|
||||
<module>spring-bom</module>
|
||||
<module>spring-boot-modules</module>
|
||||
<module>spring-cloud-modules</module>
|
||||
<!-- <module>spring-cloud-cli</module> --> <!-- Not a maven project -->
|
||||
<module>spring-di</module>
|
||||
<module>spring-di-2</module>
|
||||
<module>spring-ejb-modules</module>
|
||||
|
||||
<module>spring-exceptions</module>
|
||||
<module>spring-integration</module>
|
||||
<module>spring-jenkins-pipeline</module>
|
||||
<module>spring-jinq</module>
|
||||
|
||||
<module>spring-katharsis</module>
|
||||
<module>spring-mobile</module>
|
||||
<module>spring-remoting-modules</module>
|
||||
|
@ -728,9 +674,7 @@
|
|||
<module>libraries-5</module>
|
||||
<module>libraries-6</module>
|
||||
<module>spring-boot-modules/spring-boot-react</module>
|
||||
<module>spring-ejb-modules/ejb-beans</module>
|
||||
<module>vaadin</module>
|
||||
<module>vavr-modules</module>
|
||||
</modules>
|
||||
|
||||
</profile>
|
||||
|
@ -796,9 +740,20 @@
|
|||
</build>
|
||||
|
||||
<modules>
|
||||
<module>spring-ejb-modules</module>
|
||||
<module>spring-di</module>
|
||||
<module>spring-di-2</module>
|
||||
<module>spring-jinq</module>
|
||||
<module>vavr-modules</module>
|
||||
<module>java-websocket</module>
|
||||
<module>azure</module>
|
||||
<module>netflix-modules</module>
|
||||
<module>spf4j</module>
|
||||
|
||||
<module>spring-jersey</module>
|
||||
<module>jersey</module>
|
||||
<module>jaxb</module>
|
||||
|
||||
<module>javafx</module>
|
||||
<module>spring-batch</module>
|
||||
<module>spring-boot-rest</module>
|
||||
|
@ -884,7 +839,7 @@
|
|||
<module>drools</module>
|
||||
<module>guava-modules</module>
|
||||
<module>apache-httpclient-2</module>
|
||||
<module>kubernetes-modules/kubernetes-spring</module>
|
||||
<module>kubernetes-modules</module>
|
||||
<module>libraries-concurrency</module>
|
||||
<module>libraries-testing</module>
|
||||
<module>maven-modules/compiler-plugin-java-9</module>
|
||||
|
@ -904,6 +859,7 @@
|
|||
<module>spring-swagger-codegen/custom-validations-opeanpi-codegen</module>
|
||||
<module>testing-modules/testing-assertions</module>
|
||||
<module>persistence-modules/fauna</module>
|
||||
<module>persistence-modules/spring-data-rest</module>
|
||||
|
||||
<module>rule-engines-modules</module>
|
||||
|
||||
|
@ -933,7 +889,7 @@
|
|||
<module>asm</module>
|
||||
<module>atomikos</module>
|
||||
<module>atomix</module>
|
||||
<!-- <module>axon</module>--><!-- JAVA-18408 -->
|
||||
<!-- <module>axon</module>--><!-- JAVA-18408 -->
|
||||
|
||||
<module>bazel</module>
|
||||
<module>code-generation</module>
|
||||
|
@ -942,7 +898,7 @@
|
|||
<module>disruptor</module>
|
||||
<module>dozer</module>
|
||||
<module>dubbo</module>
|
||||
<module>feign</module>
|
||||
<!-- <module>feign</module> --> <!-- JAVA-19475 -->
|
||||
<module>google-cloud</module>
|
||||
<module>graphql-modules</module>
|
||||
<module>grpc</module>
|
||||
|
@ -1021,9 +977,10 @@
|
|||
<module>xstream</module>
|
||||
<module>webrtc</module>
|
||||
<module>persistence-modules/java-mongodb</module>
|
||||
<module>messaging-modules/spring-apache-camel</module>
|
||||
<module>messaging-modules</module>
|
||||
<module>spring-boot-modules/spring-boot-redis</module>
|
||||
<module>spring-security-modules/spring-security-saml2</module>
|
||||
<module>persistence-modules/questdb</module>
|
||||
</modules>
|
||||
|
||||
<properties>
|
||||
|
@ -1057,9 +1014,20 @@
|
|||
</build>
|
||||
|
||||
<modules>
|
||||
<module>spring-ejb-modules</module>
|
||||
<module>spring-di</module>
|
||||
<module>spring-di-2</module>
|
||||
<module>spring-jinq</module>
|
||||
<module>vavr-modules</module>
|
||||
<module>java-websocket</module>
|
||||
<module>azure</module>
|
||||
<module>netflix-modules</module>
|
||||
<module>spf4j</module>
|
||||
|
||||
<module>spring-jersey</module>
|
||||
<module>jersey</module>
|
||||
<module>jaxb</module>
|
||||
|
||||
<module>javafx</module>
|
||||
<module>spring-batch</module>
|
||||
<module>spring-boot-rest</module>
|
||||
|
@ -1143,7 +1111,7 @@
|
|||
<module>drools</module>
|
||||
<module>guava-modules</module>
|
||||
<module>apache-httpclient-2</module>
|
||||
<module>kubernetes-modules/kubernetes-spring</module>
|
||||
<module>kubernetes-modules</module>
|
||||
<module>libraries-concurrency</module>
|
||||
<module>libraries-testing</module>
|
||||
<module>maven-modules/compiler-plugin-java-9</module>
|
||||
|
@ -1163,6 +1131,7 @@
|
|||
<module>spring-swagger-codegen/custom-validations-opeanpi-codegen</module>
|
||||
<module>testing-modules/testing-assertions</module>
|
||||
<module>persistence-modules/fauna</module>
|
||||
<module>persistence-modules/spring-data-rest</module>
|
||||
|
||||
<module>rule-engines-modules</module>
|
||||
|
||||
|
@ -1191,7 +1160,7 @@
|
|||
<module>asm</module>
|
||||
<module>atomikos</module>
|
||||
<module>atomix</module>
|
||||
<!-- <module>axon</module>--><!-- JAVA-18408 -->
|
||||
<!-- <module>axon</module>--><!-- JAVA-18408 -->
|
||||
|
||||
<module>bazel</module>
|
||||
<module>code-generation</module>
|
||||
|
@ -1201,7 +1170,7 @@
|
|||
<module>dozer</module>
|
||||
|
||||
<module>dubbo</module>
|
||||
<module>feign</module>
|
||||
<!-- <module>feign</module> -->
|
||||
<module>google-cloud</module>
|
||||
<module>graphql-modules</module>
|
||||
<module>grpc</module>
|
||||
|
@ -1282,9 +1251,10 @@
|
|||
<module>webrtc</module>
|
||||
<module>persistence-modules/java-mongodb</module>
|
||||
<module>libraries-2</module>
|
||||
<module>messaging-modules/spring-apache-camel</module>
|
||||
<module>messaging-modules</module>
|
||||
<module>spring-boot-modules/spring-boot-redis</module>
|
||||
<module>spring-security-modules/spring-security-saml2</module>
|
||||
<module>persistence-modules/questdb</module>
|
||||
</modules>
|
||||
|
||||
<properties>
|
||||
|
|
|
@ -55,11 +55,6 @@
|
|||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>${compiler.plugin.version}</version>
|
||||
<configuration>
|
||||
<source>${java.version}</source>
|
||||
<target>${java.version}</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
|
@ -98,7 +93,6 @@
|
|||
|
||||
<properties>
|
||||
<spf4j.version>8.9.0</spf4j.version>
|
||||
<compiler.plugin.version>3.8.0</compiler.plugin.version>
|
||||
<dependency.plugin.version>3.1.1</dependency.plugin.version>
|
||||
</properties>
|
||||
|
||||
|
|
|
@ -61,11 +61,6 @@
|
|||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>${compiler.plugin.version}</version>
|
||||
<configuration>
|
||||
<source>${java.version}</source>
|
||||
<target>${java.version}</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
|
@ -104,7 +99,6 @@
|
|||
|
||||
<properties>
|
||||
<spf4j.version>8.9.0</spf4j.version>
|
||||
<compiler.plugin.version>3.8.0</compiler.plugin.version>
|
||||
<dependency.plugin.version>3.1.1</dependency.plugin.version>
|
||||
</properties>
|
||||
|
||||
|
|
|
@ -28,13 +28,13 @@
|
|||
<groupId>javax.xml.bind</groupId>
|
||||
<artifactId>jaxb-api</artifactId>
|
||||
<version>${jaxb.version}</version>
|
||||
<scope>runtime</scope>
|
||||
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.glassfish.jaxb</groupId>
|
||||
<artifactId>jaxb-runtime</artifactId>
|
||||
<version>${jaxb.version}</version>
|
||||
<scope>runtime</scope>
|
||||
|
||||
</dependency>
|
||||
<!-- SQLite database driver -->
|
||||
<dependency>
|
||||
|
|
|
@ -124,6 +124,8 @@
|
|||
<mapstruct.version>1.5.2.Final</mapstruct.version>
|
||||
<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>
|
||||
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,42 @@
|
|||
package com.baeldung.recordswithjpa;
|
||||
|
||||
import com.baeldung.recordswithjpa.entity.Book;
|
||||
import com.baeldung.recordswithjpa.records.BookRecord;
|
||||
import jakarta.persistence.EntityManager;
|
||||
import jakarta.persistence.PersistenceContext;
|
||||
import jakarta.persistence.Query;
|
||||
import jakarta.persistence.TypedQuery;
|
||||
import jakarta.persistence.criteria.CriteriaBuilder;
|
||||
import jakarta.persistence.criteria.CriteriaQuery;
|
||||
import jakarta.persistence.criteria.Root;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class QueryService {
|
||||
@PersistenceContext
|
||||
private EntityManager entityManager;
|
||||
|
||||
public List<BookRecord> findAllBooks() {
|
||||
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
|
||||
CriteriaQuery<BookRecord> query = cb.createQuery(BookRecord.class);
|
||||
Root<Book> root = query.from(Book.class);
|
||||
query.select(cb
|
||||
.construct(BookRecord.class, root.get("id"), root.get("title"), root.get("author"), root.get("isbn")));
|
||||
return entityManager.createQuery(query).getResultList();
|
||||
}
|
||||
|
||||
public BookRecord findBookById(Long id) {
|
||||
TypedQuery<BookRecord> query = entityManager
|
||||
.createQuery("SELECT new com.baeldung.recordswithjpa.records.BookRecord(b.id, b.title, b.author, b.isbn) " +
|
||||
"FROM Book b WHERE b.id = :id", BookRecord.class);
|
||||
query.setParameter("id", id);
|
||||
return query.getSingleResult();
|
||||
}
|
||||
|
||||
public List<BookRecord> findAllBooksUsingMapping() {
|
||||
Query query = entityManager.createNativeQuery("SELECT * FROM book", "BookRecordMapping");
|
||||
return query.getResultList();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package com.baeldung.recordswithjpa;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class RecordsAsJpaApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(RecordsAsJpaApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
package com.baeldung.recordswithjpa.entity;
|
||||
|
||||
import com.baeldung.recordswithjpa.records.BookRecord;
|
||||
import jakarta.persistence.*;
|
||||
|
||||
@SqlResultSetMapping(
|
||||
name = "BookRecordMapping",
|
||||
classes = @ConstructorResult(
|
||||
targetClass = BookRecord.class,
|
||||
columns = {
|
||||
@ColumnResult(name = "id", type = Long.class),
|
||||
@ColumnResult(name = "title", type = String.class),
|
||||
@ColumnResult(name = "author", type = String.class),
|
||||
@ColumnResult(name = "isbn", type = String.class)
|
||||
}
|
||||
)
|
||||
)
|
||||
@Entity
|
||||
@Table(name = "book")
|
||||
public class Book {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
private String title;
|
||||
private String author;
|
||||
private String isbn;
|
||||
|
||||
public Book() {
|
||||
}
|
||||
|
||||
public Book(Long id, String title, String author, String isbn) {
|
||||
this.id = id;
|
||||
this.title = title;
|
||||
this.author = author;
|
||||
this.isbn = isbn;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getAuthor() {
|
||||
return author;
|
||||
}
|
||||
|
||||
public void setAuthor(String author) {
|
||||
this.author = author;
|
||||
}
|
||||
|
||||
public String getIsbn() {
|
||||
return isbn;
|
||||
}
|
||||
|
||||
public void setIsbn(String isbn) {
|
||||
this.isbn = isbn;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
package com.baeldung.recordswithjpa.records;
|
||||
|
||||
public record BookRecord(Long id, String title, String author, String isbn) {
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
package com.baeldung.recordswithjpa.records;
|
||||
|
||||
public record CustomBookRecord(Long id, String title) {
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package com.baeldung.recordswithjpa.repository;
|
||||
|
||||
import com.baeldung.recordswithjpa.entity.Book;
|
||||
import com.baeldung.recordswithjpa.records.BookRecord;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface BookRepository extends CrudRepository<Book, Long> {
|
||||
List<BookRecord> findBookByAuthor(String author);
|
||||
|
||||
@Query("SELECT new com.baeldung.recordswithjpa.records.BookRecord(b.id, b.title, b.author, b.isbn) " +
|
||||
"FROM Book b WHERE b.id = :id")
|
||||
BookRecord findBookById(@Param("id") Long id);
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package com.baeldung.recordswithjpa.repository;
|
||||
|
||||
import com.baeldung.recordswithjpa.records.CustomBookRecord;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface CustomBookRepository {
|
||||
List<CustomBookRecord> findAllBooks();
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package com.baeldung.recordswithjpa.repository;
|
||||
|
||||
import com.baeldung.recordswithjpa.records.CustomBookRecord;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public class CustomBookRepositoryImpl implements CustomBookRepository {
|
||||
private final JdbcTemplate jdbcTemplate;
|
||||
|
||||
public CustomBookRepositoryImpl(JdbcTemplate jdbcTemplate) {
|
||||
this.jdbcTemplate = jdbcTemplate;
|
||||
}
|
||||
|
||||
public List<CustomBookRecord> findAllBooks() {
|
||||
return jdbcTemplate.query("SELECT id, title FROM book", (rs, rowNum) -> new CustomBookRecord(rs.getLong("id"), rs.getString("title")));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package com.baeldung.recordswithjpa;
|
||||
|
||||
import com.baeldung.recordswithjpa.entity.Book;
|
||||
import com.baeldung.recordswithjpa.records.BookRecord;
|
||||
import com.baeldung.recordswithjpa.repository.BookRepository;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class QueryServiceIntegrationTest extends RecordsAsJpaIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
private QueryService queryService;
|
||||
|
||||
|
||||
@Test
|
||||
void findAllBooks() {
|
||||
List<BookRecord> allBooks = queryService.findAllBooks();
|
||||
assertEquals(3, allBooks.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
void findBookById() {
|
||||
BookRecord bookById = queryService.findBookById(1L);
|
||||
assertEquals("The Lord of the Rings", bookById.title());
|
||||
}
|
||||
|
||||
@Test
|
||||
void findAllBooksUsingMapping() {
|
||||
List<BookRecord> allBooksUsingMapping = queryService.findAllBooksUsingMapping();
|
||||
assertEquals(3, allBooksUsingMapping.size());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package com.baeldung.recordswithjpa;
|
||||
|
||||
import com.baeldung.recordswithjpa.entity.Book;
|
||||
import com.baeldung.recordswithjpa.repository.BookRepository;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
@SpringBootTest
|
||||
public class RecordsAsJpaIntegrationTest {
|
||||
@Autowired
|
||||
protected BookRepository bookRepository;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
Book book = new Book(1L,"The Lord of the Rings", "J.R.R. Tolkien", "978-0544003415");
|
||||
Book book2 = new Book(2L,"The Hobbit", "J.R.R. Tolkien", "978-0547928227");
|
||||
Book book3 = new Book(3L,"Harry Potter and the Philosopher's Stone", "J.K. Rowling", "978-0747532699");
|
||||
|
||||
bookRepository.save(book);
|
||||
bookRepository.save(book2);
|
||||
bookRepository.save(book3);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void tearDown() {
|
||||
bookRepository.deleteAll();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package com.baeldung.recordswithjpa.repository;
|
||||
|
||||
import com.baeldung.recordswithjpa.RecordsAsJpaIntegrationTest;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class BookRepositoryIntegrationTest extends RecordsAsJpaIntegrationTest {
|
||||
|
||||
@Test
|
||||
void findBookByAuthor() {
|
||||
assertEquals(2, bookRepository.findBookByAuthor("J.R.R. Tolkien").size());
|
||||
}
|
||||
|
||||
@Test
|
||||
void findBookById() {
|
||||
assertEquals("The Lord of the Rings", bookRepository.findBookById(1L).title());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package com.baeldung.recordswithjpa.repository;
|
||||
|
||||
import com.baeldung.recordswithjpa.RecordsAsJpaIntegrationTest;
|
||||
import com.baeldung.recordswithjpa.records.CustomBookRecord;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class CustomBookRepositoryIntegrationTest extends RecordsAsJpaIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
private CustomBookRepository customBookRepository;
|
||||
|
||||
@Test
|
||||
void findAllBooks() {
|
||||
List<CustomBookRecord> allBooks = customBookRepository.findAllBooks();
|
||||
assertEquals(3, allBooks.size());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package com.baeldung.springdoc.demo;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
import com.baeldung.springdoc.demo.config.SpringDocSwaggerConfig;
|
||||
|
||||
@SpringBootApplication
|
||||
public class SpringDocExampleApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication application = new SpringApplication(SpringDocExampleApplication.class);
|
||||
//Note: SpringDocExampleApplication is the name of your main class
|
||||
application.addListeners(new SpringDocSwaggerConfig());
|
||||
application.run(args);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package com.baeldung.springdoc.demo;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class SpringFoxExampleApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(SpringFoxExampleApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package com.baeldung.springdoc.demo.config;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import org.springframework.boot.context.event.ApplicationPreparedEvent;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.env.PropertiesPropertySource;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class SpringDocSwaggerConfig implements ApplicationListener<ApplicationPreparedEvent> {
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(final ApplicationPreparedEvent event) {
|
||||
ConfigurableEnvironment environment = event.getApplicationContext().getEnvironment();
|
||||
Properties props = new Properties();
|
||||
props.put("springdoc.swagger-ui.path", swaggerPath());
|
||||
environment.getPropertySources().addFirst(new PropertiesPropertySource("programmatically", props));
|
||||
}
|
||||
|
||||
private String swaggerPath() {
|
||||
return "/myproject"; // TODO: implement your logic here.
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package com.baeldung.springdoc.demo.config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import springfox.documentation.builders.PathSelectors;
|
||||
import springfox.documentation.builders.RequestHandlerSelectors;
|
||||
import springfox.documentation.service.ApiInfo;
|
||||
import springfox.documentation.spi.DocumentationType;
|
||||
import springfox.documentation.spring.web.plugins.Docket;
|
||||
|
||||
@Configuration
|
||||
public class SpringFoxSwaggerConfig {
|
||||
|
||||
@Bean
|
||||
public Docket productApi() {
|
||||
return new Docket(DocumentationType.SWAGGER_2).select().apis(RequestHandlerSelectors.any())
|
||||
.paths(PathSelectors.any()).build().apiInfo(metaInfo());
|
||||
}
|
||||
|
||||
private ApiInfo metaInfo() {
|
||||
|
||||
return new ApiInfo("Sample API REST", "API REST", "1.0", "Terms of Service", null, "Apache License Version 2.0",
|
||||
"https://www.apache.org/licesen.html", new ArrayList<>());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package com.baeldung.springdoc.demo.controller;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
@Controller
|
||||
public class SwaggerController {
|
||||
|
||||
@RequestMapping("/myproject")
|
||||
public String getRedirectUrl() {
|
||||
return "redirect:swagger-ui.html";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package com.baeldung.springdoc.demo.controller;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.baeldung.springdoc.demo.model.Topic;
|
||||
import com.baeldung.springdoc.demo.service.TopicService;
|
||||
|
||||
|
||||
@RestController
|
||||
public class TopicsController {
|
||||
|
||||
@Autowired
|
||||
TopicService topicService;
|
||||
|
||||
@GetMapping(value = "/topics")
|
||||
public ResponseEntity<List<Topic>> getAllTopics() {
|
||||
return new ResponseEntity<>(topicService.getAlllTopics(), HttpStatus.OK);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package com.baeldung.springdoc.demo.model;
|
||||
|
||||
public class Topic {
|
||||
|
||||
Integer id;
|
||||
String name;
|
||||
|
||||
public Topic(Integer id, String name) {
|
||||
super();
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package com.baeldung.springdoc.demo.service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.baeldung.springdoc.demo.model.Topic;
|
||||
|
||||
@Service
|
||||
public class TopicService {
|
||||
|
||||
private List<Topic> topicsList;
|
||||
|
||||
public TopicService(){
|
||||
this.topicsList = new ArrayList<Topic>() {{
|
||||
add(new Topic(1, "Topic1"));
|
||||
add(new Topic(2, "Topic2"));
|
||||
add(new Topic(3, "Topic3"));
|
||||
}};
|
||||
}
|
||||
|
||||
public List<Topic> getAlllTopics(){
|
||||
return topicsList;
|
||||
}
|
||||
}
|
|
@ -1,2 +1,7 @@
|
|||
springdoc.api-docs.enabled=false
|
||||
springdoc.swagger-ui.url=/api_3.yaml
|
||||
|
||||
# Properties for custom Springdoc swagger-ui url
|
||||
|
||||
#springdoc.swagger-ui.disable-swagger-default-url=true
|
||||
#springdoc.swagger-ui.path=/myproject
|
|
@ -85,7 +85,7 @@
|
|||
|
||||
<properties>
|
||||
<spring-boot.version>2.6.1</spring-boot.version>
|
||||
<aspectj-plugin.version>1.11</aspectj-plugin.version>
|
||||
<aspectj-plugin.version>1.14.0</aspectj-plugin.version>
|
||||
<javax.inject.version>1</javax.inject.version>
|
||||
<log4j2.version>2.17.1</log4j2.version>
|
||||
</properties>
|
||||
|
|
|
@ -149,6 +149,7 @@
|
|||
<spring-boot.version>1.5.2.RELEASE</spring-boot.version>
|
||||
<mockito.version>1.10.19</mockito.version>
|
||||
<aspectjweaver.version>1.9.5</aspectjweaver.version>
|
||||
<maven-war-plugin.version>3.3.2</maven-war-plugin.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -85,8 +85,6 @@
|
|||
</dependencyManagement>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<javaee-api.version>7.0</javaee-api.version>
|
||||
<wildfly-javaee7.version>10.1.0.Final</wildfly-javaee7.version>
|
||||
<hibernate-core.version>5.2.3.Final</hibernate-core.version>
|
||||
|
|
|
@ -41,4 +41,7 @@
|
|||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<maven-war-plugin.version>3.3.2</maven-war-plugin.version>
|
||||
</properties>
|
||||
</project>
|
|
@ -0,0 +1,26 @@
|
|||
package com.baeldung.spring.kafka.multiplelisteners;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.kafka.annotation.KafkaListener;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class BookConsumer {
|
||||
private static final Logger logger = LoggerFactory.getLogger(BookConsumer.class);
|
||||
|
||||
@KafkaListener(topics = "books", groupId = "books-content-search")
|
||||
public void bookContentSearchConsumer(BookEvent event) {
|
||||
logger.info("Books event received for full-text search indexing => {}", event);
|
||||
}
|
||||
|
||||
@KafkaListener(topics = "books", groupId = "books-price-index")
|
||||
public void bookPriceIndexerConsumer(BookEvent event) {
|
||||
logger.info("Books event received for price indexing => {}", event);
|
||||
}
|
||||
|
||||
@KafkaListener(topics = "books", groupId = "book-notification-consumer", concurrency = "2")
|
||||
public void bookNotificationConsumer(BookEvent event) {
|
||||
logger.info("Books event received for notification => {}", event);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package com.baeldung.spring.kafka.multiplelisteners;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class BookEvent {
|
||||
|
||||
private String title;
|
||||
private String description;
|
||||
private Double price;
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
package com.baeldung.spring.kafka.multiplelisteners;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.kafka.clients.consumer.ConsumerConfig;
|
||||
import org.apache.kafka.common.serialization.StringDeserializer;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
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.listener.DefaultErrorHandler;
|
||||
import org.springframework.kafka.support.serializer.JsonDeserializer;
|
||||
import org.springframework.util.backoff.BackOff;
|
||||
import org.springframework.util.backoff.FixedBackOff;
|
||||
|
||||
@EnableKafka
|
||||
@Configuration
|
||||
public class KafkaConsumerConfig {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(KafkaConsumerConfig.class);
|
||||
|
||||
@Value(value = "${spring.kafka.bootstrap-servers}")
|
||||
private String bootstrapAddress;
|
||||
|
||||
@Value(value = "${kafka.backoff.interval}")
|
||||
private Long interval;
|
||||
|
||||
@Value(value = "${kafka.backoff.max_failure}")
|
||||
private Long maxAttempts;
|
||||
|
||||
public ConsumerFactory<String, BookEvent> consumerFactory() {
|
||||
Map<String, Object> props = new HashMap<>();
|
||||
props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapAddress);
|
||||
props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
|
||||
props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, JsonDeserializer.class);
|
||||
props.put(ConsumerConfig.MAX_PARTITION_FETCH_BYTES_CONFIG, "20971520");
|
||||
props.put(ConsumerConfig.FETCH_MAX_BYTES_CONFIG, "20971520");
|
||||
props.put(JsonDeserializer.TRUSTED_PACKAGES, "*");
|
||||
props.put(JsonDeserializer.TYPE_MAPPINGS, "bookEvent:com.baeldung.spring.kafka.multiplelisteners.BookEvent");
|
||||
|
||||
return new DefaultKafkaConsumerFactory<>(props);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ConcurrentKafkaListenerContainerFactory<String, BookEvent> kafkaListenerContainerFactory() {
|
||||
ConcurrentKafkaListenerContainerFactory<String, BookEvent> factory = new ConcurrentKafkaListenerContainerFactory<>();
|
||||
factory.setConsumerFactory(consumerFactory());
|
||||
factory.setCommonErrorHandler(errorHandler());
|
||||
return factory;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public DefaultErrorHandler errorHandler() {
|
||||
BackOff fixedBackOff = new FixedBackOff(interval, maxAttempts);
|
||||
return new DefaultErrorHandler((consumerRecord, e) -> LOGGER.error(String.format("consumed record %s because this exception was thrown", consumerRecord.toString())), fixedBackOff);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
package com.baeldung.spring.kafka.multiplelisteners;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.kafka.clients.producer.ProducerConfig;
|
||||
import org.apache.kafka.common.serialization.StringSerializer;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.kafka.core.DefaultKafkaProducerFactory;
|
||||
import org.springframework.kafka.core.KafkaTemplate;
|
||||
import org.springframework.kafka.core.ProducerFactory;
|
||||
import org.springframework.kafka.support.serializer.JsonSerializer;
|
||||
|
||||
@Configuration
|
||||
public class KafkaProducerConfig {
|
||||
|
||||
@Value(value = "${spring.kafka.bootstrap-servers}")
|
||||
private String bootstrapAddress;
|
||||
|
||||
@Bean
|
||||
public ProducerFactory<String, String> producerFactory() {
|
||||
Map<String, Object> configProps = new HashMap<>();
|
||||
configProps.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapAddress);
|
||||
configProps.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
|
||||
configProps.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
|
||||
configProps.put(ProducerConfig.MAX_REQUEST_SIZE_CONFIG, "20971520");
|
||||
|
||||
return new DefaultKafkaProducerFactory<>(configProps);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public KafkaTemplate<String, String> kafkaTemplate() {
|
||||
return new KafkaTemplate<>(producerFactory());
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ProducerFactory<String, BookEvent> bookProducerFactory() {
|
||||
Map<String, Object> configProps = new HashMap<>();
|
||||
configProps.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapAddress);
|
||||
configProps.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
|
||||
configProps.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JsonSerializer.class);
|
||||
configProps.put(JsonSerializer.TYPE_MAPPINGS, "bookEvent:com.baeldung.spring.kafka.multiplelisteners.BookEvent");
|
||||
|
||||
return new DefaultKafkaProducerFactory<>(configProps);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public KafkaTemplate<String, BookEvent> bookKafkaTemplate() {
|
||||
return new KafkaTemplate<>(bookProducerFactory());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package com.baeldung.spring.kafka.multiplelisteners;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.kafka.clients.admin.AdminClientConfig;
|
||||
import org.apache.kafka.clients.admin.NewTopic;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.kafka.core.KafkaAdmin;
|
||||
|
||||
@Configuration
|
||||
public class KafkaTopicConfig {
|
||||
|
||||
@Value(value = "${spring.kafka.bootstrap-servers}")
|
||||
private String bootstrapAddress;
|
||||
|
||||
@Value(value = "${multiple-listeners.books.topic.name}")
|
||||
private String booksTopicName;
|
||||
|
||||
@Bean
|
||||
public KafkaAdmin kafkaAdmin() {
|
||||
Map<String, Object> configs = new HashMap<>();
|
||||
configs.put(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapAddress);
|
||||
return new KafkaAdmin(configs);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public NewTopic booksTopic() {
|
||||
return new NewTopic(booksTopicName, 1, (short) 1);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package com.baeldung.spring.kafka.multiplelisteners;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
@SpringBootApplication
|
||||
@Import(value = { KafkaTopicConfig.class, KafkaConsumerConfig.class, KafkaProducerConfig.class })
|
||||
public class MultipleListenersApplicationKafkaApp {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(MultipleListenersApplicationKafkaApp.class, args);
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package com.baeldung.spring.kafka;
|
||||
package com.baeldung.spring.kafka.retryable;
|
||||
|
||||
public class Farewell {
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.baeldung.spring.kafka;
|
||||
package com.baeldung.spring.kafka.retryable;
|
||||
|
||||
public class Greeting {
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
package com.baeldung.spring.kafka;
|
||||
package com.baeldung.spring.kafka.retryable;
|
||||
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.baeldung.spring.kafka;
|
||||
package com.baeldung.spring.kafka.retryable;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
@ -55,7 +55,7 @@ public class KafkaProducerConfig {
|
|||
configProps.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapAddress);
|
||||
configProps.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
|
||||
configProps.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JsonSerializer.class);
|
||||
configProps.put(JsonSerializer.TYPE_MAPPINGS, "greeting:com.baeldung.spring.kafka.Greeting, farewell:com.baeldung.spring.kafka.Farewell");
|
||||
configProps.put(JsonSerializer.TYPE_MAPPINGS, "greeting:com.baeldung.spring.kafka.retrayable.Greeting, farewell:com.baeldung.spring.kafka.retrayable.Farewell");
|
||||
return new DefaultKafkaProducerFactory<>(configProps);
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.baeldung.spring.kafka;
|
||||
package com.baeldung.spring.kafka.retryable;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
|
@ -1,4 +1,4 @@
|
|||
package com.baeldung.spring.kafka;
|
||||
package com.baeldung.spring.kafka.retryable;
|
||||
|
||||
import org.springframework.kafka.annotation.KafkaHandler;
|
||||
import org.springframework.kafka.annotation.KafkaListener;
|
|
@ -1,4 +1,4 @@
|
|||
package com.baeldung.spring.kafka;
|
||||
package com.baeldung.spring.kafka.retryable;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
|
@ -16,5 +16,7 @@ monitor.kafka.consumer.groupid.simulate=baeldungGrpSimulate
|
|||
test.topic=testtopic1
|
||||
kafka.backoff.interval=9000
|
||||
kafka.backoff.max_failure=5
|
||||
# multiple listeners properties
|
||||
multiple-listeners.books.topic.name=books
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
package com.baeldung.spring.kafka.multiplelisteners;
|
||||
|
||||
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.kafka.config.KafkaListenerEndpointRegistry;
|
||||
import org.springframework.kafka.core.KafkaTemplate;
|
||||
import org.springframework.kafka.listener.AcknowledgingConsumerAwareMessageListener;
|
||||
import org.springframework.kafka.listener.ConcurrentMessageListenerContainer;
|
||||
import org.springframework.kafka.test.context.EmbeddedKafka;
|
||||
|
||||
@SpringBootTest(classes = MultipleListenersApplicationKafkaApp.class)
|
||||
@EmbeddedKafka(partitions = 1, brokerProperties = { "listeners=PLAINTEXT://localhost:9092", "port=9092" })
|
||||
class KafkaMultipleListenersIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
private KafkaListenerEndpointRegistry registry;
|
||||
@Autowired
|
||||
private KafkaTemplate<String, BookEvent> bookEventKafkaTemplate;
|
||||
|
||||
private static final String TOPIC = "books";
|
||||
|
||||
@Test
|
||||
void givenEmbeddedKafkaBroker_whenSendingAMessage_thenMessageIsConsumedByAll3Listeners() throws Exception {
|
||||
BookEvent bookEvent = new BookEvent("test-book-title-1", "test-book-desc-1", 2.0);
|
||||
CountDownLatch latch = new CountDownLatch(3);
|
||||
|
||||
List<? extends ConcurrentMessageListenerContainer<?, ?>> bookListeners = registry.getAllListenerContainers()
|
||||
.stream()
|
||||
.map(c -> (ConcurrentMessageListenerContainer<?, ?>) c)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
bookListeners.forEach(listener -> {
|
||||
listener.stop();
|
||||
listener.getContainerProperties()
|
||||
.setMessageListener((AcknowledgingConsumerAwareMessageListener<String, BookEvent>) (data, acknowledgment, consumer) -> {
|
||||
assertThat(data.value()).isEqualTo(bookEvent);
|
||||
latch.countDown();
|
||||
});
|
||||
listener.start();
|
||||
});
|
||||
|
||||
bookEventKafkaTemplate.send(TOPIC, UUID.randomUUID()
|
||||
.toString(), bookEvent);
|
||||
|
||||
assertThat(bookListeners.size()).isEqualTo(3);
|
||||
assertThat(latch.await(10, TimeUnit.SECONDS)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenEmbeddedKafkaBroker_whenSendingThreeMessage_thenListenerPrintLogs() throws Exception {
|
||||
CountDownLatch latch = new CountDownLatch(3);
|
||||
Arrays.stream(new int[] { 1, 2, 3 })
|
||||
.mapToObj(i -> new BookEvent(String.format("book %s", i), String.format("description %s", i), (double) i))
|
||||
.forEach(bookEvent -> {
|
||||
bookEventKafkaTemplate.send(TOPIC, UUID.randomUUID()
|
||||
.toString(), bookEvent);
|
||||
latch.countDown();
|
||||
});
|
||||
|
||||
// wait for messages to be printed
|
||||
Thread.sleep(1000);
|
||||
|
||||
assertThat(latch.await(10, TimeUnit.SECONDS)).isTrue();
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package com.baeldung.spring.kafka;
|
||||
package com.baeldung.spring.kafka.retryable;
|
||||
|
||||
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
|
||||
|
||||
|
@ -17,6 +17,8 @@ import org.springframework.kafka.listener.ConcurrentMessageListenerContainer;
|
|||
import org.springframework.kafka.test.EmbeddedKafkaBroker;
|
||||
import org.springframework.kafka.test.context.EmbeddedKafka;
|
||||
|
||||
import com.baeldung.spring.kafka.retryable.Greeting;
|
||||
import com.baeldung.spring.kafka.retryable.RetryableApplicationKafkaApp;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
@SpringBootTest(classes = RetryableApplicationKafkaApp.class)
|
|
@ -42,6 +42,7 @@
|
|||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.22</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.projectreactor</groupId>
|
||||
|
|
|
@ -5,54 +5,54 @@ import java.util.Optional;
|
|||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.vault.core.VaultKeyValueOperations;
|
||||
import org.springframework.vault.core.VaultKeyValueOperationsSupport;
|
||||
import org.springframework.vault.core.VaultTemplate;
|
||||
import org.springframework.vault.support.VaultResponseSupport;
|
||||
|
||||
/**
|
||||
* Sample service to demonstrate storing and retrieval of secrets.
|
||||
*
|
||||
*
|
||||
* NOTE: We need to configure Vault and provide the Vault uri in the properties file.
|
||||
*
|
||||
*/
|
||||
@Service
|
||||
public class CredentialsService {
|
||||
private final VaultTemplate vaultTemplate;
|
||||
private final VaultKeyValueOperations vaultKeyValueOperations;
|
||||
private final CredentialsRepository credentialsRepository;
|
||||
|
||||
@Autowired
|
||||
private VaultTemplate vaultTemplate;
|
||||
|
||||
@Autowired
|
||||
private CredentialsRepository credentialsRepository;
|
||||
public CredentialsService(VaultTemplate vaultTemplate, CredentialsRepository credentialsRepository) {
|
||||
this.vaultTemplate = vaultTemplate;
|
||||
this.credentialsRepository = credentialsRepository;
|
||||
this.vaultKeyValueOperations = vaultTemplate.opsForKeyValue("credentials/myapp", VaultKeyValueOperationsSupport.KeyValueBackend.KV_2);
|
||||
}
|
||||
|
||||
/**
|
||||
* To Secure Credentials
|
||||
* @param credentials
|
||||
* @return VaultResponse
|
||||
* @throws URISyntaxException
|
||||
*/
|
||||
public void secureCredentials(Credentials credentials) throws URISyntaxException {
|
||||
|
||||
vaultTemplate.write("credentials/myapp", credentials);
|
||||
* To Secure Credentials
|
||||
* @param credentials
|
||||
* @return VaultResponse
|
||||
* @throws URISyntaxException
|
||||
*/
|
||||
public void secureCredentials(Credentials credentials) {
|
||||
vaultKeyValueOperations.put(credentials.getUsername(), credentials);
|
||||
}
|
||||
|
||||
/**
|
||||
* To Retrieve Credentials
|
||||
* @return Credentials
|
||||
* @throws URISyntaxException
|
||||
*/
|
||||
public Credentials accessCredentials() throws URISyntaxException {
|
||||
|
||||
VaultResponseSupport<Credentials> response = vaultTemplate.read("credentials/myapp", Credentials.class);
|
||||
public Credentials accessCredentials(String username) {
|
||||
VaultResponseSupport<Credentials> response = vaultKeyValueOperations.get(username, Credentials.class);
|
||||
return response.getData();
|
||||
}
|
||||
|
||||
public Credentials saveCredentials(Credentials credentials) {
|
||||
|
||||
return credentialsRepository.save(credentials);
|
||||
}
|
||||
|
||||
public Optional<Credentials> findById(String username) {
|
||||
|
||||
return credentialsRepository.findById(username);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import org.junit.Test;
|
|||
import org.junit.runner.RunWith;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.vault.repository.configuration.EnableVaultRepositories;
|
||||
|
||||
/**
|
||||
* This live test requires:
|
||||
|
@ -17,6 +18,7 @@ import org.springframework.test.context.junit4.SpringRunner;
|
|||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = SpringVaultApplication.class)
|
||||
@EnableVaultRepositories
|
||||
public class SpringContextLiveTest {
|
||||
|
||||
@Test
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue