Merge branch 'master' of github.com:eugenp/tutorials into master

This commit is contained in:
Karsten Silz 2020-09-01 20:09:01 +01:00
commit 506a145955
211 changed files with 2721 additions and 311 deletions

View File

@ -74,6 +74,7 @@
<plugins> <plugins>
<plugin> <plugin>
<artifactId>maven-assembly-plugin</artifactId> <artifactId>maven-assembly-plugin</artifactId>
<version>3.3.0</version>
<executions> <executions>
<execution> <execution>
<phase>package</phase> <phase>package</phase>

View File

@ -10,5 +10,6 @@ public class CopyListServiceUnitTest {
@Test(expected = UnsupportedOperationException.class) @Test(expected = UnsupportedOperationException.class)
public void whenModifyCopyOfList_thenThrowsException() { public void whenModifyCopyOfList_thenThrowsException() {
List<Integer> copyList = List.copyOf(Arrays.asList(1, 2, 3, 4)); List<Integer> copyList = List.copyOf(Arrays.asList(1, 2, 3, 4));
copyList.add(4);
} }
} }

View File

@ -0,0 +1,11 @@
package com.baeldung.array.arraystoreexception;
public class ArrayStoreExampleCE {
public static void main(String[] args) {
//String array[] = new String[5]; //This will lead to compile-time error at line-8 when uncommented
//array[0] = 2;
}
}

View File

@ -0,0 +1,16 @@
package com.baeldung.array.arraystoreexception;
public class ArrayStoreExceptionExample {
public static void main(String[] args) {
try {
Object array[] = new String[5];
array[0] = 2;
} catch (ArrayStoreException e) {
// handle the exception
}
}
}

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="15 seconds" debug="false">
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>[%d{ISO8601}]-[%thread] %-5level %logger - %msg%n</pattern>
</encoder>
</appender>
<root level="WARN">
<appender-ref ref="STDOUT" />
</root>
</configuration>

View File

@ -0,0 +1,60 @@
package com.baeldung.algorithms.largestpowerof2;
import org.nd4j.linalg.io.Assert;
public class LargestPowerOf2 {
public long findLargestPowerOf2LessThanTheGivenNumber(long input) {
Assert.isTrue(input > 1, "Invalid input");
long firstPowerOf2 = 1;
long nextPowerOf2 = 2;
while (nextPowerOf2 < input) {
firstPowerOf2 = nextPowerOf2;
nextPowerOf2 = nextPowerOf2 * 2;
}
return firstPowerOf2;
}
public long findLargestPowerOf2LessThanTheGivenNumberUsingLogBase2(long input) {
Assert.isTrue(input > 1, "Invalid input");
long temp = input;
if (input % 2 == 0) {
temp = input - 1;
}
// Find log base 2 of a given number
long power = (long) (Math.log(temp) / Math.log(2));
long result = (long) Math.pow(2, power);
return result;
}
public long findLargestPowerOf2LessThanTheGivenNumberUsingBitwiseAnd(long input) {
Assert.isTrue(input > 1, "Invalid input");
long result = 1;
for (long i = input - 1; i > 1; i--) {
if ((i & (i - 1)) == 0) {
result = i;
break;
}
}
return result;
}
public long findLargestPowerOf2LessThanTheGivenNumberUsingBitShiftApproach(long input) {
Assert.isTrue(input > 1, "Invalid input");
long result = 1;
long powerOf2;
for (long i = 0; i < Long.BYTES * 8; i++) {
powerOf2 = 1 << i;
if (powerOf2 >= input) {
break;
}
result = powerOf2;
}
return result;
}
}

View File

@ -0,0 +1,67 @@
package com.baeldung.algorithms.largestpowerof2;
import java.util.Arrays;
import java.util.Collection;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@RunWith(Parameterized.class)
public class LargestPowerOf2UnitTest {
private long input;
private long expectedResult;
public LargestPowerOf2UnitTest(long input, long expectedResult) {
this.input = input;
this.expectedResult = expectedResult;
}
@Parameterized.Parameters(name = "{index}: verifyLargestPowerOf2LessThanTheGivenNumber({0}) = {1}")
public static Collection<Object[]> data() {
return Arrays.asList(new Object[][] { { 2, 1 }, { 4, 2 }, { 500, 256 }, { 512, 256 }, { 1050, 1024 } });
}
@Test
public void givenValidInput_verifyLargestPowerOf2LessThanTheGivenNumber() {
LargestPowerOf2 largestPowerOf2 = new LargestPowerOf2();
long result = largestPowerOf2.findLargestPowerOf2LessThanTheGivenNumber(input);
Assert.assertEquals(expectedResult, result);
}
@Test
public void givenValidInput_verifyLargestPowerOf2LessThanTheGivenNumberUsingLogBase2() {
LargestPowerOf2 largestPowerOf2 = new LargestPowerOf2();
long result = largestPowerOf2.findLargestPowerOf2LessThanTheGivenNumberUsingLogBase2(input);
Assert.assertEquals(expectedResult, result);
}
@Test
public void givenValidInput_verifyLargestPowerOf2LessThanTheGivenNumberBitwiseAnd() {
LargestPowerOf2 largestPowerOf2 = new LargestPowerOf2();
long result = largestPowerOf2.findLargestPowerOf2LessThanTheGivenNumberUsingBitwiseAnd(input);
Assert.assertEquals(expectedResult, result);
}
@Test
public void givenValidInput_verifyLargestPowerOf2LessThanTheGivenNumberBitShiftApproach() {
LargestPowerOf2 largestPowerOf2 = new LargestPowerOf2();
long result = largestPowerOf2.findLargestPowerOf2LessThanTheGivenNumberUsingBitShiftApproach(input);
Assert.assertEquals(expectedResult, result);
}
@Test(expected = IllegalArgumentException.class)
public void givenInvalidInput_ShouldThrowException() {
LargestPowerOf2 largestPowerOf2 = new LargestPowerOf2();
largestPowerOf2.findLargestPowerOf2LessThanTheGivenNumber(1);
}
}

View File

@ -0,0 +1,7 @@
## Core Kotlin Collections
This module contains articles about core Kotlin collections.
### Relevant articles:

