Merge branch 'master' of https://github.com/eugenp/tutorials into BAEL-10897
This commit is contained in:
commit
0b7d4a4d64
|
@ -0,0 +1,45 @@
|
|||
package com.baeldung.algorithms.relativelyprime;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
class RelativelyPrime {
|
||||
|
||||
static boolean iterativeRelativelyPrime(int a, int b) {
|
||||
return iterativeGCD(a, b) == 1;
|
||||
}
|
||||
|
||||
static boolean recursiveRelativelyPrime(int a, int b) {
|
||||
return recursiveGCD(a, b) == 1;
|
||||
}
|
||||
|
||||
static boolean bigIntegerRelativelyPrime(int a, int b) {
|
||||
return BigInteger.valueOf(a).gcd(BigInteger.valueOf(b)).equals(BigInteger.ONE);
|
||||
}
|
||||
|
||||
private static int iterativeGCD(int a, int b) {
|
||||
int tmp;
|
||||
while (b != 0) {
|
||||
if (a < b) {
|
||||
tmp = a;
|
||||
a = b;
|
||||
b = tmp;
|
||||
}
|
||||
tmp = b;
|
||||
b = a % b;
|
||||
a = tmp;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
private static int recursiveGCD(int a, int b) {
|
||||
if (b == 0) {
|
||||
return a;
|
||||
}
|
||||
if (a < b) {
|
||||
return recursiveGCD(b, a);
|
||||
}
|
||||
return recursiveGCD(b, a % b);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
package com.baeldung.algorithms.relativelyprime;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static com.baeldung.algorithms.relativelyprime.RelativelyPrime.*;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class RelativelyPrimeUnitTest {
|
||||
|
||||
@Test
|
||||
public void givenNonRelativelyPrimeNumbers_whenCheckingIteratively_shouldReturnFalse() {
|
||||
|
||||
boolean result = iterativeRelativelyPrime(45, 35);
|
||||
assertThat(result).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenRelativelyPrimeNumbers_whenCheckingIteratively_shouldReturnTrue() {
|
||||
|
||||
boolean result = iterativeRelativelyPrime(500, 501);
|
||||
assertThat(result).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenNonRelativelyPrimeNumbers_whenCheckingRecursively_shouldReturnFalse() {
|
||||
|
||||
boolean result = recursiveRelativelyPrime(45, 35);
|
||||
assertThat(result).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenRelativelyPrimeNumbers_whenCheckingRecursively_shouldReturnTrue() {
|
||||
|
||||
boolean result = recursiveRelativelyPrime(500, 501);
|
||||
assertThat(result).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenNonRelativelyPrimeNumbers_whenCheckingUsingBigIntegers_shouldReturnFalse() {
|
||||
|
||||
boolean result = bigIntegerRelativelyPrime(45, 35);
|
||||
assertThat(result).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenRelativelyPrimeNumbers_whenCheckingBigIntegers_shouldReturnTrue() {
|
||||
|
||||
boolean result = bigIntegerRelativelyPrime(500, 501);
|
||||
assertThat(result).isTrue();
|
||||
}
|
||||
}
|
|
@ -9,3 +9,5 @@
|
|||
- [A Quick Guide to Iterating a Map in Groovy](https://www.baeldung.com/groovy-map-iterating)
|
||||
- [An Introduction to Traits in Groovy](https://www.baeldung.com/groovy-traits)
|
||||
- [Lists in Groovy](https://www.baeldung.com/groovy-lists)
|
||||
- [Converting a String to a Date in Groovy](https://www.baeldung.com/groovy-string-to-date)
|
||||
- [Guide to I/O in Groovy](https://www.baeldung.com/groovy-io)
|
||||
|
|
|
@ -5,3 +5,4 @@
|
|||
- [Java 11 String API Additions](https://www.baeldung.com/java-11-string-api)
|
||||
- [Java 11 Nest Based Access Control](https://www.baeldung.com/java-nest-based-access-control)
|
||||
- [Exploring the New HTTP Client in Java 9 and 11](https://www.baeldung.com/java-9-http-client)
|
||||
- [An Introduction to Epsilon GC: A No-Op Experimental Garbage Collector](https://www.baeldung.com/jvm-epsilon-gc-garbage-collector)
|
||||
|
|
|
@ -27,3 +27,6 @@
|
|||
- [Immutable Set in Java](https://www.baeldung.com/java-immutable-set)
|
||||
- [Multi-Release Jar Files](https://www.baeldung.com/java-multi-release-jar)
|
||||
- [Ahead of Time Compilation (AoT)](https://www.baeldung.com/ahead-of-time-compilation)
|
||||
- [Java 9 Process API Improvements](https://www.baeldung.com/java-9-process-api)
|
||||
- [Guide to java.lang.Process API](https://www.baeldung.com/java-process-api)
|
||||
|
||||
|
|
|
@ -33,3 +33,4 @@
|
|||
- [Differences Between HashMap and Hashtable](https://www.baeldung.com/hashmap-hashtable-differences)
|
||||
- [Java ArrayList vs Vector](https://www.baeldung.com/java-arraylist-vs-vector)
|
||||
- [Defining a Char Stack in Java](https://www.baeldung.com/java-char-stack)
|
||||
- [Time Comparison of Arrays.sort(Object[]) and Arrays.sort(int[])](https://www.baeldung.com/arrays-sortobject-vs-sortint)
|
||||
|
|
|
@ -16,3 +16,4 @@
|
|||
- [Life Cycle of a Thread in Java](http://www.baeldung.com/java-thread-lifecycle)
|
||||
- [Runnable vs. Callable in Java](http://www.baeldung.com/java-runnable-callable)
|
||||
- [What is Thread-Safety and How to Achieve it](https://www.baeldung.com/java-thread-safety)
|
||||
- [How to Start a Thread in Java](https://www.baeldung.com/java-start-thread)
|
||||
|
|
|
@ -6,3 +6,5 @@ This module uses Java 9, so make sure to have the JDK 9 installed to run it.
|
|||
### Relevant Articles:
|
||||
- [Java 9 Process API Improvements](http://www.baeldung.com/java-9-process-api)
|
||||
- [Guide to java.lang.Process API](https://www.baeldung.com/java-process-api)
|
||||
- [Guide to java.lang.ProcessBuilder API](https://www.baeldung.com/java-lang-processbuilder-api)
|
||||
|
||||
|
|
|
@ -50,3 +50,4 @@
|
|||
- [Finding Leap Years in Java](https://www.baeldung.com/java-leap-year)
|
||||
- [Java Bitwise Operators](https://www.baeldung.com/java-bitwise-operators)
|
||||
- [Guide to Creating and Running a Jar File in Java](https://www.baeldung.com/java-create-jar)
|
||||
- [Making a JSON POST Request With HttpURLConnection](https://www.baeldung.com/httpurlconnection-post)
|
||||
|
|
|
@ -3,4 +3,4 @@
|
|||
- [Void Type in Kotlin](https://www.baeldung.com/kotlin-void-type)
|
||||
- [How to use Kotlin Range Expressions](https://www.baeldung.com/kotlin-ranges)
|
||||
- [Split a List into Parts in Kotlin](https://www.baeldung.com/kotlin-split-list-into-parts)
|
||||
|
||||
- [String Comparison in Kotlin](https://www.baeldung.com/kotlin-string-comparison)
|
||||
|
|
|
@ -13,4 +13,66 @@
|
|||
<relativePath>../parent-kotlin</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-stdlib-jdk8</artifactId>
|
||||
<version>${kotlin.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.platform</groupId>
|
||||
<artifactId>junit-platform-runner</artifactId>
|
||||
<version>${junit.platform.version}</version>
|
||||
<scope>test</scope>
|
||||
</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>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-maven-plugin</artifactId>
|
||||
<version>${kotlin.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>compile</id>
|
||||
<phase>compile</phase>
|
||||
<goals>
|
||||
<goal>compile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>test-compile</id>
|
||||
<phase>test-compile</phase>
|
||||
<goals>
|
||||
<goal>test-compile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<jvmTarget>1.8</jvmTarget>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<kotlin.version>1.2.71</kotlin.version>
|
||||
<junit.platform.version>1.1.1</junit.platform.version>
|
||||
<junit.vintage.version>5.2.0</junit.vintage.version>
|
||||
<assertj.version>3.10.0</assertj.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,13 @@
|
|||
package com.baeldung.range
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
|
||||
for (ch in 'a'..'f') {
|
||||
print(ch)
|
||||
}
|
||||
println()
|
||||
|
||||
for (ch in 'f' downTo 'a') {
|
||||
print(ch)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package com.baeldung.range
|
||||
|
||||
enum class Color(val rgb: Int) {
|
||||
BLUE(0x0000FF),
|
||||
GREEN(0x008000),
|
||||
RED(0xFF0000),
|
||||
MAGENTA(0xFF00FF),
|
||||
YELLOW(0xFFFF00);
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
|
||||
println(Color.values().toList());
|
||||
val red = Color.RED
|
||||
val yellow = Color.YELLOW
|
||||
val range = red..yellow
|
||||
|
||||
println(range.contains(Color.MAGENTA))
|
||||
println(range.contains(Color.BLUE))
|
||||
println(range.contains(Color.GREEN))
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package com.baeldung.range
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val r = 1..10
|
||||
|
||||
//Apply filter
|
||||
val f = r.filter { it -> it % 2 == 0 }
|
||||
println(f)
|
||||
|
||||
//Map
|
||||
val m = r.map { it -> it * it }
|
||||
println(m)
|
||||
|
||||
//Reduce
|
||||
val rdc = r.reduce { a, b -> a + b }
|
||||
println(rdc)
|
||||
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package com.baeldung.range
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
|
||||
println((1..9).first)
|
||||
println((1..9 step 2).step)
|
||||
println((3..9).reversed().last)
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package com.baeldung.range
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
|
||||
val r = 1..20
|
||||
println(r.min())
|
||||
println(r.max())
|
||||
println(r.sum())
|
||||
println(r.average())
|
||||
println(r.count())
|
||||
|
||||
val repeated = listOf(1, 1, 2, 4, 4, 6, 10)
|
||||
println(repeated.distinct())
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package com.baeldung.range
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
|
||||
for (i in 1..9) {
|
||||
print(i)
|
||||
}
|
||||
println()
|
||||
|
||||
for (i in 9 downTo 1) {
|
||||
print(i)
|
||||
}
|
||||
println()
|
||||
|
||||
for (i in 1.rangeTo(9)) {
|
||||
print(i)
|
||||
}
|
||||
println()
|
||||
|
||||
for (i in 9.downTo(1)) {
|
||||
print(i)
|
||||
}
|
||||
println()
|
||||
|
||||
for (i in 1 until 9) {
|
||||
print(i)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package com.baeldung.range
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
|
||||
(1..9).reversed().forEach {
|
||||
print(it)
|
||||
}
|
||||
|
||||
println()
|
||||
|
||||
(1..9).reversed().step(3).forEach {
|
||||
print(it)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package com.baeldung.range
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
|
||||
for(i in 1..9 step 2){
|
||||
print(i)
|
||||
}
|
||||
|
||||
println()
|
||||
|
||||
for (i in 9 downTo 1 step 2){
|
||||
print(i)
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package com.baeldung.range
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
|
||||
for (i in 1 until 9) {
|
||||
print(i)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package com.baeldung.range
|
||||
|
||||
import org.junit.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class CharRangeTest {
|
||||
|
||||
@Test
|
||||
fun testCharRange() {
|
||||
assertEquals(listOf('a', 'b', 'c'), ('a'..'c').toList())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testCharDownRange() {
|
||||
assertEquals(listOf('c', 'b', 'a'), ('c'.downTo('a')).toList())
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package com.baeldung.range
|
||||
|
||||
import org.junit.Test
|
||||
import kotlin.test.assertFalse
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class ColorTest {
|
||||
|
||||
@Test
|
||||
fun testEnumRange() {
|
||||
|
||||
println(Color.values().toList());
|
||||
val red = Color.RED
|
||||
val yellow = Color.YELLOW
|
||||
val range = red..yellow
|
||||
|
||||
assertTrue { range.contains(Color.MAGENTA) }
|
||||
assertFalse { range.contains(Color.BLUE) }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package com.baeldung.range
|
||||
|
||||
import org.junit.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class FilterTest {
|
||||
|
||||
val r = 1..10
|
||||
|
||||
@Test
|
||||
fun filterTest() {
|
||||
assertEquals(listOf(2, 4, 6, 8, 10), r.filter { it -> it % 2 == 0 }.toList())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun mapTest() {
|
||||
assertEquals(listOf(1, 4, 9, 16, 25, 36, 49, 64, 81, 100), r.map { it -> it * it }.toList())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun reduceTest() {
|
||||
assertEquals(55, r.reduce { a, b -> a + b })
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package com.baeldung.range
|
||||
|
||||
import org.junit.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class FirstLastTest {
|
||||
|
||||
@Test
|
||||
fun testFirst() {
|
||||
assertEquals(1, (1..9).first)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testLast() {
|
||||
assertEquals(9, (1..9).last)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testStep() {
|
||||
assertEquals(2, (1..9 step 2).step)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package com.baeldung.range
|
||||
|
||||
import org.junit.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class OtherRangeFunctionsTest {
|
||||
|
||||
val r = 1..20
|
||||
val repeated = listOf(1, 1, 2, 4, 4, 6, 10)
|
||||
|
||||
@Test
|
||||
fun testMin() {
|
||||
assertEquals(1, r.min())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testMax() {
|
||||
assertEquals(20, r.max())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSum() {
|
||||
assertEquals(210, r.sum())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAverage() {
|
||||
assertEquals(10.5, r.average())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testCount() {
|
||||
assertEquals(20, r.count())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testDistinct() {
|
||||
assertEquals(listOf(1, 2, 4, 6, 10), repeated.distinct())
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package com.baeldung.range
|
||||
|
||||
import org.junit.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class RangeTest {
|
||||
|
||||
@Test
|
||||
fun testRange() {
|
||||
assertEquals(listOf(1,2,3), (1.rangeTo(3).toList()))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testDownTo(){
|
||||
assertEquals(listOf(3,2,1), (3.downTo(1).toList()))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testUntil(){
|
||||
assertEquals(listOf(1,2), (1.until(3).toList()))
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package com.baeldung.range
|
||||
|
||||
import org.junit.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class ReverseRangeTest {
|
||||
|
||||
@Test
|
||||
fun reversedTest() {
|
||||
assertEquals(listOf(9, 6, 3), (1..9).reversed().step(3).toList())
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package com.baeldung.range
|
||||
|
||||
import org.junit.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class StepTest {
|
||||
|
||||
@Test
|
||||
fun testStep() {
|
||||
assertEquals(listOf(1, 3, 5, 7, 9), (1..9 step 2).toList())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testStepDown() {
|
||||
assertEquals(listOf(9, 7, 5, 3, 1), (9 downTo 1 step 2).toList())
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package com.baeldung.range
|
||||
|
||||
import org.junit.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class UntilRangeTest {
|
||||
|
||||
@Test
|
||||
fun testUntil() {
|
||||
assertEquals(listOf(1, 2, 3, 4), (1 until 5).toList())
|
||||
}
|
||||
}
|
|
@ -55,3 +55,4 @@
|
|||
- [Building DSLs in Kotlin](https://www.baeldung.com/kotlin-dsl)
|
||||
- [Static Methods Behavior in Kotlin](https://www.baeldung.com/kotlin-static-methods)
|
||||
- [Inline Functions in Kotlin](https://www.baeldung.com/kotlin-inline-functions)
|
||||
- [Delegation Pattern in Kotlin](https://www.baeldung.com/kotlin-delegation-pattern)
|
||||
|
|
|
@ -12,4 +12,5 @@
|
|||
- [Working with Primitive Values in Gson](https://www.baeldung.com/java-gson-primitives)
|
||||
- [Convert String to JsonObject with Gson](https://www.baeldung.com/gson-string-to-jsonobject)
|
||||
- [Mapping Multiple JSON Fields to One Java Field](https://www.baeldung.com/json-multiple-fields-single-java-field)
|
||||
- [Serializing and Deserializing a List with Gson](https://www.baeldung.com/gson-list)
|
||||
|
||||
|
|
|
@ -6,4 +6,4 @@
|
|||
The "REST With Spring" Classes: http://bit.ly/restwithspring
|
||||
|
||||
### Relevant Articles:
|
||||
- [Mapping Multiple JSON Fields to One Java Field](https://www.baeldung.com/json-multiple-fields-single-java-field)
|
||||
- [Mapping Multiple JSON Fields to a Single Java Field](https://www.baeldung.com/json-multiple-fields-single-java-field)
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
<?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>java-collections-maps-2</artifactId>
|
||||
<version>0.1.0-SNAPSHOT</version>
|
||||
<name>java-collections-maps-2</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-java</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../parent-java</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.collections</groupId>
|
||||
<artifactId>eclipse-collections</artifactId>
|
||||
<version>${eclipse-collections.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.sf.trove4j</groupId>
|
||||
<artifactId>trove4j</artifactId>
|
||||
<version>3.0.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>it.unimi.dsi</groupId>
|
||||
<artifactId>fastutil</artifactId>
|
||||
<version>8.1.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>colt</groupId>
|
||||
<artifactId>colt</artifactId>
|
||||
<version>1.2.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<eclipse-collections.version>8.2.0</eclipse-collections.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,69 @@
|
|||
package com.baeldung.map;
|
||||
|
||||
import cern.colt.map.AbstractIntDoubleMap;
|
||||
import cern.colt.map.OpenIntDoubleHashMap;
|
||||
import gnu.trove.map.TDoubleIntMap;
|
||||
import gnu.trove.map.hash.TDoubleIntHashMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2BooleanMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2BooleanOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2BooleanSortedMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2BooleanSortedMaps;
|
||||
import org.eclipse.collections.api.map.primitive.ImmutableIntIntMap;
|
||||
import org.eclipse.collections.api.map.primitive.MutableIntIntMap;
|
||||
import org.eclipse.collections.api.map.primitive.MutableObjectDoubleMap;
|
||||
import org.eclipse.collections.impl.factory.primitive.IntIntMaps;
|
||||
import org.eclipse.collections.impl.factory.primitive.ObjectDoubleMaps;
|
||||
|
||||
public class PrimitiveMaps {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
eclipseCollectionsMap();
|
||||
troveMap();
|
||||
coltMap();
|
||||
fastutilMap();
|
||||
}
|
||||
|
||||
private static void fastutilMap() {
|
||||
Int2BooleanMap int2BooleanMap = new Int2BooleanOpenHashMap();
|
||||
int2BooleanMap.put(1, true);
|
||||
int2BooleanMap.put(7, false);
|
||||
int2BooleanMap.put(4, true);
|
||||
|
||||
boolean value = int2BooleanMap.get(1);
|
||||
|
||||
Int2BooleanSortedMap int2BooleanSorted = Int2BooleanSortedMaps.EMPTY_MAP;
|
||||
}
|
||||
|
||||
private static void coltMap() {
|
||||
AbstractIntDoubleMap map = new OpenIntDoubleHashMap();
|
||||
map.put(1, 4.5);
|
||||
double value = map.get(1);
|
||||
}
|
||||
|
||||
private static void eclipseCollectionsMap() {
|
||||
MutableIntIntMap mutableIntIntMap = IntIntMaps.mutable.empty();
|
||||
mutableIntIntMap.addToValue(1, 1);
|
||||
|
||||
ImmutableIntIntMap immutableIntIntMap = IntIntMaps.immutable.empty();
|
||||
|
||||
MutableObjectDoubleMap<String> dObject = ObjectDoubleMaps.mutable.empty();
|
||||
dObject.addToValue("price", 150.5);
|
||||
dObject.addToValue("quality", 4.4);
|
||||
dObject.addToValue("stability", 0.8);
|
||||
}
|
||||
|
||||
private static void troveMap() {
|
||||
double[] doubles = new double[] {1.2, 4.5, 0.3};
|
||||
int[] ints = new int[] {1, 4, 0};
|
||||
|
||||
TDoubleIntMap doubleIntMap = new TDoubleIntHashMap(doubles, ints);
|
||||
|
||||
doubleIntMap.put(1.2, 22);
|
||||
doubleIntMap.put(4.5, 16);
|
||||
|
||||
doubleIntMap.adjustValue(1.2, 1);
|
||||
doubleIntMap.adjustValue(4.5, 4);
|
||||
doubleIntMap.adjustValue(0.3, 7);
|
||||
}
|
||||
}
|
|
@ -17,3 +17,4 @@
|
|||
- [Java Stream Filter with Lambda Expression](https://www.baeldung.com/java-stream-filter-lambda)
|
||||
- [Counting Matches on a Stream Filter](https://www.baeldung.com/java-stream-filter-count)
|
||||
- [Java 8 Streams peek() API](https://www.baeldung.com/java-streams-peek-api)
|
||||
- [Working With Maps Using Streams](https://www.baeldung.com/java-maps-streams)
|
||||
|
|
|
@ -6,4 +6,5 @@
|
|||
- [Lombok Builder with Default Value](https://www.baeldung.com/lombok-builder-default-value)
|
||||
- [Lombok Builder with Custom Setter](https://www.baeldung.com/lombok-builder-custom-setter)
|
||||
- [Setting up Lombok with Eclipse and Intellij](https://www.baeldung.com/lombok-ide)
|
||||
- [Using the @Singular Annotation with Lombok Builders](https://www.baeldung.com/lombok-builder-singular)
|
||||
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
package com.baeldung.lombok.builder.singular;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Singular;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
@Getter
|
||||
@Builder
|
||||
public class Person {
|
||||
|
||||
private final String givenName;
|
||||
private final String additionalName;
|
||||
private final String familyName;
|
||||
|
||||
private final List<String> tags;
|
||||
@Singular private final List<String> interests;
|
||||
@Singular private final Set<String> skills;
|
||||
@Singular private final Map<String, LocalDate> awards;
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package com.baeldung.lombok.builder.singular;
|
||||
|
||||
import java.util.List;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Singular;
|
||||
|
||||
@Getter
|
||||
@Builder
|
||||
public class Sea {
|
||||
|
||||
@Singular private final List<String> grasses;
|
||||
@Singular("oneFish") private final List<String> fish;
|
||||
}
|
|
@ -0,0 +1,192 @@
|
|||
package com.baeldung.lombok.builder.singular;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
|
||||
public class BuilderWithSingularSupportForCollectionsUnitTest {
|
||||
|
||||
@Test
|
||||
public void canAddMultipleElementsAsNewCollection() throws Exception {
|
||||
Person person = Person.builder()
|
||||
.givenName("Aaron")
|
||||
.additionalName("A")
|
||||
.familyName("Aardvark")
|
||||
.tags(Arrays.asList("fictional", "incidental"))
|
||||
.build();
|
||||
|
||||
assertThat(person.getTags(), containsInAnyOrder("fictional", "incidental"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void canUpdateCollectionAfterBuildIfMutableCollectionPassedToBuilder() throws Exception {
|
||||
|
||||
List<String> tags = new ArrayList();
|
||||
tags.add("fictional");
|
||||
tags.add("incidental");
|
||||
Person person = Person.builder()
|
||||
.givenName("Aaron")
|
||||
.additionalName("A")
|
||||
.familyName("Aardvark")
|
||||
.tags(tags)
|
||||
.build();
|
||||
person.getTags()
|
||||
.clear();
|
||||
person.getTags()
|
||||
.add("non-fictional");
|
||||
person.getTags()
|
||||
.add("important");
|
||||
|
||||
assertThat(person.getTags(), containsInAnyOrder("non-fictional", "important"));
|
||||
}
|
||||
|
||||
@Test(expected = UnsupportedOperationException.class)
|
||||
public void cannotUpdateCollectionAfterBuildIfImmutableCollectionPassedToBuilder() throws Exception {
|
||||
List<String> tags = Arrays.asList("fictional", "incidental");
|
||||
Person person = Person.builder()
|
||||
.givenName("Aaron")
|
||||
.additionalName("A")
|
||||
.familyName("Aardvark")
|
||||
.tags(tags)
|
||||
.build();
|
||||
person.getTags()
|
||||
.clear();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void canAssignToSingularAnnotatedCollectionOneByOne() throws Exception {
|
||||
|
||||
Person person = Person.builder()
|
||||
.givenName("Aaron")
|
||||
.additionalName("A")
|
||||
.familyName("Aardvark")
|
||||
.interest("history")
|
||||
.interest("sport")
|
||||
.build();
|
||||
|
||||
assertThat(person.getInterests(), containsInAnyOrder("sport", "history"));
|
||||
}
|
||||
|
||||
@Test(expected = UnsupportedOperationException.class)
|
||||
public void singularAnnotatedBuilderCreatesImmutableCollection() throws Exception {
|
||||
|
||||
Person person = Person.builder()
|
||||
.givenName("Aaron")
|
||||
.additionalName("A")
|
||||
.familyName("Aardvark")
|
||||
.interest("history")
|
||||
.interest("sport")
|
||||
.build();
|
||||
person.getInterests()
|
||||
.clear();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void unpopulatedListsCreatedAsNullIfNotSingularButEmptyArrayIfSingular() throws Exception {
|
||||
|
||||
Person person = Person.builder()
|
||||
.givenName("Aaron")
|
||||
.additionalName("A")
|
||||
.familyName("Aardvark")
|
||||
.build();
|
||||
assertThat(person.getInterests(), hasSize(0));
|
||||
assertThat(person.getSkills(), hasSize(0));
|
||||
assertThat(person.getAwards()
|
||||
.keySet(), hasSize(0));
|
||||
assertThat(person.getTags(), is(nullValue()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void singularSupportsSetsToo() throws Exception {
|
||||
|
||||
Person person = Person.builder()
|
||||
.givenName("Aaron")
|
||||
.additionalName("A")
|
||||
.familyName("Aardvark")
|
||||
.skill("singing")
|
||||
.skill("dancing")
|
||||
.build();
|
||||
assertThat(person.getSkills(), contains("singing", "dancing"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void singularSetsAreLenientWithDuplicates() throws Exception {
|
||||
|
||||
Person person = Person.builder()
|
||||
.givenName("Aaron")
|
||||
.additionalName("A")
|
||||
.familyName("Aardvark")
|
||||
.interest("singing")
|
||||
.interest("singing")
|
||||
.skill("singing")
|
||||
.skill("singing")
|
||||
.build();
|
||||
assertThat(person.getInterests(), contains("singing", "singing"));
|
||||
assertThat(person.getSkills(), contains("singing"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void singularSupportsMapsToo() throws Exception {
|
||||
|
||||
Person person = Person.builder()
|
||||
.givenName("Aaron")
|
||||
.additionalName("A")
|
||||
.familyName("Aardvark")
|
||||
.award("Singer of the Year", LocalDate.now()
|
||||
.minusYears(5))
|
||||
.award("Best Dancer", LocalDate.now()
|
||||
.minusYears(2))
|
||||
.build();
|
||||
assertThat(person.getAwards()
|
||||
.keySet(), contains("Singer of the Year", "Best Dancer"));
|
||||
assertThat(person.getAwards()
|
||||
.get("Best Dancer"),
|
||||
is(LocalDate.now()
|
||||
.minusYears(2)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void singularIsLenientWithMapKeys() throws Exception {
|
||||
|
||||
Person person = Person.builder()
|
||||
.givenName("Aaron")
|
||||
.additionalName("A")
|
||||
.familyName("Aardvark")
|
||||
.award("Best Dancer", LocalDate.now()
|
||||
.minusYears(5))
|
||||
.award("Best Dancer", LocalDate.now()
|
||||
.minusYears(4))
|
||||
.award("Best Dancer", LocalDate.now()
|
||||
.minusYears(3))
|
||||
.award("Best Dancer", LocalDate.now()
|
||||
.minusYears(2))
|
||||
.award("Best Dancer", LocalDate.now()
|
||||
.minusYears(1))
|
||||
.build();
|
||||
assertThat(person.getAwards()
|
||||
.keySet(), hasSize(1));
|
||||
assertThat(person.getAwards()
|
||||
.get("Best Dancer"),
|
||||
is(LocalDate.now()
|
||||
.minusYears(1)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void wordsWithNonStandardPlurals() throws Exception {
|
||||
Sea sea = Sea.builder()
|
||||
.grass("Dulse")
|
||||
.grass("Kelp")
|
||||
.oneFish("Cod")
|
||||
.oneFish("Mackerel")
|
||||
.build();
|
||||
assertThat(sea.getGrasses(), contains("Dulse", "Kelp"));
|
||||
assertThat(sea.getFish(), contains("Cod", "Mackerel"));
|
||||
}
|
||||
|
||||
}
|
|
@ -15,3 +15,4 @@
|
|||
- [Use the Latest Version of a Dependency in Maven](https://www.baeldung.com/maven-dependency-latest-version)
|
||||
- [Multi-Module Project with Maven](https://www.baeldung.com/maven-multi-module)
|
||||
- [Maven Enforcer Plugin](https://www.baeldung.com/maven-enforcer-plugin)
|
||||
- [Eclipse Error: web.xml is missing and failOnMissingWebXml is set to true](https://www.baeldung.com/eclipse-error-web-xml-missing)
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
### Relevant Articles:
|
||||
- [A Guide to the Front Controller Pattern in Java](http://www.baeldung.com/java-front-controller-pattern)
|
||||
- [Introduction to Intercepting Filter Pattern in Java](http://www.baeldung.com/intercepting-filter-pattern-in-java)
|
||||
- [Introduction to the Null Object Pattern](https://www.baeldung.com/java-null-object-pattern)
|
||||
|
|
|
@ -7,3 +7,4 @@
|
|||
- [Batch Processing in JDBC](http://www.baeldung.com/jdbc-batch-processing)
|
||||
- [Introduction to the JDBC RowSet Interface in Java](http://www.baeldung.com/java-jdbc-rowset)
|
||||
- [A Simple Guide to Connection Pooling in Java](https://www.baeldung.com/java-connection-pooling)
|
||||
- [Guide to the JDBC ResultSet Interface](https://www.baeldung.com/jdbc-resultset)
|
||||
|
|
|
@ -6,3 +6,4 @@
|
|||
- [JPA Entity Graph](https://www.baeldung.com/jpa-entity-graph)
|
||||
- [JPA 2.2 Support for Java 8 Date/Time Types](https://www.baeldung.com/jpa-java-time)
|
||||
- [Converting Between LocalDate and SQL Date](https://www.baeldung.com/java-convert-localdate-sql-date)
|
||||
- [Combining JPA And/Or Criteria Predicates](https://www.baeldung.com/jpa-and-or-criteria-predicates)
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
# Relevant Articles
|
||||
|
||||
- [Auto-Generated Field for MongoDB using Spring Boot](https://www.baeldung.com/spring-boot-mongodb-auto-generated-field)
|
||||
- [Spring Boot Integration Testing with Embedded MongoDB](http://www.baeldung.com/spring-boot-embedded-mongodb)
|
||||
|
|
|
@ -25,6 +25,11 @@
|
|||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-mongodb</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>de.flapdoodle.embed</groupId>
|
||||
<artifactId>de.flapdoodle.embed.mongo</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<!-- JUnit Jupiter dependencies -->
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
|
|
|
@ -2,7 +2,6 @@ package com.baeldung.mongodb;
|
|||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import org.baeldung.boot.Application;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
|
@ -12,10 +11,11 @@ import org.springframework.data.mongodb.core.MongoTemplate;
|
|||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
|
||||
import com.baeldung.SpringBootPersistenceApplication;
|
||||
import com.mongodb.BasicDBObjectBuilder;
|
||||
import com.mongodb.DBObject;
|
||||
|
||||
@ContextConfiguration(classes = Application.class)
|
||||
@ContextConfiguration(classes = SpringBootPersistenceApplication.class)
|
||||
@DataMongoTest
|
||||
@ExtendWith(SpringExtension.class)
|
||||
public class MongoDbSpringIntegrationTest {
|
|
@ -0,0 +1,48 @@
|
|||
package com.baeldung.exists;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
|
||||
/**
|
||||
* @author paullatzelsperger
|
||||
* @since 2019-03-20
|
||||
*/
|
||||
@Entity
|
||||
public class Car {
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private int id;
|
||||
private Integer power;
|
||||
private String model;
|
||||
|
||||
Car() {
|
||||
|
||||
}
|
||||
|
||||
public Car(int power, String model) {
|
||||
this.power = power;
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
public Integer getPower() {
|
||||
return power;
|
||||
}
|
||||
|
||||
public void setPower(Integer power) {
|
||||
this.power = power;
|
||||
}
|
||||
|
||||
public String getModel() {
|
||||
return model;
|
||||
}
|
||||
|
||||
public void setModel(String model) {
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package com.baeldung.exists;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
/**
|
||||
* @author paullatzelsperger
|
||||
* @since 2019-03-20
|
||||
*/
|
||||
@Repository
|
||||
public interface CarRepository extends JpaRepository<Car, Integer> {
|
||||
|
||||
boolean existsCarByPower(int power);
|
||||
|
||||
boolean existsCarByModel(String model);
|
||||
|
||||
@Query("select case when count(c)> 0 then true else false end from Car c where c.model = :model")
|
||||
boolean existsCarExactCustomQuery(@Param("model") String model);
|
||||
|
||||
@Query("select case when count(c)> 0 then true else false end from Car c where lower(c.model) like lower(:model)")
|
||||
boolean existsCarLikeCustomQuery(@Param("model") String model);
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
package com.baeldung.exists;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.springframework.data.domain.ExampleMatcher.GenericPropertyMatchers.ignoreCase;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.data.domain.Example;
|
||||
import org.springframework.data.domain.ExampleMatcher;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest
|
||||
public class CarRepositoryIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
private CarRepository repository;
|
||||
private int searchId;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
List<Car> cars = repository.saveAll(Arrays.asList(new Car(200, "BMW"), new Car(300, "Audi")));
|
||||
searchId = cars.get(0).getId();
|
||||
}
|
||||
|
||||
@After
|
||||
public void teardown() {
|
||||
repository.deleteAll();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenIdIsCorrect_thenExistsShouldReturnTrue() {
|
||||
assertThat(repository.existsById(searchId)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenExample_whenExists_thenIsTrue() {
|
||||
ExampleMatcher modelMatcher = ExampleMatcher.matching()
|
||||
.withIgnorePaths("id") // must explicitly ignore -> PK
|
||||
.withMatcher("model", ignoreCase());
|
||||
Car probe = new Car();
|
||||
probe.setModel("bmw");
|
||||
|
||||
Example<Car> example = Example.of(probe, modelMatcher);
|
||||
|
||||
assertThat(repository.exists(example)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenPower_whenExists_thenIsFalse() {
|
||||
assertThat(repository.existsCarByPower(200)).isTrue();
|
||||
assertThat(repository.existsCarByPower(800)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void existsByDerivedQuery_byModel() {
|
||||
assertThat(repository.existsCarByModel("Audi")).isTrue();
|
||||
assertThat(repository.existsCarByModel("audi")).isFalse();
|
||||
assertThat(repository.existsCarByModel("AUDI")).isFalse();
|
||||
assertThat(repository.existsCarByModel("")).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenModelName_whenExistsExact_thenIsTrue() {
|
||||
assertThat(repository.existsCarExactCustomQuery("BMW")).isTrue();
|
||||
assertThat(repository.existsCarExactCustomQuery("Bmw")).isFalse();
|
||||
assertThat(repository.existsCarExactCustomQuery("bmw")).isFalse();
|
||||
assertThat(repository.existsCarExactCustomQuery("")).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenModelName_whenExistsLike_thenIsTrue() {
|
||||
assertThat(repository.existsCarLikeCustomQuery("BMW")).isTrue();
|
||||
assertThat(repository.existsCarLikeCustomQuery("Bmw")).isTrue();
|
||||
assertThat(repository.existsCarLikeCustomQuery("bmw")).isTrue();
|
||||
assertThat(repository.existsCarLikeCustomQuery("")).isFalse();
|
||||
}
|
||||
|
||||
}
|
|
@ -22,6 +22,7 @@
|
|||
- [Spring Data JPA Query by Example](https://www.baeldung.com/spring-data-query-by-example)
|
||||
- [DB Integration Tests with Spring Boot and Testcontainers](https://www.baeldung.com/spring-boot-testcontainers-integration-test)
|
||||
- [Spring Data JPA @Modifying Annotation](https://www.baeldung.com/spring-data-jpa-modifying-annotation)
|
||||
- [Spring Data JPA Batch Inserts](https://www.baeldung.com/spring-data-jpa-batch-inserts)
|
||||
|
||||
### Eclipse Config
|
||||
After importing the project into Eclipse, you may see the following error:
|
||||
|
|
|
@ -53,6 +53,15 @@
|
|||
<artifactId>spring-security-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
package com.baeldung.batchinserts;
|
||||
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.baeldung.batchinserts.model.Customer;
|
||||
import com.baeldung.batchinserts.repository.CustomerRepository;
|
||||
|
||||
/**
|
||||
* A simple controller to test the JPA CrudRepository operations
|
||||
* controllers
|
||||
*
|
||||
* @author ysharma2512
|
||||
*
|
||||
*/
|
||||
@RestController
|
||||
public class CustomerController {
|
||||
|
||||
@Autowired
|
||||
CustomerRepository customerRepository;
|
||||
|
||||
public CustomerController(CustomerRepository customerRepository2) {
|
||||
this.customerRepository = customerRepository2;
|
||||
}
|
||||
|
||||
@PostMapping("/customers")
|
||||
public ResponseEntity<List<Customer>> insertCustomers() throws URISyntaxException {
|
||||
Customer c1 = new Customer("James", "Gosling");
|
||||
Customer c2 = new Customer("Doug", "Lea");
|
||||
Customer c3 = new Customer("Martin", "Fowler");
|
||||
Customer c4 = new Customer("Brian", "Goetz");
|
||||
List<Customer> customers = Arrays.asList(c1, c2, c3, c4);
|
||||
customerRepository.saveAll(customers);
|
||||
return ResponseEntity.ok(customers);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
package com.baeldung.batchinserts.model;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
|
||||
/**
|
||||
* Customer Entity class
|
||||
* @author ysharma2512
|
||||
*
|
||||
*/
|
||||
@Entity
|
||||
public class Customer {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
private Long id;
|
||||
private String firstName;
|
||||
private String lastName;
|
||||
|
||||
public Customer(String firstName, String lastName) {
|
||||
this.firstName = firstName;
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
public void setFirstName(String firstName) {
|
||||
this.firstName = firstName;
|
||||
}
|
||||
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
|
||||
public void setLastName(String lastName) {
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("Customer[id=%d, firstName='%s', lastName='%s']", id, firstName, lastName);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package com.baeldung.batchinserts.repository;
|
||||
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
|
||||
import com.baeldung.batchinserts.model.Customer;
|
||||
|
||||
/**
|
||||
* JPA CrudRepository interface
|
||||
*
|
||||
* @author ysharma2512
|
||||
*
|
||||
*/
|
||||
public interface CustomerRepository extends CrudRepository<Customer, Long>{
|
||||
|
||||
}
|
|
@ -15,3 +15,8 @@ hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.EhCacheRegionFa
|
|||
spring.datasource.data=import_entities.sql
|
||||
|
||||
spring.main.allow-bean-definition-overriding=true
|
||||
|
||||
spring.jpa.properties.hibernate.jdbc.batch_size=4
|
||||
spring.jpa.properties.hibernate.order_inserts=true
|
||||
spring.jpa.properties.hibernate.order_updates=true
|
||||
spring.jpa.properties.hibernate.generate_statistics=true
|
|
@ -0,0 +1,44 @@
|
|||
package com.baeldung.batchinserts;
|
||||
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
|
||||
import com.baeldung.batchinserts.CustomerController;
|
||||
import com.baeldung.batchinserts.repository.CustomerRepository;
|
||||
import com.baeldung.config.PersistenceConfiguration;
|
||||
import com.baeldung.config.PersistenceProductConfiguration;
|
||||
import com.baeldung.config.PersistenceUserConfiguration;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest
|
||||
@AutoConfigureMockMvc
|
||||
@ContextConfiguration(classes = { PersistenceConfiguration.class, PersistenceProductConfiguration.class, PersistenceUserConfiguration.class })
|
||||
public class BatchInsertIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
private CustomerRepository customerRepository;
|
||||
private MockMvc mockMvc;
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
mockMvc = MockMvcBuilders.standaloneSetup( new CustomerController(customerRepository))
|
||||
.build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenInsertingCustomers_thenCustomersAreCreated() throws Exception {
|
||||
this.mockMvc.perform(post("/customers"))
|
||||
.andExpect(status().isOk());
|
||||
}
|
||||
|
||||
}
|
2
pom.xml
2
pom.xml
|
@ -577,12 +577,12 @@
|
|||
<module>spring-4</module>
|
||||
|
||||
<module>spring-5</module>
|
||||
<module>spring-5-webflux</module>
|
||||
<module>spring-5-mvc</module>
|
||||
<module>spring-5-reactive</module>
|
||||
<module>spring-5-reactive-client</module>
|
||||
<module>spring-5-reactive-oauth</module>
|
||||
<module>spring-5-reactive-security</module>
|
||||
<module>spring-5-reactive-netty</module>
|
||||
<module>spring-5-security</module>
|
||||
<module>spring-5-security-oauth</module>
|
||||
|
||||
|
|
|
@ -2,3 +2,4 @@
|
|||
|
||||
- [Intro To Reactor Core](http://www.baeldung.com/reactor-core)
|
||||
- [Combining Publishers in Project Reactor](http://www.baeldung.com/reactor-combine-streams)
|
||||
- [Programmatically Creating Sequences with Project Reactor](https://www.baeldung.com/flux-sequences-reactor)
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
# Folders #
|
||||
**/.idea
|
||||
**/target
|
||||
|
||||
# Files #
|
||||
*.log
|
||||
|
||||
# Packaged files #
|
||||
*.jar
|
||||
*.war
|
||||
*.ear
|
|
@ -1,3 +0,0 @@
|
|||
## Spring 5 Reactive Project With Netty Server
|
||||
|
||||
Includes configuration options for Netty server.
|
|
@ -1,51 +0,0 @@
|
|||
<?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>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>spring-5-reactive-netty</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>spring-5-reactive-netty</name>
|
||||
<packaging>jar</packaging>
|
||||
<description>Spring 5 sample project about reactive web with Netty server</description>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-boot-2</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../parent-boot-2</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-webflux</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-devtools</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
|
@ -19,3 +19,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring
|
|||
- [Logging a Reactive Sequence](https://www.baeldung.com/spring-reactive-sequence-logging)
|
||||
- [Testing Reactive Streams Using StepVerifier and TestPublisher](https://www.baeldung.com/reactive-streams-step-verifier-test-publisher)
|
||||
- [Debugging Reactive Streams in Spring 5](https://www.baeldung.com/spring-debugging-reactive-streams)
|
||||
- [Static Content in Spring WebFlux](https://www.baeldung.com/spring-webflux-static-content)
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
# Files #
|
||||
*.log
|
|
@ -1,23 +1,20 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>spring-5-webflux</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
|
||||
<name>spring-5-webflux</name>
|
||||
|
||||
<url>http://www.baeldung.com</url>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<spring-boot.version>2.0.2.RELEASE</spring-boot.version>
|
||||
</properties>
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-boot-2</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../parent-boot-2</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
|
@ -58,12 +55,8 @@
|
|||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.8.0</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>2.22.1</version>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package com.baeldung.serverconfig;
|
||||
package com.baeldung.spring.serverconfig;
|
||||
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
import io.netty.channel.nio.NioEventLoopGroup;
|
|
@ -1,4 +1,4 @@
|
|||
package com.baeldung.serverconfig;
|
||||
package com.baeldung.spring.serverconfig;
|
||||
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
|
@ -1,4 +1,4 @@
|
|||
package com.baeldung.serverconfig;
|
||||
package com.baeldung.spring.serverconfig;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
import reactor.core.publisher.Mono;
|
|
@ -1,4 +1,4 @@
|
|||
package com.baeldung.serverconfig;
|
||||
package com.baeldung.spring.serverconfig;
|
||||
|
||||
import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory;
|
||||
import org.springframework.boot.web.embedded.netty.NettyServerCustomizer;
|
|
@ -1,4 +1,4 @@
|
|||
package com.baeldung.serverconfig;
|
||||
package com.baeldung.spring.serverconfig;
|
||||
|
||||
import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory;
|
||||
import org.springframework.boot.web.embedded.netty.SslServerCustomizer;
|
|
@ -1,4 +1,4 @@
|
|||
package com.baeldung.serverconfig;
|
||||
package com.baeldung.spring.serverconfig;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
|
@ -9,7 +9,7 @@ import org.springframework.test.web.reactive.server.WebTestClient;
|
|||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||
public class ResponseStatusControllerTests {
|
||||
public class ResponseStatusControllerLiveTest {
|
||||
|
||||
@Autowired
|
||||
private WebTestClient testClient;
|
|
@ -1,4 +1,4 @@
|
|||
package com.baeldung.serverconfig;
|
||||
package com.baeldung.spring.serverconfig;
|
||||
|
||||
import static org.mockito.Mockito.when;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.baeldung.serverconfig;
|
||||
package com.baeldung.spring.serverconfig;
|
||||
|
||||
import io.netty.handler.ssl.SslContext;
|
||||
import io.netty.handler.ssl.SslContextBuilder;
|
||||
|
@ -10,7 +10,7 @@ import org.junit.runner.RunWith;
|
|||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||
import org.springframework.test.web.reactive.server.WebTestClient.ResponseSpec;
|
||||
|
@ -18,6 +18,7 @@ import reactor.netty.http.client.HttpClient;
|
|||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(webEnvironment = WebEnvironment.DEFINED_PORT)
|
||||
@DirtiesContext
|
||||
public class GreetingLiveTest {
|
||||
|
||||
private static final String BASE_URL = "https://localhost:8443";
|
|
@ -1,4 +1,4 @@
|
|||
package com.baeldung.serverconfig;
|
||||
package com.baeldung.spring.serverconfig;
|
||||
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
|
|
@ -7,7 +7,7 @@
|
|||
"build": "ng build",
|
||||
"postbuild": "npm run deploy",
|
||||
"predeploy": "rimraf ../resources/static/ && mkdirp ../resources/static",
|
||||
"deploy": "copyfiles -f dist/** ../resources/static",
|
||||
"deploy": "copyfiles -f dist/frontend/** ../resources/static",
|
||||
"test": "ng test",
|
||||
"lint": "ng lint",
|
||||
"e2e": "ng e2e"
|
||||
|
|
|
@ -10,3 +10,5 @@
|
|||
- [Spring Boot Console Application](http://www.baeldung.com/spring-boot-console-app)
|
||||
- [Comparing Embedded Servlet Containers in Spring Boot](http://www.baeldung.com/spring-boot-servlet-containers)
|
||||
- [Programmatically Restarting a Spring Boot Application](https://www.baeldung.com/java-restart-spring-boot-app)
|
||||
- [Spring Properties File Outside jar](https://www.baeldung.com/spring-properties-file-outside-jar)
|
||||
|
||||
|
|
|
@ -10,3 +10,4 @@ Module for the articles that are part of the Spring REST E-book:
|
|||
8. [Http Message Converters with the Spring Framework](http://www.baeldung.com/spring-httpmessageconverter-rest)
|
||||
9. [ETags for REST with Spring](http://www.baeldung.com/etags-for-rest-with-spring)
|
||||
10. [Testing REST with multiple MIME types](http://www.baeldung.com/testing-rest-api-with-multiple-media-types)
|
||||
11. [Testing Web APIs with Postman Collections](https://www.baeldung.com/postman-testing-collections)
|
||||
|
|
|
@ -28,7 +28,6 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring
|
|||
- [Spring Boot Exit Codes](http://www.baeldung.com/spring-boot-exit-codes)
|
||||
- [Guide to the Favicon in Spring Boot](http://www.baeldung.com/spring-boot-favicon)
|
||||
- [Spring Shutdown Callbacks](http://www.baeldung.com/spring-shutdown-callbacks)
|
||||
- [Spring Boot Integration Testing with Embedded MongoDB](http://www.baeldung.com/spring-boot-embedded-mongodb)
|
||||
- [Container Configuration in Spring Boot 2](http://www.baeldung.com/embeddedservletcontainercustomizer-configurableembeddedservletcontainer-spring-boot)
|
||||
- [Introduction to Chaos Monkey](https://www.baeldung.com/spring-boot-chaos-monkey)
|
||||
- [Spring Component Scanning](https://www.baeldung.com/spring-component-scanning)
|
||||
|
@ -37,3 +36,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring
|
|||
- [Injecting Git Information Into Spring](https://www.baeldung.com/spring-git-information)
|
||||
- [Validation in Spring Boot](https://www.baeldung.com/spring-boot-bean-validation)
|
||||
- [Entity To DTO Conversion for a Spring REST API](https://www.baeldung.com/entity-to-and-from-dto-for-a-java-spring-application)
|
||||
- [Guide to Creating and Running a Jar File in Java](https://www.baeldung.com/java-create-jar)
|
||||
|
|
|
@ -15,16 +15,7 @@
|
|||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<!-- MongoDB -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-mongodb</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>de.flapdoodle.embed</groupId>
|
||||
<artifactId>de.flapdoodle.embed.mongo</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- JUnit Jupiter dependencies -->
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
|
|
|
@ -17,4 +17,5 @@
|
|||
- [Dockerizing a Spring Boot Application](http://www.baeldung.com/dockerizing-spring-boot-application)
|
||||
- [Instance Profile Credentials using Spring Cloud](http://www.baeldung.com/spring-cloud-instance-profiles)
|
||||
- [Running Spring Boot Applications With Minikube](http://www.baeldung.com/spring-boot-minikube)
|
||||
- [Introduction to Spring Cloud OpenFeign](https://www.baeldung.com/spring-cloud-openfeign)
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
<module>spring-cloud-zuul-eureka-integration</module>
|
||||
<module>spring-cloud-contract</module>
|
||||
<module>spring-cloud-kubernetes</module>
|
||||
<module>spring-cloud-kubernetes-2</module>
|
||||
<module>spring-cloud-archaius</module>
|
||||
<module>spring-cloud-functions</module>
|
||||
<module>spring-cloud-vault</module>
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
target/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
|
||||
### STS ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
### NetBeans ###
|
||||
nbproject/private/
|
||||
build/
|
||||
nbbuild/
|
||||
dist/
|
||||
nbdist/
|
||||
.nb-gradle/
|
|
@ -0,0 +1,5 @@
|
|||
FROM openjdk:8-jdk-alpine
|
||||
VOLUME /tmp
|
||||
COPY target/client-service-1.0-SNAPSHOT.jar app.jar
|
||||
ENV JAVA_OPTS=""
|
||||
ENTRYPOINT exec java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=9999 -jar /app.jar
|
|
@ -0,0 +1,8 @@
|
|||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: client-service
|
||||
data:
|
||||
application.properties: |-
|
||||
bean.message=Testing reload ! Message from backend is: %s <br/> Services : %s
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
kind: Service
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: client-service
|
||||
spec:
|
||||
selector:
|
||||
app: client-service
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 8080
|
||||
nodePort: 30083
|
||||
type: NodePort
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: client-service
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: client-service
|
||||
replicas: 1
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: client-service
|
||||
spec:
|
||||
containers:
|
||||
- name: client-service
|
||||
image: client-service:latest
|
||||
imagePullPolicy: Never
|
||||
ports:
|
||||
- containerPort: 8080
|
|
@ -0,0 +1,96 @@
|
|||
<?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>client-service</artifactId>
|
||||
<name>client-service</name>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung.spring.cloud</groupId>
|
||||
<artifactId>spring-cloud-kubernetes-2</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
<spring-cloud-dependencies.version>Finchley.SR2</spring-cloud-dependencies.version>
|
||||
<spring.cloud.k8s.version>1.0.0.RELEASE</spring.cloud.k8s.version>
|
||||
</properties>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-dependencies</artifactId>
|
||||
<version>${spring-cloud-dependencies.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-kubernetes-dependencies</artifactId>
|
||||
<version>${spring.cloud.k8s.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-kubernetes-discovery</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-kubernetes-config</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-kubernetes-ribbon</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<mainClass>com.baeldung.spring.cloud.kubernetes.client.Application</mainClass>
|
||||
<layout>JAR</layout>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,27 @@
|
|||
package com.baeldung.spring.cloud.kubernetes.client;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonClient;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableDiscoveryClient
|
||||
@EnableCircuitBreaker
|
||||
@RibbonClient(name = "travel-agency-service", configuration = RibbonConfiguration.class)
|
||||
public class Application {
|
||||
|
||||
@LoadBalanced
|
||||
@Bean
|
||||
RestTemplate restTemplate() {
|
||||
return new RestTemplate();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package com.baeldung.spring.cloud.kubernetes.client;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
@ConfigurationProperties(prefix = "bean")
|
||||
public class ClientConfig {
|
||||
|
||||
private String message = "Message from backend is: %s <br/> Services : %s";
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
package com.baeldung.spring.cloud.kubernetes.client;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
import org.springframework.cloud.client.discovery.DiscoveryClient;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
public class ClientController {
|
||||
|
||||
@Autowired
|
||||
private DiscoveryClient discoveryClient;
|
||||
|
||||
@Autowired
|
||||
private ClientConfig config;
|
||||
|
||||
@Autowired
|
||||
private TravelAgencyService travelAgencyService;
|
||||
|
||||
@RequestMapping("/deals")
|
||||
public String getDeals() {
|
||||
return travelAgencyService.getDeals();
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public String load() {
|
||||
|
||||
RestTemplate restTemplate = new RestTemplate();
|
||||
String resourceUrl = "http://travel-agency-service:8080";
|
||||
ResponseEntity<String> response = restTemplate.getForEntity(resourceUrl, String.class);
|
||||
|
||||
String serviceList = "";
|
||||
if (discoveryClient != null) {
|
||||
List<String> services = this.discoveryClient.getServices();
|
||||
|
||||
for (String service : services) {
|
||||
|
||||
List<ServiceInstance> instances = this.discoveryClient.getInstances(service);
|
||||
|
||||
serviceList += ("[" + service + " : " + ((!CollectionUtils.isEmpty(instances)) ? instances.size() : 0) + " instances ]");
|
||||
}
|
||||
}
|
||||
|
||||
return String.format(config.getMessage(), response.getBody(), serviceList);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright (C) 2016 to the original authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.baeldung.spring.cloud.kubernetes.client;
|
||||
|
||||
import com.netflix.client.config.IClientConfig;
|
||||
import com.netflix.loadbalancer.AvailabilityFilteringRule;
|
||||
import com.netflix.loadbalancer.IPing;
|
||||
import com.netflix.loadbalancer.IRule;
|
||||
import com.netflix.loadbalancer.PingUrl;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
public class RibbonConfiguration {
|
||||
|
||||
@Autowired
|
||||
IClientConfig ribbonClientConfig;
|
||||
|
||||
/**
|
||||
* PingUrl will ping a URL to check the status of each server.
|
||||
* Say Hello has, as you’ll recall, a method mapped to the /path; that means that Ribbon will get an HTTP 200 response when it pings a running Backend Server
|
||||
*
|
||||
* @param config Client configuration
|
||||
* @return The URL to be used for the Ping
|
||||
*/
|
||||
@Bean
|
||||
public IPing ribbonPing(IClientConfig config) {
|
||||
return new PingUrl();
|
||||
}
|
||||
|
||||
/**
|
||||
* AvailabilityFilteringRule will use Ribbon’s built-in circuit breaker functionality to filter out any servers in an “open-circuit” state:
|
||||
* if a ping fails to connect to a given server, or if it gets a read failure for the server, Ribbon will consider that server “dead” until it begins to respond normally.
|
||||
*
|
||||
* @param config Client configuration
|
||||
* @return The Load Balancer rule
|
||||
*/
|
||||
@Bean
|
||||
public IRule ribbonRule(IClientConfig config) {
|
||||
return new AvailabilityFilteringRule();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package com.baeldung.spring.cloud.kubernetes.client;
|
||||
|
||||
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
|
||||
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
@Service
|
||||
public class TravelAgencyService {
|
||||
|
||||
private final RestTemplate restTemplate;
|
||||
|
||||
public TravelAgencyService(RestTemplate restTemplate) {
|
||||
this.restTemplate = restTemplate;
|
||||
}
|
||||
|
||||
@HystrixCommand(fallbackMethod = "getFallbackName", commandProperties = {
|
||||
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1000") })
|
||||
public String getDeals() {
|
||||
return this.restTemplate.getForObject("http://travel-agency-service:8080/deals", String.class);
|
||||
}
|
||||
|
||||
private String getFallbackName() {
|
||||
return "Fallback";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
spring:
|
||||
application.name: client-service
|
||||
cloud.kubernetes.reload.enabled: true
|
||||
server.port: 8080
|
||||
management:
|
||||
endpoint:
|
||||
restart:
|
||||
enabled: true
|
||||
health:
|
||||
enabled: true
|
||||
info:
|
||||
enabled: true
|
||||
ribbon:
|
||||
http:
|
||||
client:
|
||||
enabled: true
|
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
|
||||
</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
</configuration>
|
|
@ -0,0 +1,17 @@
|
|||
package org.baeldung;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import com.baeldung.spring.cloud.kubernetes.client.Application;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = Application.class)
|
||||
public class SpringContextIntegrationTest {
|
||||
|
||||
@Test
|
||||
public void contextLoads() {
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
### build the repository
|
||||
mvn clean install
|
||||
|
||||
### set docker env
|
||||
eval $(minikube docker-env)
|
||||
|
||||
### build the docker images on minikube
|
||||
cd travel-agency-service
|
||||
docker build -t travel-agency-service .
|
||||
cd ../client-service
|
||||
docker build -t client-service .
|
||||
cd ..
|
||||
|
||||
### secret and mongodb
|
||||
kubectl delete -f secret.yaml
|
||||
kubectl delete -f mongo-deployment.yaml
|
||||
|
||||
kubectl create -f secret.yaml
|
||||
kubectl create -f mongo-deployment.yaml
|
||||
|
||||
### travel-agency-service
|
||||
kubectl delete -f travel-agency-service/travel-agency-deployment.yaml
|
||||
kubectl create -f travel-agency-service/travel-agency-deployment.yaml
|
||||
|
||||
|
||||
### client-service
|
||||
kubectl delete configmap client-service
|
||||
kubectl delete -f client-service/client-service-deployment.yaml
|
||||
|
||||
kubectl create -f client-service/client-config.yaml
|
||||
kubectl create -f client-service/client-service-deployment.yaml
|
||||
|
||||
# Check that the pods are running
|
||||
kubectl get pods
|
|
@ -0,0 +1,45 @@
|
|||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
labels:
|
||||
app: mongo
|
||||
name: mongodb-service
|
||||
spec:
|
||||
type: NodePort
|
||||
ports:
|
||||
- name: "http"
|
||||
port: 27017
|
||||
protocol: TCP
|
||||
targetPort: 27017
|
||||
selector:
|
||||
service: mongo
|
||||
---
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: mongo
|
||||
spec:
|
||||
replicas: 1
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
service: mongo
|
||||
name: mongodb-service
|
||||
spec:
|
||||
containers:
|
||||
- args:
|
||||
- mongod
|
||||
- --smallfiles
|
||||
image: mongo:latest
|
||||
name: mongo
|
||||
env:
|
||||
- name: MONGO_INITDB_ROOT_USERNAME
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: db-secret
|
||||
key: username
|
||||
- name: MONGO_INITDB_ROOT_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: db-secret
|
||||
key: password
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue