Merge remote-tracking branch 'eugenp/master'
This commit is contained in:
commit
293751596e
@ -33,3 +33,4 @@
|
|||||||
- [Display All Time Zones With GMT And UTC in Java](http://www.baeldung.com/java-time-zones)
|
- [Display All Time Zones With GMT And UTC in Java](http://www.baeldung.com/java-time-zones)
|
||||||
- [Copy a File with Java](http://www.baeldung.com/java-copy-file)
|
- [Copy a File with Java](http://www.baeldung.com/java-copy-file)
|
||||||
- [Generating Prime Numbers in Java](http://www.baeldung.com/java-generate-prime-numbers)
|
- [Generating Prime Numbers in Java](http://www.baeldung.com/java-generate-prime-numbers)
|
||||||
|
- [Static and Default Methods in Interfaces in Java](http://www.baeldung.com/java-static-default-methods)
|
||||||
|
@ -0,0 +1,18 @@
|
|||||||
|
package com.baeldung.defaultstaticinterfacemethods.application;
|
||||||
|
|
||||||
|
import com.baeldung.defaultstaticinterfacemethods.model.Car;
|
||||||
|
import com.baeldung.defaultstaticinterfacemethods.model.Vehicle;
|
||||||
|
|
||||||
|
public class Application {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
Vehicle car = new Car("BMW");
|
||||||
|
System.out.println(car.getBrand());
|
||||||
|
System.out.println(car.speedUp());
|
||||||
|
System.out.println(car.slowDown());
|
||||||
|
System.out.println(car.turnAlarmOn());
|
||||||
|
System.out.println(car.turnAlarmOff());
|
||||||
|
System.out.println(Vehicle.getHorsePower(2500, 480));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
package com.baeldung.defaultstaticinterfacemethods.model;
|
||||||
|
|
||||||
|
public interface Alarm {
|
||||||
|
|
||||||
|
default String turnAlarmOn() {
|
||||||
|
return "Turning the alarm on.";
|
||||||
|
}
|
||||||
|
|
||||||
|
default String turnAlarmOff() {
|
||||||
|
return "Turning the alarm off.";
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
package com.baeldung.defaultstaticinterfacemethods.model;
|
||||||
|
|
||||||
|
public class Car implements Vehicle {
|
||||||
|
|
||||||
|
private final String brand;
|
||||||
|
|
||||||
|
public Car(String brand) {
|
||||||
|
this.brand = brand;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getBrand() {
|
||||||
|
return brand;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String speedUp() {
|
||||||
|
return "The car is speeding up.";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String slowDown() {
|
||||||
|
return "The car is slowing down.";
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
package com.baeldung.defaultstaticinterfacemethods.model;
|
||||||
|
|
||||||
|
public class Motorbike implements Vehicle {
|
||||||
|
|
||||||
|
private final String brand;
|
||||||
|
|
||||||
|
public Motorbike(String brand) {
|
||||||
|
this.brand = brand;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getBrand() {
|
||||||
|
return brand;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String speedUp() {
|
||||||
|
return "The motorbike is speeding up.";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String slowDown() {
|
||||||
|
return "The motorbike is slowing down.";
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
package com.baeldung.defaultstaticinterfacemethods.model;
|
||||||
|
|
||||||
|
public class MultiAlarmCar implements Vehicle, Alarm {
|
||||||
|
|
||||||
|
private final String brand;
|
||||||
|
|
||||||
|
public MultiAlarmCar(String brand) {
|
||||||
|
this.brand = brand;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getBrand() {
|
||||||
|
return brand;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String speedUp() {
|
||||||
|
return "The motorbike is speeding up.";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String slowDown() {
|
||||||
|
return "The mootorbike is slowing down.";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String turnAlarmOn() {
|
||||||
|
return Vehicle.super.turnAlarmOn() + " " + Alarm.super.turnAlarmOn();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String turnAlarmOff() {
|
||||||
|
return Vehicle.super.turnAlarmOff() + " " + Alarm.super.turnAlarmOff();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
package com.baeldung.defaultstaticinterfacemethods.model;
|
||||||
|
|
||||||
|
public interface Vehicle {
|
||||||
|
|
||||||
|
String getBrand();
|
||||||
|
|
||||||
|
String speedUp();
|
||||||
|
|
||||||
|
String slowDown();
|
||||||
|
|
||||||
|
default String turnAlarmOn() {
|
||||||
|
return "Turning the vehice alarm on.";
|
||||||
|
}
|
||||||
|
|
||||||
|
default String turnAlarmOff() {
|
||||||
|
return "Turning the vehicle alarm off.";
|
||||||
|
}
|
||||||
|
|
||||||
|
static int getHorsePower(int rpm, int torque) {
|
||||||
|
return (rpm * torque) / 5252;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,80 @@
|
|||||||
|
package com.baeldung.iterators;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Source code https://github.com/eugenp/tutorials
|
||||||
|
*
|
||||||
|
* @author Santosh Thakur
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class Iterators {
|
||||||
|
|
||||||
|
public static int failFast1() {
|
||||||
|
ArrayList<Integer> numbers = new ArrayList<>();
|
||||||
|
|
||||||
|
numbers.add(10);
|
||||||
|
numbers.add(20);
|
||||||
|
numbers.add(30);
|
||||||
|
numbers.add(40);
|
||||||
|
|
||||||
|
Iterator<Integer> iterator = numbers.iterator();
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
Integer number = iterator.next();
|
||||||
|
numbers.add(50);
|
||||||
|
}
|
||||||
|
|
||||||
|
return numbers.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int failFast2() {
|
||||||
|
ArrayList<Integer> numbers = new ArrayList<>();
|
||||||
|
numbers.add(10);
|
||||||
|
numbers.add(20);
|
||||||
|
numbers.add(30);
|
||||||
|
numbers.add(40);
|
||||||
|
|
||||||
|
Iterator<Integer> iterator = numbers.iterator();
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
if (iterator.next() == 30) {
|
||||||
|
// will not throw Exception
|
||||||
|
iterator.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("using iterator's remove method = " + numbers);
|
||||||
|
|
||||||
|
iterator = numbers.iterator();
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
if (iterator.next() == 40) {
|
||||||
|
// will throw Exception on
|
||||||
|
// next call of next() method
|
||||||
|
numbers.remove(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return numbers.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int failSafe1() {
|
||||||
|
ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
map.put("First", 10);
|
||||||
|
map.put("Second", 20);
|
||||||
|
map.put("Third", 30);
|
||||||
|
map.put("Fourth", 40);
|
||||||
|
|
||||||
|
Iterator<String> iterator = map.keySet()
|
||||||
|
.iterator();
|
||||||
|
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
String key = iterator.next();
|
||||||
|
map.put("Fifth", 50);
|
||||||
|
}
|
||||||
|
|
||||||
|
return map.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -2,6 +2,7 @@ package com.baeldung.counter;
|
|||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
import org.openjdk.jmh.annotations.Benchmark;
|
import org.openjdk.jmh.annotations.Benchmark;
|
||||||
import org.openjdk.jmh.annotations.BenchmarkMode;
|
import org.openjdk.jmh.annotations.BenchmarkMode;
|
||||||
@ -18,6 +19,16 @@ public class CounterStatistics {
|
|||||||
private static final Map<String, MutableInteger> counterWithMutableIntMap = new HashMap<>();
|
private static final Map<String, MutableInteger> counterWithMutableIntMap = new HashMap<>();
|
||||||
private static final Map<String, int[]> counterWithIntArrayMap = new HashMap<>();
|
private static final Map<String, int[]> counterWithIntArrayMap = new HashMap<>();
|
||||||
private static final Map<String, Long> counterWithLongWrapperMap = new HashMap<>();
|
private static final Map<String, Long> counterWithLongWrapperMap = new HashMap<>();
|
||||||
|
private static final Map<String, Long> counterWithLongWrapperStreamMap = new HashMap<>();
|
||||||
|
|
||||||
|
static {
|
||||||
|
CounterUtil.COUNTRY_NAMES = new String[10000];
|
||||||
|
final String prefix = "NewString";
|
||||||
|
Random random = new Random();
|
||||||
|
for (int i=0; i<10000; i++) {
|
||||||
|
CounterUtil.COUNTRY_NAMES[i] = new String(prefix + random.nextInt(1000));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Benchmark
|
@Benchmark
|
||||||
public void wrapperAsCounter() {
|
public void wrapperAsCounter() {
|
||||||
@ -29,6 +40,11 @@ public class CounterStatistics {
|
|||||||
CounterUtil.counterWithLambdaAndWrapper(counterWithLongWrapperMap);
|
CounterUtil.counterWithLambdaAndWrapper(counterWithLongWrapperMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public void parallelStreamWithWrapper() {
|
||||||
|
CounterUtil.counterWithParallelStreamAndWrapper(counterWithLongWrapperStreamMap);
|
||||||
|
}
|
||||||
|
|
||||||
@Benchmark
|
@Benchmark
|
||||||
public void mutableIntegerAsCounter() {
|
public void mutableIntegerAsCounter() {
|
||||||
CounterUtil.counterWithMutableInteger(counterWithMutableIntMap);
|
CounterUtil.counterWithMutableInteger(counterWithMutableIntMap);
|
||||||
|
@ -6,7 +6,7 @@ import java.util.stream.Stream;
|
|||||||
|
|
||||||
public class CounterUtil {
|
public class CounterUtil {
|
||||||
|
|
||||||
private final static String[] COUNTRY_NAMES = { "China", "Australia", "India", "USA", "USSR", "UK", "China", "France", "Poland", "Austria", "India", "USA", "Egypt", "China" };
|
public static String[] COUNTRY_NAMES = { "China", "Australia", "India", "USA", "USSR", "UK", "China", "France", "Poland", "Austria", "India", "USA", "Egypt", "China" };
|
||||||
|
|
||||||
public static void counterWithWrapperObject(Map<String, Integer> counterMap) {
|
public static void counterWithWrapperObject(Map<String, Integer> counterMap) {
|
||||||
for (String country : COUNTRY_NAMES) {
|
for (String country : COUNTRY_NAMES) {
|
||||||
@ -15,9 +15,14 @@ public class CounterUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void counterWithLambdaAndWrapper(Map<String, Long> counterMap) {
|
public static void counterWithLambdaAndWrapper(Map<String, Long> counterMap) {
|
||||||
counterMap.putAll(Stream.of(COUNTRY_NAMES)
|
Stream.of(COUNTRY_NAMES)
|
||||||
|
.collect(Collectors.groupingBy(k -> k, () -> counterMap, Collectors.counting()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void counterWithParallelStreamAndWrapper(Map<String, Long> counterMap) {
|
||||||
|
Stream.of(COUNTRY_NAMES)
|
||||||
.parallel()
|
.parallel()
|
||||||
.collect(Collectors.groupingBy(k -> k, Collectors.counting())));
|
.collect(Collectors.groupingBy(k -> k, () -> counterMap, Collectors.counting()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class MutableInteger {
|
public static class MutableInteger {
|
||||||
|
@ -0,0 +1,79 @@
|
|||||||
|
package com.baeldung.defaultistaticinterfacemethods.test;
|
||||||
|
|
||||||
|
import com.baeldung.defaultstaticinterfacemethods.model.Car;
|
||||||
|
import com.baeldung.defaultstaticinterfacemethods.model.Motorbike;
|
||||||
|
import com.baeldung.defaultstaticinterfacemethods.model.Vehicle;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
import static org.assertj.core.api.Assertions.*;
|
||||||
|
|
||||||
|
public class StaticDefaulInterfaceMethodUnitTest {
|
||||||
|
|
||||||
|
private static Car car;
|
||||||
|
private static Motorbike motorbike;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void setUpCarInstance() {
|
||||||
|
car = new Car("BMW");
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void setUpMotorbikeInstance() {
|
||||||
|
motorbike = new Motorbike("Yamaha");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenCarInstace_whenBrandisBMW_thenOneAssertion() {
|
||||||
|
assertThat(car.getBrand()).isEqualTo("BMW");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenCarInstance_whenCallingSpeedUp_thenOneAssertion() {
|
||||||
|
assertThat(car.speedUp()).isEqualTo("The car is speeding up.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenCarInstance_whenCallingSlowDown_thenOneAssertion() {
|
||||||
|
assertThat(car.slowDown()).isEqualTo("The car is slowing down.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenCarInstance_whenCallingTurnAlarmOn_thenOneAssertion() {
|
||||||
|
assertThat(car.turnAlarmOn()).isEqualTo("Turning the vehice alarm on.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenCarInstance_whenCallingTurnAlarmOff_thenOneAssertion() {
|
||||||
|
assertThat(car.turnAlarmOff()).isEqualTo("Turning the vehicle alarm off.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenVehicleInterface_whenCallinggetHorsePower_thenOneAssertion() {
|
||||||
|
assertThat(Vehicle.getHorsePower(2500, 480)).isEqualTo(228);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenMooorbikeInstace_whenBrandisYamaha_thenOneAssertion() {
|
||||||
|
assertThat(motorbike.getBrand()).isEqualTo("Yamaha");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenMotorbikeInstance_whenCallingSpeedUp_thenOneAssertion() {
|
||||||
|
assertThat(motorbike.speedUp()).isEqualTo("The motorbike is speeding up.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenMotorbikeInstance_whenCallingSlowDown_thenOneAssertion() {
|
||||||
|
assertThat(motorbike.slowDown()).isEqualTo("The motorbike is slowing down.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenMotorbikeInstance_whenCallingTurnAlarmOn_thenOneAssertion() {
|
||||||
|
assertThat(motorbike.turnAlarmOn()).isEqualTo("Turning the vehice alarm on.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenMotorbikeInstance_whenCallingTurnAlarmOff_thenOneAssertion() {
|
||||||
|
assertThat(motorbike.turnAlarmOff()).isEqualTo("Turning the vehicle alarm off.");
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
package com.baeldung.iterators;
|
||||||
|
|
||||||
|
import static com.baeldung.iterators.Iterators.failFast1;
|
||||||
|
import static com.baeldung.iterators.Iterators.failFast2;
|
||||||
|
import static com.baeldung.iterators.Iterators.failSafe1;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||||
|
|
||||||
|
import java.util.ConcurrentModificationException;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Source code https://github.com/eugenp/tutorials
|
||||||
|
*
|
||||||
|
* @author Santosh Thakur
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class IteratorsTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenFailFast_ThenThrowsException() {
|
||||||
|
assertThatThrownBy(() -> {
|
||||||
|
failFast1();
|
||||||
|
}).isInstanceOf(ConcurrentModificationException.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenFailFast_ThenThrowsExceptionInSecondIteration() {
|
||||||
|
assertThatThrownBy(() -> {
|
||||||
|
failFast2();
|
||||||
|
}).isInstanceOf(ConcurrentModificationException.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenFailSafe_ThenDoesNotThrowException() {
|
||||||
|
assertThat(failSafe1()).isGreaterThanOrEqualTo(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -19,3 +19,4 @@
|
|||||||
- [Java 9 java.util.Objects Additions](http://www.baeldung.com/java-9-objects-new)
|
- [Java 9 java.util.Objects Additions](http://www.baeldung.com/java-9-objects-new)
|
||||||
- [Compact Strings in Java 9](http://www.baeldung.com/java-9-compact-string)
|
- [Compact Strings in Java 9](http://www.baeldung.com/java-9-compact-string)
|
||||||
- [Convert Date to LocalDate or LocalDateTime and Back](http://www.baeldung.com/java-date-to-localdate-and-localdatetime)
|
- [Convert Date to LocalDate or LocalDateTime and Back](http://www.baeldung.com/java-date-to-localdate-and-localdatetime)
|
||||||
|
- [Java 9 Variable Handles Demistyfied](http://www.baeldung.com/java-variable-handles)
|
||||||
|
@ -127,3 +127,8 @@
|
|||||||
- [Introduction to the Java ArrayDeque](http://www.baeldung.com/java-array-deque)
|
- [Introduction to the Java ArrayDeque](http://www.baeldung.com/java-array-deque)
|
||||||
- [Guide to java.util.Formatter](http://www.baeldung.com/java-string-formatter)
|
- [Guide to java.util.Formatter](http://www.baeldung.com/java-string-formatter)
|
||||||
- [Batch Processing in JDBC](http://www.baeldung.com/jdbc-batch-processing)
|
- [Batch Processing in JDBC](http://www.baeldung.com/jdbc-batch-processing)
|
||||||
|
- [Check if a Java Array Contains a Value](http://www.baeldung.com/java-array-contains-value)
|
||||||
|
- [How to Invert an Array in Java](http://www.baeldung.com/java-invert-array)
|
||||||
|
- [Guide to the Cipher Class](http://www.baeldung.com/java-cipher-class)
|
||||||
|
- [A Guide to Java Initialization](http://www.baeldung.com/java-initialization)
|
||||||
|
|
||||||
|
35
core-java/src/main/java/com/baeldung/cipher/Encryptor.java
Normal file
35
core-java/src/main/java/com/baeldung/cipher/Encryptor.java
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
package com.baeldung.cipher;
|
||||||
|
|
||||||
|
import javax.crypto.*;
|
||||||
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
|
import java.security.InvalidKeyException;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.cert.Certificate;
|
||||||
|
|
||||||
|
public class Encryptor {
|
||||||
|
|
||||||
|
public byte[] encryptMessage(byte[] message, byte[] keyBytes) throws InvalidKeyException, NoSuchPaddingException, NoSuchAlgorithmException, BadPaddingException, IllegalBlockSizeException {
|
||||||
|
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
|
||||||
|
SecretKey secretKey = new SecretKeySpec(keyBytes, "AES");
|
||||||
|
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
|
||||||
|
byte[] encryptedMessage = cipher.doFinal(message);
|
||||||
|
return encryptedMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] encryptMessage(byte[] message, Certificate publicKeyCertificate) throws InvalidKeyException, NoSuchPaddingException, NoSuchAlgorithmException, BadPaddingException, IllegalBlockSizeException {
|
||||||
|
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
|
||||||
|
cipher.init(Cipher.ENCRYPT_MODE, publicKeyCertificate);
|
||||||
|
byte[] encryptedMessage = cipher.doFinal(message);
|
||||||
|
return encryptedMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] decryptMessage(byte[] encryptedMessage, byte[] keyBytes) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
|
||||||
|
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
|
||||||
|
SecretKey secretKey = new SecretKeySpec(keyBytes, "AES");
|
||||||
|
cipher.init(Cipher.DECRYPT_MODE, secretKey);
|
||||||
|
byte[] clearMessage = cipher.doFinal(encryptedMessage);
|
||||||
|
return clearMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,53 @@
|
|||||||
|
package com.baeldung.initializationguide;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
public class User implements Serializable, Cloneable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
static String forum;
|
||||||
|
private String name;
|
||||||
|
private int id;
|
||||||
|
|
||||||
|
{
|
||||||
|
id = 0;
|
||||||
|
System.out.println("Instance Initializer");
|
||||||
|
}
|
||||||
|
|
||||||
|
static {
|
||||||
|
forum = "Java";
|
||||||
|
System.out.println("Static Initializer");
|
||||||
|
}
|
||||||
|
|
||||||
|
public User(String name, int id) {
|
||||||
|
super();
|
||||||
|
this.name = name;
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public User() {
|
||||||
|
System.out.println("Constructor");
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(int id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Object clone() throws CloneNotSupportedException {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -8,15 +8,7 @@ public class BinaryTree {
|
|||||||
Node root;
|
Node root;
|
||||||
|
|
||||||
public void add(int value) {
|
public void add(int value) {
|
||||||
|
root = addRecursive(root, value);
|
||||||
Node newNode = new Node(value);
|
|
||||||
|
|
||||||
if (root == null) {
|
|
||||||
root = newNode;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
addRecursive(root, value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Node addRecursive(Node current, int value) {
|
private Node addRecursive(Node current, int value) {
|
||||||
@ -27,34 +19,41 @@ public class BinaryTree {
|
|||||||
|
|
||||||
if (value < current.value) {
|
if (value < current.value) {
|
||||||
current.left = addRecursive(current.left, value);
|
current.left = addRecursive(current.left, value);
|
||||||
} else {
|
} else if (value > current.value) {
|
||||||
current.right = addRecursive(current.right, value);
|
current.right = addRecursive(current.right, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
return current;
|
return current;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isEmpty() {
|
public boolean isEmpty() {
|
||||||
return root == null;
|
return root == null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getSize() {
|
||||||
|
return getSizeRecursive(root);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getSizeRecursive(Node current) {
|
||||||
|
return current == null ? 0 : getSizeRecursive(current.left) + 1 + getSizeRecursive(current.right);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean containsNode(int value) {
|
public boolean containsNode(int value) {
|
||||||
return containsNodeRecursive(root, value);
|
return containsNodeRecursive(root, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean containsNodeRecursive(Node current, int value) {
|
private boolean containsNodeRecursive(Node current, int value) {
|
||||||
|
|
||||||
if (current == null) {
|
if (current == null) {
|
||||||
return false;
|
return false;
|
||||||
} else if (value == current.value) {
|
|
||||||
return true;
|
|
||||||
} else if (value < current.value) {
|
|
||||||
return containsNodeRecursive(current.left, value);
|
|
||||||
} else {
|
|
||||||
return containsNodeRecursive(current.right, value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (value == current.value) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value < current.value
|
||||||
|
? containsNodeRecursive(current.left, value)
|
||||||
|
: containsNodeRecursive(current.right, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void delete(int value) {
|
public void delete(int value) {
|
||||||
@ -86,23 +85,18 @@ public class BinaryTree {
|
|||||||
current.value = smallestValue;
|
current.value = smallestValue;
|
||||||
current.right = deleteRecursive(current.right, smallestValue);
|
current.right = deleteRecursive(current.right, smallestValue);
|
||||||
return current;
|
return current;
|
||||||
|
}
|
||||||
} else if (value < current.value) {
|
if (value < current.value) {
|
||||||
current.left = deleteRecursive(current.left, value);
|
current.left = deleteRecursive(current.left, value);
|
||||||
return current;
|
return current;
|
||||||
} else {
|
}
|
||||||
|
|
||||||
current.right = deleteRecursive(current.right, value);
|
current.right = deleteRecursive(current.right, value);
|
||||||
return current;
|
return current;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private int findSmallestValue(Node root) {
|
private int findSmallestValue(Node root) {
|
||||||
|
return root.left == null ? root.value : findSmallestValue(root.left);
|
||||||
if (root.left == null) {
|
|
||||||
return root.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
return findSmallestValue(root.left);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void traverseInOrder(Node node) {
|
public void traverseInOrder(Node node) {
|
||||||
@ -125,12 +119,15 @@ public class BinaryTree {
|
|||||||
if (node != null) {
|
if (node != null) {
|
||||||
traversePostOrder(node.left);
|
traversePostOrder(node.left);
|
||||||
traversePostOrder(node.right);
|
traversePostOrder(node.right);
|
||||||
|
|
||||||
System.out.print(" " + node.value);
|
System.out.print(" " + node.value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void traverseLevelOrder() {
|
public void traverseLevelOrder() {
|
||||||
|
if (root == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Queue<Node> nodes = new LinkedList<>();
|
Queue<Node> nodes = new LinkedList<>();
|
||||||
nodes.add(root);
|
nodes.add(root);
|
||||||
|
|
||||||
|
@ -0,0 +1,70 @@
|
|||||||
|
package com.baeldung.cipher;
|
||||||
|
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.security.cert.CertificateFactory;
|
||||||
|
import java.security.cert.X509Certificate;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
public class EncryptorUnitTest {
|
||||||
|
private String encKeyString;
|
||||||
|
private String message;
|
||||||
|
private String certificateString;
|
||||||
|
private Encryptor encryptor;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void init(){
|
||||||
|
encKeyString = "1234567890123456";
|
||||||
|
message = "This is a secret message";
|
||||||
|
encryptor = new Encryptor();
|
||||||
|
certificateString = "-----BEGIN CERTIFICATE-----\n" +
|
||||||
|
"MIICVjCCAb8CAg37MA0GCSqGSIb3DQEBBQUAMIGbMQswCQYDVQQGEwJKUDEOMAwG\n" +
|
||||||
|
"A1UECBMFVG9reW8xEDAOBgNVBAcTB0NodW8ta3UxETAPBgNVBAoTCEZyYW5rNERE\n" +
|
||||||
|
"MRgwFgYDVQQLEw9XZWJDZXJ0IFN1cHBvcnQxGDAWBgNVBAMTD0ZyYW5rNEREIFdl\n" +
|
||||||
|
"YiBDQTEjMCEGCSqGSIb3DQEJARYUc3VwcG9ydEBmcmFuazRkZC5jb20wHhcNMTIw\n" +
|
||||||
|
"ODIyMDUyNzIzWhcNMTcwODIxMDUyNzIzWjBKMQswCQYDVQQGEwJKUDEOMAwGA1UE\n" +
|
||||||
|
"CAwFVG9reW8xETAPBgNVBAoMCEZyYW5rNEREMRgwFgYDVQQDDA93d3cuZXhhbXBs\n" +
|
||||||
|
"ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMYBBrx5PlP0WNI/ZdzD\n" +
|
||||||
|
"+6Pktmurn+F2kQYbtc7XQh8/LTBvCo+P6iZoLEmUA9e7EXLRxgU1CVqeAi7QcAn9\n" +
|
||||||
|
"MwBlc8ksFJHB0rtf9pmf8Oza9E0Bynlq/4/Kb1x+d+AyhL7oK9tQwB24uHOueHi1\n" +
|
||||||
|
"C/iVv8CSWKiYe6hzN1txYe8rAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAASPdjigJ\n" +
|
||||||
|
"kXCqKWpnZ/Oc75EUcMi6HztaW8abUMlYXPIgkV2F7YanHOB7K4f7OOLjiz8DTPFf\n" +
|
||||||
|
"jC9UeuErhaA/zzWi8ewMTFZW/WshOrm3fNvcMrMLKtH534JKvcdMg6qIdjTFINIr\n" +
|
||||||
|
"evnAhf0cwULaebn+lMs8Pdl7y37+sfluVok=\n" +
|
||||||
|
"-----END CERTIFICATE-----";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenEncryptionKey_whenMessageIsPassedToEncryptor_thenMessageIsEncrypted() throws Exception {
|
||||||
|
byte[] encryptedMessage = encryptor.encryptMessage(message.getBytes(),encKeyString.getBytes());
|
||||||
|
|
||||||
|
assertThat(encryptedMessage).isNotNull();
|
||||||
|
assertThat(encryptedMessage.length % 32).isEqualTo(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenCertificateWithPublicKey_whenMessageIsPassedToEncryptor_thenMessageIsEncrypted() throws Exception {
|
||||||
|
CertificateFactory factory = CertificateFactory.getInstance("X.509");
|
||||||
|
InputStream is = new ByteArrayInputStream(certificateString.getBytes());
|
||||||
|
X509Certificate certificate = (X509Certificate) factory.generateCertificate(is);
|
||||||
|
|
||||||
|
byte[] encryptedMessage = encryptor.encryptMessage(message.getBytes(),certificate);
|
||||||
|
|
||||||
|
assertThat(encryptedMessage).isNotNull();
|
||||||
|
assertThat(encryptedMessage.length % 128).isEqualTo(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenEncryptionKey_whenMessageIsEncrypted_thenDecryptMessage() throws Exception{
|
||||||
|
byte[] encryptedMessageBytes = encryptor.encryptMessage(message.getBytes(),encKeyString.getBytes());
|
||||||
|
|
||||||
|
byte[] clearMessageBytes = encryptor.decryptMessage(encryptedMessageBytes, encKeyString.getBytes());
|
||||||
|
|
||||||
|
assertThat(message).isEqualTo(new String(clearMessageBytes));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
package com.baeldung.initializationguide;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.*;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
|
||||||
|
public class UserTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenUserInstance_whenIntializedWithNew_thenInstanceIsNotNull() {
|
||||||
|
User user = new User("Alice", 1);
|
||||||
|
assertThat(user).isNotNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenUserInstance_whenInitializedWithReflection_thenInstanceIsNotNull() throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
|
||||||
|
User user = User.class.getConstructor(String.class, int.class)
|
||||||
|
.newInstance("Alice", 2);
|
||||||
|
assertThat(user).isNotNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenUserInstance_whenCopiedWithClone_thenExactMatchIsCreated() throws CloneNotSupportedException {
|
||||||
|
User user = new User("Alice", 3);
|
||||||
|
User clonedUser = (User) user.clone();
|
||||||
|
assertThat(clonedUser).isEqualTo(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenUserInstance_whenValuesAreNotInitialized_thenUserNameAndIdReturnDefault() {
|
||||||
|
User user = new User();
|
||||||
|
assertThat(user.getName()).isNull();
|
||||||
|
assertThat(user.getId() == 0);
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
package com.baeldung.tree;
|
package com.baeldung.tree;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
@ -26,6 +27,26 @@ public class BinaryTreeTest {
|
|||||||
assertFalse(bt.containsNode(1));
|
assertFalse(bt.containsNode(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenABinaryTree_WhenAddingExistingElement_ThenElementIsNotAdded() {
|
||||||
|
|
||||||
|
BinaryTree bt = createBinaryTree();
|
||||||
|
|
||||||
|
int initialSize = bt.getSize();
|
||||||
|
|
||||||
|
assertTrue(bt.containsNode(3));
|
||||||
|
bt.add(3);
|
||||||
|
assertEquals(initialSize, bt.getSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenABinaryTree_WhenLookingForNonExistingElement_ThenReturnsFalse() {
|
||||||
|
|
||||||
|
BinaryTree bt = createBinaryTree();
|
||||||
|
|
||||||
|
assertFalse(bt.containsNode(99));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenABinaryTree_WhenDeletingElements_ThenTreeDoesNotContainThoseElements() {
|
public void givenABinaryTree_WhenDeletingElements_ThenTreeDoesNotContainThoseElements() {
|
||||||
|
|
||||||
@ -36,6 +57,19 @@ public class BinaryTreeTest {
|
|||||||
assertFalse(bt.containsNode(9));
|
assertFalse(bt.containsNode(9));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenABinaryTree_WhenDeletingNonExistingElement_ThenTreeDoesNotDelete() {
|
||||||
|
|
||||||
|
BinaryTree bt = createBinaryTree();
|
||||||
|
|
||||||
|
int initialSize = bt.getSize();
|
||||||
|
|
||||||
|
assertFalse(bt.containsNode(99));
|
||||||
|
bt.delete(99);
|
||||||
|
assertFalse(bt.containsNode(99));
|
||||||
|
assertEquals(initialSize, bt.getSize());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenABinaryTree_WhenTraversingInOrder_ThenPrintValues() {
|
public void givenABinaryTree_WhenTraversingInOrder_ThenPrintValues() {
|
||||||
|
|
||||||
|
@ -1,59 +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>
|
|
||||||
|
|
||||||
<artifactId>flyway-callbacks</artifactId>
|
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
|
||||||
<packaging>jar</packaging>
|
|
||||||
|
|
||||||
<name>flyway-callbacks</name>
|
|
||||||
<description>Flyway Callbacks Demo</description>
|
|
||||||
|
|
||||||
<parent>
|
|
||||||
<artifactId>flyway</artifactId>
|
|
||||||
<groupId>com.baeldung</groupId>
|
|
||||||
<version>1.0</version>
|
|
||||||
<relativePath>../../flyway</relativePath>
|
|
||||||
</parent>
|
|
||||||
|
|
||||||
<properties>
|
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
|
||||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
|
||||||
<java.version>1.8</java.version>
|
|
||||||
</properties>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.flywaydb</groupId>
|
|
||||||
<artifactId>flyway-core</artifactId>
|
|
||||||
<version>5.0.2</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-jdbc</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.h2database</groupId>
|
|
||||||
<artifactId>h2</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-test</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
<build>
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
|
|
||||||
|
|
||||||
</project>
|
|
70
flyway/pom.xml
Normal file
70
flyway/pom.xml
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
<?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>flyway</artifactId>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>flyway</name>
|
||||||
|
<description>Flyway Callbacks Demo</description>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<artifactId>parent-boot-5</artifactId>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<relativePath>../parent-boot-5</relativePath>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||||
|
<java.version>1.8</java.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.flywaydb</groupId>
|
||||||
|
<artifactId>flyway-core</artifactId>
|
||||||
|
<version>5.0.2</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-jdbc</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>mysql</groupId>
|
||||||
|
<artifactId>mysql-connector-java</artifactId>
|
||||||
|
<version>6.0.3</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.h2database</groupId>
|
||||||
|
<artifactId>h2</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.flywaydb</groupId>
|
||||||
|
<artifactId>flyway-maven-plugin</artifactId>
|
||||||
|
<version>5.0.2</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
|
||||||
|
</project>
|
@ -1,13 +1,10 @@
|
|||||||
package com.baeldung.flywaycallbacks;
|
package com.baeldung.flywaycallbacks;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.flywaydb.core.Flyway;
|
import org.flywaydb.core.Flyway;
|
||||||
import org.flywaydb.core.api.MigrationInfoService;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@ -15,7 +12,6 @@ import org.springframework.test.annotation.DirtiesContext;
|
|||||||
import org.springframework.test.annotation.DirtiesContext.ClassMode;
|
import org.springframework.test.annotation.DirtiesContext.ClassMode;
|
||||||
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 com.baeldung.flywaycallbacks.FlywayCallbackTestConfig;
|
|
||||||
|
|
||||||
@RunWith(SpringRunner.class)
|
@RunWith(SpringRunner.class)
|
||||||
@DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)
|
@DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)
|
@ -41,7 +41,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.h2database</groupId>
|
<groupId>com.h2database</groupId>
|
||||||
<artifactId>h2</artifactId>
|
<artifactId>h2</artifactId>
|
||||||
<version>1.4.194</version>
|
<version>1.4.196</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.hibernate</groupId>
|
<groupId>org.hibernate</groupId>
|
||||||
|
@ -1,30 +0,0 @@
|
|||||||
package com.baeldung.hibernate;
|
|
||||||
|
|
||||||
import org.hibernate.Session;
|
|
||||||
import org.hibernate.SessionFactory;
|
|
||||||
import org.hibernate.Transaction;
|
|
||||||
|
|
||||||
import com.baeldung.hibernate.pojo.Supplier;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Hello world!
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class App {
|
|
||||||
public static void main(String[] args) {
|
|
||||||
try {
|
|
||||||
// NOTE: this is just for boostrap testing for multitenancy.
|
|
||||||
System.out.println("Checking the system.");
|
|
||||||
SessionFactory sessionFactory = HibernateMultiTenantUtil.getSessionFactory();
|
|
||||||
Session currentSession = sessionFactory.withOptions().tenantIdentifier("h2db1").openSession();
|
|
||||||
Transaction transaction = currentSession.getTransaction();
|
|
||||||
transaction.begin();
|
|
||||||
currentSession.createCriteria(Supplier.class).list().stream().forEach(System.out::println);
|
|
||||||
transaction.commit();
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,41 +0,0 @@
|
|||||||
package com.baeldung.hibernate;
|
|
||||||
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.hibernate.engine.jdbc.connections.spi.AbstractMultiTenantConnectionProvider;
|
|
||||||
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
|
|
||||||
|
|
||||||
public class ConfigurableMultiTenantConnectionProvider extends AbstractMultiTenantConnectionProvider {
|
|
||||||
|
|
||||||
private final Map<String, ConnectionProvider> connectionProviderMap =
|
|
||||||
new HashMap<>();
|
|
||||||
|
|
||||||
|
|
||||||
public ConfigurableMultiTenantConnectionProvider(
|
|
||||||
Map<String, ConnectionProvider> connectionProviderMap) {
|
|
||||||
this.connectionProviderMap.putAll( connectionProviderMap );
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
protected ConnectionProvider getAnyConnectionProvider() {
|
|
||||||
System.out.println("Any");
|
|
||||||
return connectionProviderMap.values().iterator().next();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected ConnectionProvider selectConnectionProvider(String tenantIdentifier) {
|
|
||||||
System.out.println("Specific");
|
|
||||||
return connectionProviderMap.get( tenantIdentifier );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Connection getConnection(String tenantIdentifier) throws SQLException {
|
|
||||||
Connection connection = super.getConnection(tenantIdentifier);
|
|
||||||
// uncomment to see option 2 for SCHEMA strategy.
|
|
||||||
//connection.createStatement().execute("SET SCHEMA '" + tenantIdentifier + "'");
|
|
||||||
return connection;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,115 +0,0 @@
|
|||||||
package com.baeldung.hibernate;
|
|
||||||
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Properties;
|
|
||||||
|
|
||||||
import org.hibernate.SessionFactory;
|
|
||||||
import org.hibernate.boot.Metadata;
|
|
||||||
import org.hibernate.boot.MetadataSources;
|
|
||||||
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
|
||||||
import org.hibernate.cfg.AvailableSettings;
|
|
||||||
import org.hibernate.cfg.Configuration;
|
|
||||||
import org.hibernate.cfg.Environment;
|
|
||||||
import org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl;
|
|
||||||
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
|
|
||||||
import org.hibernate.service.ServiceRegistry;
|
|
||||||
|
|
||||||
import com.baeldung.hibernate.pojo.Supplier;
|
|
||||||
|
|
||||||
public class HibernateMultiTenantUtil {
|
|
||||||
private static SessionFactory sessionFactory;
|
|
||||||
private static Map<String, ConnectionProvider> connectionProviderMap = new HashMap<>();
|
|
||||||
private static final String[] tenantDBNames = { "mydb1", "mydb2" };
|
|
||||||
|
|
||||||
public static SessionFactory getSessionFactory() throws UnsupportedTenancyException, IOException {
|
|
||||||
if (sessionFactory == null) {
|
|
||||||
// Configuration configuration = new Configuration().configure();
|
|
||||||
ServiceRegistry serviceRegistry = configureServiceRegistry();
|
|
||||||
sessionFactory = makeSessionFactory(serviceRegistry);
|
|
||||||
|
|
||||||
}
|
|
||||||
return sessionFactory;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static SessionFactory makeSessionFactory(ServiceRegistry serviceRegistry) {
|
|
||||||
MetadataSources metadataSources = new MetadataSources(serviceRegistry);
|
|
||||||
for (Class annotatedClasses : getAnnotatedClasses()) {
|
|
||||||
metadataSources.addAnnotatedClass(annotatedClasses);
|
|
||||||
}
|
|
||||||
|
|
||||||
Metadata metadata = metadataSources.buildMetadata();
|
|
||||||
return metadata.getSessionFactoryBuilder()
|
|
||||||
.build();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Class<?>[] getAnnotatedClasses() {
|
|
||||||
return new Class<?>[] { Supplier.class };
|
|
||||||
}
|
|
||||||
|
|
||||||
private static ServiceRegistry configureServiceRegistry() throws UnsupportedTenancyException, IOException {
|
|
||||||
|
|
||||||
// Properties properties = configuration.getProperties();
|
|
||||||
Properties properties = getProperties();
|
|
||||||
|
|
||||||
connectionProviderMap = setUpConnectionProviders(properties, tenantDBNames);
|
|
||||||
properties.put(AvailableSettings.MULTI_TENANT_CONNECTION_PROVIDER, new ConfigurableMultiTenantConnectionProvider(connectionProviderMap));
|
|
||||||
|
|
||||||
return new StandardServiceRegistryBuilder().applySettings(properties)
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Properties getProperties() throws IOException {
|
|
||||||
Properties properties = new Properties();
|
|
||||||
URL propertiesURL = Thread.currentThread()
|
|
||||||
.getContextClassLoader()
|
|
||||||
.getResource("hibernate-multitenancy.properties");
|
|
||||||
FileInputStream inputStream = new FileInputStream(propertiesURL.getFile());
|
|
||||||
properties.load(inputStream);
|
|
||||||
System.out.println("LOADED PROPERTIES FROM hibernate.properties");
|
|
||||||
|
|
||||||
return properties;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Map<String, ConnectionProvider> setUpConnectionProviders(Properties properties, String[] tenantNames) throws UnsupportedTenancyException {
|
|
||||||
Map<String, ConnectionProvider> providerMap = new HashMap<>();
|
|
||||||
for (String tenant : tenantNames) {
|
|
||||||
DriverManagerConnectionProviderImpl connectionProvider = new DriverManagerConnectionProviderImpl();
|
|
||||||
|
|
||||||
String tenantStrategy = properties.getProperty("hibernate.multiTenancy");
|
|
||||||
System.out.println("Strategy:" + tenantStrategy);
|
|
||||||
properties.put(Environment.URL, tenantUrl(properties.getProperty(Environment.URL), tenant, tenantStrategy));
|
|
||||||
System.out.println("URL:" + properties.getProperty(Environment.URL));
|
|
||||||
connectionProvider.configure(properties);
|
|
||||||
System.out.println("Tenant:" + tenant);
|
|
||||||
providerMap.put(tenant, connectionProvider);
|
|
||||||
|
|
||||||
}
|
|
||||||
System.out.println("Added connections for:");
|
|
||||||
providerMap.keySet()
|
|
||||||
.stream()
|
|
||||||
.forEach(System.out::println);
|
|
||||||
return providerMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Object tenantUrl(String originalUrl, String tenant, String tenantStrategy) throws UnsupportedTenancyException {
|
|
||||||
if (tenantStrategy.toUpperCase()
|
|
||||||
.equals("DATABASE")) {
|
|
||||||
return originalUrl.replace(DEFAULT_DB_NAME, tenant);
|
|
||||||
} else if (tenantStrategy.toUpperCase()
|
|
||||||
.equals("SCHEMA")) {
|
|
||||||
return originalUrl + String.format(SCHEMA_TOKEN, tenant);
|
|
||||||
} else {
|
|
||||||
throw new UnsupportedTenancyException("Not yet supported");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final String SCHEMA_TOKEN = ";INIT=CREATE SCHEMA IF NOT EXISTS %1$s\\;SET SCHEMA %1$s";
|
|
||||||
public static final String DEFAULT_DB_NAME = "mydb1";
|
|
||||||
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
package com.baeldung.hibernate.dao;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public interface GenericDao<T> {
|
|
||||||
|
|
||||||
void save (T entity);
|
|
||||||
void delete (T Entity);
|
|
||||||
T findByName(String name);
|
|
||||||
List<T> findAll();
|
|
||||||
void populate();
|
|
||||||
}
|
|
@ -1,80 +0,0 @@
|
|||||||
package com.baeldung.hibernate.dao;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.hibernate.Criteria;
|
|
||||||
import org.hibernate.Session;
|
|
||||||
import org.hibernate.SessionFactory;
|
|
||||||
import org.hibernate.Transaction;
|
|
||||||
import org.hibernate.criterion.Expression;
|
|
||||||
|
|
||||||
import com.baeldung.hibernate.pojo.Supplier;
|
|
||||||
|
|
||||||
public class SupplierDao implements GenericDao<Supplier>{
|
|
||||||
private SessionFactory sessionFactory;
|
|
||||||
private String tenant;
|
|
||||||
|
|
||||||
public SupplierDao(SessionFactory sessionFactory, String tenant) {
|
|
||||||
this.sessionFactory = sessionFactory;
|
|
||||||
this.tenant = tenant;
|
|
||||||
populate();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void save(Supplier entity) {
|
|
||||||
Session session = sessionFactory.withOptions().tenantIdentifier(tenant).openSession();
|
|
||||||
session.save(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void delete(Supplier supplier) {
|
|
||||||
Session session = sessionFactory.withOptions().tenantIdentifier(tenant).openSession();
|
|
||||||
session.delete(supplier);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Supplier findByName(String name) {
|
|
||||||
Session session = sessionFactory.withOptions().tenantIdentifier(tenant).openSession();
|
|
||||||
List<Supplier> fetchedSuppliers = session.createCriteria(Supplier.class).add(Expression.eq("name", name)).list();
|
|
||||||
if (fetchedSuppliers.size()>0) {
|
|
||||||
return fetchedSuppliers.get(0);
|
|
||||||
}else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<Supplier> findAll() {
|
|
||||||
Session session = sessionFactory.withOptions().tenantIdentifier(tenant).openSession();
|
|
||||||
return session.createCriteria(Supplier.class).list();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void populate() {
|
|
||||||
System.out.println("Init DB1");
|
|
||||||
Session session = sessionFactory.withOptions().tenantIdentifier(tenant).openSession();
|
|
||||||
Transaction transaction = session.getTransaction();
|
|
||||||
|
|
||||||
transaction.begin();
|
|
||||||
session.createSQLQuery("DROP ALL OBJECTS").executeUpdate();
|
|
||||||
session
|
|
||||||
.createSQLQuery(
|
|
||||||
"create table Supplier (id integer generated by default as identity, country varchar(255), name varchar(255), primary key (id))")
|
|
||||||
.executeUpdate();
|
|
||||||
Supplier genertedSupplier = generateEntityForTenant(tenant);
|
|
||||||
System.out.println("Inserting Supplier"+genertedSupplier);
|
|
||||||
save (genertedSupplier);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private Supplier generateEntityForTenant(String forTenant) {
|
|
||||||
if (forTenant.equals("mydb1")) {
|
|
||||||
return new Supplier ("John","USA");
|
|
||||||
}
|
|
||||||
return new Supplier ("Miller","UK");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@ -0,0 +1,32 @@
|
|||||||
|
package com.baeldung.hibernate.interceptors;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import org.hibernate.EmptyInterceptor;
|
||||||
|
import org.hibernate.type.Type;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import com.baeldung.hibernate.interceptors.entity.User;
|
||||||
|
|
||||||
|
public class CustomInterceptor extends EmptyInterceptor {
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(CustomInterceptor.class);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) {
|
||||||
|
if (entity instanceof User) {
|
||||||
|
logger.info(((User) entity).toString());
|
||||||
|
}
|
||||||
|
return super.onSave(entity, id, state, propertyNames, types);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onFlushDirty(Object entity, Serializable id, Object[] currentState, Object [] previousState, String[] propertyNames, Type[] types) {
|
||||||
|
if (entity instanceof User) {
|
||||||
|
((User) entity).setLastModified(new Date());
|
||||||
|
logger.info(((User) entity).toString());
|
||||||
|
}
|
||||||
|
return super.onFlushDirty(entity, id, currentState, previousState, propertyNames, types);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,122 @@
|
|||||||
|
package com.baeldung.hibernate.interceptors;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
import org.hibernate.CallbackException;
|
||||||
|
import org.hibernate.EntityMode;
|
||||||
|
import org.hibernate.Interceptor;
|
||||||
|
import org.hibernate.Transaction;
|
||||||
|
import org.hibernate.type.Type;
|
||||||
|
|
||||||
|
public class CustomInterceptorImpl implements Interceptor {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onLoad(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) throws CallbackException {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onFlushDirty(Object entity, Serializable id, Object[] currentState, Object[] previousState, String[] propertyNames, Type[] types) throws CallbackException {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) throws CallbackException {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDelete(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) throws CallbackException {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCollectionRecreate(Object collection, Serializable key) throws CallbackException {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCollectionRemove(Object collection, Serializable key) throws CallbackException {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCollectionUpdate(Object collection, Serializable key) throws CallbackException {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void preFlush(Iterator entities) throws CallbackException {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void postFlush(Iterator entities) throws CallbackException {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean isTransient(Object entity) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int[] findDirty(Object entity, Serializable id, Object[] currentState, Object[] previousState, String[] propertyNames, Type[] types) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object instantiate(String entityName, EntityMode entityMode, Serializable id) throws CallbackException {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getEntityName(Object object) throws CallbackException {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getEntity(String entityName, Serializable id) throws CallbackException {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterTransactionBegin(Transaction tx) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beforeTransactionCompletion(Transaction tx) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterTransactionCompletion(Transaction tx) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String onPrepareStatement(String sql) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,79 @@
|
|||||||
|
package com.baeldung.hibernate.interceptors;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.hibernate.Interceptor;
|
||||||
|
import org.hibernate.Session;
|
||||||
|
import org.hibernate.SessionFactory;
|
||||||
|
import org.hibernate.boot.Metadata;
|
||||||
|
import org.hibernate.boot.MetadataSources;
|
||||||
|
import org.hibernate.boot.SessionFactoryBuilder;
|
||||||
|
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
||||||
|
import org.hibernate.service.ServiceRegistry;
|
||||||
|
|
||||||
|
import com.baeldung.hibernate.interceptors.entity.User;
|
||||||
|
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
public class HibernateUtil {
|
||||||
|
private static SessionFactory sessionFactory;
|
||||||
|
private static String PROPERTY_FILE_NAME;
|
||||||
|
|
||||||
|
public static SessionFactory getSessionFactory() throws IOException {
|
||||||
|
return getSessionFactory(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SessionFactory getSessionFactory(String propertyFileName) throws IOException {
|
||||||
|
PROPERTY_FILE_NAME = propertyFileName;
|
||||||
|
if (sessionFactory == null) {
|
||||||
|
ServiceRegistry serviceRegistry = configureServiceRegistry();
|
||||||
|
sessionFactory = getSessionFactoryBuilder(serviceRegistry).build();
|
||||||
|
}
|
||||||
|
return sessionFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SessionFactory getSessionFactoryWithInterceptor(String propertyFileName, Interceptor interceptor) throws IOException {
|
||||||
|
PROPERTY_FILE_NAME = propertyFileName;
|
||||||
|
if (sessionFactory == null) {
|
||||||
|
ServiceRegistry serviceRegistry = configureServiceRegistry();
|
||||||
|
sessionFactory = getSessionFactoryBuilder(serviceRegistry).applyInterceptor(interceptor)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
return sessionFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Session getSessionWithInterceptor(Interceptor interceptor) throws IOException {
|
||||||
|
return getSessionFactory().withOptions()
|
||||||
|
.interceptor(interceptor)
|
||||||
|
.openSession();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static SessionFactoryBuilder getSessionFactoryBuilder(ServiceRegistry serviceRegistry) {
|
||||||
|
MetadataSources metadataSources = new MetadataSources(serviceRegistry);
|
||||||
|
metadataSources.addPackage("com.baeldung.hibernate.interceptors");
|
||||||
|
metadataSources.addAnnotatedClass(User.class);
|
||||||
|
|
||||||
|
Metadata metadata = metadataSources.buildMetadata();
|
||||||
|
return metadata.getSessionFactoryBuilder();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ServiceRegistry configureServiceRegistry() throws IOException {
|
||||||
|
Properties properties = getProperties();
|
||||||
|
return new StandardServiceRegistryBuilder().applySettings(properties)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Properties getProperties() throws IOException {
|
||||||
|
Properties properties = new Properties();
|
||||||
|
URL propertiesURL = Thread.currentThread()
|
||||||
|
.getContextClassLoader()
|
||||||
|
.getResource(StringUtils.defaultString(PROPERTY_FILE_NAME, "hibernate-interceptors.properties"));
|
||||||
|
try (FileInputStream inputStream = new FileInputStream(propertiesURL.getFile())) {
|
||||||
|
properties.load(inputStream);
|
||||||
|
}
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,64 @@
|
|||||||
|
package com.baeldung.hibernate.interceptors.entity;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import javax.persistence.Basic;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.GenerationType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Temporal;
|
||||||
|
import javax.persistence.TemporalType;
|
||||||
|
|
||||||
|
@Entity(name = "hbi_user")
|
||||||
|
public class User {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.SEQUENCE)
|
||||||
|
private long id;
|
||||||
|
private String name;
|
||||||
|
private String about;
|
||||||
|
@Basic
|
||||||
|
@Temporal(TemporalType.DATE)
|
||||||
|
private Date lastModified;
|
||||||
|
|
||||||
|
public User() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public User(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getLastModified() {
|
||||||
|
return lastModified;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastModified(Date lastModified) {
|
||||||
|
this.lastModified = lastModified;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAbout() {
|
||||||
|
return about;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAbout(String about) {
|
||||||
|
this.about = about;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return String.format("ID: %d\nName: %s\nLast Modified: %s\nAbout: %s\n", getId(), getName(), getLastModified(), getAbout());
|
||||||
|
}
|
||||||
|
}
|
@ -1,67 +0,0 @@
|
|||||||
package com.baeldung.hibernate.pojo;
|
|
||||||
// Generated Feb 9, 2017 11:31:36 AM by Hibernate Tools 5.1.0.Final
|
|
||||||
|
|
||||||
import javax.persistence.Entity;
|
|
||||||
import javax.persistence.GeneratedValue;
|
|
||||||
import javax.persistence.GenerationType;
|
|
||||||
import javax.persistence.Id;
|
|
||||||
import javax.persistence.Table;
|
|
||||||
|
|
||||||
import org.junit.runners.Suite.SuiteClasses;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Suppliers generated by hbm2java
|
|
||||||
*/
|
|
||||||
@Entity(name = "Supplier")
|
|
||||||
@Table(name ="Supplier")
|
|
||||||
public class Supplier implements java.io.Serializable {
|
|
||||||
|
|
||||||
@Id
|
|
||||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
|
||||||
private Integer id;
|
|
||||||
private String name;
|
|
||||||
private String country;
|
|
||||||
|
|
||||||
public Supplier() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public Supplier(String name, String country) {
|
|
||||||
this.name = name;
|
|
||||||
this.country = country;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getId() {
|
|
||||||
return this.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setId(Integer id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return this.name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setName(String name) {
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getCountry() {
|
|
||||||
return this.country;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCountry(String country) {
|
|
||||||
this.country = country;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return new StringBuffer().append("[").append(id).append(",").append(name).append(",").append(country).append("]").toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj) {
|
|
||||||
return name.equals(((Supplier) obj).getName());
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,30 +0,0 @@
|
|||||||
package com.baeldung.hibernate;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import org.hibernate.SessionFactory;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import com.baeldung.hibernate.dao.SupplierDao;
|
|
||||||
import com.baeldung.hibernate.pojo.Supplier;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertNull;;
|
|
||||||
|
|
||||||
public class MultiTenantDaoHibernateIntegrationTest {
|
|
||||||
@Test
|
|
||||||
public void givenDBMode_whenFetchingSuppliersByName_thenChecking() throws UnsupportedTenancyException, IOException {
|
|
||||||
SessionFactory sessionFactory = HibernateMultiTenantUtil.getSessionFactory();
|
|
||||||
|
|
||||||
SupplierDao myDb1Dao = new SupplierDao(sessionFactory, "mydb1");
|
|
||||||
Supplier db1SupplierName = myDb1Dao.findByName("John");
|
|
||||||
|
|
||||||
// finding the same supplier name in another tenant
|
|
||||||
// and we should not be able to find in there and both dbs are different.
|
|
||||||
SupplierDao myDb2Dao = new SupplierDao(sessionFactory, "mydb2");
|
|
||||||
Supplier db2SupplierName = myDb2Dao.findByName(db1SupplierName.getName());
|
|
||||||
|
|
||||||
assertNull(db2SupplierName);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -0,0 +1,62 @@
|
|||||||
|
package com.baeldung.hibernate.interceptors;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import org.hibernate.Session;
|
||||||
|
import org.hibernate.SessionFactory;
|
||||||
|
import org.hibernate.Transaction;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.baeldung.hibernate.interceptors.entity.User;
|
||||||
|
|
||||||
|
public class HibernateInterceptorTest {
|
||||||
|
private static SessionFactory sessionFactory;
|
||||||
|
private static Serializable userId;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void init() throws IOException {
|
||||||
|
sessionFactory = HibernateUtil.getSessionFactoryWithInterceptor(null, new CustomInterceptor());
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
|
public static void finish() {
|
||||||
|
if(userId != null) {
|
||||||
|
Session session = sessionFactory.getCurrentSession();
|
||||||
|
Transaction transaction = session.beginTransaction();
|
||||||
|
User user = session.load(User.class, userId);
|
||||||
|
if(user != null) {
|
||||||
|
session.delete(user);
|
||||||
|
}
|
||||||
|
transaction.commit();
|
||||||
|
session.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenHibernateInterceptorAndSessionScoped_whenUserCreated_shouldSucceed() {
|
||||||
|
Session session = sessionFactory.withOptions().interceptor(new CustomInterceptor()).openSession();
|
||||||
|
User user = new User("Benjamin Franklin");
|
||||||
|
Transaction transaction = session.beginTransaction();
|
||||||
|
userId = session.save(user);
|
||||||
|
transaction.commit();
|
||||||
|
session.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenHibernateInterceptorAndSessionFactoryScoped_whenUserModified_shouldSucceed() {
|
||||||
|
Session session = sessionFactory.openSession();
|
||||||
|
Transaction transaction = session.beginTransaction();
|
||||||
|
User user = session.load(User.class, userId);
|
||||||
|
if(user != null) {
|
||||||
|
user.setAbout("I am a scientist.");
|
||||||
|
session.update(user);
|
||||||
|
}
|
||||||
|
transaction.commit();
|
||||||
|
session.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
package com.baeldung.hibernate.multitenancy;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
@Entity(name = "Car")
|
||||||
|
@Table(name = "Car")
|
||||||
|
public class Car implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1015320564683423342L;
|
||||||
|
|
||||||
|
private String brand;
|
||||||
|
|
||||||
|
@Id
|
||||||
|
public String getBrand() {
|
||||||
|
return brand;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBrand(String brand) {
|
||||||
|
this.brand = brand;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,104 @@
|
|||||||
|
package com.baeldung.hibernate.multitenancy;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import org.hibernate.Session;
|
||||||
|
import org.hibernate.SessionFactory;
|
||||||
|
import org.hibernate.Transaction;
|
||||||
|
import org.hibernate.boot.MetadataSources;
|
||||||
|
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
||||||
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
|
import org.hibernate.context.spi.CurrentTenantIdentifierResolver;
|
||||||
|
import org.hibernate.service.ServiceRegistry;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
|
|
||||||
|
import com.baeldung.hibernate.multitenancy.database.TenantIdNames;
|
||||||
|
|
||||||
|
public abstract class MultitenancyIntegrationTest {
|
||||||
|
|
||||||
|
public abstract String getPropertyFile();
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private CurrentTenantIdentifierResolver currentTenantIdentifierResolver;
|
||||||
|
|
||||||
|
private SessionFactory sessionFactory;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setup() throws IOException {
|
||||||
|
MockitoAnnotations.initMocks(this);
|
||||||
|
|
||||||
|
Mockito.when(currentTenantIdentifierResolver.validateExistingCurrentSessions())
|
||||||
|
.thenReturn(false);
|
||||||
|
|
||||||
|
Properties properties = getHibernateProperties();
|
||||||
|
properties.put(AvailableSettings.MULTI_TENANT_IDENTIFIER_RESOLVER, currentTenantIdentifierResolver);
|
||||||
|
|
||||||
|
sessionFactory = buildSessionFactory(properties);
|
||||||
|
|
||||||
|
initTenant(TenantIdNames.MYDB1);
|
||||||
|
initTenant(TenantIdNames.MYDB2);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void initTenant(String tenantId) {
|
||||||
|
whenCurrentTenantIs(tenantId);
|
||||||
|
createCarTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void whenCurrentTenantIs(String tenantId) {
|
||||||
|
Mockito.when(currentTenantIdentifierResolver.resolveCurrentTenantIdentifier())
|
||||||
|
.thenReturn(tenantId);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void whenAddCar(String brand) {
|
||||||
|
Session session = sessionFactory.openSession();
|
||||||
|
Transaction tx = session.beginTransaction();
|
||||||
|
Car car = new Car();
|
||||||
|
car.setBrand(brand);
|
||||||
|
session.save(car);
|
||||||
|
tx.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void thenCarFound(String brand) {
|
||||||
|
Session session = sessionFactory.openSession();
|
||||||
|
assertNotNull(session.get(Car.class, brand));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void thenCarNotFound(String brand) {
|
||||||
|
Session session = sessionFactory.openSession();
|
||||||
|
assertNull(session.get(Car.class, brand));
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
private void createCarTable() {
|
||||||
|
Session session = sessionFactory.openSession();
|
||||||
|
Transaction tx = session.beginTransaction();
|
||||||
|
session.createSQLQuery("drop table Car if exists")
|
||||||
|
.executeUpdate();
|
||||||
|
session.createSQLQuery("create table Car (brand varchar(255) primary key)")
|
||||||
|
.executeUpdate();
|
||||||
|
tx.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Properties getHibernateProperties() throws IOException {
|
||||||
|
Properties properties = new Properties();
|
||||||
|
properties.load(getClass().getResourceAsStream(getPropertyFile()));
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static SessionFactory buildSessionFactory(Properties properties) {
|
||||||
|
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(properties)
|
||||||
|
.build();
|
||||||
|
MetadataSources metadataSources = new MetadataSources(serviceRegistry);
|
||||||
|
metadataSources.addAnnotatedClass(Car.class);
|
||||||
|
return metadataSources.buildMetadata()
|
||||||
|
.buildSessionFactory();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
package com.baeldung.hibernate.multitenancy.database;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.baeldung.hibernate.multitenancy.MultitenancyIntegrationTest;
|
||||||
|
|
||||||
|
public class DatabaseApproachMultitenancyIntegrationTest extends MultitenancyIntegrationTest {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPropertyFile() {
|
||||||
|
return "/hibernate-database-multitenancy.properties";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenDatabaseApproach_whenAddingEntries_thenOnlyAddedToConcreteDatabase() throws IOException {
|
||||||
|
whenCurrentTenantIs(TenantIdNames.MYDB1);
|
||||||
|
whenAddCar("myCar");
|
||||||
|
thenCarFound("myCar");
|
||||||
|
whenCurrentTenantIs(TenantIdNames.MYDB2);
|
||||||
|
thenCarNotFound("myCar");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
package com.baeldung.hibernate.multitenancy.database;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl;
|
||||||
|
import org.hibernate.engine.jdbc.connections.spi.AbstractMultiTenantConnectionProvider;
|
||||||
|
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
|
||||||
|
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
public class MapMultiTenantConnectionProvider extends AbstractMultiTenantConnectionProvider {
|
||||||
|
|
||||||
|
private final Map<String, ConnectionProvider> connectionProviderMap = new HashMap<>();
|
||||||
|
|
||||||
|
public MapMultiTenantConnectionProvider() throws IOException {
|
||||||
|
initConnectionProviderForTenant(TenantIdNames.MYDB1);
|
||||||
|
initConnectionProviderForTenant(TenantIdNames.MYDB2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ConnectionProvider getAnyConnectionProvider() {
|
||||||
|
return connectionProviderMap.values()
|
||||||
|
.iterator()
|
||||||
|
.next();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ConnectionProvider selectConnectionProvider(String tenantIdentifier) {
|
||||||
|
return connectionProviderMap.get(tenantIdentifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initConnectionProviderForTenant(String tenantId) throws IOException {
|
||||||
|
Properties properties = new Properties();
|
||||||
|
properties.load(getClass().getResourceAsStream(String.format("/hibernate-database-%s.properties", tenantId)));
|
||||||
|
DriverManagerConnectionProviderImpl connectionProvider = new DriverManagerConnectionProviderImpl();
|
||||||
|
connectionProvider.configure(properties);
|
||||||
|
this.connectionProviderMap.put(tenantId, connectionProvider);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
package com.baeldung.hibernate.multitenancy.database;
|
||||||
|
|
||||||
|
public class TenantIdNames {
|
||||||
|
public static final String MYDB1 = "mydb1";
|
||||||
|
public static final String MYDB2 = "mydb2";
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
package com.baeldung.hibernate.multitenancy.schema;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.baeldung.hibernate.multitenancy.MultitenancyIntegrationTest;
|
||||||
|
import com.baeldung.hibernate.multitenancy.database.TenantIdNames;
|
||||||
|
|
||||||
|
public class SchemaApproachMultitenancyIntegrationTest extends MultitenancyIntegrationTest {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPropertyFile() {
|
||||||
|
return "/hibernate-schema-multitenancy.properties";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenSchemaApproach_whenAddingEntries_thenOnlyAddedToConcreteSchema() throws IOException {
|
||||||
|
whenCurrentTenantIs(TenantIdNames.MYDB1);
|
||||||
|
whenAddCar("Ferrari");
|
||||||
|
thenCarFound("Ferrari");
|
||||||
|
whenCurrentTenantIs(TenantIdNames.MYDB2);
|
||||||
|
thenCarNotFound("Ferrari");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,49 @@
|
|||||||
|
package com.baeldung.hibernate.multitenancy.schema;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl;
|
||||||
|
import org.hibernate.engine.jdbc.connections.spi.AbstractMultiTenantConnectionProvider;
|
||||||
|
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
|
||||||
|
import org.junit.Assert;
|
||||||
|
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
public class SchemaMultiTenantConnectionProvider extends AbstractMultiTenantConnectionProvider {
|
||||||
|
|
||||||
|
private final ConnectionProvider connectionProvider = initConnectionProvider();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ConnectionProvider getAnyConnectionProvider() {
|
||||||
|
return connectionProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ConnectionProvider selectConnectionProvider(String tenantIdentifier) {
|
||||||
|
return connectionProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Connection getConnection(String tenantIdentifier) throws SQLException {
|
||||||
|
Connection connection = super.getConnection(tenantIdentifier);
|
||||||
|
connection.createStatement()
|
||||||
|
.execute(String.format("SET SCHEMA %s;", tenantIdentifier));
|
||||||
|
return connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ConnectionProvider initConnectionProvider() {
|
||||||
|
Properties properties = new Properties();
|
||||||
|
try {
|
||||||
|
properties.load(getClass().getResourceAsStream("/hibernate-schema-multitenancy.properties"));
|
||||||
|
} catch (IOException e) {
|
||||||
|
Assert.fail("Error loading resource. Cause: " + e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
DriverManagerConnectionProviderImpl connectionProvider = new DriverManagerConnectionProviderImpl();
|
||||||
|
connectionProvider.configure(properties);
|
||||||
|
return connectionProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
package com.baeldung.hibernate.multitenancy.schema;
|
||||||
|
|
||||||
|
public class TenantIdNames {
|
||||||
|
public static final String MYDB1 = "mydb1";
|
||||||
|
public static final String MYDB2 = "mydb2";
|
||||||
|
}
|
@ -0,0 +1,2 @@
|
|||||||
|
hibernate.multiTenancy=DATABASE
|
||||||
|
hibernate.multi_tenant_connection_provider=com.baeldung.hibernate.multitenancy.database.MapMultiTenantConnectionProvider
|
@ -0,0 +1,4 @@
|
|||||||
|
hibernate.connection.driver_class=org.h2.Driver
|
||||||
|
hibernate.connection.url=jdbc:h2:mem:mydb1;DB_CLOSE_DELAY=-1
|
||||||
|
hibernate.connection.username=sa
|
||||||
|
hibernate.dialect=org.hibernate.dialect.H2Dialect
|
@ -0,0 +1,4 @@
|
|||||||
|
hibernate.connection.driver_class=org.h2.Driver
|
||||||
|
hibernate.connection.url=jdbc:h2:mem:mydb2;DB_CLOSE_DELAY=-1
|
||||||
|
hibernate.connection.username=sa
|
||||||
|
hibernate.dialect=org.hibernate.dialect.H2Dialect
|
@ -6,4 +6,5 @@ jdbc.password=
|
|||||||
|
|
||||||
hibernate.dialect=org.hibernate.dialect.H2Dialect
|
hibernate.dialect=org.hibernate.dialect.H2Dialect
|
||||||
hibernate.show_sql=true
|
hibernate.show_sql=true
|
||||||
hibernate.multiTenancy=DATABASE
|
hibernate.hbm2ddl.auto=create-drop
|
||||||
|
hibernate.current_session_context_class=org.hibernate.context.internal.ThreadLocalSessionContext
|
@ -0,0 +1,7 @@
|
|||||||
|
hibernate.connection.driver_class=org.h2.Driver
|
||||||
|
hibernate.connection.url=jdbc:h2:mem:mydb1;DB_CLOSE_DELAY=-1;INIT=CREATE SCHEMA IF NOT EXISTS MYDB1\\;CREATE SCHEMA IF NOT EXISTS MYDB2\\;
|
||||||
|
hibernate.connection.username=sa
|
||||||
|
hibernate.connection.autocommit=true
|
||||||
|
hibernate.dialect=org.hibernate.dialect.H2Dialect
|
||||||
|
hibernate.multiTenancy=SCHEMA
|
||||||
|
hibernate.multi_tenant_connection_provider=com.baeldung.hibernate.multitenancy.schema.SchemaMultiTenantConnectionProvider
|
17
influxdb/README.md
Normal file
17
influxdb/README.md
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
## Influx SDK Tutorial Project
|
||||||
|
|
||||||
|
### Relevant Article:
|
||||||
|
- [Introduction to using InfluxDB with Java](http://www.baeldung.com/using-influxdb-with-java/)
|
||||||
|
|
||||||
|
### Overview
|
||||||
|
This Maven project contains the Java code for the article linked above.
|
||||||
|
|
||||||
|
### Package Organization
|
||||||
|
Java classes for the intro tutorial are in the
|
||||||
|
org.baeldung.influxdb package.
|
||||||
|
|
||||||
|
|
||||||
|
### Running the tests
|
||||||
|
The test class expects an InfluxDB server to be available on localhost, at the default port of 8086 and with the default "admin" credentials.
|
||||||
|
|
||||||
|
```
|
44
influxdb/pom.xml
Normal file
44
influxdb/pom.xml
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
<?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>influxdb</artifactId>
|
||||||
|
<version>0.1-SNAPSHOT</version>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
<name>influxdb</name>
|
||||||
|
<description>InfluxDB SDK Tutorial</description>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>parent-modules</artifactId>
|
||||||
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.influxdb</groupId>
|
||||||
|
<artifactId>influxdb-java</artifactId>
|
||||||
|
<version>${influxdb.sdk.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<!-- Check for the most recent available version: https://projectlombok.org/changelog.html -->
|
||||||
|
<version>${lombok.version}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<java.version>1.8</java.version>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<influxdb.sdk.version>2.8</influxdb.sdk.version>
|
||||||
|
<lombok.version>1.16.18</lombok.version>
|
||||||
|
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
</project>
|
@ -0,0 +1,28 @@
|
|||||||
|
package com.baeldung.influxdb;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import org.influxdb.annotation.Column;
|
||||||
|
import org.influxdb.annotation.Measurement;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Measurement(name = "memory")
|
||||||
|
public class MemoryPoint {
|
||||||
|
|
||||||
|
@Column(name = "time")
|
||||||
|
private Instant time;
|
||||||
|
|
||||||
|
@Column(name = "name")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Column(name = "free")
|
||||||
|
private Long free;
|
||||||
|
|
||||||
|
@Column(name = "used")
|
||||||
|
private Long used;
|
||||||
|
|
||||||
|
@Column(name = "buffer")
|
||||||
|
private Long buffer;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,179 @@
|
|||||||
|
package com.baeldung.influxdb;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.influxdb.InfluxDB;
|
||||||
|
import org.influxdb.InfluxDBFactory;
|
||||||
|
import org.influxdb.InfluxDBIOException;
|
||||||
|
import org.influxdb.dto.*;
|
||||||
|
import org.influxdb.impl.InfluxDBResultMapper;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import static junit.framework.TestCase.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class InfluxDBConnectionLiveTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenCorrectInfoDatabaseConnects() {
|
||||||
|
|
||||||
|
InfluxDB connection = connectDatabase();
|
||||||
|
assertTrue(pingServer(connection));
|
||||||
|
}
|
||||||
|
|
||||||
|
private InfluxDB connectDatabase() {
|
||||||
|
|
||||||
|
// Connect to database assumed on localhost with default credentials.
|
||||||
|
return InfluxDBFactory.connect("http://127.0.0.1:8086", "admin", "admin");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean pingServer(InfluxDB influxDB) {
|
||||||
|
try {
|
||||||
|
// Ping and check for version string
|
||||||
|
Pong response = influxDB.ping();
|
||||||
|
if (response.getVersion().equalsIgnoreCase("unknown")) {
|
||||||
|
log.error("Error pinging server.");
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
log.info("Database version: {}", response.getVersion());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch (InfluxDBIOException idbo) {
|
||||||
|
log.error("Exception while pinging database: ", idbo);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenDatabaseCreatedDatabaseChecksOk() {
|
||||||
|
|
||||||
|
InfluxDB connection = connectDatabase();
|
||||||
|
|
||||||
|
// Create "baeldung and check for it
|
||||||
|
connection.createDatabase("baeldung");
|
||||||
|
assertTrue(connection.databaseExists("baeldung"));
|
||||||
|
|
||||||
|
// Verify that nonsense databases are not there
|
||||||
|
assertFalse(connection.databaseExists("foobar"));
|
||||||
|
|
||||||
|
// Drop "baeldung" and check again
|
||||||
|
connection.deleteDatabase("baeldung");
|
||||||
|
assertFalse(connection.databaseExists("baeldung"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenPointsWrittenPointsExists() throws Exception {
|
||||||
|
|
||||||
|
InfluxDB connection = connectDatabase();
|
||||||
|
|
||||||
|
String dbName = "baeldung";
|
||||||
|
connection.createDatabase(dbName);
|
||||||
|
|
||||||
|
// Need a retention policy before we can proceed
|
||||||
|
connection.createRetentionPolicy("defaultPolicy", "baeldung", "30d", 1, true);
|
||||||
|
|
||||||
|
// Since we are doing a batch thread, we need to set this as a default
|
||||||
|
connection.setRetentionPolicy("defaultPolicy");
|
||||||
|
|
||||||
|
// Enable batch mode
|
||||||
|
connection.enableBatch(10, 10, TimeUnit.MILLISECONDS);
|
||||||
|
|
||||||
|
for (int i = 0; i < 10; i++) {
|
||||||
|
Point point = Point.measurement("memory")
|
||||||
|
.time(System.currentTimeMillis(), TimeUnit.MILLISECONDS)
|
||||||
|
.addField("name", "server1")
|
||||||
|
.addField("free", 4743656L)
|
||||||
|
.addField("used", 1015096L)
|
||||||
|
.addField("buffer", 1010467L)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
connection.write(dbName, "defaultPolicy", point);
|
||||||
|
Thread.sleep(2);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unfortunately, the sleep inside the loop doesn't always add enough time to insure
|
||||||
|
// that Influx's batch thread flushes all of the writes and this sometimes fails without
|
||||||
|
// another brief pause.
|
||||||
|
Thread.sleep(10);
|
||||||
|
|
||||||
|
List<MemoryPoint> memoryPointList = getPoints(connection, "Select * from memory", "baeldung");
|
||||||
|
|
||||||
|
assertEquals(10, memoryPointList.size());
|
||||||
|
|
||||||
|
// Turn off batch and clean up
|
||||||
|
connection.disableBatch();
|
||||||
|
connection.deleteDatabase("baeldung");
|
||||||
|
connection.close();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<MemoryPoint> getPoints(InfluxDB connection, String query, String databaseName) {
|
||||||
|
|
||||||
|
// Run the query
|
||||||
|
Query queryObject = new Query(query, databaseName);
|
||||||
|
QueryResult queryResult = connection.query(queryObject);
|
||||||
|
|
||||||
|
// Map it
|
||||||
|
InfluxDBResultMapper resultMapper = new InfluxDBResultMapper();
|
||||||
|
return resultMapper.toPOJO(queryResult, MemoryPoint.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenBatchWrittenBatchExists() {
|
||||||
|
|
||||||
|
InfluxDB connection = connectDatabase();
|
||||||
|
|
||||||
|
String dbName = "baeldung";
|
||||||
|
connection.createDatabase(dbName);
|
||||||
|
|
||||||
|
// Need a retention policy before we can proceed
|
||||||
|
// Since we are doing batches, we need not set it
|
||||||
|
connection.createRetentionPolicy("defaultPolicy", "baeldung", "30d", 1, true);
|
||||||
|
|
||||||
|
|
||||||
|
BatchPoints batchPoints = BatchPoints
|
||||||
|
.database(dbName)
|
||||||
|
.retentionPolicy("defaultPolicy")
|
||||||
|
.build();
|
||||||
|
Point point1 = Point.measurement("memory")
|
||||||
|
.time(System.currentTimeMillis(), TimeUnit.MILLISECONDS)
|
||||||
|
.addField("free", 4743656L)
|
||||||
|
.addField("used", 1015096L)
|
||||||
|
.addField("buffer", 1010467L)
|
||||||
|
.build();
|
||||||
|
Point point2 = Point.measurement("memory")
|
||||||
|
.time(System.currentTimeMillis() - 100, TimeUnit.MILLISECONDS)
|
||||||
|
.addField("free", 4743696L)
|
||||||
|
.addField("used", 1016096L)
|
||||||
|
.addField("buffer", 1008467L)
|
||||||
|
.build();
|
||||||
|
batchPoints.point(point1);
|
||||||
|
batchPoints.point(point2);
|
||||||
|
connection.write(batchPoints);
|
||||||
|
|
||||||
|
List<MemoryPoint> memoryPointList = getPoints(connection, "Select * from memory", "baeldung");
|
||||||
|
|
||||||
|
assertEquals(2, memoryPointList.size());
|
||||||
|
assertTrue(4743696L == memoryPointList.get(0).getFree());
|
||||||
|
|
||||||
|
|
||||||
|
memoryPointList = getPoints(connection, "Select * from memory order by time desc", "baeldung");
|
||||||
|
|
||||||
|
assertEquals(2, memoryPointList.size());
|
||||||
|
assertTrue(4743656L == memoryPointList.get(0).getFree());
|
||||||
|
|
||||||
|
// Clean up database
|
||||||
|
connection.deleteDatabase("baeldung");
|
||||||
|
connection.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
13
influxdb/src/test/resources/logback.xml
Normal file
13
influxdb/src/test/resources/logback.xml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<configuration>
|
||||||
|
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||||
|
<encoder>
|
||||||
|
<pattern>web - %date [%thread] %-5level %logger{36} - %message%n
|
||||||
|
</pattern>
|
||||||
|
</encoder>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<root level="INFO">
|
||||||
|
<appender-ref ref="STDOUT" />
|
||||||
|
</root>
|
||||||
|
</configuration>
|
@ -1,5 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?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">
|
<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>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung</groupId>
|
||||||
@ -41,6 +42,29 @@
|
|||||||
<artifactId>ormlite-jdbc</artifactId>
|
<artifactId>ormlite-jdbc</artifactId>
|
||||||
<version>${ormlite.version}</version>
|
<version>${ormlite.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.kafka</groupId>
|
||||||
|
<artifactId>kafka-streams</artifactId>
|
||||||
|
<version>${kafka.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.kafka</groupId>
|
||||||
|
<artifactId>kafka-clients</artifactId>
|
||||||
|
<version>${kafka.version}</version>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>slf4j-log4j12</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.kafka</groupId>
|
||||||
|
<artifactId>kafka-clients</artifactId>
|
||||||
|
<version>${kafka.version}</version>
|
||||||
|
<classifier>test</classifier>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
@ -143,6 +167,12 @@
|
|||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>Apache Staging</id>
|
||||||
|
<url>https://repository.apache.org/content/groups/staging</url>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
<properties>
|
<properties>
|
||||||
<kryo.version>4.0.1</kryo.version>
|
<kryo.version>4.0.1</kryo.version>
|
||||||
<h2.version>1.4.196</h2.version>
|
<h2.version>1.4.196</h2.version>
|
||||||
@ -150,5 +180,6 @@
|
|||||||
<junit.version>4.12</junit.version>
|
<junit.version>4.12</junit.version>
|
||||||
<maven-compiler-plugin.version>3.7.0</maven-compiler-plugin.version>
|
<maven-compiler-plugin.version>3.7.0</maven-compiler-plugin.version>
|
||||||
<ormlite.version>5.0</ormlite.version>
|
<ormlite.version>5.0</ormlite.version>
|
||||||
|
<kafka.version>1.0.0</kafka.version>
|
||||||
</properties>
|
</properties>
|
||||||
</project>
|
</project>
|
@ -0,0 +1,62 @@
|
|||||||
|
package com.baeldung.kafkastreams;
|
||||||
|
|
||||||
|
import org.apache.kafka.clients.consumer.ConsumerConfig;
|
||||||
|
import org.apache.kafka.common.serialization.Serde;
|
||||||
|
import org.apache.kafka.common.serialization.Serdes;
|
||||||
|
import org.apache.kafka.streams.KafkaStreams;
|
||||||
|
import org.apache.kafka.streams.StreamsConfig;
|
||||||
|
import org.apache.kafka.streams.kstream.KStream;
|
||||||
|
import org.apache.kafka.streams.kstream.KStreamBuilder;
|
||||||
|
import org.apache.kafka.streams.kstream.KTable;
|
||||||
|
import org.apache.kafka.test.TestUtils;
|
||||||
|
import org.junit.Ignore;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public class KafkaStreamsLiveTest {
|
||||||
|
private String bootstrapServers = "localhost:9092";
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Ignore("it needs to have kafka broker running on local")
|
||||||
|
public void shouldTestKafkaStreams() throws InterruptedException {
|
||||||
|
//given
|
||||||
|
String inputTopic = "inputTopic";
|
||||||
|
|
||||||
|
Properties streamsConfiguration = new Properties();
|
||||||
|
streamsConfiguration.put(StreamsConfig.APPLICATION_ID_CONFIG, "wordcount-live-test");
|
||||||
|
streamsConfiguration.put(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers);
|
||||||
|
streamsConfiguration.put(StreamsConfig.DEFAULT_KEY_SERDE_CLASS_CONFIG, Serdes.String().getClass().getName());
|
||||||
|
streamsConfiguration.put(StreamsConfig.DEFAULT_VALUE_SERDE_CLASS_CONFIG, Serdes.String().getClass().getName());
|
||||||
|
streamsConfiguration.put(StreamsConfig.COMMIT_INTERVAL_MS_CONFIG, 1000);
|
||||||
|
streamsConfiguration.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
|
||||||
|
// Use a temporary directory for storing state, which will be automatically removed after the test.
|
||||||
|
streamsConfiguration.put(StreamsConfig.STATE_DIR_CONFIG, TestUtils.tempDirectory().getAbsolutePath());
|
||||||
|
|
||||||
|
//when
|
||||||
|
KStreamBuilder builder = new KStreamBuilder();
|
||||||
|
KStream<String, String> textLines = builder.stream(inputTopic);
|
||||||
|
Pattern pattern = Pattern.compile("\\W+", Pattern.UNICODE_CHARACTER_CLASS);
|
||||||
|
|
||||||
|
KTable<String, Long> wordCounts = textLines
|
||||||
|
.flatMapValues(value -> Arrays.asList(pattern.split(value.toLowerCase())))
|
||||||
|
.groupBy((key, word) -> word)
|
||||||
|
.count();
|
||||||
|
|
||||||
|
wordCounts.foreach((word, count) -> System.out.println("word: " + word + " -> " + count));
|
||||||
|
|
||||||
|
String outputTopic = "outputTopic";
|
||||||
|
final Serde<String> stringSerde = Serdes.String();
|
||||||
|
final Serde<Long> longSerde = Serdes.Long();
|
||||||
|
wordCounts.to(stringSerde, longSerde, outputTopic);
|
||||||
|
|
||||||
|
KafkaStreams streams = new KafkaStreams(builder, streamsConfiguration);
|
||||||
|
streams.start();
|
||||||
|
|
||||||
|
//then
|
||||||
|
Thread.sleep(30000);
|
||||||
|
streams.close();
|
||||||
|
}
|
||||||
|
}
|
@ -655,6 +655,29 @@
|
|||||||
<artifactId>google-api-services-sheets</artifactId>
|
<artifactId>google-api-services-sheets</artifactId>
|
||||||
<version>${google-sheets.version}</version>
|
<version>${google-sheets.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.kafka</groupId>
|
||||||
|
<artifactId>kafka-streams</artifactId>
|
||||||
|
<version>${kafka.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.kafka</groupId>
|
||||||
|
<artifactId>kafka-clients</artifactId>
|
||||||
|
<version>${kafka.version}</version>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>slf4j-log4j12</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.kafka</groupId>
|
||||||
|
<artifactId>kafka-clients</artifactId>
|
||||||
|
<version>${kafka.version}</version>
|
||||||
|
<classifier>test</classifier>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<repositories>
|
<repositories>
|
||||||
<repository>
|
<repository>
|
||||||
@ -670,6 +693,10 @@
|
|||||||
<name>bintray</name>
|
<name>bintray</name>
|
||||||
<url>http://dl.bintray.com/cuba-platform/main</url>
|
<url>http://dl.bintray.com/cuba-platform/main</url>
|
||||||
</repository>
|
</repository>
|
||||||
|
<repository>
|
||||||
|
<id>Apache Staging</id>
|
||||||
|
<url>https://repository.apache.org/content/groups/staging</url>
|
||||||
|
</repository>
|
||||||
</repositories>
|
</repositories>
|
||||||
<properties>
|
<properties>
|
||||||
<googleclient.version>1.23.0</googleclient.version>
|
<googleclient.version>1.23.0</googleclient.version>
|
||||||
@ -730,5 +757,6 @@
|
|||||||
<caffeine.version>2.5.5</caffeine.version>
|
<caffeine.version>2.5.5</caffeine.version>
|
||||||
<google-api.version>1.23.0</google-api.version>
|
<google-api.version>1.23.0</google-api.version>
|
||||||
<google-sheets.version>v4-rev493-1.21.0</google-sheets.version>
|
<google-sheets.version>v4-rev493-1.21.0</google-sheets.version>
|
||||||
|
<kafka.version>1.0.0</kafka.version>
|
||||||
</properties>
|
</properties>
|
||||||
</project>
|
</project>
|
@ -0,0 +1,62 @@
|
|||||||
|
package com.baeldung.kafkastreams;
|
||||||
|
|
||||||
|
import org.apache.kafka.clients.consumer.ConsumerConfig;
|
||||||
|
import org.apache.kafka.common.serialization.Serde;
|
||||||
|
import org.apache.kafka.common.serialization.Serdes;
|
||||||
|
import org.apache.kafka.streams.KafkaStreams;
|
||||||
|
import org.apache.kafka.streams.StreamsConfig;
|
||||||
|
import org.apache.kafka.streams.kstream.KStream;
|
||||||
|
import org.apache.kafka.streams.kstream.KStreamBuilder;
|
||||||
|
import org.apache.kafka.streams.kstream.KTable;
|
||||||
|
import org.apache.kafka.test.TestUtils;
|
||||||
|
import org.junit.Ignore;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public class KafkaStreamsLiveTest {
|
||||||
|
private String bootstrapServers = "localhost:9092";
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Ignore("it needs to have kafka broker running on local")
|
||||||
|
public void shouldTestKafkaStreams() throws InterruptedException {
|
||||||
|
//given
|
||||||
|
String inputTopic = "inputTopic";
|
||||||
|
|
||||||
|
Properties streamsConfiguration = new Properties();
|
||||||
|
streamsConfiguration.put(StreamsConfig.APPLICATION_ID_CONFIG, "wordcount-live-test");
|
||||||
|
streamsConfiguration.put(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers);
|
||||||
|
streamsConfiguration.put(StreamsConfig.DEFAULT_KEY_SERDE_CLASS_CONFIG, Serdes.String().getClass().getName());
|
||||||
|
streamsConfiguration.put(StreamsConfig.DEFAULT_VALUE_SERDE_CLASS_CONFIG, Serdes.String().getClass().getName());
|
||||||
|
streamsConfiguration.put(StreamsConfig.COMMIT_INTERVAL_MS_CONFIG, 1000);
|
||||||
|
streamsConfiguration.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
|
||||||
|
// Use a temporary directory for storing state, which will be automatically removed after the test.
|
||||||
|
streamsConfiguration.put(StreamsConfig.STATE_DIR_CONFIG, TestUtils.tempDirectory().getAbsolutePath());
|
||||||
|
|
||||||
|
//when
|
||||||
|
KStreamBuilder builder = new KStreamBuilder();
|
||||||
|
KStream<String, String> textLines = builder.stream(inputTopic);
|
||||||
|
Pattern pattern = Pattern.compile("\\W+", Pattern.UNICODE_CHARACTER_CLASS);
|
||||||
|
|
||||||
|
KTable<String, Long> wordCounts = textLines
|
||||||
|
.flatMapValues(value -> Arrays.asList(pattern.split(value.toLowerCase())))
|
||||||
|
.groupBy((key, word) -> word)
|
||||||
|
.count();
|
||||||
|
|
||||||
|
wordCounts.foreach((word, count) -> System.out.println("word: " + word + " -> " + count));
|
||||||
|
|
||||||
|
String outputTopic = "outputTopic";
|
||||||
|
final Serde<String> stringSerde = Serdes.String();
|
||||||
|
final Serde<Long> longSerde = Serdes.Long();
|
||||||
|
wordCounts.to(stringSerde, longSerde, outputTopic);
|
||||||
|
|
||||||
|
KafkaStreams streams = new KafkaStreams(builder, streamsConfiguration);
|
||||||
|
streams.start();
|
||||||
|
|
||||||
|
//then
|
||||||
|
Thread.sleep(30000);
|
||||||
|
streams.close();
|
||||||
|
}
|
||||||
|
}
|
BIN
orientdb/.mvn/wrapper/maven-wrapper.jar
vendored
Normal file
BIN
orientdb/.mvn/wrapper/maven-wrapper.jar
vendored
Normal file
Binary file not shown.
1
orientdb/.mvn/wrapper/maven-wrapper.properties
vendored
Normal file
1
orientdb/.mvn/wrapper/maven-wrapper.properties
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.3.9/apache-maven-3.3.9-bin.zip
|
25
orientdb/README.md
Normal file
25
orientdb/README.md
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
Introduction to the OrientDB Java APIs
|
||||||
|
======================================
|
||||||
|
|
||||||
|
This is a simple maven project that shows how to use OrientDB's Java APIs.
|
||||||
|
|
||||||
|
### Requirements
|
||||||
|
|
||||||
|
- Maven
|
||||||
|
- Java 7 or higher
|
||||||
|
- OrientDB
|
||||||
|
|
||||||
|
### Build
|
||||||
|
|
||||||
|
To build and start the server simply type
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ mvn clean install
|
||||||
|
```
|
||||||
|
|
||||||
|
### Run Tests
|
||||||
|
|
||||||
|
Before launching unit tests:
|
||||||
|
- Install OrientDB
|
||||||
|
- Create BaeldungDB, BaeldungDBTwo and BaeldungDBThree databases
|
||||||
|
- Uncomment annotations on the test files
|
233
orientdb/mvnw
vendored
Executable file
233
orientdb/mvnw
vendored
Executable file
@ -0,0 +1,233 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
|
# Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
# or more contributor license agreements. See the NOTICE file
|
||||||
|
# distributed with this work for additional information
|
||||||
|
# regarding copyright ownership. The ASF licenses this file
|
||||||
|
# to you 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.
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
|
# Maven2 Start Up Batch script
|
||||||
|
#
|
||||||
|
# Required ENV vars:
|
||||||
|
# ------------------
|
||||||
|
# JAVA_HOME - location of a JDK home dir
|
||||||
|
#
|
||||||
|
# Optional ENV vars
|
||||||
|
# -----------------
|
||||||
|
# M2_HOME - location of maven2's installed home dir
|
||||||
|
# MAVEN_OPTS - parameters passed to the Java VM when running Maven
|
||||||
|
# e.g. to debug Maven itself, use
|
||||||
|
# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
|
||||||
|
# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
if [ -z "$MAVEN_SKIP_RC" ] ; then
|
||||||
|
|
||||||
|
if [ -f /etc/mavenrc ] ; then
|
||||||
|
. /etc/mavenrc
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f "$HOME/.mavenrc" ] ; then
|
||||||
|
. "$HOME/.mavenrc"
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
# OS specific support. $var _must_ be set to either true or false.
|
||||||
|
cygwin=false;
|
||||||
|
darwin=false;
|
||||||
|
mingw=false
|
||||||
|
case "`uname`" in
|
||||||
|
CYGWIN*) cygwin=true ;;
|
||||||
|
MINGW*) mingw=true;;
|
||||||
|
Darwin*) darwin=true
|
||||||
|
#
|
||||||
|
# Look for the Apple JDKs first to preserve the existing behaviour, and then look
|
||||||
|
# for the new JDKs provided by Oracle.
|
||||||
|
#
|
||||||
|
if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK ] ; then
|
||||||
|
#
|
||||||
|
# Apple JDKs
|
||||||
|
#
|
||||||
|
export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Java/JavaVirtualMachines/CurrentJDK ] ; then
|
||||||
|
#
|
||||||
|
# Apple JDKs
|
||||||
|
#
|
||||||
|
export JAVA_HOME=/System/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$JAVA_HOME" ] && [ -L "/Library/Java/JavaVirtualMachines/CurrentJDK" ] ; then
|
||||||
|
#
|
||||||
|
# Oracle JDKs
|
||||||
|
#
|
||||||
|
export JAVA_HOME=/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$JAVA_HOME" ] && [ -x "/usr/libexec/java_home" ]; then
|
||||||
|
#
|
||||||
|
# Apple JDKs
|
||||||
|
#
|
||||||
|
export JAVA_HOME=`/usr/libexec/java_home`
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [ -z "$JAVA_HOME" ] ; then
|
||||||
|
if [ -r /etc/gentoo-release ] ; then
|
||||||
|
JAVA_HOME=`java-config --jre-home`
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$M2_HOME" ] ; then
|
||||||
|
## resolve links - $0 may be a link to maven's home
|
||||||
|
PRG="$0"
|
||||||
|
|
||||||
|
# need this for relative symlinks
|
||||||
|
while [ -h "$PRG" ] ; do
|
||||||
|
ls=`ls -ld "$PRG"`
|
||||||
|
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||||
|
if expr "$link" : '/.*' > /dev/null; then
|
||||||
|
PRG="$link"
|
||||||
|
else
|
||||||
|
PRG="`dirname "$PRG"`/$link"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
saveddir=`pwd`
|
||||||
|
|
||||||
|
M2_HOME=`dirname "$PRG"`/..
|
||||||
|
|
||||||
|
# make it fully qualified
|
||||||
|
M2_HOME=`cd "$M2_HOME" && pwd`
|
||||||
|
|
||||||
|
cd "$saveddir"
|
||||||
|
# echo Using m2 at $M2_HOME
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Cygwin, ensure paths are in UNIX format before anything is touched
|
||||||
|
if $cygwin ; then
|
||||||
|
[ -n "$M2_HOME" ] &&
|
||||||
|
M2_HOME=`cygpath --unix "$M2_HOME"`
|
||||||
|
[ -n "$JAVA_HOME" ] &&
|
||||||
|
JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
|
||||||
|
[ -n "$CLASSPATH" ] &&
|
||||||
|
CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Migwn, ensure paths are in UNIX format before anything is touched
|
||||||
|
if $mingw ; then
|
||||||
|
[ -n "$M2_HOME" ] &&
|
||||||
|
M2_HOME="`(cd "$M2_HOME"; pwd)`"
|
||||||
|
[ -n "$JAVA_HOME" ] &&
|
||||||
|
JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
|
||||||
|
# TODO classpath?
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$JAVA_HOME" ]; then
|
||||||
|
javaExecutable="`which javac`"
|
||||||
|
if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
|
||||||
|
# readlink(1) is not available as standard on Solaris 10.
|
||||||
|
readLink=`which readlink`
|
||||||
|
if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
|
||||||
|
if $darwin ; then
|
||||||
|
javaHome="`dirname \"$javaExecutable\"`"
|
||||||
|
javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
|
||||||
|
else
|
||||||
|
javaExecutable="`readlink -f \"$javaExecutable\"`"
|
||||||
|
fi
|
||||||
|
javaHome="`dirname \"$javaExecutable\"`"
|
||||||
|
javaHome=`expr "$javaHome" : '\(.*\)/bin'`
|
||||||
|
JAVA_HOME="$javaHome"
|
||||||
|
export JAVA_HOME
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$JAVACMD" ] ; then
|
||||||
|
if [ -n "$JAVA_HOME" ] ; then
|
||||||
|
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||||
|
# IBM's JDK on AIX uses strange locations for the executables
|
||||||
|
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||||
|
else
|
||||||
|
JAVACMD="$JAVA_HOME/bin/java"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
JAVACMD="`which java`"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -x "$JAVACMD" ] ; then
|
||||||
|
echo "Error: JAVA_HOME is not defined correctly." >&2
|
||||||
|
echo " We cannot execute $JAVACMD" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$JAVA_HOME" ] ; then
|
||||||
|
echo "Warning: JAVA_HOME environment variable is not set."
|
||||||
|
fi
|
||||||
|
|
||||||
|
CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
|
||||||
|
|
||||||
|
# For Cygwin, switch paths to Windows format before running java
|
||||||
|
if $cygwin; then
|
||||||
|
[ -n "$M2_HOME" ] &&
|
||||||
|
M2_HOME=`cygpath --path --windows "$M2_HOME"`
|
||||||
|
[ -n "$JAVA_HOME" ] &&
|
||||||
|
JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
|
||||||
|
[ -n "$CLASSPATH" ] &&
|
||||||
|
CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
|
||||||
|
fi
|
||||||
|
|
||||||
|
# traverses directory structure from process work directory to filesystem root
|
||||||
|
# first directory with .mvn subdirectory is considered project base directory
|
||||||
|
find_maven_basedir() {
|
||||||
|
local basedir=$(pwd)
|
||||||
|
local wdir=$(pwd)
|
||||||
|
while [ "$wdir" != '/' ] ; do
|
||||||
|
if [ -d "$wdir"/.mvn ] ; then
|
||||||
|
basedir=$wdir
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
wdir=$(cd "$wdir/.."; pwd)
|
||||||
|
done
|
||||||
|
echo "${basedir}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# concatenates all lines of a file
|
||||||
|
concat_lines() {
|
||||||
|
if [ -f "$1" ]; then
|
||||||
|
echo "$(tr -s '\n' ' ' < "$1")"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-$(find_maven_basedir)}
|
||||||
|
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
|
||||||
|
|
||||||
|
# Provide a "standardized" way to retrieve the CLI args that will
|
||||||
|
# work with both Windows and non-Windows executions.
|
||||||
|
MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
|
||||||
|
export MAVEN_CMD_LINE_ARGS
|
||||||
|
|
||||||
|
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
|
||||||
|
|
||||||
|
exec "$JAVACMD" \
|
||||||
|
$MAVEN_OPTS \
|
||||||
|
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
|
||||||
|
"-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
|
||||||
|
${WRAPPER_LAUNCHER} "$@"
|
145
orientdb/mvnw.cmd
vendored
Normal file
145
orientdb/mvnw.cmd
vendored
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
@REM ----------------------------------------------------------------------------
|
||||||
|
@REM Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
@REM or more contributor license agreements. See the NOTICE file
|
||||||
|
@REM distributed with this work for additional information
|
||||||
|
@REM regarding copyright ownership. The ASF licenses this file
|
||||||
|
@REM to you under the Apache License, Version 2.0 (the
|
||||||
|
@REM "License"); you may not use this file except in compliance
|
||||||
|
@REM with the License. You may obtain a copy of the License at
|
||||||
|
@REM
|
||||||
|
@REM http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
@REM
|
||||||
|
@REM Unless required by applicable law or agreed to in writing,
|
||||||
|
@REM software distributed under the License is distributed on an
|
||||||
|
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
@REM KIND, either express or implied. See the License for the
|
||||||
|
@REM specific language governing permissions and limitations
|
||||||
|
@REM under the License.
|
||||||
|
@REM ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@REM ----------------------------------------------------------------------------
|
||||||
|
@REM Maven2 Start Up Batch script
|
||||||
|
@REM
|
||||||
|
@REM Required ENV vars:
|
||||||
|
@REM JAVA_HOME - location of a JDK home dir
|
||||||
|
@REM
|
||||||
|
@REM Optional ENV vars
|
||||||
|
@REM M2_HOME - location of maven2's installed home dir
|
||||||
|
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
|
||||||
|
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
|
||||||
|
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
|
||||||
|
@REM e.g. to debug Maven itself, use
|
||||||
|
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
|
||||||
|
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
|
||||||
|
@REM ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
|
||||||
|
@echo off
|
||||||
|
@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
|
||||||
|
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
|
||||||
|
|
||||||
|
@REM set %HOME% to equivalent of $HOME
|
||||||
|
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
|
||||||
|
|
||||||
|
@REM Execute a user defined script before this one
|
||||||
|
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
|
||||||
|
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
|
||||||
|
if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
|
||||||
|
if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
|
||||||
|
:skipRcPre
|
||||||
|
|
||||||
|
@setlocal
|
||||||
|
|
||||||
|
set ERROR_CODE=0
|
||||||
|
|
||||||
|
@REM To isolate internal variables from possible post scripts, we use another setlocal
|
||||||
|
@setlocal
|
||||||
|
|
||||||
|
@REM ==== START VALIDATION ====
|
||||||
|
if not "%JAVA_HOME%" == "" goto OkJHome
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo Error: JAVA_HOME not found in your environment. >&2
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the >&2
|
||||||
|
echo location of your Java installation. >&2
|
||||||
|
echo.
|
||||||
|
goto error
|
||||||
|
|
||||||
|
:OkJHome
|
||||||
|
if exist "%JAVA_HOME%\bin\java.exe" goto init
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo Error: JAVA_HOME is set to an invalid directory. >&2
|
||||||
|
echo JAVA_HOME = "%JAVA_HOME%" >&2
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the >&2
|
||||||
|
echo location of your Java installation. >&2
|
||||||
|
echo.
|
||||||
|
goto error
|
||||||
|
|
||||||
|
@REM ==== END VALIDATION ====
|
||||||
|
|
||||||
|
:init
|
||||||
|
|
||||||
|
set MAVEN_CMD_LINE_ARGS=%*
|
||||||
|
|
||||||
|
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
|
||||||
|
@REM Fallback to current working directory if not found.
|
||||||
|
|
||||||
|
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
|
||||||
|
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
|
||||||
|
|
||||||
|
set EXEC_DIR=%CD%
|
||||||
|
set WDIR=%EXEC_DIR%
|
||||||
|
:findBaseDir
|
||||||
|
IF EXIST "%WDIR%"\.mvn goto baseDirFound
|
||||||
|
cd ..
|
||||||
|
IF "%WDIR%"=="%CD%" goto baseDirNotFound
|
||||||
|
set WDIR=%CD%
|
||||||
|
goto findBaseDir
|
||||||
|
|
||||||
|
:baseDirFound
|
||||||
|
set MAVEN_PROJECTBASEDIR=%WDIR%
|
||||||
|
cd "%EXEC_DIR%"
|
||||||
|
goto endDetectBaseDir
|
||||||
|
|
||||||
|
:baseDirNotFound
|
||||||
|
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
|
||||||
|
cd "%EXEC_DIR%"
|
||||||
|
|
||||||
|
:endDetectBaseDir
|
||||||
|
|
||||||
|
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
|
||||||
|
|
||||||
|
@setlocal EnableExtensions EnableDelayedExpansion
|
||||||
|
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
|
||||||
|
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
|
||||||
|
|
||||||
|
:endReadAdditionalConfig
|
||||||
|
|
||||||
|
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
|
||||||
|
|
||||||
|
set WRAPPER_JAR="".\.mvn\wrapper\maven-wrapper.jar""
|
||||||
|
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
|
||||||
|
|
||||||
|
%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CMD_LINE_ARGS%
|
||||||
|
if ERRORLEVEL 1 goto error
|
||||||
|
goto end
|
||||||
|
|
||||||
|
:error
|
||||||
|
set ERROR_CODE=1
|
||||||
|
|
||||||
|
:end
|
||||||
|
@endlocal & set ERROR_CODE=%ERROR_CODE%
|
||||||
|
|
||||||
|
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
|
||||||
|
@REM check for post script, once with legacy .bat ending and once with .cmd ending
|
||||||
|
if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
|
||||||
|
if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
|
||||||
|
:skipRcPost
|
||||||
|
|
||||||
|
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
|
||||||
|
if "%MAVEN_BATCH_PAUSE%" == "on" pause
|
||||||
|
|
||||||
|
if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
|
||||||
|
|
||||||
|
exit /B %ERROR_CODE%
|
57
orientdb/pom.xml
Normal file
57
orientdb/pom.xml
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
<?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>orientdb</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>intro-orientdb</name>
|
||||||
|
<description>introduction to the OrientDB Java APIs</description>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>parent-modules</artifactId>
|
||||||
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||||
|
<java.version>1.8</java.version>
|
||||||
|
<orientdb.version>2.2.31</orientdb.version>
|
||||||
|
<blueprints.version>2.6.0</blueprints.version>
|
||||||
|
<junit.version>4.12</junit.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.orientechnologies</groupId>
|
||||||
|
<artifactId>orientdb-core</artifactId>
|
||||||
|
<version>${orientdb.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.orientechnologies</groupId>
|
||||||
|
<artifactId>orientdb-graphdb</artifactId>
|
||||||
|
<version>${orientdb.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.orientechnologies</groupId>
|
||||||
|
<artifactId>orientdb-object</artifactId>
|
||||||
|
<version>${orientdb.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.tinkerpop.blueprints</groupId>
|
||||||
|
<artifactId>blueprints-core</artifactId>
|
||||||
|
<version>${blueprints.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>${junit.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
54
orientdb/src/main/java/com/baeldung/orientdb/Author.java
Normal file
54
orientdb/src/main/java/com/baeldung/orientdb/Author.java
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
package com.baeldung.orientdb;
|
||||||
|
|
||||||
|
import javax.persistence.Id;
|
||||||
|
|
||||||
|
public class Author {
|
||||||
|
@Id
|
||||||
|
private Object id;
|
||||||
|
|
||||||
|
private String firstName;
|
||||||
|
private String lastName;
|
||||||
|
private int level;
|
||||||
|
|
||||||
|
public Author() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Author(String firstName, String lastName, int level) {
|
||||||
|
this.firstName = firstName;
|
||||||
|
this.lastName = lastName;
|
||||||
|
this.level = level;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLevel() {
|
||||||
|
return level;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLevel(int level) {
|
||||||
|
this.level = level;
|
||||||
|
}
|
||||||
|
|
||||||
|
@java.lang.Override
|
||||||
|
public java.lang.String toString() {
|
||||||
|
return "Author{" +
|
||||||
|
"firstName='" + firstName + '\'' +
|
||||||
|
", lastName='" + lastName + '\'' +
|
||||||
|
", level=" + level +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,60 @@
|
|||||||
|
package com.baeldung.orientdb;
|
||||||
|
|
||||||
|
import com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx;
|
||||||
|
import com.orientechnologies.orient.core.record.impl.ODocument;
|
||||||
|
import com.orientechnologies.orient.core.sql.query.OSQLSynchQuery;
|
||||||
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static junit.framework.Assert.assertEquals;
|
||||||
|
|
||||||
|
public class OrientDBDocumentAPITest {
|
||||||
|
private static ODatabaseDocumentTx db = null;
|
||||||
|
|
||||||
|
// @BeforeClass
|
||||||
|
public static void setup() {
|
||||||
|
String orientDBFolder = System.getenv("ORIENTDB_HOME");
|
||||||
|
db = new ODatabaseDocumentTx("plocal:" + orientDBFolder + "/databases/BaeldungDBTwo").open("admin", "admin");
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Test
|
||||||
|
public void givenDB_whenSavingDocument_thenClassIsAutoCreated() {
|
||||||
|
ODocument author = new ODocument("Author");
|
||||||
|
author.field("firstName", "Paul");
|
||||||
|
author.field("lastName", "Smith");
|
||||||
|
author.field("country", "USA");
|
||||||
|
author.field("publicProfile", false);
|
||||||
|
author.field("level", 7);
|
||||||
|
author.save();
|
||||||
|
|
||||||
|
assertEquals("Author", author.getSchemaClass().getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Test
|
||||||
|
public void givenDB_whenSavingAuthors_thenWeGetOnesWithLevelSeven() {
|
||||||
|
for (ODocument author : db.browseClass("Author")) author.delete();
|
||||||
|
|
||||||
|
ODocument authorOne = new ODocument("Author");
|
||||||
|
authorOne.field("firstName", "Leo");
|
||||||
|
authorOne.field("level", 7);
|
||||||
|
authorOne.save();
|
||||||
|
|
||||||
|
ODocument authorTwo = new ODocument("Author");
|
||||||
|
authorTwo.field("firstName", "Lucien");
|
||||||
|
authorTwo.field("level", 9);
|
||||||
|
authorTwo.save();
|
||||||
|
|
||||||
|
List<ODocument> result = db.query(
|
||||||
|
new OSQLSynchQuery<ODocument>("select * from Author where level = 7"));
|
||||||
|
|
||||||
|
assertEquals(1, result.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
// @AfterClass
|
||||||
|
public static void closeDB() {
|
||||||
|
db.close();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,89 @@
|
|||||||
|
package com.baeldung.orientdb;
|
||||||
|
|
||||||
|
import com.orientechnologies.orient.core.metadata.schema.OType;
|
||||||
|
import com.tinkerpop.blueprints.Vertex;
|
||||||
|
import com.tinkerpop.blueprints.impls.orient.OrientGraphNoTx;
|
||||||
|
import com.tinkerpop.blueprints.impls.orient.OrientVertexType;
|
||||||
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static junit.framework.Assert.assertEquals;
|
||||||
|
|
||||||
|
public class OrientDBGraphAPITest {
|
||||||
|
private static OrientGraphNoTx graph = null;
|
||||||
|
|
||||||
|
// @BeforeClass
|
||||||
|
public static void setup() {
|
||||||
|
String orientDBFolder = System.getenv("ORIENTDB_HOME");
|
||||||
|
graph = new OrientGraphNoTx("plocal:" + orientDBFolder + "/databases/BaeldungDB", "admin", "admin");
|
||||||
|
}
|
||||||
|
|
||||||
|
// @BeforeClass
|
||||||
|
public static void init() {
|
||||||
|
graph.createVertexType("Article");
|
||||||
|
|
||||||
|
OrientVertexType writerType = graph.createVertexType("Writer");
|
||||||
|
writerType.setStrictMode(true);
|
||||||
|
writerType.createProperty("firstName", OType.STRING);
|
||||||
|
writerType.createProperty("lastName", OType.STRING);
|
||||||
|
writerType.createProperty("country", OType.STRING);
|
||||||
|
|
||||||
|
OrientVertexType authorType = graph.createVertexType("Author", "Writer");
|
||||||
|
authorType.createProperty("level", OType.INTEGER).setMax("3");
|
||||||
|
|
||||||
|
OrientVertexType editorType = graph.createVertexType("Editor", "Writer");
|
||||||
|
editorType.createProperty("level", OType.INTEGER).setMin("3");
|
||||||
|
|
||||||
|
Vertex vEditor = graph.addVertex("class:Editor");
|
||||||
|
vEditor.setProperty("firstName", "Maxim");
|
||||||
|
vEditor.setProperty("lastName", "Mink's");
|
||||||
|
vEditor.setProperty("country", "Cameroon");
|
||||||
|
vEditor.setProperty("publicProfile", true);
|
||||||
|
vEditor.setProperty("level", "7");
|
||||||
|
|
||||||
|
Vertex vAuthor = graph.addVertex("class:Author");
|
||||||
|
vAuthor.setProperty("firstName", "Jerome");
|
||||||
|
vAuthor.setProperty("country", "Romania");
|
||||||
|
vAuthor.setProperty("publicProfile", false);
|
||||||
|
vAuthor.setProperty("level", "3");
|
||||||
|
|
||||||
|
Vertex vArticle = graph.addVertex("class:Article");
|
||||||
|
vArticle.setProperty("title", "Introduction to the OrientDB Java APIs.");
|
||||||
|
vArticle.setProperty("priority", "High");
|
||||||
|
vArticle.setProperty("type", "Article");
|
||||||
|
vArticle.setProperty("level", "+L4");
|
||||||
|
|
||||||
|
graph.addEdge(null, vAuthor, vEditor, "has");
|
||||||
|
graph.addEdge(null, vAuthor, vArticle, "wrote");
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Test
|
||||||
|
public void givenBaeldungDB_checkWeHaveThreeRecords() {
|
||||||
|
long size = graph.countVertices();
|
||||||
|
|
||||||
|
assertEquals(3, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Test
|
||||||
|
public void givenBaeldungDB_checkWeHaveTwoWriters() {
|
||||||
|
long size = graph.countVertices("Writer");
|
||||||
|
|
||||||
|
assertEquals(2, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Test
|
||||||
|
public void givenBaeldungDB_getEditorWithLevelSeven() {
|
||||||
|
String onlyEditor = "";
|
||||||
|
for(Vertex v : graph.getVertices("Editor.level", 7)) {
|
||||||
|
onlyEditor = v.getProperty("firstName").toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEquals("Maxim", onlyEditor);
|
||||||
|
}
|
||||||
|
|
||||||
|
// @AfterClass
|
||||||
|
public static void closeDB() {
|
||||||
|
graph.getRawGraph().getStorage().close(true, false);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,56 @@
|
|||||||
|
package com.baeldung.orientdb;
|
||||||
|
|
||||||
|
import com.orientechnologies.orient.core.sql.query.OSQLSynchQuery;
|
||||||
|
import com.orientechnologies.orient.object.db.OObjectDatabaseTx;
|
||||||
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static junit.framework.Assert.assertEquals;
|
||||||
|
|
||||||
|
public class OrientDBObjectAPITest {
|
||||||
|
private static OObjectDatabaseTx db = null;
|
||||||
|
|
||||||
|
// @BeforeClass
|
||||||
|
public static void setup() {
|
||||||
|
String orientDBFolder = System.getenv("ORIENTDB_HOME");
|
||||||
|
db = new OObjectDatabaseTx("plocal:" + orientDBFolder + "/databases/BaeldungDBThree").open("admin", "admin");
|
||||||
|
db.setSaveOnlyDirty(true);
|
||||||
|
db.getEntityManager().registerEntityClass(Author.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Test
|
||||||
|
public void givenDB_whenSavingObject_thenHisIdExists() {
|
||||||
|
Author author = db.newInstance(Author.class);
|
||||||
|
author.setFirstName("Luke");
|
||||||
|
author.setLastName("Sky");
|
||||||
|
author.setLevel(9);
|
||||||
|
|
||||||
|
long authors = db.countClass(Author.class);
|
||||||
|
|
||||||
|
db.save(author);
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Test
|
||||||
|
public void givenDB_whenSavingAuthors_thenWeGetOnesWithLevelSeven() {
|
||||||
|
for (Author author : db.browseClass(Author.class)) db.delete(author);
|
||||||
|
|
||||||
|
Author authorOne = db.newInstance(Author.class, "Leo", "Marta", 7);
|
||||||
|
db.save(authorOne);
|
||||||
|
|
||||||
|
Author authorTwo = db.newInstance(Author.class, "Lucien", "Aurelien", 9);
|
||||||
|
db.save(authorTwo);
|
||||||
|
|
||||||
|
List<Author> result = db.query(
|
||||||
|
new OSQLSynchQuery<Author>("select * from Author where level = 7"));
|
||||||
|
|
||||||
|
assertEquals(1, result.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
// @AfterClass
|
||||||
|
public static void closeDB() {
|
||||||
|
db.close();
|
||||||
|
}
|
||||||
|
}
|
3
persistence-modules/spring-data-eclipselink/README.md
Normal file
3
persistence-modules/spring-data-eclipselink/README.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
### Relevant articles
|
||||||
|
|
||||||
|
- [A Guide to EclipseLink with Spring](http://www.baeldung.com/spring-eclipselink)
|
3
pom.xml
3
pom.xml
@ -80,6 +80,7 @@
|
|||||||
|
|
||||||
<module>image-processing</module>
|
<module>image-processing</module>
|
||||||
<module>immutables</module>
|
<module>immutables</module>
|
||||||
|
<module>influxdb</module>
|
||||||
|
|
||||||
<module>jackson</module>
|
<module>jackson</module>
|
||||||
<!-- <module>persistence-modules/java-cassandra</module> -->
|
<!-- <module>persistence-modules/java-cassandra</module> -->
|
||||||
@ -115,7 +116,7 @@
|
|||||||
<module>testing-modules/mocks</module>
|
<module>testing-modules/mocks</module>
|
||||||
<module>mustache</module>
|
<module>mustache</module>
|
||||||
<module>noexception</module>
|
<module>noexception</module>
|
||||||
|
<module>orientdb</module>
|
||||||
<module>osgi</module>
|
<module>osgi</module>
|
||||||
<module>orika</module>
|
<module>orika</module>
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-parent</artifactId>
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
<version>2.0.0.M3</version>
|
<version>2.0.0.M7</version>
|
||||||
<relativePath/>
|
<relativePath/>
|
||||||
<!-- lookup parent from repository -->
|
<!-- lookup parent from repository -->
|
||||||
</parent>
|
</parent>
|
||||||
@ -190,6 +190,7 @@
|
|||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||||
<java.version>1.8</java.version>
|
<java.version>1.8</java.version>
|
||||||
|
<spring.version>5.0.2.RELEASE</spring.version>
|
||||||
<kotlin.version>1.1.2</kotlin.version>
|
<kotlin.version>1.1.2</kotlin.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
|
@ -191,7 +191,7 @@
|
|||||||
<junit.platform.version>1.0.0</junit.platform.version>
|
<junit.platform.version>1.0.0</junit.platform.version>
|
||||||
<junit.jupiter.version>5.0.0</junit.jupiter.version>
|
<junit.jupiter.version>5.0.0</junit.jupiter.version>
|
||||||
<maven-surefire-plugin.version>2.20</maven-surefire-plugin.version>
|
<maven-surefire-plugin.version>2.20</maven-surefire-plugin.version>
|
||||||
<spring.version>5.0.1.RELEASE</spring.version>
|
<spring.version>5.0.2.RELEASE</spring.version>
|
||||||
<reactor-spring.version>1.0.1.RELEASE</reactor-spring.version>
|
<reactor-spring.version>1.0.1.RELEASE</reactor-spring.version>
|
||||||
<johnzon.version>1.1.3</johnzon.version>
|
<johnzon.version>1.1.3</johnzon.version>
|
||||||
<jsonb-api.version>1.0</jsonb-api.version>
|
<jsonb-api.version>1.0</jsonb-api.version>
|
||||||
|
@ -191,7 +191,7 @@
|
|||||||
<junit.platform.version>1.0.0</junit.platform.version>
|
<junit.platform.version>1.0.0</junit.platform.version>
|
||||||
<junit.jupiter.version>5.0.0</junit.jupiter.version>
|
<junit.jupiter.version>5.0.0</junit.jupiter.version>
|
||||||
<maven-surefire-plugin.version>2.20</maven-surefire-plugin.version>
|
<maven-surefire-plugin.version>2.20</maven-surefire-plugin.version>
|
||||||
<spring.version>5.0.1.RELEASE</spring.version>
|
<spring.version>5.0.2.RELEASE</spring.version>
|
||||||
<reactor-spring.version>1.0.1.RELEASE</reactor-spring.version>
|
<reactor-spring.version>1.0.1.RELEASE</reactor-spring.version>
|
||||||
<johnzon.version>1.1.3</johnzon.version>
|
<johnzon.version>1.1.3</johnzon.version>
|
||||||
<jsonb-api.version>1.0</jsonb-api.version>
|
<jsonb-api.version>1.0</jsonb-api.version>
|
||||||
|
@ -194,7 +194,7 @@
|
|||||||
<junit.platform.version>1.0.0</junit.platform.version>
|
<junit.platform.version>1.0.0</junit.platform.version>
|
||||||
<junit.jupiter.version>5.0.0</junit.jupiter.version>
|
<junit.jupiter.version>5.0.0</junit.jupiter.version>
|
||||||
<maven-surefire-plugin.version>2.20</maven-surefire-plugin.version>
|
<maven-surefire-plugin.version>2.20</maven-surefire-plugin.version>
|
||||||
<spring.version>5.0.1.RELEASE</spring.version>
|
<spring.version>5.0.2.RELEASE</spring.version>
|
||||||
<reactor-spring.version>1.0.1.RELEASE</reactor-spring.version>
|
<reactor-spring.version>1.0.1.RELEASE</reactor-spring.version>
|
||||||
<johnzon.version>1.1.3</johnzon.version>
|
<johnzon.version>1.1.3</johnzon.version>
|
||||||
<jsonb-api.version>1.0</jsonb-api.version>
|
<jsonb-api.version>1.0</jsonb-api.version>
|
||||||
|
@ -50,7 +50,7 @@ public class WebClientController {
|
|||||||
map.add("key1", "value1");
|
map.add("key1", "value1");
|
||||||
map.add("key2", "value2");
|
map.add("key2", "value2");
|
||||||
|
|
||||||
BodyInserter<MultiValueMap<String, ?>, ClientHttpRequest> inserter2 = BodyInserters.fromMultipartData(map);
|
// BodyInserter<MultiValueMap<String, ?>, ClientHttpRequest> inserter2 = BodyInserters.fromMultipartData(map);
|
||||||
BodyInserter<String, ReactiveHttpOutputMessage> inserter3 = BodyInserters.fromObject("body");
|
BodyInserter<String, ReactiveHttpOutputMessage> inserter3 = BodyInserters.fromObject("body");
|
||||||
|
|
||||||
// responses
|
// responses
|
||||||
|
@ -31,25 +31,36 @@ node {
|
|||||||
|
|
||||||
stage("Tests and Deployment") {
|
stage("Tests and Deployment") {
|
||||||
parallel 'Unit tests': {
|
parallel 'Unit tests': {
|
||||||
stage("Runing unit tests") {
|
stage("Running unit tests") {
|
||||||
|
try {
|
||||||
if (isUnix()) {
|
if (isUnix()) {
|
||||||
sh "./mvnw test -Punit"
|
sh "./mvnw test -Punit"
|
||||||
} else {
|
} else {
|
||||||
bat "./mvnw.cmd test -Punit"
|
bat "./mvnw.cmd test -Punit"
|
||||||
}
|
}
|
||||||
|
} catch(err) {
|
||||||
|
step([$class: 'JUnitResultArchiver', testResults: '**/target/surefire-reports/TEST-*UnitTest.xml'])
|
||||||
|
throw err
|
||||||
|
}
|
||||||
step([$class: 'JUnitResultArchiver', testResults: '**/target/surefire-reports/TEST-*UnitTest.xml'])
|
step([$class: 'JUnitResultArchiver', testResults: '**/target/surefire-reports/TEST-*UnitTest.xml'])
|
||||||
|
|
||||||
}
|
}
|
||||||
}, 'Integration tests': {
|
}, 'Integration tests': {
|
||||||
stage("Runing integration tests") {
|
stage("Running integration tests") {
|
||||||
|
try {
|
||||||
if (isUnix()) {
|
if (isUnix()) {
|
||||||
sh "./mvnw test -Pintegration"
|
sh "./mvnw test -Pintegration"
|
||||||
} else {
|
} else {
|
||||||
bat "./mvnw.cmd test -Pintegration"
|
bat "./mvnw.cmd test -Pintegration"
|
||||||
}
|
}
|
||||||
|
} catch(err) {
|
||||||
|
step([$class: 'JUnitResultArchiver', testResults: '**/target/surefire-reports/TEST-*IntegrationTest.xml'])
|
||||||
|
throw err
|
||||||
|
}
|
||||||
step([$class: 'JUnitResultArchiver', testResults: '**/target/surefire-reports/TEST-*IntegrationTest.xml'])
|
step([$class: 'JUnitResultArchiver', testResults: '**/target/surefire-reports/TEST-*IntegrationTest.xml'])
|
||||||
}
|
}
|
||||||
}, 'Deployment': {
|
}
|
||||||
|
|
||||||
stage("Staging") {
|
stage("Staging") {
|
||||||
if (isUnix()) {
|
if (isUnix()) {
|
||||||
sh "pid=\$(lsof -i:8989 -t); kill -TERM \$pid || kill -KILL \$pid"
|
sh "pid=\$(lsof -i:8989 -t); kill -TERM \$pid || kill -KILL \$pid"
|
||||||
@ -68,4 +79,3 @@ node {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
@ -36,12 +36,16 @@
|
|||||||
<artifactId>katharsis-servlet</artifactId>
|
<artifactId>katharsis-servlet</artifactId>
|
||||||
<version>${katharsis.version}</version>
|
<version>${katharsis.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.reflections</groupId>
|
||||||
|
<artifactId>reflections</artifactId>
|
||||||
|
<version>0.9.10</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<katharsis.version>1.0.1</katharsis.version>
|
<katharsis.version>2.1.3</katharsis.version>
|
||||||
<cargo-maven2-plugin.version>1.6.1</cargo-maven2-plugin.version>
|
<cargo-maven2-plugin.version>1.6.1</cargo-maven2-plugin.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package org.baeldung.persistence.katharsis;
|
package org.baeldung.persistence.katharsis;
|
||||||
|
|
||||||
import io.katharsis.queryParams.RequestParams;
|
import io.katharsis.queryParams.QueryParams;
|
||||||
import io.katharsis.repository.ResourceRepository;
|
import io.katharsis.repository.ResourceRepository;
|
||||||
|
|
||||||
import org.baeldung.persistence.dao.RoleRepository;
|
import org.baeldung.persistence.dao.RoleRepository;
|
||||||
@ -15,17 +15,17 @@ public class RoleResourceRepository implements ResourceRepository<Role, Long> {
|
|||||||
private RoleRepository roleRepository;
|
private RoleRepository roleRepository;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Role findOne(Long id, RequestParams params) {
|
public Role findOne(Long id, QueryParams params) {
|
||||||
return roleRepository.findOne(id);
|
return roleRepository.findOne(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<Role> findAll(RequestParams params) {
|
public Iterable<Role> findAll(QueryParams params) {
|
||||||
return roleRepository.findAll();
|
return roleRepository.findAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<Role> findAll(Iterable<Long> ids, RequestParams params) {
|
public Iterable<Role> findAll(Iterable<Long> ids, QueryParams params) {
|
||||||
return roleRepository.findAll(ids);
|
return roleRepository.findAll(ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package org.baeldung.persistence.katharsis;
|
package org.baeldung.persistence.katharsis;
|
||||||
|
|
||||||
import io.katharsis.queryParams.RequestParams;
|
import io.katharsis.queryParams.QueryParams;
|
||||||
import io.katharsis.repository.ResourceRepository;
|
import io.katharsis.repository.ResourceRepository;
|
||||||
|
|
||||||
import org.baeldung.persistence.dao.UserRepository;
|
import org.baeldung.persistence.dao.UserRepository;
|
||||||
@ -15,17 +15,17 @@ public class UserResourceRepository implements ResourceRepository<User, Long> {
|
|||||||
private UserRepository userRepository;
|
private UserRepository userRepository;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public User findOne(Long id, RequestParams params) {
|
public User findOne(Long id, QueryParams params) {
|
||||||
return userRepository.findOne(id);
|
return userRepository.findOne(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<User> findAll(RequestParams params) {
|
public Iterable<User> findAll(QueryParams params) {
|
||||||
return userRepository.findAll();
|
return userRepository.findAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<User> findAll(Iterable<Long> ids, RequestParams params) {
|
public Iterable<User> findAll(Iterable<Long> ids, QueryParams params) {
|
||||||
return userRepository.findAll(ids);
|
return userRepository.findAll(ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package org.baeldung.persistence.katharsis;
|
package org.baeldung.persistence.katharsis;
|
||||||
|
|
||||||
import io.katharsis.queryParams.RequestParams;
|
import io.katharsis.queryParams.QueryParams;
|
||||||
import io.katharsis.repository.RelationshipRepository;
|
import io.katharsis.repository.RelationshipRepository;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
@ -52,13 +52,13 @@ public class UserToRoleRelationshipRepository implements RelationshipRepository<
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Role findOneTarget(Long sourceId, String fieldName, RequestParams requestParams) {
|
public Role findOneTarget(Long sourceId, String fieldName, QueryParams QueryParams) {
|
||||||
// not for many-to-many
|
// not for many-to-many
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<Role> findManyTargets(Long sourceId, String fieldName, RequestParams requestParams) {
|
public Iterable<Role> findManyTargets(Long sourceId, String fieldName, QueryParams QueryParams) {
|
||||||
final User user = userRepository.findOne(sourceId);
|
final User user = userRepository.findOne(sourceId);
|
||||||
return user.getRoles();
|
return user.getRoles();
|
||||||
}
|
}
|
||||||
|
@ -16,3 +16,4 @@
|
|||||||
- [Introduction to Lambda Behave](http://www.baeldung.com/lambda-behave)
|
- [Introduction to Lambda Behave](http://www.baeldung.com/lambda-behave)
|
||||||
- [Introduction to Jukito](http://www.baeldung.com/jukito)
|
- [Introduction to Jukito](http://www.baeldung.com/jukito)
|
||||||
- [Custom JUnit 4 Test Runners](http://www.baeldung.com/junit-4-custom-runners)
|
- [Custom JUnit 4 Test Runners](http://www.baeldung.com/junit-4-custom-runners)
|
||||||
|
- [Guide to JSpec](http://www.baeldung.com/jspec)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user