View File

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>core-kotlin-collections-2</artifactId>
<name>core-kotlin-collections-2</name>
<packaging>jar</packaging>
<parent>
<groupId>com.baeldung.core-kotlin-modules</groupId>
<artifactId>core-kotlin-modules</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jdk8</artifactId>
<version>${kotlin.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-math3</artifactId>
<version>${commons-math3.version}</version>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>${assertj.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-test</artifactId>
<version>${kotlin.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<properties>
<kotlin.version>1.3.30</kotlin.version>
<commons-math3.version>3.6.1</commons-math3.version>
<assertj.version>3.10.0</assertj.version>
</properties>
</project>

View File

@ -0,0 +1,107 @@
package com.baeldung.aggregate
class AggregateOperations {
private val numbers = listOf(1, 15, 3, 8)
fun countList(): Int {
return numbers.count()
}
fun sumList(): Int {
return numbers.sum()
}
fun averageList(): Double {
return numbers.average()
}
fun maximumInList(): Int? {
return numbers.max()
}
fun minimumInList(): Int? {
return numbers.min()
}
fun maximumByList(): Int? {
return numbers.maxBy { it % 5 }
}
fun minimumByList(): Int? {
return numbers.minBy { it % 5 }
}
fun maximumWithList(): String? {
val strings = listOf("Berlin", "Kolkata", "Prague", "Barcelona")
return strings.maxWith(compareBy { it.length % 4 })
}
fun minimumWithList(): String? {
val strings = listOf("Berlin", "Kolkata", "Prague", "Barcelona")
return strings.minWith(compareBy { it.length % 4 })
}
fun sumByList(): Int {
return numbers.sumBy { it * 5 }
}
fun sumByDoubleList(): Double {
return numbers.sumByDouble { it.toDouble() / 8 }
}
fun foldList(): Int {
return numbers.fold(100) { total, it ->
println("total = $total, it = $it")
total - it
} // ((((100 - 1)-15)-3)-8) = 73
}
fun foldRightList(): Int {
return numbers.foldRight(100) { it, total ->
println("total = $total, it = $it")
total - it
} // ((((100-8)-3)-15)-1) = 73
}
fun foldIndexedList(): Int {
return numbers.foldIndexed(100) { index, total, it ->
println("total = $total, it = $it, index = $index")
if (index.minus(2) >= 0) total - it else total
} // ((100 - 3)-8) = 89
}
fun foldRightIndexedList(): Int {
return numbers.foldRightIndexed(100) { index, it, total ->
println("total = $total, it = $it, index = $index")
if (index.minus(2) >= 0) total - it else total
} // ((100 - 8)-3) = 89
}
fun reduceList(): Int {
return numbers.reduce { total, it ->
println("total = $total, it = $it")
total - it
} // (((1 - 15)-3)-8) = -25
}
fun reduceRightList(): Int {
return numbers.reduceRight() { it, total ->
println("total = $total, it = $it")
total - it
} // ((8-3)-15)-1) = -11
}
fun reduceIndexedList(): Int {
return numbers.reduceIndexed { index, total, it ->
println("total = $total, it = $it, index = $index")
if (index.minus(2) >= 0) total - it else total
} // ((1-3)-8) = -10
}
fun reduceRightIndexedList(): Int {
return numbers.reduceRightIndexed { index, it, total ->
println("total = $total, it = $it, index = $index")
if (index.minus(2) >= 0) total - it else total
} // ((8-3) = 5
}
}

View File

@ -0,0 +1,104 @@
package com.baeldung.aggregate
import org.junit.jupiter.api.Test
import kotlin.test.assertEquals
class AggregateOperationsUnitTest {
private val classUnderTest: AggregateOperations = AggregateOperations()
@Test
fun whenCountOfList_thenReturnsValue() {
assertEquals(4, classUnderTest.countList())
}
@Test
fun whenSumOfList_thenReturnsTotalValue() {
assertEquals(27, classUnderTest.sumList())
}
@Test
fun whenAverageOfList_thenReturnsValue() {
assertEquals(6.75, classUnderTest.averageList())
}
@Test
fun whenMaximumOfList_thenReturnsMaximumValue() {
assertEquals(15, classUnderTest.maximumInList())
}
@Test
fun whenMinimumOfList_thenReturnsMinimumValue() {
assertEquals(1, classUnderTest.minimumInList())
}
@Test
fun whenMaxByList_thenReturnsLargestValue() {
assertEquals(3, classUnderTest.maximumByList())
}
@Test
fun whenMinByList_thenReturnsSmallestValue() {
assertEquals(15, classUnderTest.minimumByList())
}
@Test
fun whenMaxWithList_thenReturnsLargestValue(){
assertEquals("Kolkata", classUnderTest.maximumWithList())
}
@Test
fun whenMinWithList_thenReturnsSmallestValue(){
assertEquals("Barcelona", classUnderTest.minimumWithList())
}
@Test
fun whenSumByList_thenReturnsIntegerValue(){
assertEquals(135, classUnderTest.sumByList())
}
@Test
fun whenSumByDoubleList_thenReturnsDoubleValue(){
assertEquals(3.375, classUnderTest.sumByDoubleList())
}
@Test
fun whenFoldList_thenReturnsValue(){
assertEquals(73, classUnderTest.foldList())
}
@Test
fun whenFoldRightList_thenReturnsValue(){
assertEquals(73, classUnderTest.foldRightList())
}
@Test
fun whenFoldIndexedList_thenReturnsValue(){
assertEquals(89, classUnderTest.foldIndexedList())
}
@Test
fun whenFoldRightIndexedList_thenReturnsValue(){
assertEquals(89, classUnderTest.foldRightIndexedList())
}
@Test
fun whenReduceList_thenReturnsValue(){
assertEquals(-25, classUnderTest.reduceList())
}
@Test
fun whenReduceRightList_thenReturnsValue(){
assertEquals(-11, classUnderTest.reduceRightList())
}
@Test
fun whenReduceIndexedList_thenReturnsValue(){
assertEquals(-10, classUnderTest.reduceIndexedList())
}
@Test
fun whenReduceRightIndexedList_thenReturnsValue(){
assertEquals(5, classUnderTest.reduceRightIndexedList())
}
}

View File

@ -21,6 +21,7 @@
<module>core-kotlin-advanced</module> <module>core-kotlin-advanced</module>
<module>core-kotlin-annotations</module> <module>core-kotlin-annotations</module>
<module>core-kotlin-collections</module> <module>core-kotlin-collections</module>
<module>core-kotlin-collections-2</module>
<module>core-kotlin-concurrency</module> <module>core-kotlin-concurrency</module>
<module>core-kotlin-date-time</module> <module>core-kotlin-date-time</module>
<module>core-kotlin-design-patterns</module> <module>core-kotlin-design-patterns</module>

View File

@ -1,3 +0,0 @@
### Relevant Article:
- [Creating Docker Images with Spring Boot](https://www.baeldung.com/spring-boot-docker-images)

View File

@ -6,3 +6,4 @@ This module contains articles about Drools
- [Introduction to Drools](https://www.baeldung.com/drools) - [Introduction to Drools](https://www.baeldung.com/drools)
- [An Example of Backward Chaining in Drools](https://www.baeldung.com/drools-backward-chaining) - [An Example of Backward Chaining in Drools](https://www.baeldung.com/drools-backward-chaining)
- [Drools Using Rules from Excel Files](https://www.baeldung.com/drools-excel)

View File

@ -1,3 +1,4 @@
rootProject.name='gradle-5-articles' rootProject.name='gradle-5-articles'
include 'java-exec' include 'java-exec'
include 'unused-dependencies' include 'unused-dependencies'
include 'source-sets'

1
gradle-5/source-sets/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/build/

View File

@ -0,0 +1,67 @@
apply plugin: "eclipse"
apply plugin: "java"
description = "Source Sets example"
task printSourceSetInformation(){
description = "Print source set information"
doLast{
sourceSets.each { srcSet ->
println "["+srcSet.name+"]"
print "-->Source directories: "+srcSet.allJava.srcDirs+"\n"
print "-->Output directories: "+srcSet.output.classesDirs.files+"\n"
print "-->Compile classpath:\n"
srcSet.compileClasspath.files.each {
print " "+it.path+"\n"
}
println ""
}
}
}
sourceSets{
itest {
compileClasspath += sourceSets.main.output
runtimeClasspath += sourceSets.main.output
java {
}
}
}
test {
testLogging {
events "passed","skipped", "failed"
}
}
dependencies {
implementation('org.apache.httpcomponents:httpclient:4.5.12')
testImplementation('junit:junit:4.12')
itestImplementation('com.google.guava:guava:29.0-jre')
}
task itest(type: Test) {
description = "Run integration tests"
group = "verification"
testClassesDirs = sourceSets.itest.output.classesDirs
classpath = sourceSets.itest.runtimeClasspath
}
itest {
testLogging {
events "passed","skipped", "failed"
}
}
configurations {
itestImplementation.extendsFrom(testImplementation)
itestRuntimeOnly.extendsFrom(testRuntimeOnly)
}
eclipse {
classpath {
plusConfigurations+=[configurations.itestCompileClasspath]
}
}

View File

@ -0,0 +1,25 @@
package com.baeldung.itest;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import java.util.List;
import org.junit.Test;
import com.baeldung.main.SourceSetsObject;
import com.google.common.collect.ImmutableList;
public class SourceSetsItest {
@Test
public void givenImmutableList_whenRun_ThenSuccess() {
SourceSetsObject underTest = new SourceSetsObject("lorem", "ipsum");
List<String> someStrings = ImmutableList.of("Baeldung", "is", "cool");
assertThat(underTest.getUser(), is("lorem"));
assertThat(underTest.getPassword(), is("ipsum"));
assertThat(someStrings.size(), is(3));
}
}

View File

@ -0,0 +1,9 @@
package com.baeldung.main;
public class SourceSetsMain {
public static void main(String[] args) {
System.out.println("Hell..oh...world!");
}
}

View File

@ -0,0 +1,21 @@
package com.baeldung.main;
public class SourceSetsObject {
private final String user;
private final String password;
public SourceSetsObject(String user, String password) {
this.user = user;
this.password = password;
}
public String getPassword() {
return password;
}
public String getUser() {
return user;
}
}

View File

@ -0,0 +1,20 @@
package com.baeldung.test;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import org.junit.Test;
import com.baeldung.main.SourceSetsObject;
public class SourceSetsTest {
@Test
public void whenRun_ThenSuccess() {
SourceSetsObject underTest = new SourceSetsObject("lorem", "ipsum");
assertThat(underTest.getUser(), is("lorem"));
assertThat(underTest.getPassword(), is("ipsum"));
}
}

View File

@ -237,6 +237,26 @@
<build> <build>
<defaultGoal>spring-boot:run</defaultGoal> <defaultGoal>spring-boot:run</defaultGoal>
<plugins> <plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>properties-maven-plugin</artifactId>
<version>1.0.0</version>
<executions>
<execution>
<goals>
<goal>set-system-properties</goal>
</goals>
<configuration>
<properties>
<property>
<name>org.slf4j.simpleLogger.log.com.github.eirslett</name>
<value>error</value>
</property>
</properties>
</configuration>
</execution>
</executions>
</plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId> <artifactId>maven-compiler-plugin</artifactId>

View File

@ -9,6 +9,8 @@
<packaging>pom</packaging> <packaging>pom</packaging>
<parent> <parent>
<!-- Jhipster project is autogenerated and upgrading it will need a newly generated project.
Also, we already have jhipster-5 which has new version of boot-2. So, this project should be left as a legacy version. -->
<artifactId>parent-boot-1</artifactId> <artifactId>parent-boot-1</artifactId>
<groupId>com.baeldung</groupId> <groupId>com.baeldung</groupId>
<version>0.0.1-SNAPSHOT</version> <version>0.0.1-SNAPSHOT</version>

View File

@ -14,29 +14,24 @@
</parent> </parent>
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId> <artifactId>spring-boot-starter-web</artifactId>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework.security.oauth</groupId> <groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId> <artifactId>spring-security-oauth2</artifactId>
<version>${spring-boot.version}</version> <version>${spring-boot.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework</groupId> <groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId> <artifactId>spring-web</artifactId>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.github.scribejava</groupId> <groupId>com.github.scribejava</groupId>
<artifactId>scribejava-apis</artifactId> <artifactId>scribejava-apis</artifactId>
<version>${scribejava.version}</version> <version>${scribejava.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.google.crypto.tink</groupId> <groupId>com.google.crypto.tink</groupId>
<artifactId>tink</artifactId> <artifactId>tink</artifactId>
@ -72,6 +67,16 @@
<artifactId>jasypt</artifactId> <artifactId>jasypt</artifactId>
<version>${jasypt.version}</version> <version>${jasypt.version}</version>
</dependency> </dependency>
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>${jsch.version}</version>
</dependency>
<dependency>
<groupId>org.apache.sshd</groupId>
<artifactId>sshd-core</artifactId>
<version>${apache-mina.version}</version>
</dependency>
</dependencies> </dependencies>
<properties> <properties>
@ -81,6 +86,8 @@
<cryptacular.version>1.2.2</cryptacular.version> <cryptacular.version>1.2.2</cryptacular.version>
<jasypt.version>1.9.2</jasypt.version> <jasypt.version>1.9.2</jasypt.version>
<bouncycastle.version>1.58</bouncycastle.version> <bouncycastle.version>1.58</bouncycastle.version>
<jsch.version>0.1.55</jsch.version>
<apache-mina.version>2.5.1</apache-mina.version>
</properties> </properties>
</project> </project>

View File

@ -0,0 +1,64 @@
package com.baeldung.ssh.apachesshd;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.util.EnumSet;
import java.util.concurrent.TimeUnit;
import org.apache.sshd.client.SshClient;
import org.apache.sshd.client.channel.ClientChannel;
import org.apache.sshd.client.channel.ClientChannelEvent;
import org.apache.sshd.client.session.ClientSession;
import org.apache.sshd.common.channel.Channel;
public class SshdDemo {
public static void main(String[] args) throws Exception {
String username = "demo";
String password = "password";
String host = "test.rebex.net";
int port = 22;
long defaultTimeoutSeconds = 10l;
String command = "ls\n";
listFolderStructure(username, password, host, port, defaultTimeoutSeconds, command);
}
public static String listFolderStructure(String username, String password, String host, int port, long defaultTimeoutSeconds, String command) throws Exception {
SshClient client = SshClient.setUpDefaultClient();
client.start();
try (ClientSession session = client.connect(username, host, port)
.verify(defaultTimeoutSeconds, TimeUnit.SECONDS)
.getSession()) {
session.addPasswordIdentity(password);
session.auth()
.verify(5L, TimeUnit.SECONDS);
try (ByteArrayOutputStream responseStream = new ByteArrayOutputStream();
ByteArrayOutputStream errorResponseStream = new ByteArrayOutputStream();
ClientChannel channel = session.createChannel(Channel.CHANNEL_SHELL)) {
channel.setOut(responseStream);
channel.setErr(errorResponseStream);
try {
channel.open()
.verify(defaultTimeoutSeconds, TimeUnit.SECONDS);
try (OutputStream pipedIn = channel.getInvertedIn()) {
pipedIn.write(command.getBytes());
pipedIn.flush();
}
channel.waitFor(EnumSet.of(ClientChannelEvent.CLOSED), TimeUnit.SECONDS.toMillis(defaultTimeoutSeconds));
String errorString = new String(errorResponseStream.toByteArray());
if(!errorString.isEmpty()) {
throw new Exception(errorString);
}
String responseString = new String(responseStream.toByteArray());
return responseString;
} finally {
channel.close(false);
}
}
} finally {
client.stop();
}
}
}

View File

@ -0,0 +1,52 @@
package com.baeldung.ssh.jsch;
import java.io.ByteArrayOutputStream;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
public class JschDemo {
public static void main(String args[]) throws Exception {
String username = "demo";
String password = "password";
String host = "test.rebex.net";
int port = 22;
String command = "ls";
listFolderStructure(username, password, host, port, command);
}
public static String listFolderStructure(String username, String password, String host, int port, String command) throws Exception {
Session session = null;
ChannelExec channel = null;
String response = null;
try {
session = new JSch().getSession(username, host, port);
session.setPassword(password);
session.setConfig("StrictHostKeyChecking", "no");
session.connect();
channel = (ChannelExec) session.openChannel("exec");
channel.setCommand(command);
ByteArrayOutputStream responseStream = new ByteArrayOutputStream();
ByteArrayOutputStream errorResponseStream = new ByteArrayOutputStream();
channel.setOutputStream(responseStream);
channel.setErrStream(errorResponseStream);
channel.connect();
while (channel.isConnected()) {
Thread.sleep(100);
}
String errorResponse = new String(errorResponseStream.toByteArray());
response = new String(responseStream.toByteArray());
if(!errorResponse.isEmpty()) {
throw new Exception(errorResponse);
}
} finally {
if (session != null)
session.disconnect();
if (channel != null)
channel.disconnect();
}
return response;
}
}

View File

@ -0,0 +1,38 @@
package com.baeldung.ssh;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import org.junit.Test;
import com.baeldung.ssh.apachesshd.SshdDemo;
public class ApacheMinaSshdLiveTest {
@Test
public void givenValidCredentials_whenConnectionIsEstablished_thenServerReturnsResponse() throws Exception {
String username = "demo";
String password = "password";
String host = "test.rebex.net";
int port = 22;
long defaultTimeoutSeconds = 10l;
String command = "ls\n";
String responseString = SshdDemo.listFolderStructure(username, password, host, port, defaultTimeoutSeconds, command);
assertNotNull(responseString);
}
@Test(expected = Exception.class)
public void givenInvalidCredentials_whenConnectionAttemptIsMade_thenServerReturnsErrorResponse() throws Exception {
String username = "invalidUsername";
String password = "password";
String host = "test.rebex.net";
int port = 22;
long defaultTimeoutSeconds = 10l;
String command = "ls\n";
String responseString = SshdDemo.listFolderStructure(username, password, host, port, defaultTimeoutSeconds, command);
assertNull(responseString);
}
}

View File

@ -0,0 +1,35 @@
package com.baeldung.ssh;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import org.junit.Test;
import com.baeldung.ssh.jsch.JschDemo;
public class JSchLiveTest {
@Test
public void givenValidCredentials_whenConnectionIsEstablished_thenServerReturnsResponse() throws Exception {
String username = "demo";
String password = "password";
String host = "test.rebex.net";
int port = 22;
String command = "ls";
String responseString = JschDemo.listFolderStructure(username, password, host, port, command);
assertNotNull(responseString);
}
@Test(expected = Exception.class)
public void givenInvalidCredentials_whenConnectionAttemptIsMade_thenServerReturnsErrorResponse() throws Exception {
String username = "invalidUsername";
String password = "password";
String host = "test.rebex.net";
int port = 22;
String command = "ls";
String responseString = JschDemo.listFolderStructure(username, password, host, port, command);
assertNull(responseString);
}
}

View File

View File

@ -1,8 +1,6 @@
### Relevant Articles: ### Relevant Articles:
- TBD
- [Improved Java Logging with Mapped Diagnostic Context (MDC)](https://www.baeldung.com/mdc-in-log4j-2-logback) - [Improved Java Logging with Mapped Diagnostic Context (MDC)](https://www.baeldung.com/mdc-in-log4j-2-logback)
- [Java Logging with Nested Diagnostic Context (NDC)](https://www.baeldung.com/java-logging-ndc-log4j) - [Java Logging with Nested Diagnostic Context (NDC)](https://www.baeldung.com/java-logging-ndc-log4j)
- [Drools Using Rules from Excel Files](https://www.baeldung.com/drools-excel)
### References ### References

View File

@ -10,9 +10,9 @@
<parent> <parent>
<groupId>com.baeldung</groupId> <groupId>com.baeldung</groupId>
<artifactId>parent-spring-4</artifactId> <artifactId>parent-spring-5</artifactId>
<version>0.0.1-SNAPSHOT</version> <version>0.0.1-SNAPSHOT</version>
<relativePath>../../parent-spring-4</relativePath> <relativePath>../../parent-spring-5</relativePath>
</parent> </parent>
<dependencies> <dependencies>

View File

@ -27,6 +27,7 @@
<groupId>org.apache.derby</groupId> <groupId>org.apache.derby</groupId>
<artifactId>derby</artifactId> <artifactId>derby</artifactId>
<version>${version.derby}</version> <version>${version.derby}</version>
<scope>provided</scope>
</dependency> </dependency>
<!-- For tests --> <!-- For tests -->
@ -70,27 +71,16 @@
<groupId>io.openliberty.tools</groupId> <groupId>io.openliberty.tools</groupId>
<artifactId>liberty-maven-plugin</artifactId> <artifactId>liberty-maven-plugin</artifactId>
<version>${version.liberty-maven-plugin}</version> <version>${version.liberty-maven-plugin}</version>
</plugin> <configuration>
<plugin> <copyDependencies>
<groupId>org.apache.maven.plugins</groupId> <location>${project.build.directory}/liberty/wlp/usr/shared/resources/</location>
<artifactId>maven-dependency-plugin</artifactId> <dependency>
<version>${version.maven-dependency-plugin}</version> <groupId>org.apache.derby</groupId>
<executions> <artifactId>derby</artifactId>
<execution> <version>${version.derby}</version>
<id>copy-derby-dependency</id> </dependency>
<phase>package</phase> </copyDependencies>
<goals> </configuration>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<includeArtifactIds>derby</includeArtifactIds>
<outputDirectory>${project.build.directory}/liberty/wlp/usr/shared/resources/</outputDirectory>
<systemPropertyVariables>
<liberty.test.port>${testServerHttpPort}</liberty.test.port>
</systemPropertyVariables>
</configuration>
</execution>
</executions>
</plugin> </plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
@ -112,8 +102,7 @@
<version.jakarta.jakartaee-web-api>8.0.0</version.jakarta.jakartaee-web-api> <version.jakarta.jakartaee-web-api>8.0.0</version.jakarta.jakartaee-web-api>
<version.microprofile>3.2</version.microprofile> <version.microprofile>3.2</version.microprofile>
<version.derby>10.14.2.0</version.derby> <version.derby>10.14.2.0</version.derby>
<version.liberty-maven-plugin>3.1</version.liberty-maven-plugin> <version.liberty-maven-plugin>3.3-M3</version.liberty-maven-plugin>
<version.maven-dependency-plugin>2.10</version.maven-dependency-plugin>
<version.maven-war-plugin>3.2.3</version.maven-war-plugin> <version.maven-war-plugin>3.2.3</version.maven-war-plugin>
<version.junit>4.12</version.junit> <version.junit>4.12</version.junit>
<version.yasson>1.0.5</version.yasson> <version.yasson>1.0.5</version.yasson>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="15 seconds" debug="false">
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>[%d{ISO8601}]-[%thread] %-5level %logger - %msg%n</pattern>
</encoder>
</appender>
<root level="WARN">
<appender-ref ref="STDOUT" />
</root>
</configuration>

View File

@ -44,7 +44,7 @@ public class EqualByBusinessKey {
return false; return false;
} }
if (obj instanceof EqualByBusinessKey) { if (obj instanceof EqualByBusinessKey) {
if (((EqualByBusinessKey) obj).getEmail() == getEmail()) { if (((EqualByBusinessKey) obj).getEmail().equals(getEmail())) {
return true; return true;
} }
} }

View File

@ -5,6 +5,6 @@ hibernate.connection.autocommit=true
jdbc.password= jdbc.password=
hibernate.dialect=org.hibernate.dialect.H2Dialect hibernate.dialect=org.hibernate.dialect.H2Dialect
hibernate.show_sql=true hibernate.show_sql=false
hibernate.hbm2ddl.auto=create-drop hibernate.hbm2ddl.auto=create-drop

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="15 seconds" debug="false">
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>[%d{ISO8601}]-[%thread] %-5level %logger - %msg%n</pattern>
</encoder>
</appender>
<root level="WARN">
<appender-ref ref="STDOUT" />
</root>
</configuration>

View File

@ -1,14 +1,9 @@
package com.baeldung.manytomany.model; package com.baeldung.manytomany.model;
import javax.persistence.*;
import java.util.HashSet;
import java.util.Set; import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;
import javax.persistence.Table;
@Entity @Entity
@Table(name = "course") @Table(name = "course")
public class Course { public class Course {
@ -18,31 +13,55 @@ public class Course {
private Long id; private Long id;
@ManyToMany(mappedBy = "likedCourses") @ManyToMany(mappedBy = "likedCourses")
private Set<Student> likes; private Set<Student> likes = new HashSet<>();
@OneToMany(mappedBy = "course") @OneToMany(mappedBy = "course")
private Set<CourseRating> ratings; private Set<CourseRating> ratings = new HashSet<>();
@OneToMany(mappedBy = "course") @OneToMany(mappedBy = "course")
private Set<CourseRegistration> registrations; private Set<CourseRegistration> registrations = new HashSet<>();
// additional properties // additional properties
public Course() { public Course() {
} }
public Course(Long id) {
this.id = id;
}
public Long getId() { public Long getId() {
return id; return id;
} }
public void setId(Long id) {
this.id = id;
}
public Set<Student> getLikes() {
return likes;
}
public void setLikes(Set<Student> likes) {
this.likes = likes;
}
public Set<CourseRating> getRatings() { public Set<CourseRating> getRatings() {
return ratings; return ratings;
} }
public void setRatings(Set<CourseRating> ratings) {
this.ratings = ratings;
}
public Set<CourseRegistration> getRegistrations() { public Set<CourseRegistration> getRegistrations() {
return registrations; return registrations;
} }
public void setRegistrations(Set<CourseRegistration> registrations) {
this.registrations = registrations;
}
@Override @Override
public int hashCode() { public int hashCode() {
final int prime = 31; final int prime = 31;

View File

@ -1,12 +1,6 @@
package com.baeldung.manytomany.model; package com.baeldung.manytomany.model;
import javax.persistence.Column; import javax.persistence.*;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.MapsId;
import javax.persistence.Table;
@Entity @Entity
@Table(name = "course_rating") @Table(name = "course_rating")
@ -16,12 +10,12 @@ public class CourseRating {
private CourseRatingKey id; private CourseRatingKey id;
@ManyToOne @ManyToOne
@MapsId("student_id") @MapsId("studentId")
@JoinColumn(name = "student_id") @JoinColumn(name = "student_id")
private Student student; private Student student;
@ManyToOne @ManyToOne
@MapsId("course_id") @MapsId("courseId")
@JoinColumn(name = "course_id") @JoinColumn(name = "course_id")
private Course course; private Course course;
@ -31,26 +25,38 @@ public class CourseRating {
public CourseRating() { public CourseRating() {
} }
public int getRating() {
return rating;
}
public void setRating(int rating) {
this.rating = rating;
}
public CourseRatingKey getId() { public CourseRatingKey getId() {
return id; return id;
} }
public void setId(CourseRatingKey id) {
this.id = id;
}
public Student getStudent() { public Student getStudent() {
return student; return student;
} }
public void setStudent(Student student) {
this.student = student;
}
public Course getCourse() { public Course getCourse() {
return course; return course;
} }
public void setCourse(Course course) {
this.course = course;
}
public int getRating() {
return rating;
}
public void setRating(int rating) {
this.rating = rating;
}
@Override @Override
public int hashCode() { public int hashCode() {
final int prime = 31; final int prime = 31;

View File

@ -1,9 +1,8 @@
package com.baeldung.manytomany.model; package com.baeldung.manytomany.model;
import java.io.Serializable;
import javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.Embeddable; import javax.persistence.Embeddable;
import java.io.Serializable;
@Embeddable @Embeddable
public class CourseRatingKey implements Serializable { public class CourseRatingKey implements Serializable {
@ -17,14 +16,27 @@ public class CourseRatingKey implements Serializable {
public CourseRatingKey() { public CourseRatingKey() {
} }
public CourseRatingKey(Long studentId, Long courseId) {
this.studentId = studentId;
this.courseId = courseId;
}
public Long getStudentId() { public Long getStudentId() {
return studentId; return studentId;
} }
public void setStudentId(Long studentId) {
this.studentId = studentId;
}
public Long getCourseId() { public Long getCourseId() {
return courseId; return courseId;
} }
public void setCourseId(Long courseId) {
this.courseId = courseId;
}
@Override @Override
public int hashCode() { public int hashCode() {
final int prime = 31; final int prime = 31;

View File

@ -1,14 +1,8 @@
package com.baeldung.manytomany.model; package com.baeldung.manytomany.model;
import javax.persistence.*;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
@Entity @Entity
@Table(name = "course_registration") @Table(name = "course_registration")
public class CourseRegistration { public class CourseRegistration {
@ -36,6 +30,14 @@ public class CourseRegistration {
public CourseRegistration() { public CourseRegistration() {
} }
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Student getStudent() { public Student getStudent() {
return student; return student;
} }
@ -68,10 +70,6 @@ public class CourseRegistration {
this.grade = grade; this.grade = grade;
} }
public Long getId() {
return id;
}
@Override @Override
public int hashCode() { public int hashCode() {
final int prime = 31; final int prime = 31;

View File

@ -1,16 +1,9 @@
package com.baeldung.manytomany.model; package com.baeldung.manytomany.model;
import javax.persistence.*;
import java.util.HashSet;
import java.util.Set; import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;
import javax.persistence.Table;
@Entity @Entity
@Table(name = "student") @Table(name = "student")
public class Student { public class Student {
@ -21,35 +14,55 @@ public class Student {
@ManyToMany @ManyToMany
@JoinTable(name = "course_like", joinColumns = @JoinColumn(name = "student_id"), inverseJoinColumns = @JoinColumn(name = "course_id")) @JoinTable(name = "course_like", joinColumns = @JoinColumn(name = "student_id"), inverseJoinColumns = @JoinColumn(name = "course_id"))
private Set<Course> likedCourses; private Set<Course> likedCourses = new HashSet<>();
@OneToMany(mappedBy = "student") @OneToMany(mappedBy = "student")
private Set<CourseRating> ratings; private Set<CourseRating> ratings = new HashSet<>();
@OneToMany(mappedBy = "student") @OneToMany(mappedBy = "student")
private Set<CourseRegistration> registrations; private Set<CourseRegistration> registrations = new HashSet<>();
// additional properties // additional properties
public Student() { public Student() {
} }
public Student(Long id) {
this.id = id;
}
public Long getId() { public Long getId() {
return id; return id;
} }
public void setId(Long id) {
this.id = id;
}
public Set<Course> getLikedCourses() { public Set<Course> getLikedCourses() {
return likedCourses; return likedCourses;
} }
public void setLikedCourses(Set<Course> likedCourses) {
this.likedCourses = likedCourses;
}
public Set<CourseRating> getRatings() { public Set<CourseRating> getRatings() {
return ratings; return ratings;
} }
public void setRatings(Set<CourseRating> ratings) {
this.ratings = ratings;
}
public Set<CourseRegistration> getRegistrations() { public Set<CourseRegistration> getRegistrations() {
return registrations; return registrations;
} }
public void setRegistrations(Set<CourseRegistration> registrations) {
this.registrations = registrations;
}
@Override @Override
public int hashCode() { public int hashCode() {
final int prime = 31; final int prime = 31;

View File

@ -1,17 +1,27 @@
package com.baeldung.manytomany; package com.baeldung.manytomany;
import javax.persistence.EntityManager; import com.baeldung.manytomany.model.Course;
import javax.persistence.PersistenceContext; import com.baeldung.manytomany.model.CourseRating;
import com.baeldung.manytomany.model.CourseRatingKey;
import com.baeldung.manytomany.model.Student;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.junit.Assert.assertThat;
@RunWith(SpringRunner.class) @RunWith(SpringRunner.class)
@ContextConfiguration(classes = ManyToManyTestConfiguration.class) @ContextConfiguration(classes = ManyToManyTestConfiguration.class)
@DirtiesContext @DirtiesContext
@Transactional
public class ManyToManyIntegrationTest { public class ManyToManyIntegrationTest {
@PersistenceContext @PersistenceContext
@ -21,4 +31,25 @@ public class ManyToManyIntegrationTest {
public void contextStarted() { public void contextStarted() {
} }
@Test
public void whenCourseRatingPersisted_thenCorrect() {
Student student = new Student(101L);
entityManager.persist(student);
Course course = new Course(201L);
entityManager.persist(course);
CourseRating courseRating = new CourseRating();
courseRating.setId(new CourseRatingKey());
courseRating.setStudent(student);
courseRating.setCourse(course);
courseRating.setRating(100);
entityManager.persist(courseRating);
CourseRating persistedCourseRating = entityManager.find(CourseRating.class, new CourseRatingKey(101L, 201L));
assertThat(persistedCourseRating, notNullValue());
assertThat(persistedCourseRating.getStudent().getId(), is(101L));
assertThat(persistedCourseRating.getCourse().getId(), is(201L));
}
} }

View File

@ -1,20 +1,21 @@
package com.baeldung.manytomany; package com.baeldung.manytomany;
import java.util.HashMap;
import java.util.Map;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource; import org.springframework.context.annotation.PropertySource;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.JpaVendorAdapter; import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
@Configuration @Configuration
@PropertySource("manytomany/test.properties") @PropertySource("manytomany/test.properties")
public class ManyToManyTestConfiguration { public class ManyToManyTestConfiguration {
@ -23,8 +24,8 @@ public class ManyToManyTestConfiguration {
public DataSource dataSource() { public DataSource dataSource() {
EmbeddedDatabaseBuilder dbBuilder = new EmbeddedDatabaseBuilder(); EmbeddedDatabaseBuilder dbBuilder = new EmbeddedDatabaseBuilder();
return dbBuilder.setType(EmbeddedDatabaseType.H2) return dbBuilder.setType(EmbeddedDatabaseType.H2)
.addScript("classpath:/manytomany/db.sql") .addScript("classpath:/manytomany/db.sql")
.build(); .build();
} }
@Bean @Bean
@ -44,6 +45,13 @@ public class ManyToManyTestConfiguration {
return result; return result;
} }
@Bean
JpaTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory);
return transactionManager;
}
public JpaVendorAdapter jpaVendorAdapter() { public JpaVendorAdapter jpaVendorAdapter() {
return new HibernateJpaVendorAdapter(); return new HibernateJpaVendorAdapter();
} }

View File

@ -30,9 +30,48 @@
<groupId>io.quarkus</groupId> <groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy</artifactId> <artifactId>quarkus-resteasy</artifactId>
</dependency> </dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-jackson</artifactId>
<version>${quarkus.version}</version>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-orm-panache</artifactId>
<version>${quarkus.version}</version>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-jdbc-h2</artifactId>
<version>${quarkus.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.9</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.6</version>
<scope>provided</scope>
</dependency>
<dependency> <dependency>
<groupId>io.quarkus</groupId> <groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5</artifactId> <artifactId>quarkus-junit5</artifactId>
<version>${quarkus.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5-mockito</artifactId>
<version>${quarkus.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-test-h2</artifactId>
<version>${quarkus.version}</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
@ -117,7 +156,8 @@
<properties> <properties>
<surefire-plugin.version>2.22.0</surefire-plugin.version> <surefire-plugin.version>2.22.0</surefire-plugin.version>
<quarkus.version>0.15.0</quarkus.version> <quarkus.version>1.7.0.Final</quarkus.version>
<junit-jupiter.version>5.6.0</junit-jupiter.version>
</properties> </properties>
</project> </project>

View File

@ -0,0 +1,25 @@
package com.baeldung.quarkus;
import com.baeldung.quarkus.model.Book;
import com.baeldung.quarkus.service.LibraryService;
import javax.inject.Inject;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import java.util.Set;
@Path("/library")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class LibraryResource {
@Inject
LibraryService libraryService;
@GET
@Path("/book")
public Set<Book> findBooks(@QueryParam("query") String query) {
return libraryService.find(query);
}
}

View File

@ -0,0 +1,17 @@
package com.baeldung.quarkus.model;
import io.quarkus.hibernate.orm.panache.PanacheEntity;
import lombok.*;
import javax.persistence.Entity;
@Data
@Entity
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Book extends PanacheEntity {
private String title;
private String author;
}

View File

@ -0,0 +1,18 @@
package com.baeldung.quarkus.repository;
import com.baeldung.quarkus.model.Book;
import io.quarkus.hibernate.orm.panache.PanacheRepository;
import javax.enterprise.context.ApplicationScoped;
import java.util.stream.Stream;
import static io.quarkus.panache.common.Parameters.with;
@ApplicationScoped
public class BookRepository implements PanacheRepository<Book> {
public Stream<Book> findBy(String query) {
return find("author like :query or title like :query", with("query", "%"+query+"%")).stream();
}
}

View File

@ -0,0 +1,28 @@
package com.baeldung.quarkus.service;
import com.baeldung.quarkus.model.Book;
import com.baeldung.quarkus.repository.BookRepository;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import javax.transaction.Transactional;
import java.util.Set;
import static java.util.stream.Collectors.toSet;
@Transactional
@ApplicationScoped
public class LibraryService {
@Inject
BookRepository bookRepository;
public Set<Book> find(String query) {
if (query == null) {
return bookRepository.findAll().stream().collect(toSet());
}
return bookRepository.findBy(query).collect(toSet());
}
}

View File

@ -1,3 +1,12 @@
# Configuration file # Configuration file
# key = value # key = value
greeting=Good morning greeting=Good morning
quarkus.datasource.db-kind = h2
quarkus.datasource.jdbc.url = jdbc:h2:tcp://localhost/mem:test
quarkus.hibernate-orm.database.generation = drop-and-create
%custom-profile.quarkus.datasource.jdbc.url = jdbc:h2:file:./testdb
quarkus.http.test-port=0

View File

@ -0,0 +1,27 @@
package com.baeldung.quarkus;
import com.baeldung.quarkus.utils.CustomTestProfile;
import io.quarkus.test.junit.QuarkusTest;
import io.quarkus.test.junit.TestProfile;
import io.restassured.http.ContentType;
import org.junit.jupiter.api.Test;
import static io.restassured.RestAssured.given;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.Matchers.hasItems;
@QuarkusTest
@TestProfile(CustomTestProfile.class)
class CustomLibraryResourceManualTest {
public static final String BOOKSTORE_ENDPOINT = "/custom/library/book";
@Test
void whenGetBooksGivenNoQuery_thenAllBooksShouldBeReturned() {
given().contentType(ContentType.JSON)
.when().get(BOOKSTORE_ENDPOINT)
.then().statusCode(200)
.body("size()", is(2))
.body("title", hasItems("Foundation", "Dune"));
}
}

View File

@ -0,0 +1,21 @@
package com.baeldung.quarkus;
import io.quarkus.test.common.http.TestHTTPEndpoint;
import io.quarkus.test.junit.QuarkusTest;
import io.restassured.http.ContentType;
import org.junit.jupiter.api.Test;
import static io.restassured.RestAssured.given;
@QuarkusTest
@TestHTTPEndpoint(LibraryResource.class)
class LibraryHttpEndpointIntegrationTest {
@Test
void whenGetBooks_thenShouldReturnSuccessfully() {
given().contentType(ContentType.JSON)
.when().get("book")
.then().statusCode(200);
}
}

View File

@ -0,0 +1,40 @@
package com.baeldung.quarkus;
import io.quarkus.test.common.http.TestHTTPEndpoint;
import io.quarkus.test.common.http.TestHTTPResource;
import io.quarkus.test.junit.QuarkusTest;
import io.restassured.http.ContentType;
import org.apache.commons.io.IOUtils;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.net.URL;
import static io.restassured.RestAssured.given;
import static java.nio.charset.Charset.defaultCharset;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.Matchers.hasItem;
import static org.junit.jupiter.api.Assertions.assertTrue;
@QuarkusTest
class LibraryResourceHttpResourceIntegrationTest {
@TestHTTPEndpoint(LibraryResource.class)
@TestHTTPResource("book")
URL libraryEndpoint;
@Test
void whenGetBooksByTitle_thenBookShouldBeFound() {
given().contentType(ContentType.JSON).param("query", "Dune")
.when().get(libraryEndpoint)
.then().statusCode(200)
.body("size()", is(1))
.body("title", hasItem("Dune"))
.body("author", hasItem("Frank Herbert"));
}
@Test
void whenGetBooks_thenBooksShouldBeFound() throws IOException {
assertTrue(IOUtils.toString(libraryEndpoint.openStream(), defaultCharset()).contains("Asimov"));
}
}

View File

@ -0,0 +1,27 @@
package com.baeldung.quarkus;
import com.baeldung.quarkus.service.LibraryService;
import io.quarkus.test.junit.QuarkusTest;
import io.quarkus.test.junit.mockito.InjectSpy;
import io.restassured.http.ContentType;
import org.junit.jupiter.api.Test;
import static io.restassured.RestAssured.given;
import static org.mockito.Mockito.verify;
@QuarkusTest
class LibraryResourceInjectSpyIntegrationTest {
@InjectSpy
LibraryService libraryService;
@Test
void whenGetBooksByAuthor_thenBookShouldBeFound() {
given().contentType(ContentType.JSON).param("query", "Asimov")
.when().get("/library/book")
.then().statusCode(200);
verify(libraryService).find("Asimov");
}
}

View File

@ -0,0 +1,24 @@
package com.baeldung.quarkus;
import io.quarkus.test.junit.QuarkusTest;
import io.restassured.http.ContentType;
import org.junit.jupiter.api.Test;
import static io.restassured.RestAssured.given;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.Matchers.hasItem;
@QuarkusTest
class LibraryResourceIntegrationTest {
@Test
void whenGetBooksByTitle_thenBookShouldBeFound() {
given().contentType(ContentType.JSON).param("query", "Dune")
.when().get("/library/book")
.then().statusCode(200)
.body("size()", is(1))
.body("title", hasItem("Dune"))
.body("author", hasItem("Frank Herbert"));
}
}

View File

@ -1,8 +1,11 @@
package com.baeldung.quarkus; package com.baeldung.quarkus;
import io.quarkus.test.junit.SubstrateTest; import io.quarkus.test.common.QuarkusTestResource;
import io.quarkus.test.h2.H2DatabaseTestResource;
import io.quarkus.test.junit.NativeImageTest;
@SubstrateTest @NativeImageTest
@QuarkusTestResource(H2DatabaseTestResource.class)
public class NativeHelloResourceIT extends HelloResourceUnitTest { public class NativeHelloResourceIT extends HelloResourceUnitTest {
// Execute the same tests but in native mode. // Execute the same tests but in native mode.

View File

@ -0,0 +1,10 @@
package com.baeldung.quarkus;
import io.quarkus.test.common.QuarkusTestResource;
import io.quarkus.test.h2.H2DatabaseTestResource;
import io.quarkus.test.junit.NativeImageTest;
@NativeImageTest
@QuarkusTestResource(H2DatabaseTestResource.class)
class NativeLibraryResourceIT extends LibraryHttpEndpointIntegrationTest {
}

View File

@ -0,0 +1,20 @@
package com.baeldung.quarkus.repository;
import com.baeldung.quarkus.utils.QuarkusTransactionalTest;
import org.junit.jupiter.api.Test;
import javax.inject.Inject;
import static org.junit.jupiter.api.Assertions.assertTrue;
@QuarkusTransactionalTest
class BookRepositoryIntegrationTest {
@Inject
BookRepository bookRepository;
@Test
void givenBookInRepository_whenFindByAuthor_thenShouldReturnBookFromRepository() {
assertTrue(bookRepository.findBy("Herbert").findAny().isPresent());
}
}

View File

@ -0,0 +1,38 @@
package com.baeldung.quarkus.service;
import com.baeldung.quarkus.model.Book;
import com.baeldung.quarkus.repository.BookRepository;
import io.quarkus.test.junit.QuarkusTest;
import io.quarkus.test.junit.mockito.InjectMock;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import javax.inject.Inject;
import java.util.Arrays;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.when;
@QuarkusTest
class LibraryServiceInjectMockUnitTest {
@Inject
LibraryService libraryService;
@InjectMock
BookRepository bookRepository;
@BeforeEach
void setUp() {
when(bookRepository.findBy("Frank Herbert"))
.thenReturn(Arrays.stream(new Book[] {
new Book("Dune", "Frank Herbert"),
new Book("Children of Dune", "Frank Herbert")}));
}
@Test
void whenFindByAuthor_thenBooksShouldBeFound() {
assertEquals(2, libraryService.find("Frank Herbert").size());
}
}

View File

@ -0,0 +1,21 @@
package com.baeldung.quarkus.service;
import io.quarkus.test.junit.QuarkusTest;
import org.junit.jupiter.api.Test;
import javax.inject.Inject;
import static org.junit.jupiter.api.Assertions.assertFalse;
@QuarkusTest
class LibraryServiceIntegrationTest {
@Inject
LibraryService libraryService;
@Test
void whenFindByAuthor_thenBookShouldBeFound() {
assertFalse(libraryService.find("Frank Herbert").isEmpty());
}
}

View File

@ -0,0 +1,38 @@
package com.baeldung.quarkus.service;
import com.baeldung.quarkus.model.Book;
import com.baeldung.quarkus.repository.BookRepository;
import com.baeldung.quarkus.utils.TestBookRepository;
import io.quarkus.test.junit.QuarkusMock;
import io.quarkus.test.junit.QuarkusTest;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import javax.inject.Inject;
import java.util.Arrays;
import static org.junit.jupiter.api.Assertions.assertEquals;
@QuarkusTest
class LibraryServiceQuarkusMockUnitTest {
@Inject
LibraryService libraryService;
@BeforeEach
void setUp() {
BookRepository mock = Mockito.mock(TestBookRepository.class);
Mockito.when(mock.findBy("Asimov"))
.thenReturn(Arrays.stream(new Book[] {
new Book("Foundation", "Isaac Asimov"),
new Book("I Robot", "Isaac Asimov")}));
QuarkusMock.installMockForType(mock, BookRepository.class);
}
@Test
void whenFindByAuthor_thenBooksShouldBeFound() {
assertEquals(2, libraryService.find("Asimov").size());
}
}

View File

@ -0,0 +1,26 @@
package com.baeldung.quarkus.utils;
import io.quarkus.test.junit.QuarkusTestProfile;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
public class CustomTestProfile implements QuarkusTestProfile {
@Override
public Map<String, String> getConfigOverrides() {
return Collections.singletonMap("quarkus.resteasy.path", "/custom");
}
@Override
public Set<Class<?>> getEnabledAlternatives() {
return Collections.singleton(TestBookRepository.class);
}
@Override
public String getConfigProfile() {
return "custom-profile";
}
}

View File

@ -0,0 +1,18 @@
package com.baeldung.quarkus.utils;
import io.quarkus.test.junit.QuarkusTest;
import javax.enterprise.inject.Stereotype;
import javax.transaction.Transactional;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@QuarkusTest
@Stereotype
@Transactional
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface QuarkusTransactionalTest {
}

View File

@ -0,0 +1,22 @@
package com.baeldung.quarkus.utils;
import com.baeldung.quarkus.model.Book;
import com.baeldung.quarkus.repository.BookRepository;
import javax.annotation.PostConstruct;
import javax.annotation.Priority;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.Alternative;
@Priority(1)
@Alternative
@ApplicationScoped
public class TestBookRepository extends BookRepository {
@PostConstruct
public void init() {
persist(new Book("Dune", "Frank Herbert"),
new Book("Foundation", "Isaac Asimov"));
}
}

View File

@ -34,7 +34,7 @@
</dependencies> </dependencies>
<properties> <properties>
<reactor.version>3.2.6.RELEASE</reactor.version> <reactor.version>3.3.9.RELEASE</reactor.version>
<assertj.version>3.6.1</assertj.version> <assertj.version>3.6.1</assertj.version>
</properties> </properties>

View File

@ -1,4 +1,4 @@
package com.baeldung.reactor; package com.baeldung.reactor.introduction;
import org.junit.Test; import org.junit.Test;
import org.reactivestreams.Subscriber; import org.reactivestreams.Subscriber;
@ -15,7 +15,7 @@ import static org.assertj.core.api.Assertions.assertThat;
public class ReactorIntegrationTest { public class ReactorIntegrationTest {
@Test @Test
public void givenFlux_whenSubscribing_thenStream() throws InterruptedException { public void givenFlux_whenSubscribing_thenStream() {
List<Integer> elements = new ArrayList<>(); List<Integer> elements = new ArrayList<>();
@ -48,14 +48,12 @@ public class ReactorIntegrationTest {
} }
@Test @Test
public void givenFlux_whenApplyingBackPressure_thenPushElementsInBatches() throws InterruptedException { public void givenFlux_whenApplyingBackPressure_thenPushElementsInBatches() {
List<Integer> elements = new ArrayList<>(); List<Integer> elements = new ArrayList<>();
Flux.just(1, 2, 3, 4) Flux.just(1, 2, 3, 4)
.log() .log()
.map(i -> i * 2)
.onBackpressureBuffer()
.subscribe(new Subscriber<Integer>() { .subscribe(new Subscriber<Integer>() {
private Subscription s; private Subscription s;
int onNextAmount; int onNextAmount;
@ -81,11 +79,10 @@ public class ReactorIntegrationTest {
@Override @Override
public void onComplete() { public void onComplete() {
int ham = 2;
} }
}); });
assertThat(elements).containsExactly(2, 4, 6, 8); assertThat(elements).containsExactly(1, 2, 3, 4);
} }
@Test @Test

View File

@ -8,6 +8,7 @@
<packaging>jar</packaging> <packaging>jar</packaging>
<parent> <parent>
<!-- this module uses legacy Spring features, so can't upgrade to boot-2 -->
<groupId>com.baeldung</groupId> <groupId>com.baeldung</groupId>
<artifactId>parent-boot-1</artifactId> <artifactId>parent-boot-1</artifactId>
<version>0.0.1-SNAPSHOT</version> <version>0.0.1-SNAPSHOT</version>

View File

@ -8,6 +8,7 @@
<description>Demo project for Spring Boot</description> <description>Demo project for Spring Boot</description>
<parent> <parent>
<!-- This module uses Activiti version 6.0.0 with support for Spring Boot 1. Upgrade to Boot 2 should be clubbed with upgrade to Activiti 7 -->
<groupId>com.baeldung</groupId> <groupId>com.baeldung</groupId>
<artifactId>parent-boot-1</artifactId> <artifactId>parent-boot-1</artifactId>
<version>0.0.1-SNAPSHOT</version> <version>0.0.1-SNAPSHOT</version>

View File

@ -61,6 +61,7 @@
<module>spring-boot-runtime</module> <module>spring-boot-runtime</module>
<module>spring-boot-security</module> <module>spring-boot-security</module>
<module>spring-boot-springdoc</module> <module>spring-boot-springdoc</module>
<module>spring-boot-swagger</module>
<module>spring-boot-testing</module> <module>spring-boot-testing</module>
<module>spring-boot-vue</module> <module>spring-boot-vue</module>
<module>spring-boot-xml</module> <module>spring-boot-xml</module>

View File

@ -7,6 +7,7 @@
<description>Module for Spring Boot version 1.x</description> <description>Module for Spring Boot version 1.x</description>
<parent> <parent>
<!-- This module contains article about Spring Boot Actuator in Spring Boot version 1.x -->
<groupId>com.baeldung</groupId> <groupId>com.baeldung</groupId>
<artifactId>parent-boot-1</artifactId> <artifactId>parent-boot-1</artifactId>
<version>0.0.1-SNAPSHOT</version> <version>0.0.1-SNAPSHOT</version>

View File

@ -8,3 +8,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring
### Relevant Articles: ### Relevant Articles:
- [Liveness and Readiness Probes in Spring Boot](https://www.baeldung.com/spring-liveness-readiness-probes) - [Liveness and Readiness Probes in Spring Boot](https://www.baeldung.com/spring-liveness-readiness-probes)
- [Custom Information in Spring Boot Info Endpoint](https://www.baeldung.com/spring-boot-info-actuator-custom)

View File

@ -24,6 +24,14 @@
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId> <artifactId>spring-boot-starter-web</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>

View File

@ -0,0 +1,13 @@
package com.baeldung.endpoints.info;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

View File

@ -3,7 +3,6 @@ package com.baeldung.endpoints.info;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import com.baeldung.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.info.Info; import org.springframework.boot.actuate.info.Info;
import org.springframework.boot.actuate.info.InfoContributor; import org.springframework.boot.actuate.info.InfoContributor;

View File

@ -0,0 +1,49 @@
package com.baeldung.endpoints.info;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue
private Integer id;
private String name;
private Integer status;
public User() {
}
public User(String name, Integer status) {
this.name = name;
this.status = status;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
}

View File

@ -0,0 +1,78 @@
package com.baeldung.endpoints.info;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Repository;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
@Repository("userRepository")
public interface UserRepository extends JpaRepository<User, Integer> {
int countByStatus(int status);
Optional<User> findOneByName(String name);
@Async
CompletableFuture<User> findOneByStatus(Integer status);
@Query("SELECT u FROM User u WHERE u.status = 1")
Collection<User> findAllActiveUsers();
@Query(value = "SELECT * FROM USERS u WHERE u.status = 1", nativeQuery = true)
Collection<User> findAllActiveUsersNative();
@Query("SELECT u FROM User u WHERE u.status = ?1")
User findUserByStatus(Integer status);
@Query(value = "SELECT * FROM Users u WHERE u.status = ?1", nativeQuery = true)
User findUserByStatusNative(Integer status);
@Query("SELECT u FROM User u WHERE u.status = ?1 and u.name = ?2")
User findUserByStatusAndName(Integer status, String name);
@Query("SELECT u FROM User u WHERE u.status = :status and u.name = :name")
User findUserByStatusAndNameNamedParams(@Param("status") Integer status, @Param("name") String name);
@Query(value = "SELECT * FROM Users u WHERE u.status = :status AND u.name = :name", nativeQuery = true)
User findUserByStatusAndNameNamedParamsNative(@Param("status") Integer status, @Param("name") String name);
@Query("SELECT u FROM User u WHERE u.status = :status and u.name = :name")
User findUserByUserStatusAndUserName(@Param("status") Integer userStatus, @Param("name") String userName);
@Query("SELECT u FROM User u WHERE u.name like ?1%")
User findUserByNameLike(String name);
@Query("SELECT u FROM User u WHERE u.name like :name%")
User findUserByNameLikeNamedParam(@Param("name") String name);
@Query(value = "SELECT * FROM users u WHERE u.name LIKE ?1%", nativeQuery = true)
User findUserByNameLikeNative(String name);
@Query(value = "SELECT u FROM User u")
List<User> findAllUsers(Sort sort);
@Query(value = "SELECT u FROM User u ORDER BY id")
Page<User> findAllUsersWithPagination(Pageable pageable);
@Query(value = "SELECT * FROM Users ORDER BY id \n-- #pageable\n", countQuery = "SELECT count(*) FROM Users", nativeQuery = true)
Page<User> findAllUsersWithPaginationNative(Pageable pageable);
@Modifying
@Query("update User u set u.status = :status where u.name = :name")
int updateUserSetStatusForName(@Param("status") Integer status, @Param("name") String name);
@Modifying
@Query(value = "UPDATE Users u SET u.status = ? WHERE u.name = ?", nativeQuery = true)
int updateUserSetStatusForNameNative(Integer status, String name);
}

View File

@ -2,4 +2,10 @@ management.health.probes.enabled=true
management.endpoint.health.show-details=always management.endpoint.health.show-details=always
management.endpoint.health.status.http-mapping.down=500 management.endpoint.health.status.http-mapping.down=500
management.endpoint.health.status.http-mapping.out_of_service=503 management.endpoint.health.status.http-mapping.out_of_service=503
management.endpoint.health.status.http-mapping.warning=500 management.endpoint.health.status.http-mapping.warning=500
## Configuring info endpoint
info.app.name=Spring Sample Application
info.app.description=This is my first spring boot application G1
info.app.version=1.0.0
info.java-vendor = ${java.specification.vendor}

View File

@ -0,0 +1,12 @@
package com.baeldung.conditionalonproperty;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class NotificationApplication {
public static void main(String[] args) {
SpringApplication.run(NotificationApplication.class, args);
}
}

View File

@ -0,0 +1,26 @@
package com.baeldung.conditionalonproperty.config;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.baeldung.conditionalonproperty.service.EmailNotification;
import com.baeldung.conditionalonproperty.service.NotificationSender;
import com.baeldung.conditionalonproperty.service.SmsNotification;
@Configuration
public class NotificationConfig {
@Bean(name = "emailNotification")
@ConditionalOnProperty(prefix = "notification", name = "service", havingValue = "email")
public NotificationSender notificationSender() {
return new EmailNotification();
}
@Bean(name = "smsNotification")
@ConditionalOnProperty(prefix = "notification", name = "service", havingValue = "sms")
public NotificationSender notificationSender2() {
return new SmsNotification();
}
}

View File

@ -0,0 +1,10 @@
package com.baeldung.conditionalonproperty.service;
public class EmailNotification implements NotificationSender {
@Override
public String send(String message) {
return "Email Notification: " + message;
}
}

View File

@ -0,0 +1,5 @@
package com.baeldung.conditionalonproperty.service;
public interface NotificationSender {
String send(String message);
}

View File

@ -0,0 +1,10 @@
package com.baeldung.conditionalonproperty.service;
public class SmsNotification implements NotificationSender {
@Override
public String send(String message) {
return "SMS notification: " + message;
}
}

View File

@ -1,2 +1,4 @@
spring.jpa.show-sql=true spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto = update spring.jpa.hibernate.ddl-auto = update
notification.service=email

View File

@ -0,0 +1,27 @@
package com.baeldung.conditionalonproperty;
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import com.baeldung.conditionalonproperty.config.NotificationConfig;
import com.baeldung.conditionalonproperty.service.EmailNotification;
import com.baeldung.conditionalonproperty.service.NotificationSender;
public class NotificationUnitTest {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner();
@Test
public void whenValueSetToEmail_thenCreateEmailNotification() {
this.contextRunner.withPropertyValues("notification.service=email")
.withUserConfiguration(NotificationConfig.class)
.run(context -> {
assertThat(context).hasBean("emailNotification");
NotificationSender notificationSender = context.getBean(EmailNotification.class);
assertThat(notificationSender.send("Hello From Baeldung!")).isEqualTo("Email Notification: Hello From Baeldung!");
assertThat(context).doesNotHaveBean("smsNotification");
});
}
}

View File

@ -9,9 +9,9 @@
<parent> <parent>
<groupId>com.baeldung</groupId> <groupId>com.baeldung</groupId>
<artifactId>parent-boot-1</artifactId> <artifactId>parent-boot-2</artifactId>
<version>0.0.1-SNAPSHOT</version> <version>0.0.1-SNAPSHOT</version>
<relativePath>../../parent-boot-1</relativePath> <relativePath>../../parent-boot-2</relativePath>
</parent> </parent>
<dependencies> <dependencies>
@ -38,12 +38,10 @@
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId> <artifactId>spring-boot-starter-web</artifactId>
<version>${spring-boot-starter.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId> <artifactId>spring-boot-starter-test</artifactId>
<version>${spring-boot-starter.version}</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
</dependencies> </dependencies>
@ -55,7 +53,6 @@
<plugin> <plugin>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId> <artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot-starter.version}</version>
<executions> <executions>
<execution> <execution>
<goals> <goals>
@ -68,8 +65,7 @@
</build> </build>
<properties> <properties>
<camel.version>2.19.1</camel.version> <camel.version>3.0.0-M4</camel.version>
<spring-boot-starter.version>1.5.4.RELEASE</spring-boot-starter.version>
</properties> </properties>
</project> </project>

View File

@ -12,33 +12,36 @@ import org.apache.camel.model.rest.RestBindingMode;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.aop.AopAutoConfiguration;
import org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration;
import org.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration;
import org.springframework.boot.autoconfigure.websocket.servlet.WebSocketServletAutoConfiguration;
import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.ComponentScan;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@SpringBootApplication @SpringBootApplication(exclude = { WebSocketServletAutoConfiguration.class, AopAutoConfiguration.class, OAuth2ResourceServerAutoConfiguration.class, EmbeddedWebServerFactoryCustomizerAutoConfiguration.class })
@ComponentScan(basePackages="com.baeldung.camel") @ComponentScan(basePackages = "com.baeldung.camel")
public class Application{ public class Application {
@Value("${server.port}") @Value("${server.port}")
String serverPort; String serverPort;
@Value("${baeldung.api.path}") @Value("${baeldung.api.path}")
String contextPath; String contextPath;
public static void main(String[] args) { public static void main(String[] args) {
SpringApplication.run(Application.class, args); SpringApplication.run(Application.class, args);
} }
@Bean @Bean
ServletRegistrationBean servletRegistrationBean() { ServletRegistrationBean servletRegistrationBean() {
ServletRegistrationBean servlet = new ServletRegistrationBean(new CamelHttpTransportServlet(), contextPath+"/*"); ServletRegistrationBean servlet = new ServletRegistrationBean(new CamelHttpTransportServlet(), contextPath + "/*");
servlet.setName("CamelServlet"); servlet.setName("CamelServlet");
return servlet; return servlet;
} }
@Component @Component
class RestApi extends RouteBuilder { class RestApi extends RouteBuilder {
@ -47,7 +50,6 @@ public class Application{
CamelContext context = new DefaultCamelContext(); CamelContext context = new DefaultCamelContext();
// http://localhost:8080/camel/api-doc // http://localhost:8080/camel/api-doc
restConfiguration().contextPath(contextPath) // restConfiguration().contextPath(contextPath) //
.port(serverPort) .port(serverPort)
@ -60,43 +62,43 @@ public class Application{
.component("servlet") .component("servlet")
.bindingMode(RestBindingMode.json) .bindingMode(RestBindingMode.json)
.dataFormatProperty("prettyPrint", "true"); .dataFormatProperty("prettyPrint", "true");
/** /**
The Rest DSL supports automatic binding json/xml contents to/from The Rest DSL supports automatic binding json/xml contents to/from
POJOs using Camels Data Format. POJOs using Camels Data Format.
By default the binding mode is off, meaning there is no automatic By default the binding mode is off, meaning there is no automatic
binding happening for incoming and outgoing messages. binding happening for incoming and outgoing messages.
You may want to use binding if you develop POJOs that maps to You may want to use binding if you develop POJOs that maps to
your REST services request and response types. your REST services request and response types.
*/ */
rest("/api/").description("Teste REST Service") rest("/api/").description("Teste REST Service")
.id("api-route") .id("api-route")
.post("/bean") .post("/bean")
.produces(MediaType.APPLICATION_JSON) .produces(MediaType.APPLICATION_JSON)
.consumes(MediaType.APPLICATION_JSON) .consumes(MediaType.APPLICATION_JSON)
// .get("/hello/{place}") // .get("/hello/{place}")
.bindingMode(RestBindingMode.auto) .bindingMode(RestBindingMode.auto)
.type(MyBean.class) .type(MyBean.class)
.enableCORS(true) .enableCORS(true)
// .outType(OutBean.class) // .outType(OutBean.class)
.to("direct:remoteService"); .to("direct:remoteService");
from("direct:remoteService").routeId("direct-route")
from("direct:remoteService")
.routeId("direct-route")
.tracing() .tracing()
.log(">>> ${body.id}") .log(">>> ${body.id}")
.log(">>> ${body.name}") .log(">>> ${body.name}")
// .transform().simple("blue ${in.body.name}") // .transform().simple("blue ${in.body.name}")
.process(new Processor() { .process(new Processor() {
@Override @Override
public void process(Exchange exchange) throws Exception { public void process(Exchange exchange) throws Exception {
MyBean bodyIn = (MyBean) exchange.getIn().getBody(); MyBean bodyIn = (MyBean) exchange.getIn()
.getBody();
ExampleServices.example(bodyIn); ExampleServices.example(bodyIn);
exchange.getIn().setBody(bodyIn); exchange.getIn()
.setBody(bodyIn);
} }
}) })
.setHeader(Exchange.HTTP_RESPONSE_CODE, constant(201)); .setHeader(Exchange.HTTP_RESPONSE_CODE, constant(201));

View File

@ -12,4 +12,6 @@ management.port=8081
# disable all management enpoints except health # disable all management enpoints except health
endpoints.enabled = true endpoints.enabled = true
endpoints.health.enabled = true endpoints.health.enabled = true
spring.main.allow-bean-definition-overriding=true

View File

@ -9,3 +9,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring
- [Spring Component Scanning](https://www.baeldung.com/spring-component-scanning) - [Spring Component Scanning](https://www.baeldung.com/spring-component-scanning)
- [Spring @ComponentScan Filter Types](https://www.baeldung.com/spring-componentscan-filter-type) - [Spring @ComponentScan Filter Types](https://www.baeldung.com/spring-componentscan-filter-type)
- [How to Get All Spring-Managed Beans?](https://www.baeldung.com/spring-show-all-beans)

View File

@ -27,6 +27,12 @@
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId> <artifactId>spring-boot-starter-web</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId> <artifactId>spring-boot-starter-tomcat</artifactId>

View File

@ -12,3 +12,6 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring
- [Generating Barcodes and QR Codes in Java](https://www.baeldung.com/java-generating-barcodes-qr-codes) - [Generating Barcodes and QR Codes in Java](https://www.baeldung.com/java-generating-barcodes-qr-codes)
- [Rate Limiting a Spring API Using Bucket4j](https://www.baeldung.com/spring-bucket4j) - [Rate Limiting a Spring API Using Bucket4j](https://www.baeldung.com/spring-bucket4j)
- [Spring Boot and Caffeine Cache](https://www.baeldung.com/spring-boot-caffeine-cache) - [Spring Boot and Caffeine Cache](https://www.baeldung.com/spring-boot-caffeine-cache)
- [Spring Boot and Togglz Aspect](https://www.baeldung.com/spring-togglz)
- [Getting Started with GraphQL and Spring Boot](https://www.baeldung.com/spring-graphql)
- [An Introduction to Kong](https://www.baeldung.com/kong)

View File

@ -37,6 +37,36 @@
<artifactId>spring-boot-starter-test</artifactId> <artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<!-- togglez -->
<dependency>
<groupId>org.togglz</groupId>
<artifactId>togglz-spring-boot-starter</artifactId>
<version>${togglz.version}</version>
</dependency>
<dependency>
<groupId>org.togglz</groupId>
<artifactId>togglz-spring-security</artifactId>
<version>${togglz.version}</version>
</dependency>
<!-- graphql -->
<dependency>
<groupId>com.graphql-java</groupId>
<artifactId>graphql-spring-boot-starter</artifactId>
<version>${graphql-spring-boot-starter.version}</version>
</dependency>
<dependency>
<groupId>com.graphql-java</groupId>
<artifactId>graphql-java-tools</artifactId>
<version>${graphql-java-tools.version}</version>
</dependency>
<dependency>
<groupId>com.graphql-java</groupId>
<artifactId>graphiql-spring-boot-starter</artifactId>
<version>${graphql-spring-boot-starter.version}</version>
</dependency>
<!-- Problem Spring Web --> <!-- Problem Spring Web -->
<dependency> <dependency>
@ -216,7 +246,6 @@
<rome.version>1.9.0</rome.version> <rome.version>1.9.0</rome.version>
<chaos.monkey.version>2.0.0</chaos.monkey.version> <chaos.monkey.version>2.0.0</chaos.monkey.version>
<graphql-spring-boot-starter.version>5.0.2</graphql-spring-boot-starter.version> <graphql-spring-boot-starter.version>5.0.2</graphql-spring-boot-starter.version>
<graphiql-spring-boot-starter.version>5.0.2</graphiql-spring-boot-starter.version>
<graphql-java-tools.version>5.2.4</graphql-java-tools.version> <graphql-java-tools.version>5.2.4</graphql-java-tools.version>
<guava.version>18.0</guava.version> <guava.version>18.0</guava.version>
<git-commit-id-plugin.version>2.2.4</git-commit-id-plugin.version> <git-commit-id-plugin.version>2.2.4</git-commit-id-plugin.version>

View File

@ -0,0 +1,18 @@
package com.baeldung.demo;
import com.baeldung.graphql.GraphqlConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Import;
@SpringBootApplication
@Import(GraphqlConfiguration.class)
public class DemoApplication {
public static void main(String[] args) {
System.setProperty("spring.config.name", "demo");
SpringApplication.run(DemoApplication.class, args);
}
}

Some files were not shown because too many files have changed in this diff Show More