Merge branch 'master' into JAVA-5223
This commit is contained in:
commit
8cc6444700
|
@ -50,6 +50,11 @@
|
||||||
<version>${junit.jupiter.version}</version>
|
<version>${junit.jupiter.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-lang3</artifactId>
|
||||||
|
<version>${commons-lang3.version}</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
@ -73,6 +78,7 @@
|
||||||
<junit.jupiter.version>5.7.0</junit.jupiter.version>
|
<junit.jupiter.version>5.7.0</junit.jupiter.version>
|
||||||
<assertj.version>3.17.2</assertj.version>
|
<assertj.version>3.17.2</assertj.version>
|
||||||
<mockserver.version>5.11.1</mockserver.version>
|
<mockserver.version>5.11.1</mockserver.version>
|
||||||
|
<commons-lang3.version>3.12.0</commons-lang3.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
|
@ -0,0 +1,48 @@
|
||||||
|
package com.baeldung.version;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.SystemUtils;
|
||||||
|
import org.assertj.core.api.Assertions;
|
||||||
|
import org.junit.jupiter.api.Disabled;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
public class VersionUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenJava_whenUsingRuntime_thenGetVersion() {
|
||||||
|
String expectedVersion = "11";
|
||||||
|
Runtime.Version runtimeVersion = Runtime.version();
|
||||||
|
String version = String.valueOf(runtimeVersion.version().get(0));
|
||||||
|
Assertions.assertThat(version).isEqualTo(expectedVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Disabled("Only valid for Java 8 and lower")
|
||||||
|
public void givenJava_whenUsingCommonsLang_thenGetVersion() {
|
||||||
|
int expectedVersion = 8;
|
||||||
|
String[] versionElements = SystemUtils.JAVA_SPECIFICATION_VERSION.split("\\.");
|
||||||
|
int discard = Integer.parseInt(versionElements[0]);
|
||||||
|
int version;
|
||||||
|
if (discard == 1) {
|
||||||
|
version = Integer.parseInt(versionElements[1]);
|
||||||
|
} else {
|
||||||
|
version = discard;
|
||||||
|
}
|
||||||
|
Assertions.assertThat(version).isEqualTo(expectedVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Disabled("Only valid for Java 8 and lower")
|
||||||
|
public void givenJava_whenUsingSystemProp_thenGetVersion() {
|
||||||
|
int expectedVersion = 8;
|
||||||
|
String[] versionElements = System.getProperty("java.version").split("\\.");
|
||||||
|
int discard = Integer.parseInt(versionElements[0]);
|
||||||
|
int version;
|
||||||
|
if (discard == 1) {
|
||||||
|
version = Integer.parseInt(versionElements[1]);
|
||||||
|
} else {
|
||||||
|
version = discard;
|
||||||
|
}
|
||||||
|
Assertions.assertThat(version).isEqualTo(expectedVersion);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,91 @@
|
||||||
|
package com.baeldung.hash;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class Player {
|
||||||
|
private String firstName;
|
||||||
|
private String lastName;
|
||||||
|
private String position;
|
||||||
|
|
||||||
|
public Player() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Player(String firstName, String lastName, String position) {
|
||||||
|
this.firstName = firstName;
|
||||||
|
this.lastName = lastName;
|
||||||
|
this.position = position;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 String getPosition() {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPosition(String position) {
|
||||||
|
this.position = position;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(firstName, lastName, position);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getClass() != obj.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Player other = (Player) obj;
|
||||||
|
|
||||||
|
if (firstName == null) {
|
||||||
|
if (other.firstName != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (!firstName.equals(other.firstName)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lastName == null) {
|
||||||
|
if (other.lastName != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (!lastName.equals(other.lastName)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (position == null) {
|
||||||
|
if (other.position != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (!position.equals(other.position)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
package com.baeldung.hash;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNotEquals;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class HashCodeUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenCallingObjectsHashCodeOnIndenticalObjects_thenSameHashCodeReturned() {
|
||||||
|
String stringOne = "test";
|
||||||
|
String stringTwo = "test";
|
||||||
|
int hashCode1 = Objects.hashCode(stringOne);
|
||||||
|
int hashCode2 = Objects.hashCode(stringTwo);
|
||||||
|
|
||||||
|
assertEquals(hashCode1, hashCode2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenCallingObjectsHashCodeOnNullObject_thenZeroReturned() {
|
||||||
|
String nullString = null;
|
||||||
|
int hashCode = Objects.hashCode(nullString);
|
||||||
|
assertEquals(0, hashCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenCallingObjectHashCodeOnIndenticalObjects_thenSameHashCodeReturned() {
|
||||||
|
Double valueOne = Double.valueOf(1.0012);
|
||||||
|
Double valueTwo = Double.valueOf(1.0012);
|
||||||
|
|
||||||
|
int hashCode1 = valueOne.hashCode();
|
||||||
|
int hashCode2 = valueTwo.hashCode();
|
||||||
|
|
||||||
|
assertEquals(hashCode1, hashCode2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = NullPointerException.class)
|
||||||
|
public void whenCallingObjectHashCodeOnNullObject_theNullPointerExceptionThrown() {
|
||||||
|
Double value = null;
|
||||||
|
value.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenCallingObjectsHashOnStrings_thenSameHashCodeReturned() {
|
||||||
|
String strOne = "one";
|
||||||
|
String strTwo = "two";
|
||||||
|
String strOne2 = "one";
|
||||||
|
String strTwo2 = "two";
|
||||||
|
|
||||||
|
int hashCode1 = Objects.hash(strOne, strTwo);
|
||||||
|
int hashCode2 = Objects.hash(strOne2, strTwo2);
|
||||||
|
|
||||||
|
assertEquals(hashCode1, hashCode2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenCallingObjectsHashOnSingleString_thenDifferentHashcodeFromObjectsHashCodeCallReturned() {
|
||||||
|
String testString = "test string";
|
||||||
|
int hashCode1 = Objects.hash(testString);
|
||||||
|
int hashCode2 = Objects.hashCode(testString);
|
||||||
|
|
||||||
|
assertNotEquals(hashCode1, hashCode2);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
package com.baeldung.hash;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class PlayerUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenCallingHashCodeOnIdenticalValue_thenSameHashCodeReturned() {
|
||||||
|
Player player = new Player("Eduardo", "Rodriguez", "Pitcher");
|
||||||
|
Player indenticalPlayer = new Player("Eduardo", "Rodriguez", "Pitcher");
|
||||||
|
|
||||||
|
int hashCode1 = player.hashCode();
|
||||||
|
int hashCode2 = player.hashCode();
|
||||||
|
int hashCode3 = indenticalPlayer.hashCode();
|
||||||
|
|
||||||
|
assertEquals(hashCode1, hashCode2);
|
||||||
|
assertEquals(hashCode1, hashCode3);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenCallingHashCodeAndArraysHashCode_thenSameHashCodeReturned() {
|
||||||
|
Player player = new Player("Bobby", "Dalbec", "First Base");
|
||||||
|
int hashcode1 = player.hashCode();
|
||||||
|
String[] playerInfo = { "Bobby", "Dalbec", "First Base" };
|
||||||
|
int hashcode2 = Arrays.hashCode(playerInfo);
|
||||||
|
|
||||||
|
assertEquals(hashcode1, hashcode2);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
package com.baeldung.interfacevsabstractclass;
|
||||||
|
|
||||||
|
public class Car extends Vehicle {
|
||||||
|
|
||||||
|
public Car(String vechicleName) {
|
||||||
|
super(vechicleName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Car(String vechicleName, String vehicleModel) {
|
||||||
|
super(vechicleName, vehicleModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Car(String vechicleName, String vehicleModel, Long makeYear) {
|
||||||
|
super(vechicleName, vehicleModel, makeYear);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void start() {
|
||||||
|
// code implementation details on starting a car.
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void stop() {
|
||||||
|
// code implementation details on stopping a car.
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void drive() {
|
||||||
|
// code implementation details on start driving a car.
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void changeGear() {
|
||||||
|
// code implementation details on changing the car gear.
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void reverse() {
|
||||||
|
// code implementation details on reverse driving a car.
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
package com.baeldung.interfacevsabstractclass;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
public class ImageSender implements Sender {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void send(File fileToBeSent) {
|
||||||
|
// image sending implementation code.
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
package com.baeldung.interfacevsabstractclass;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
public interface Sender {
|
||||||
|
|
||||||
|
void send(File fileToBeSent);
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
package com.baeldung.interfacevsabstractclass;
|
||||||
|
|
||||||
|
public abstract class Vehicle {
|
||||||
|
|
||||||
|
private String vehicleName;
|
||||||
|
private String vehicleModel;
|
||||||
|
private Long makeYear;
|
||||||
|
|
||||||
|
public Vehicle(String vehicleName) {
|
||||||
|
this.vehicleName = vehicleName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vehicle(String vehicleName, String vehicleModel) {
|
||||||
|
this(vehicleName);
|
||||||
|
this.vehicleModel = vehicleModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vehicle(String vechicleName, String vehicleModel, Long makeYear) {
|
||||||
|
this(vechicleName, vehicleModel);
|
||||||
|
this.makeYear = makeYear;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getVehicleName() {
|
||||||
|
return vehicleName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVehicleName(String vehicleName) {
|
||||||
|
this.vehicleName = vehicleName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getVehicleModel() {
|
||||||
|
return vehicleModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVehicleModel(String vehicleModel) {
|
||||||
|
this.vehicleModel = vehicleModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getMakeYear() {
|
||||||
|
return makeYear;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMakeYear(Long makeYear) {
|
||||||
|
this.makeYear = makeYear;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void start();
|
||||||
|
|
||||||
|
protected abstract void stop();
|
||||||
|
|
||||||
|
protected abstract void drive();
|
||||||
|
|
||||||
|
protected abstract void changeGear();
|
||||||
|
|
||||||
|
protected abstract void reverse();
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
package com.baeldung.interfacevsabstractclass;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
public class VideoSender implements Sender {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void send(File fileToBeSent) {
|
||||||
|
// video sending implementation code
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package com.baeldung.interfacevsabstractclass;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import com.baeldung.interfacevsabstractclass.ImageSender;
|
||||||
|
import com.baeldung.interfacevsabstractclass.Sender;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
class SenderUnitTest {
|
||||||
|
|
||||||
|
public final static String IMAGE_FILE_PATH = "/sample_image_file_path/photo.jpg";
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenImageUploaded_whenButtonClicked_thenSendImage() {
|
||||||
|
File imageFile = new File(IMAGE_FILE_PATH);
|
||||||
|
|
||||||
|
Sender sender = new ImageSender();
|
||||||
|
sender.send(imageFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
package com.baeldung.interfacevsabstractclass;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import com.baeldung.interfacevsabstractclass.Car;
|
||||||
|
import com.baeldung.interfacevsabstractclass.Vehicle;
|
||||||
|
|
||||||
|
class VehicleUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenVehicle_whenNeedToDrive_thenStart() {
|
||||||
|
Vehicle car = new Car("BMW");
|
||||||
|
|
||||||
|
car.start();
|
||||||
|
car.drive();
|
||||||
|
car.changeGear();
|
||||||
|
car.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -17,9 +17,9 @@ import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
public class FileDownloadIntegrationTest {
|
public class FileDownloadIntegrationTest {
|
||||||
|
|
||||||
static String FILE_URL = "http://ovh.net/files/1Mio.dat";
|
static String FILE_URL = "https://s3.amazonaws.com/baeldung.com/Do+JSON+with+Jackson+by+Baeldung.pdf";
|
||||||
static String FILE_NAME = "file.dat";
|
static String FILE_NAME = "file.dat";
|
||||||
static String FILE_MD5_HASH = "6cb91af4ed4c60c11613b75cd1fc6116";
|
static String FILE_MD5_HASH = "c959feb066b37f5c4f0e0f45bbbb4f86";
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenJavaIO_whenDownloadingFile_thenDownloadShouldBeCorrect() throws NoSuchAlgorithmException, IOException {
|
public void givenJavaIO_whenDownloadingFile_thenDownloadShouldBeCorrect() throws NoSuchAlgorithmException, IOException {
|
||||||
|
|
|
@ -27,6 +27,17 @@
|
||||||
<version>${lombok.version}</version>
|
<version>${lombok.version}</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.openjdk.jmh</groupId>
|
||||||
|
<artifactId>jmh-core</artifactId>
|
||||||
|
<version>${jmh.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.openjdk.jmh</groupId>
|
||||||
|
<artifactId>jmh-generator-annprocess</artifactId>
|
||||||
|
<version>${jmh.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
<!-- test scoped -->
|
<!-- test scoped -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.assertj</groupId>
|
<groupId>org.assertj</groupId>
|
||||||
|
@ -44,11 +55,30 @@
|
||||||
<filtering>true</filtering>
|
<filtering>true</filtering>
|
||||||
</resource>
|
</resource>
|
||||||
</resources>
|
</resources>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<source>1.8</source>
|
||||||
|
<target>1.8</target>
|
||||||
|
<annotationProcessorPaths>
|
||||||
|
<path>
|
||||||
|
<groupId>org.openjdk.jmh</groupId>
|
||||||
|
<artifactId>jmh-generator-annprocess</artifactId>
|
||||||
|
<version>${jmh.version}</version>
|
||||||
|
</path>
|
||||||
|
</annotationProcessorPaths>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
|
<lombok.version>1.18.20</lombok.version>
|
||||||
<!-- testing -->
|
<!-- testing -->
|
||||||
<assertj.version>3.6.1</assertj.version>
|
<assertj.version>3.6.1</assertj.version>
|
||||||
|
<jmh.version>1.29</jmh.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
|
@ -0,0 +1,9 @@
|
||||||
|
package com.baeldung.streams.parallel;
|
||||||
|
|
||||||
|
public class BenchmarkRunner {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
org.openjdk.jmh.Main.main(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
package com.baeldung.streams.parallel;
|
||||||
|
|
||||||
|
import org.openjdk.jmh.annotations.Benchmark;
|
||||||
|
import org.openjdk.jmh.annotations.BenchmarkMode;
|
||||||
|
import org.openjdk.jmh.annotations.Mode;
|
||||||
|
import org.openjdk.jmh.annotations.OutputTimeUnit;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
|
public class DifferentSourceSplitting {
|
||||||
|
|
||||||
|
private static final List<Integer> arrayListOfNumbers = new ArrayList<>();
|
||||||
|
private static final List<Integer> linkedListOfNumbers = new LinkedList<>();
|
||||||
|
|
||||||
|
static {
|
||||||
|
IntStream.rangeClosed(1, 1_000_000).forEach(i -> {
|
||||||
|
arrayListOfNumbers.add(i);
|
||||||
|
linkedListOfNumbers.add(i);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
@BenchmarkMode(Mode.AverageTime)
|
||||||
|
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||||
|
public static void differentSourceArrayListSequential() {
|
||||||
|
arrayListOfNumbers.stream().reduce(0, Integer::sum);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
@BenchmarkMode(Mode.AverageTime)
|
||||||
|
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||||
|
public static void differentSourceArrayListParallel() {
|
||||||
|
arrayListOfNumbers.parallelStream().reduce(0, Integer::sum);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
@BenchmarkMode(Mode.AverageTime)
|
||||||
|
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||||
|
public static void differentSourceLinkedListSequential() {
|
||||||
|
linkedListOfNumbers.stream().reduce(0, Integer::sum);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
@BenchmarkMode(Mode.AverageTime)
|
||||||
|
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||||
|
public static void differentSourceLinkedListParallel() {
|
||||||
|
linkedListOfNumbers.parallelStream().reduce(0, Integer::sum);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
package com.baeldung.streams.parallel;
|
||||||
|
|
||||||
|
import org.openjdk.jmh.annotations.Benchmark;
|
||||||
|
import org.openjdk.jmh.annotations.BenchmarkMode;
|
||||||
|
import org.openjdk.jmh.annotations.Mode;
|
||||||
|
import org.openjdk.jmh.annotations.OutputTimeUnit;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
|
public class MemoryLocalityCosts {
|
||||||
|
|
||||||
|
private static final int[] intArray = new int[1_000_000];
|
||||||
|
private static final Integer[] integerArray = new Integer[1_000_000];
|
||||||
|
|
||||||
|
static {
|
||||||
|
IntStream.rangeClosed(1, 1_000_000).forEach(i -> {
|
||||||
|
intArray[i-1] = i;
|
||||||
|
integerArray[i-1] = i;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
@BenchmarkMode(Mode.AverageTime)
|
||||||
|
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||||
|
public static void localityIntArraySequential() {
|
||||||
|
Arrays.stream(intArray).reduce(0, Integer::sum);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
@BenchmarkMode(Mode.AverageTime)
|
||||||
|
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||||
|
public static void localityIntArrayParallel() {
|
||||||
|
Arrays.stream(intArray).parallel().reduce(0, Integer::sum);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
@BenchmarkMode(Mode.AverageTime)
|
||||||
|
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||||
|
public static void localityIntegerArraySequential() {
|
||||||
|
Arrays.stream(integerArray).reduce(0, Integer::sum);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
@BenchmarkMode(Mode.AverageTime)
|
||||||
|
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||||
|
public static void localityIntegerArrayParallel() {
|
||||||
|
Arrays.stream(integerArray).parallel().reduce(0, Integer::sum);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
package com.baeldung.streams.parallel;
|
||||||
|
|
||||||
|
import org.openjdk.jmh.annotations.Benchmark;
|
||||||
|
import org.openjdk.jmh.annotations.BenchmarkMode;
|
||||||
|
import org.openjdk.jmh.annotations.Mode;
|
||||||
|
import org.openjdk.jmh.annotations.OutputTimeUnit;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
|
public class MergingCosts {
|
||||||
|
|
||||||
|
private static final List<Integer> arrayListOfNumbers = new ArrayList<>();
|
||||||
|
|
||||||
|
static {
|
||||||
|
IntStream.rangeClosed(1, 1_000_000).forEach(i -> {
|
||||||
|
arrayListOfNumbers.add(i);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
@BenchmarkMode(Mode.AverageTime)
|
||||||
|
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||||
|
public static void mergingCostsSumSequential() {
|
||||||
|
arrayListOfNumbers.stream().reduce(0, Integer::sum);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
@BenchmarkMode(Mode.AverageTime)
|
||||||
|
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||||
|
public static void mergingCostsSumParallel() {
|
||||||
|
arrayListOfNumbers.stream().parallel().reduce(0, Integer::sum);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
@BenchmarkMode(Mode.AverageTime)
|
||||||
|
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||||
|
public static void mergingCostsGroupingSequential() {
|
||||||
|
arrayListOfNumbers.stream().collect(Collectors.toSet());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
@BenchmarkMode(Mode.AverageTime)
|
||||||
|
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||||
|
public static void mergingCostsGroupingParallel() {
|
||||||
|
arrayListOfNumbers.stream().parallel().collect(Collectors.toSet());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package com.baeldung.streams.parallel;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ParallelStream {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
List<Integer> listOfNumbers = Arrays.asList(1, 2, 3, 4);
|
||||||
|
listOfNumbers.parallelStream().forEach(number ->
|
||||||
|
System.out.println(number + " " + Thread.currentThread().getName())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package com.baeldung.streams.parallel;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class SequentialStream {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
List<Integer> listOfNumbers = Arrays.asList(1, 2, 3, 4);
|
||||||
|
listOfNumbers.stream().forEach(number ->
|
||||||
|
System.out.println(number + " " + Thread.currentThread().getName())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
package com.baeldung.streams.parallel;
|
||||||
|
|
||||||
|
import org.openjdk.jmh.annotations.Benchmark;
|
||||||
|
import org.openjdk.jmh.annotations.BenchmarkMode;
|
||||||
|
import org.openjdk.jmh.annotations.Mode;
|
||||||
|
import org.openjdk.jmh.annotations.OutputTimeUnit;
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
|
public class SplittingCosts {
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
@BenchmarkMode(Mode.AverageTime)
|
||||||
|
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||||
|
public static void sourceSplittingIntStreamSequential() {
|
||||||
|
IntStream.rangeClosed(1, 100).reduce(0, Integer::sum);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
@BenchmarkMode(Mode.AverageTime)
|
||||||
|
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||||
|
public static void sourceSplittingIntStreamParallel() {
|
||||||
|
IntStream.rangeClosed(1, 100).parallel().reduce(0, Integer::sum);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
package com.baeldung.streams.parallel;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.ForkJoinPool;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
class ForkJoinUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenSequentialStreamOfNumbers_whenReducingSumWithIdentityFive_thenResultIsCorrect() {
|
||||||
|
List<Integer> listOfNumbers = Arrays.asList(1, 2, 3, 4);
|
||||||
|
int sum = listOfNumbers.stream().reduce(5, Integer::sum);
|
||||||
|
assertThat(sum).isEqualTo(15);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenParallelStreamOfNumbers_whenReducingSumWithIdentityFive_thenResultIsNotCorrect() {
|
||||||
|
List<Integer> listOfNumbers = Arrays.asList(1, 2, 3, 4);
|
||||||
|
int sum = listOfNumbers.parallelStream().reduce(5, Integer::sum);
|
||||||
|
assertThat(sum).isNotEqualTo(15);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenParallelStreamOfNumbers_whenReducingSumWithIdentityZero_thenResultIsCorrect() {
|
||||||
|
List<Integer> listOfNumbers = Arrays.asList(1, 2, 3, 4);
|
||||||
|
int sum = listOfNumbers.parallelStream().reduce(0, Integer::sum) + 5;
|
||||||
|
assertThat(sum).isEqualTo(15);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenParallelStreamOfNumbers_whenUsingCustomThreadPool_thenResultIsCorrect()
|
||||||
|
throws InterruptedException, ExecutionException {
|
||||||
|
List<Integer> listOfNumbers = Arrays.asList(1, 2, 3, 4);
|
||||||
|
ForkJoinPool customThreadPool = new ForkJoinPool(4);
|
||||||
|
int sum = customThreadPool.submit(
|
||||||
|
() -> listOfNumbers.parallelStream().reduce(0, Integer::sum)).get();
|
||||||
|
customThreadPool.shutdown();
|
||||||
|
assertThat(sum).isEqualTo(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
package com.baeldung.splitkeepdelimiters;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import com.google.common.base.Splitter;
|
||||||
|
|
||||||
|
public class SplitAndKeepDelimitersUnitTest {
|
||||||
|
|
||||||
|
private final String positivelookAheadRegex = "((?=@))";
|
||||||
|
private final String positivelookBehindRegex = "((?<=@))";
|
||||||
|
private final String positivelookAroundRegex = "((?=@)|(?<=@))";
|
||||||
|
private final String positiveLookAroundMultiDelimiterRegex = "((?=:|#|@)|(?<=:|#|@))";
|
||||||
|
|
||||||
|
private String text = "Hello@World@This@Is@A@Java@Program";
|
||||||
|
private String textMixed = "@HelloWorld@This:Is@A#Java#Program";
|
||||||
|
private String textMixed2 = "pg@no;10@hello;world@this;is@a#10words;Java#Program";
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenString_splitAndKeepDelimiters_using_javaLangString() {
|
||||||
|
|
||||||
|
assertThat(text.split(positivelookAheadRegex)).containsExactly("Hello", "@World", "@This", "@Is", "@A", "@Java", "@Program");
|
||||||
|
|
||||||
|
assertThat(text.split(positivelookBehindRegex)).containsExactly("Hello@", "World@", "This@", "Is@", "A@", "Java@", "Program");
|
||||||
|
|
||||||
|
assertThat(text.split(positivelookAroundRegex)).containsExactly("Hello", "@", "World", "@", "This", "@", "Is", "@", "A", "@", "Java", "@", "Program");
|
||||||
|
|
||||||
|
assertThat(textMixed.split(positiveLookAroundMultiDelimiterRegex)).containsExactly("@", "HelloWorld", "@", "This", ":", "Is", "@", "A", "#", "Java", "#", "Program");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenString_splitAndKeepDelimiters_using_ApacheCommonsLang3StringUtils() {
|
||||||
|
|
||||||
|
assertThat(StringUtils.splitByCharacterType(textMixed2)).containsExactly("pg", "@", "no", ";", "10", "@", "hello", ";", "world", "@", "this", ";", "is", "@", "a", "#", "10", "words", ";", "J", "ava", "#", "P", "rogram");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenString_splitAndKeepDelimiters_using_GuavaSplitter() {
|
||||||
|
|
||||||
|
assertThat(Splitter.onPattern(positivelookAroundRegex)
|
||||||
|
.splitToList(text)).containsExactly("Hello", "@", "World", "@", "This", "@", "Is", "@", "A", "@", "Java", "@", "Program");
|
||||||
|
|
||||||
|
assertThat(Splitter.on(Pattern.compile(positivelookAroundRegex))
|
||||||
|
.splitToList(text)).containsExactly("Hello", "@", "World", "@", "This", "@", "Is", "@", "A", "@", "Java", "@", "Program");
|
||||||
|
|
||||||
|
assertThat(Splitter.onPattern(positiveLookAroundMultiDelimiterRegex)
|
||||||
|
.splitToList(textMixed)).containsExactly("@", "HelloWorld", "@", "This", ":", "Is", "@", "A", "#", "Java", "#", "Program");
|
||||||
|
|
||||||
|
assertThat(Splitter.on(Pattern.compile(positiveLookAroundMultiDelimiterRegex))
|
||||||
|
.splitToList(textMixed)).containsExactly("@", "HelloWorld", "@", "This", ":", "Is", "@", "A", "#", "Java", "#", "Program");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,18 +1,17 @@
|
||||||
package com.baeldung.javaxval.bigdecimal;
|
package com.baeldung.javaxval.bigdecimal;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import javax.validation.ConstraintViolation;
|
|
||||||
import javax.validation.Validation;
|
|
||||||
import javax.validation.Validator;
|
|
||||||
|
|
||||||
import com.baeldung.javaxval.LocaleAwareUnitTest;
|
import com.baeldung.javaxval.LocaleAwareUnitTest;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import javax.validation.ConstraintViolation;
|
||||||
|
import javax.validation.Validation;
|
||||||
|
import javax.validation.Validator;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
public class InvoiceUnitTest extends LocaleAwareUnitTest {
|
public class InvoiceUnitTest extends LocaleAwareUnitTest {
|
||||||
|
|
||||||
private static Validator validator;
|
private static Validator validator;
|
||||||
|
@ -24,41 +23,67 @@ public class InvoiceUnitTest extends LocaleAwareUnitTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenPriceIntegerDigitLessThanThreeWithDecimalValue_thenShouldGiveConstraintViolations() {
|
public void whenLessThanThreeIntegerDigits_thenShouldNotGiveConstraintViolations() {
|
||||||
Invoice invoice = new Invoice(new BigDecimal(10.21), "Book purchased");
|
Invoice invoice = new Invoice(new BigDecimal("10.21"), "Book purchased");
|
||||||
Set<ConstraintViolation<Invoice>> violations = validator.validate(invoice);
|
Set<ConstraintViolation<Invoice>> violations = validator.validate(invoice);
|
||||||
assertThat(violations.size()).isEqualTo(1);
|
assertThat(violations).isEmpty();
|
||||||
violations.forEach(action -> assertThat(action.getMessage()).isEqualTo("numeric value out of bounds (<3 digits>.<2 digits> expected)"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenPriceIntegerDigitLessThanThreeWithIntegerValue_thenShouldNotGiveConstraintViolations() {
|
public void whenThreeIntegerDigits_thenShouldNotGiveConstraintViolations() {
|
||||||
Invoice invoice = new Invoice(new BigDecimal(10), "Book purchased");
|
Invoice invoice = new Invoice(new BigDecimal("102.21"), "Book purchased");
|
||||||
Set<ConstraintViolation<Invoice>> violations = validator.validate(invoice);
|
Set<ConstraintViolation<Invoice>> violations = validator.validate(invoice);
|
||||||
assertThat(violations.size()).isEqualTo(0);
|
assertThat(violations).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenPriceIntegerDigitGreaterThanThree_thenShouldGiveConstraintViolations() {
|
public void whenMoreThanThreeIntegerDigits_thenShouldGiveConstraintViolations() {
|
||||||
Invoice invoice = new Invoice(new BigDecimal(1021.21), "Book purchased");
|
Invoice invoice = new Invoice(new BigDecimal("1021.21"), "Book purchased");
|
||||||
Set<ConstraintViolation<Invoice>> violations = validator.validate(invoice);
|
Set<ConstraintViolation<Invoice>> violations = validator.validate(invoice);
|
||||||
assertThat(violations.size()).isEqualTo(1);
|
assertThat(violations).hasSize(1);
|
||||||
violations.forEach(action -> assertThat(action.getMessage()).isEqualTo("numeric value out of bounds (<3 digits>.<2 digits> expected)"));
|
assertThat(violations)
|
||||||
|
.extracting("message")
|
||||||
|
.containsOnly("numeric value out of bounds (<3 digits>.<2 digits> expected)");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenLessThanTwoFractionDigits_thenShouldNotGiveConstraintViolations() {
|
||||||
|
Invoice invoice = new Invoice(new BigDecimal("99.9"), "Book purchased");
|
||||||
|
Set<ConstraintViolation<Invoice>> violations = validator.validate(invoice);
|
||||||
|
assertThat(violations).isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenTwoFractionDigits_thenShouldNotGiveConstraintViolations() {
|
||||||
|
Invoice invoice = new Invoice(new BigDecimal("99.99"), "Book purchased");
|
||||||
|
Set<ConstraintViolation<Invoice>> violations = validator.validate(invoice);
|
||||||
|
assertThat(violations).isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenMoreThanTwoFractionDigits_thenShouldGiveConstraintViolations() {
|
||||||
|
Invoice invoice = new Invoice(new BigDecimal("99.999"), "Book purchased");
|
||||||
|
Set<ConstraintViolation<Invoice>> violations = validator.validate(invoice);
|
||||||
|
assertThat(violations).hasSize(1);
|
||||||
|
assertThat(violations)
|
||||||
|
.extracting("message")
|
||||||
|
.containsOnly("numeric value out of bounds (<3 digits>.<2 digits> expected)");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenPriceIsZero_thenShouldGiveConstraintViolations() {
|
public void whenPriceIsZero_thenShouldGiveConstraintViolations() {
|
||||||
Invoice invoice = new Invoice(new BigDecimal(000.00), "Book purchased");
|
Invoice invoice = new Invoice(new BigDecimal("0.00"), "Book purchased");
|
||||||
Set<ConstraintViolation<Invoice>> violations = validator.validate(invoice);
|
Set<ConstraintViolation<Invoice>> violations = validator.validate(invoice);
|
||||||
assertThat(violations.size()).isEqualTo(1);
|
assertThat(violations).hasSize(1);
|
||||||
violations.forEach(action -> assertThat(action.getMessage()).isEqualTo("must be greater than 0.0"));
|
assertThat(violations)
|
||||||
|
.extracting("message")
|
||||||
|
.containsOnly("must be greater than 0.0");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenPriceIsGreaterThanZero_thenShouldNotGiveConstraintViolations() {
|
public void whenPriceIsGreaterThanZero_thenShouldNotGiveConstraintViolations() {
|
||||||
Invoice invoice = new Invoice(new BigDecimal(100.50), "Book purchased");
|
Invoice invoice = new Invoice(new BigDecimal("100.50"), "Book purchased");
|
||||||
Set<ConstraintViolation<Invoice>> violations = validator.validate(invoice);
|
Set<ConstraintViolation<Invoice>> violations = validator.validate(invoice);
|
||||||
assertThat(violations.size()).isEqualTo(0);
|
assertThat(violations).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,3 +16,4 @@ If you get a valid response, then you're good to go.
|
||||||
|
|
||||||
- [Paging and Async Calls with the Kubernetes API](https://www.baeldung.com/java-kubernetes-paging-async)
|
- [Paging and Async Calls with the Kubernetes API](https://www.baeldung.com/java-kubernetes-paging-async)
|
||||||
- [Using Watch with the Kubernetes API](https://www.baeldung.com/java-kubernetes-watch)
|
- [Using Watch with the Kubernetes API](https://www.baeldung.com/java-kubernetes-watch)
|
||||||
|
- [Using Namespaces and Selectors With the Kubernetes Java API](https://www.baeldung.com/java-kubernetes-namespaces-selectors)
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Namespace
|
||||||
|
metadata:
|
||||||
|
name: ns1
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Namespace
|
||||||
|
metadata:
|
||||||
|
name: ns2
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: httpd
|
||||||
|
namespace: ns1
|
||||||
|
labels:
|
||||||
|
app: httpd
|
||||||
|
version: "1"
|
||||||
|
spec:
|
||||||
|
replicas: 3
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: httpd
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: httpd
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: main
|
||||||
|
image: httpd:alpine
|
||||||
|
ports:
|
||||||
|
- containerPort: 80
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: httpd
|
||||||
|
namespace: ns2
|
||||||
|
labels:
|
||||||
|
app: httpd
|
||||||
|
version: "2"
|
||||||
|
foo: bar
|
||||||
|
spec:
|
||||||
|
replicas: 3
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: httpd
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: httpd
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: main
|
||||||
|
image: httpd:alpine
|
||||||
|
ports:
|
||||||
|
- containerPort: 80
|
|
@ -0,0 +1,68 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package com.baeldung.kubernetes.intro;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import io.kubernetes.client.openapi.ApiClient;
|
||||||
|
import io.kubernetes.client.openapi.apis.CoreV1Api;
|
||||||
|
import io.kubernetes.client.openapi.models.V1NodeList;
|
||||||
|
import io.kubernetes.client.openapi.models.V1PodList;
|
||||||
|
import io.kubernetes.client.util.Config;
|
||||||
|
import okhttp3.OkHttpClient;
|
||||||
|
import okhttp3.logging.HttpLoggingInterceptor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Philippe
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ListPodsWithFieldSelectors {
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(ListPodsWithFieldSelectors.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param args
|
||||||
|
*/
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
|
||||||
|
ApiClient client = Config.defaultClient();
|
||||||
|
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(message -> log.info(message));
|
||||||
|
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
|
||||||
|
OkHttpClient newClient = client.getHttpClient()
|
||||||
|
.newBuilder()
|
||||||
|
.addInterceptor(interceptor)
|
||||||
|
.readTimeout(0, TimeUnit.SECONDS)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
client.setHttpClient(newClient);
|
||||||
|
CoreV1Api api = new CoreV1Api(client);
|
||||||
|
|
||||||
|
String fs = createSelector(args);
|
||||||
|
V1PodList items = api.listPodForAllNamespaces(null, null, fs, null, null, null, null, null, 10, false);
|
||||||
|
items.getItems()
|
||||||
|
.stream()
|
||||||
|
.map((pod) -> pod.getMetadata().getName() )
|
||||||
|
.forEach((name) -> System.out.println("name=" + name));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String createSelector(String[] args) {
|
||||||
|
|
||||||
|
StringBuilder b = new StringBuilder();
|
||||||
|
for( int i = 0 ; i < args.length; i++ ) {
|
||||||
|
if( b.length() > 0 ) {
|
||||||
|
b.append(',');
|
||||||
|
}
|
||||||
|
|
||||||
|
b.append(args[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return b.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package com.baeldung.kubernetes.intro;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import io.kubernetes.client.openapi.ApiClient;
|
||||||
|
import io.kubernetes.client.openapi.apis.CoreV1Api;
|
||||||
|
import io.kubernetes.client.openapi.models.V1NodeList;
|
||||||
|
import io.kubernetes.client.openapi.models.V1PodList;
|
||||||
|
import io.kubernetes.client.util.Config;
|
||||||
|
import okhttp3.OkHttpClient;
|
||||||
|
import okhttp3.logging.HttpLoggingInterceptor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Philippe
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ListPodsWithLabelSelectors {
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(ListPodsWithLabelSelectors.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param args
|
||||||
|
*/
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
|
||||||
|
ApiClient client = Config.defaultClient();
|
||||||
|
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(message -> log.info(message));
|
||||||
|
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
|
||||||
|
OkHttpClient newClient = client.getHttpClient()
|
||||||
|
.newBuilder()
|
||||||
|
.addInterceptor(interceptor)
|
||||||
|
.readTimeout(0, TimeUnit.SECONDS)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
client.setHttpClient(newClient);
|
||||||
|
CoreV1Api api = new CoreV1Api(client);
|
||||||
|
|
||||||
|
String selector = createSelector(args);
|
||||||
|
V1PodList items = api.listPodForAllNamespaces(null, null, null, selector, null, null, null, null, 10, false);
|
||||||
|
items.getItems()
|
||||||
|
.stream()
|
||||||
|
.map((pod) -> pod.getMetadata().getName() )
|
||||||
|
.forEach((name) -> System.out.println("name=" + name));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String createSelector(String[] args) {
|
||||||
|
|
||||||
|
StringBuilder b = new StringBuilder();
|
||||||
|
for( int i = 0 ; i < args.length; i++ ) {
|
||||||
|
if( b.length() > 0 ) {
|
||||||
|
b.append(',');
|
||||||
|
}
|
||||||
|
|
||||||
|
b.append(args[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return b.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package com.baeldung.kubernetes.intro;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import io.kubernetes.client.openapi.ApiClient;
|
||||||
|
import io.kubernetes.client.openapi.apis.CoreV1Api;
|
||||||
|
import io.kubernetes.client.openapi.models.V1NodeList;
|
||||||
|
import io.kubernetes.client.openapi.models.V1PodList;
|
||||||
|
import io.kubernetes.client.util.Config;
|
||||||
|
import okhttp3.OkHttpClient;
|
||||||
|
import okhttp3.logging.HttpLoggingInterceptor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Philippe
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ListPodsWithNamespaces {
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(ListPodsWithNamespaces.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param args
|
||||||
|
*/
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
|
||||||
|
ApiClient client = Config.defaultClient();
|
||||||
|
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(message -> log.info(message));
|
||||||
|
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
|
||||||
|
OkHttpClient newClient = client.getHttpClient()
|
||||||
|
.newBuilder()
|
||||||
|
.addInterceptor(interceptor)
|
||||||
|
.readTimeout(0, TimeUnit.SECONDS)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
client.setHttpClient(newClient);
|
||||||
|
CoreV1Api api = new CoreV1Api(client);
|
||||||
|
String namespace = "ns1";
|
||||||
|
V1PodList items = api.listNamespacedPod(namespace,null, null, null, null, null, null, null, null, 10, false);
|
||||||
|
items.getItems()
|
||||||
|
.stream()
|
||||||
|
.map((pod) -> pod.getMetadata().getName() )
|
||||||
|
.forEach((name) -> System.out.println("name=" + name));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
package com.baeldung.kubernetes.intro;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
class ListPodsWithFieldSelectorsLiveTest {
|
||||||
|
@Test
|
||||||
|
void givenEqualitySelector_whenListPodsWithFieldSelectors_thenSuccess() throws Exception {
|
||||||
|
ListPodsWithFieldSelectors.main(new String[] {
|
||||||
|
"metadata.namespace=ns1"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenInequalitySelector_whenListPodsWithFieldSelectors_thenSuccess() throws Exception {
|
||||||
|
ListPodsWithFieldSelectors.main(new String[] {
|
||||||
|
"metadata.namespace!=ns1"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenChainedSelector_whenListPodsWithFieldSelectors_thenSuccess() throws Exception {
|
||||||
|
ListPodsWithFieldSelectors.main(new String[] {
|
||||||
|
"metadata.namespace=ns1",
|
||||||
|
"status.phase=Running"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
package com.baeldung.kubernetes.intro;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
class ListPodsWithLabelSelectorsLiveTest {
|
||||||
|
@Test
|
||||||
|
void givenEqualitySelector_whenListPodsWithLabelSelectors_thenSuccess() throws Exception {
|
||||||
|
ListPodsWithLabelSelectors.main(new String[] {
|
||||||
|
"app=httpd"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenInqualitySelector_whenListPodsWithLabelSelectors_thenSuccess() throws Exception {
|
||||||
|
ListPodsWithLabelSelectors.main(new String[] {
|
||||||
|
"app!=httpd"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenInSetSelector_whenListPodsWithLabelSelectors_thenSuccess() throws Exception {
|
||||||
|
ListPodsWithLabelSelectors.main(new String[] {
|
||||||
|
"app in (httpd,test)"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenNotInSetSelector_whenListPodsWithLabelSelectors_thenSuccess() throws Exception {
|
||||||
|
ListPodsWithLabelSelectors.main(new String[] {
|
||||||
|
"app notin (httpd)"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenLabelPresentSelector_whenListPodsWithLabelSelectors_thenSuccess() throws Exception {
|
||||||
|
ListPodsWithLabelSelectors.main(new String[] {
|
||||||
|
"app"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenLabelNotPresentSelector_whenListPodsWithLabelSelectors_thenSuccess() throws Exception {
|
||||||
|
ListPodsWithLabelSelectors.main(new String[] {
|
||||||
|
"!app"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenChainedSelector_whenListPodsWithLabelSelectors_thenSuccess() throws Exception {
|
||||||
|
ListPodsWithLabelSelectors.main(new String[] {
|
||||||
|
"app=httpd",
|
||||||
|
"!foo"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,5 +8,6 @@ This module contains articles about HTTP libraries.
|
||||||
- [Decode an OkHttp JSON Response](https://www.baeldung.com/okhttp-json-response)
|
- [Decode an OkHttp JSON Response](https://www.baeldung.com/okhttp-json-response)
|
||||||
- [Retrofit 2 – Dynamic URL](https://www.baeldung.com/retrofit-dynamic-url)
|
- [Retrofit 2 – Dynamic URL](https://www.baeldung.com/retrofit-dynamic-url)
|
||||||
- [Adding Interceptors in OkHTTP](https://www.baeldung.com/java-okhttp-interceptors)
|
- [Adding Interceptors in OkHTTP](https://www.baeldung.com/java-okhttp-interceptors)
|
||||||
|
- [A Guide to Events in OkHTTP](https://www.baeldung.com/java-okhttp-events)
|
||||||
- More articles [[<-- prev]](/libraries-http)
|
- More articles [[<-- prev]](/libraries-http)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,156 @@
|
||||||
|
package com.baeldung.okhttp.events;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.Proxy;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import okhttp3.Call;
|
||||||
|
import okhttp3.Connection;
|
||||||
|
import okhttp3.EventListener;
|
||||||
|
import okhttp3.Handshake;
|
||||||
|
import okhttp3.HttpUrl;
|
||||||
|
import okhttp3.Protocol;
|
||||||
|
import okhttp3.Request;
|
||||||
|
import okhttp3.Response;
|
||||||
|
|
||||||
|
public class EventTimer extends EventListener {
|
||||||
|
|
||||||
|
private long start;
|
||||||
|
|
||||||
|
private void logTimedEvent(String name) {
|
||||||
|
long now = System.nanoTime();
|
||||||
|
if (name.equals("callStart")) {
|
||||||
|
start = now;
|
||||||
|
}
|
||||||
|
long elapsedNanos = now - start;
|
||||||
|
System.out.printf("%.3f %s%n", elapsedNanos / 1000000000d, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void callStart(Call call) {
|
||||||
|
logTimedEvent("callStart");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void proxySelectStart(Call call, HttpUrl url) {
|
||||||
|
logTimedEvent("proxySelectStart");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void proxySelectEnd(Call call, HttpUrl url, List<Proxy> proxies) {
|
||||||
|
logTimedEvent("proxySelectEnd");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void dnsStart(Call call, String domainName) {
|
||||||
|
logTimedEvent("dnsStart");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void dnsEnd(Call call, String domainName, List<InetAddress> inetAddressList) {
|
||||||
|
logTimedEvent("dnsEnd");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void connectStart(Call call, InetSocketAddress inetSocketAddress, Proxy proxy) {
|
||||||
|
logTimedEvent("connectStart");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void secureConnectStart(Call call) {
|
||||||
|
logTimedEvent("secureConnectStart");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void secureConnectEnd(Call call, Handshake handshake) {
|
||||||
|
logTimedEvent("secureConnectEnd");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void connectEnd(Call call, InetSocketAddress inetSocketAddress, Proxy proxy, Protocol protocol) {
|
||||||
|
logTimedEvent("connectEnd");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void connectFailed(Call call, InetSocketAddress inetSocketAddress, Proxy proxy, Protocol protocol, IOException ioe) {
|
||||||
|
logTimedEvent("connectFailed");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void connectionAcquired(Call call, Connection connection) {
|
||||||
|
logTimedEvent("connectionAcquired");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void connectionReleased(Call call, Connection connection) {
|
||||||
|
logTimedEvent("connectionReleased");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void requestHeadersStart(Call call) {
|
||||||
|
logTimedEvent("requestHeadersStart");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void requestHeadersEnd(Call call, Request request) {
|
||||||
|
logTimedEvent("requestHeadersEnd");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void requestBodyStart(Call call) {
|
||||||
|
logTimedEvent("requestBodyStart");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void requestBodyEnd(Call call, long byteCount) {
|
||||||
|
logTimedEvent("requestBodyEnd");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void requestFailed(Call call, IOException ioe) {
|
||||||
|
logTimedEvent("requestFailed");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void responseHeadersStart(Call call) {
|
||||||
|
logTimedEvent("responseHeadersStart");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void responseHeadersEnd(Call call, Response response) {
|
||||||
|
logTimedEvent("responseHeadersEnd");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void responseBodyStart(Call call) {
|
||||||
|
logTimedEvent("responseBodyStart");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void responseBodyEnd(Call call, long byteCount) {
|
||||||
|
logTimedEvent("responseBodyEnd");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void responseFailed(Call call, IOException ioe) {
|
||||||
|
logTimedEvent("responseFailed");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void callEnd(Call call) {
|
||||||
|
logTimedEvent("callEnd");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void callFailed(Call call, IOException ioe) {
|
||||||
|
logTimedEvent("callFailed");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void canceled(Call call) {
|
||||||
|
logTimedEvent("canceled");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
package com.baeldung.okhttp.events;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import okhttp3.Call;
|
||||||
|
import okhttp3.EventListener;
|
||||||
|
import okhttp3.Request;
|
||||||
|
import okhttp3.Response;
|
||||||
|
|
||||||
|
public class SimpleLogEventsListener extends EventListener {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(SimpleLogEventsListener.class);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void callStart(Call call) {
|
||||||
|
LOGGER.info("callStart at {}", LocalDateTime.now());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void requestHeadersEnd(Call call, Request request) {
|
||||||
|
LOGGER.info("requestHeadersEnd at {} with headers {}", LocalDateTime.now(), request.headers());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void responseHeadersEnd(Call call, Response response) {
|
||||||
|
LOGGER.info("responseHeadersEnd at {} with headers {}", LocalDateTime.now(), response.headers());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void callEnd(Call call) {
|
||||||
|
LOGGER.info("callEnd at {}", LocalDateTime.now());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
package com.baeldung.okhttp.events;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import okhttp3.OkHttpClient;
|
||||||
|
import okhttp3.Request;
|
||||||
|
import okhttp3.Response;
|
||||||
|
|
||||||
|
public class EventTimerLiveTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenSimpleEventTimer_whenRequestSent_thenCallsLogged() throws IOException {
|
||||||
|
|
||||||
|
OkHttpClient client = new OkHttpClient.Builder()
|
||||||
|
.eventListener(new EventTimer())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Request request = new Request.Builder()
|
||||||
|
.url("https://www.baeldung.com/")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
try (Response response = client.newCall(request).execute()) {
|
||||||
|
assertEquals("Response code should be: ", 200, response.code());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
package com.baeldung.okhttp.events;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.SocketTimeoutException;
|
||||||
|
|
||||||
|
import org.junit.Rule;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import okhttp3.OkHttpClient;
|
||||||
|
import okhttp3.Request;
|
||||||
|
import okhttp3.Response;
|
||||||
|
import okhttp3.mockwebserver.MockResponse;
|
||||||
|
import okhttp3.mockwebserver.MockWebServer;
|
||||||
|
|
||||||
|
public class LogEventsListenerIntegrationTest {
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public MockWebServer server = new MockWebServer();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenSimpleEventLogger_whenRequestSent_thenCallsLogged() throws IOException {
|
||||||
|
server.enqueue(new MockResponse().setBody("Hello Baeldung Readers!"));
|
||||||
|
|
||||||
|
OkHttpClient client = new OkHttpClient.Builder()
|
||||||
|
.eventListener(new SimpleLogEventsListener())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Request request = new Request.Builder()
|
||||||
|
.url(server.url("/"))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
try (Response response = client.newCall(request).execute()) {
|
||||||
|
assertEquals("Response code should be: ", 200, response.code());
|
||||||
|
assertEquals("Body should be: ", "Hello Baeldung Readers!", response.body().string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test (expected = SocketTimeoutException.class)
|
||||||
|
public void givenConnectionError_whenRequestSent_thenFailedCallsLogged() throws IOException {
|
||||||
|
OkHttpClient client = new OkHttpClient.Builder()
|
||||||
|
.eventListener(new EventTimer())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Request request = new Request.Builder()
|
||||||
|
.url(server.url("/"))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
client.newCall(request).execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,92 @@
|
||||||
|
<?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>
|
||||||
|
<parent>
|
||||||
|
<artifactId>maven-copy-files</artifactId>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
<groupId>org.baeldung</groupId>
|
||||||
|
<artifactId>copy-rename-maven-plugin</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<name>copy-rename-maven-plugin</name>
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<maven.compiler.source>1.7</maven.compiler.source>
|
||||||
|
<maven.compiler.target>1.7</maven.compiler.target>
|
||||||
|
</properties>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>4.11</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>com.coderplus.maven.plugins</groupId>
|
||||||
|
<artifactId>copy-rename-maven-plugin</artifactId>
|
||||||
|
<version>1.0</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>copy-file</id>
|
||||||
|
<phase>generate-sources</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>copy</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<sourceFile>source-files/foo.txt</sourceFile>
|
||||||
|
<destinationFile>target/destination-folder/foo.txt</destinationFile>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
<pluginManagement>
|
||||||
|
<!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
|
||||||
|
<plugins>
|
||||||
|
<!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-clean-plugin</artifactId>
|
||||||
|
<version>3.1.0</version>
|
||||||
|
</plugin>
|
||||||
|
<!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-resources-plugin</artifactId>
|
||||||
|
<version>3.0.2</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.8.0</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<version>2.22.1</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
<version>3.0.2</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-install-plugin</artifactId>
|
||||||
|
<version>2.5.2</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-deploy-plugin</artifactId>
|
||||||
|
<version>2.8.2</version>
|
||||||
|
</plugin>
|
||||||
|
<!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-site-plugin</artifactId>
|
||||||
|
<version>3.7.1</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-project-info-reports-plugin</artifactId>
|
||||||
|
<version>3.0.0</version>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</pluginManagement>
|
||||||
|
</build>
|
||||||
|
</project>
|
|
@ -0,0 +1 @@
|
||||||
|
Copy File Example
|
|
@ -0,0 +1,16 @@
|
||||||
|
package org.baeldung;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
public class CopyFileUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenCopyingAFileFromSourceToDestination_thenFileShouldBeInDestination() {
|
||||||
|
File destinationFile = new File("target/destination-folder/foo.txt");
|
||||||
|
assertEquals(true, destinationFile.exists());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,94 @@
|
||||||
|
<?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>
|
||||||
|
<parent>
|
||||||
|
<artifactId>maven-copy-files</artifactId>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
<groupId>org.baeldung</groupId>
|
||||||
|
<artifactId>maven-antrun-plugin</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<name>maven-antrun-plugin</name>
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<maven.compiler.source>1.7</maven.compiler.source>
|
||||||
|
<maven.compiler.target>1.7</maven.compiler.target>
|
||||||
|
</properties>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>4.11</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-antrun-plugin</artifactId>
|
||||||
|
<version>3.0.0</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>generate-sources</phase>
|
||||||
|
<configuration>
|
||||||
|
<target>
|
||||||
|
<mkdir dir="${basedir}/target/destination-folder" />
|
||||||
|
<copy todir="${basedir}/target/destination-folder">
|
||||||
|
<fileset dir="${basedir}/source-files" includes="foo.txt" />
|
||||||
|
</copy>
|
||||||
|
</target>
|
||||||
|
</configuration>
|
||||||
|
<goals>
|
||||||
|
<goal>run</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
<pluginManagement>
|
||||||
|
<!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
|
||||||
|
<plugins>
|
||||||
|
<!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-clean-plugin</artifactId>
|
||||||
|
<version>3.1.0</version>
|
||||||
|
</plugin>
|
||||||
|
<!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-resources-plugin</artifactId>
|
||||||
|
<version>3.0.2</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.8.0</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<version>2.22.1</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
<version>3.0.2</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-install-plugin</artifactId>
|
||||||
|
<version>2.5.2</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-deploy-plugin</artifactId>
|
||||||
|
<version>2.8.2</version>
|
||||||
|
</plugin>
|
||||||
|
<!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-site-plugin</artifactId>
|
||||||
|
<version>3.7.1</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-project-info-reports-plugin</artifactId>
|
||||||
|
<version>3.0.0</version>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</pluginManagement>
|
||||||
|
</build>
|
||||||
|
</project>
|
|
@ -0,0 +1 @@
|
||||||
|
Copy File Example
|
|
@ -0,0 +1,16 @@
|
||||||
|
package org.baeldung;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
public class CopyFileUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenCopyingAFileFromSourceToDestination_thenFileShouldBeInDestination() {
|
||||||
|
File destinationFile = new File("target/destination-folder/foo.txt");
|
||||||
|
assertEquals(true, destinationFile.exists());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,92 @@
|
||||||
|
<?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>
|
||||||
|
<parent>
|
||||||
|
<artifactId>maven-copy-files</artifactId>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
<groupId>org.baeldung</groupId>
|
||||||
|
<artifactId>maven-resources-plugin</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<name>maven-resoures-plugin</name>
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<maven.compiler.source>1.7</maven.compiler.source>
|
||||||
|
<maven.compiler.target>1.7</maven.compiler.target>
|
||||||
|
</properties>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>4.11</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
<build>
|
||||||
|
<pluginManagement>
|
||||||
|
<!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
|
||||||
|
<plugins>
|
||||||
|
<!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-clean-plugin</artifactId>
|
||||||
|
<version>3.1.0</version>
|
||||||
|
</plugin>
|
||||||
|
<!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-resources-plugin</artifactId>
|
||||||
|
<version>3.0.2</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>copy-resource-one</id>
|
||||||
|
<phase>generate-sources</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>copy-resources</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<outputDirectory>${basedir}/target/destination-folder</outputDirectory>
|
||||||
|
<resources>
|
||||||
|
<resource>
|
||||||
|
<directory>source-files</directory>
|
||||||
|
<includes>
|
||||||
|
<include>foo.txt</include>
|
||||||
|
</includes>
|
||||||
|
</resource>
|
||||||
|
</resources>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.8.0</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<version>2.22.1</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
<version>3.0.2</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-install-plugin</artifactId>
|
||||||
|
<version>2.5.2</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-deploy-plugin</artifactId>
|
||||||
|
<version>2.8.2</version>
|
||||||
|
</plugin>
|
||||||
|
<!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-site-plugin</artifactId>
|
||||||
|
<version>3.7.1</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-project-info-reports-plugin</artifactId>
|
||||||
|
<version>3.0.0</version>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</pluginManagement>
|
||||||
|
</build>
|
||||||
|
</project>
|
|
@ -0,0 +1 @@
|
||||||
|
Copy File Example
|
|
@ -0,0 +1,16 @@
|
||||||
|
package org.baeldung;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
public class CopyFileUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenCopyingAFileFromSourceToDestination_thenFileShouldBeInDestination() {
|
||||||
|
File destinationFile = new File("target/destination-folder/foo.txt");
|
||||||
|
assertEquals(true, destinationFile.exists());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,80 @@
|
||||||
|
<?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>
|
||||||
|
<parent>
|
||||||
|
<artifactId>maven-modules</artifactId>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>maven-copy-files</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<packaging>pom</packaging>
|
||||||
|
<name>maven-copy-files</name>
|
||||||
|
<!-- FIXME change it to the project's website -->
|
||||||
|
<url>http://www.example.com</url>
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<maven.compiler.source>1.7</maven.compiler.source>
|
||||||
|
<maven.compiler.target>1.7</maven.compiler.target>
|
||||||
|
</properties>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>4.11</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
<build>
|
||||||
|
<pluginManagement>
|
||||||
|
<!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
|
||||||
|
<plugins>
|
||||||
|
<!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-clean-plugin</artifactId>
|
||||||
|
<version>3.1.0</version>
|
||||||
|
</plugin>
|
||||||
|
<!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-resources-plugin</artifactId>
|
||||||
|
<version>3.0.2</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.8.0</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<version>2.22.1</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
<version>3.0.2</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-install-plugin</artifactId>
|
||||||
|
<version>2.5.2</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-deploy-plugin</artifactId>
|
||||||
|
<version>2.8.2</version>
|
||||||
|
</plugin>
|
||||||
|
<!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-site-plugin</artifactId>
|
||||||
|
<version>3.7.1</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-project-info-reports-plugin</artifactId>
|
||||||
|
<version>3.0.0</version>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</pluginManagement>
|
||||||
|
</build>
|
||||||
|
<modules>
|
||||||
|
<module>maven-resources-plugin</module>
|
||||||
|
<module>maven-antrun-plugin</module>
|
||||||
|
<module>copy-rename-maven-plugin</module>
|
||||||
|
</modules>
|
||||||
|
</project>
|
|
@ -0,0 +1 @@
|
||||||
|
logs/
|
|
@ -0,0 +1,85 @@
|
||||||
|
<?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>maven-printing-plugins</artifactId>
|
||||||
|
<name>maven-printing-plugins</name>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>parent-modules</artifactId>
|
||||||
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
|
<relativePath>../..</relativePath>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-antrun-plugin</artifactId>
|
||||||
|
<version>3.0.0</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>antrun-plugin</id>
|
||||||
|
<phase>validate</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>run</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<target>
|
||||||
|
<echo message="Hello, world"/>
|
||||||
|
<echo message="Embed a line break: ${line.separator}"/>
|
||||||
|
<echo message="Build dir: ${project.build.directory}" level="info"/>
|
||||||
|
<echo file="${basedir}/logs/log-ant-run.txt" append="true"
|
||||||
|
message="Save to file!"/>
|
||||||
|
</target>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>com.github.ekryd.echo-maven-plugin</groupId>
|
||||||
|
<artifactId>echo-maven-plugin</artifactId>
|
||||||
|
<version>1.3.2</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>echo-maven-plugin-1</id>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>echo</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<message>Hello, world</message>
|
||||||
|
<message>Embed a line break: ${line.separator}</message>
|
||||||
|
<message>ArtifactId is ${project.artifactId}</message>
|
||||||
|
<level>INFO</level>
|
||||||
|
<toFile>/logs/log-echo.txt</toFile>
|
||||||
|
<append>true</append>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.codehaus.gmaven</groupId>
|
||||||
|
<artifactId>groovy-maven-plugin</artifactId>
|
||||||
|
<version>2.1.1</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>validate</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>execute</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<source>
|
||||||
|
log.info('Test message: {}', 'Hello, World!')
|
||||||
|
log.info('Embed a line break {}', System.lineSeparator())
|
||||||
|
log.info('ArtifactId is: ${project.artifactId}')
|
||||||
|
log.warn('Message only in debug mode')
|
||||||
|
</source>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
<!-- <module>compiler-plugin-java-9</module> --> <!-- We haven't upgraded to java 9. -->
|
<!-- <module>compiler-plugin-java-9</module> --> <!-- We haven't upgraded to java 9. -->
|
||||||
|
<module>maven-copy-files</module>
|
||||||
<module>maven-custom-plugin</module>
|
<module>maven-custom-plugin</module>
|
||||||
<module>maven-exec-plugin</module>
|
<module>maven-exec-plugin</module>
|
||||||
<module>maven-integration-test</module>
|
<module>maven-integration-test</module>
|
||||||
|
@ -30,6 +31,7 @@
|
||||||
<module>version-collision</module>
|
<module>version-collision</module>
|
||||||
<module>version-overriding-plugins</module>
|
<module>version-overriding-plugins</module>
|
||||||
<module>versions-maven-plugin</module>
|
<module>versions-maven-plugin</module>
|
||||||
|
<module>maven-printing-plugins</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
</project>
|
</project>
|
|
@ -19,7 +19,6 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter</artifactId>
|
<artifactId>spring-boot-starter</artifactId>
|
||||||
<version>2.1.3.RELEASE</version>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.mantisrx</groupId>
|
<groupId>io.mantisrx</groupId>
|
||||||
|
@ -35,36 +34,31 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.fasterxml.jackson.core</groupId>
|
<groupId>com.fasterxml.jackson.core</groupId>
|
||||||
<artifactId>jackson-databind</artifactId>
|
<artifactId>jackson-databind</artifactId>
|
||||||
<version>2.10.2</version>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.andreinc.mockneat</groupId>
|
<groupId>net.andreinc.mockneat</groupId>
|
||||||
<artifactId>mockneat</artifactId>
|
<artifactId>mockneat</artifactId>
|
||||||
<version>0.3.8</version>
|
<version>0.4.2</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.projectlombok</groupId>
|
<groupId>org.projectlombok</groupId>
|
||||||
<artifactId>lombok</artifactId>
|
<artifactId>lombok</artifactId>
|
||||||
<version>1.18.12</version>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework</groupId>
|
<groupId>org.springframework</groupId>
|
||||||
<artifactId>spring-webflux</artifactId>
|
<artifactId>spring-webflux</artifactId>
|
||||||
<version>5.0.9.RELEASE</version>
|
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.projectreactor.netty</groupId>
|
<groupId>io.projectreactor.netty</groupId>
|
||||||
<artifactId>reactor-netty</artifactId>
|
<artifactId>reactor-netty</artifactId>
|
||||||
<version>0.9.12.RELEASE</version>
|
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<repositories>
|
<repositories>
|
||||||
<repository>
|
<repository>
|
||||||
<id>SpringLibReleaseRepo</id>
|
<id>jcenter</id>
|
||||||
<url>https://repo.spring.io/libs-release/</url>
|
<url>https://jcenter.bintray.com/</url>
|
||||||
</repository>
|
</repository>
|
||||||
</repositories>
|
</repositories>
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
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">
|
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>
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
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">
|
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>
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project
|
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
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">
|
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>
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
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">
|
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>
|
||||||
|
|
|
@ -26,6 +26,11 @@
|
||||||
<version>${lombok.version}</version>
|
<version>${lombok.version}</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.code.findbugs</groupId>
|
||||||
|
<artifactId>annotations</artifactId>
|
||||||
|
<version>${findbugs.annotations.version}</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.commons</groupId>
|
<groupId>org.apache.commons</groupId>
|
||||||
<artifactId>commons-lang3</artifactId>
|
<artifactId>commons-lang3</artifactId>
|
||||||
|
@ -41,6 +46,7 @@
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<intellij.annotations.version>16.0.2</intellij.annotations.version>
|
<intellij.annotations.version>16.0.2</intellij.annotations.version>
|
||||||
|
<findbugs.annotations.version>3.0.1</findbugs.annotations.version>
|
||||||
<assertj-core.version>3.9.1</assertj-core.version>
|
<assertj-core.version>3.9.1</assertj-core.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
package com.baeldung.nulls;
|
package com.baeldung.nulls;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
|
import edu.umd.cs.findbugs.annotations.NonNull;
|
||||||
|
import edu.umd.cs.findbugs.annotations.Nullable;
|
||||||
|
|
||||||
public class FindBugsAnnotations {
|
public class FindBugsAnnotations {
|
||||||
|
|
||||||
public void accept(@NotNull Object param) {
|
public void accept(@NonNull Object param) {
|
||||||
System.out.println(param.toString());
|
System.out.println(param.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ public class FindBugsAnnotations {
|
||||||
System.out.println("Printing " + param);
|
System.out.println("Printing " + param);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NonNull
|
||||||
public Object process() throws Exception {
|
public Object process() throws Exception {
|
||||||
Object result = doSomething();
|
Object result = doSomething();
|
||||||
if (result == null) {
|
if (result == null) {
|
||||||
|
|
|
@ -13,3 +13,4 @@ This module contains articles about Object-relational Mapping (ORM) with Hiberna
|
||||||
- [Hibernate – Mapping Date and Time](https://www.baeldung.com/hibernate-date-time)
|
- [Hibernate – Mapping Date and Time](https://www.baeldung.com/hibernate-date-time)
|
||||||
- [Mapping LOB Data in Hibernate](https://www.baeldung.com/hibernate-lob)
|
- [Mapping LOB Data in Hibernate](https://www.baeldung.com/hibernate-lob)
|
||||||
- [FetchMode in Hibernate](https://www.baeldung.com/hibernate-fetchmode)
|
- [FetchMode in Hibernate](https://www.baeldung.com/hibernate-fetchmode)
|
||||||
|
- [Mapping PostgreSQL Array With Hibernate](https://www.baeldung.com/java-hibernate-map-postgresql-array)
|
||||||
|
|
|
@ -13,11 +13,22 @@
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.postgresql</groupId>
|
||||||
|
<artifactId>postgresql</artifactId>
|
||||||
|
<version>${postgresql.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.hibernate</groupId>
|
<groupId>org.hibernate</groupId>
|
||||||
<artifactId>hibernate-core</artifactId>
|
<artifactId>hibernate-core</artifactId>
|
||||||
<version>${hibernate.version}</version>
|
<version>${hibernate.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.vladmihalcea</groupId>
|
||||||
|
<artifactId>hibernate-types-52</artifactId>
|
||||||
|
<version>${hibernate-types.version}</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.assertj</groupId>
|
<groupId>org.assertj</groupId>
|
||||||
<artifactId>assertj-core</artifactId>
|
<artifactId>assertj-core</artifactId>
|
||||||
|
@ -64,7 +75,9 @@
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
|
<postgresql.version>42.2.20</postgresql.version>
|
||||||
<hibernate.version>5.4.12.Final</hibernate.version>
|
<hibernate.version>5.4.12.Final</hibernate.version>
|
||||||
|
<hibernate-types.version>2.10.4</hibernate-types.version>
|
||||||
<assertj-core.version>3.8.0</assertj-core.version>
|
<assertj-core.version>3.8.0</assertj-core.version>
|
||||||
<hibernate-validator.version>6.0.16.Final</hibernate-validator.version>
|
<hibernate-validator.version>6.0.16.Final</hibernate-validator.version>
|
||||||
<org.glassfish.javax.el.version>3.0.1-b11</org.glassfish.javax.el.version>
|
<org.glassfish.javax.el.version>3.0.1-b11</org.glassfish.javax.el.version>
|
||||||
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
package com.baeldung.hibernate.arraymapping;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.sql.Array;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Types;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import org.hibernate.HibernateException;
|
||||||
|
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||||
|
import org.hibernate.usertype.UserType;
|
||||||
|
|
||||||
|
public class CustomIntegerArrayType implements UserType {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int[] sqlTypes() {
|
||||||
|
return new int[]{Types.ARRAY};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class returnedClass() {
|
||||||
|
return Integer[].class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object x, Object y) throws HibernateException {
|
||||||
|
if (x instanceof Integer[] && y instanceof Integer[]) {
|
||||||
|
return Arrays.deepEquals((Integer[])x, (Integer[])y);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode(Object x) throws HibernateException {
|
||||||
|
return Arrays.hashCode((Integer[])x);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object nullSafeGet(ResultSet rs, String[] names, SharedSessionContractImplementor session, Object owner)
|
||||||
|
throws HibernateException, SQLException {
|
||||||
|
Array array = rs.getArray(names[0]);
|
||||||
|
return array != null ? array.getArray() : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void nullSafeSet(PreparedStatement st, Object value, int index, SharedSessionContractImplementor session)
|
||||||
|
throws HibernateException, SQLException {
|
||||||
|
if (value != null && st != null) {
|
||||||
|
Array array = session.connection().createArrayOf("int", (Integer[])value);
|
||||||
|
st.setArray(index, array);
|
||||||
|
} else {
|
||||||
|
st.setNull(index, sqlTypes()[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object deepCopy(Object value) throws HibernateException {
|
||||||
|
Integer[] a = (Integer[])value;
|
||||||
|
return Arrays.copyOf(a, a.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isMutable() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Serializable disassemble(Object value) throws HibernateException {
|
||||||
|
return (Serializable) value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object assemble(Serializable cached, Object owner) throws HibernateException {
|
||||||
|
return cached;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object replace(Object original, Object target, Object owner) throws HibernateException {
|
||||||
|
return original;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,85 @@
|
||||||
|
package com.baeldung.hibernate.arraymapping;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.sql.Array;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Types;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import org.hibernate.HibernateException;
|
||||||
|
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||||
|
import org.hibernate.usertype.UserType;
|
||||||
|
|
||||||
|
public class CustomStringArrayType implements UserType {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int[] sqlTypes() {
|
||||||
|
return new int[]{Types.ARRAY};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class returnedClass() {
|
||||||
|
return String[].class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object x, Object y) throws HibernateException {
|
||||||
|
if (x instanceof String[] && y instanceof String[]) {
|
||||||
|
return Arrays.deepEquals((String[])x, (String[])y);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode(Object x) throws HibernateException {
|
||||||
|
return Arrays.hashCode((String[])x);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object nullSafeGet(ResultSet rs, String[] names, SharedSessionContractImplementor session, Object owner)
|
||||||
|
throws HibernateException, SQLException {
|
||||||
|
Array array = rs.getArray(names[0]);
|
||||||
|
return array != null ? array.getArray() : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void nullSafeSet(PreparedStatement st, Object value, int index, SharedSessionContractImplementor session)
|
||||||
|
throws HibernateException, SQLException {
|
||||||
|
if (value != null && st != null) {
|
||||||
|
Array array = session.connection().createArrayOf("text", (String[])value);
|
||||||
|
st.setArray(index, array);
|
||||||
|
} else {
|
||||||
|
st.setNull(index, sqlTypes()[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object deepCopy(Object value) throws HibernateException {
|
||||||
|
String[] a = (String[])value;
|
||||||
|
return Arrays.copyOf(a, a.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isMutable() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Serializable disassemble(Object value) throws HibernateException {
|
||||||
|
return (Serializable) value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object assemble(Serializable cached, Object owner) throws HibernateException {
|
||||||
|
return cached;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object replace(Object original, Object target, Object owner) throws HibernateException {
|
||||||
|
return original;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
package com.baeldung.hibernate.arraymapping;
|
||||||
|
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.hibernate.SessionFactory;
|
||||||
|
import org.hibernate.boot.Metadata;
|
||||||
|
import org.hibernate.boot.MetadataSources;
|
||||||
|
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
||||||
|
import org.hibernate.service.ServiceRegistry;
|
||||||
|
|
||||||
|
import com.baeldung.hibernate.arraymapping.User;
|
||||||
|
|
||||||
|
public class HibernateSessionUtil {
|
||||||
|
|
||||||
|
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 = makeSessionFactory(serviceRegistry);
|
||||||
|
}
|
||||||
|
return sessionFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static SessionFactory makeSessionFactory(ServiceRegistry serviceRegistry) {
|
||||||
|
MetadataSources metadataSources = new MetadataSources(serviceRegistry);
|
||||||
|
metadataSources.addAnnotatedClass(User.class);
|
||||||
|
|
||||||
|
Metadata metadata = metadataSources.buildMetadata();
|
||||||
|
return metadata.getSessionFactoryBuilder()
|
||||||
|
.build();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
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_postgres.properties"));
|
||||||
|
try (FileInputStream inputStream = new FileInputStream(propertiesURL.getFile())) {
|
||||||
|
properties.load(inputStream);
|
||||||
|
}
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,82 @@
|
||||||
|
package com.baeldung.hibernate.arraymapping;
|
||||||
|
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
|
||||||
|
import org.hibernate.annotations.Type;
|
||||||
|
|
||||||
|
import com.vladmihalcea.hibernate.type.array.StringArrayType;
|
||||||
|
|
||||||
|
import org.hibernate.annotations.*;
|
||||||
|
|
||||||
|
@TypeDefs({
|
||||||
|
@TypeDef(
|
||||||
|
name = "string-array",
|
||||||
|
typeClass = StringArrayType.class
|
||||||
|
)
|
||||||
|
})
|
||||||
|
@Entity
|
||||||
|
public class User {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Column(columnDefinition = "text[]")
|
||||||
|
@Type(type = "com.baeldung.hibernate.arraymapping.CustomStringArrayType")
|
||||||
|
private String[] roles;
|
||||||
|
|
||||||
|
@Column(columnDefinition = "int[]")
|
||||||
|
@Type(type = "com.baeldung.hibernate.arraymapping.CustomIntegerArrayType")
|
||||||
|
private Integer[] locations;
|
||||||
|
|
||||||
|
@Type(type = "string-array")
|
||||||
|
@Column(
|
||||||
|
name = "phone_numbers",
|
||||||
|
columnDefinition = "text[]"
|
||||||
|
)
|
||||||
|
private String[] phoneNumbers;
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String[] getRoles() {
|
||||||
|
return roles;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRoles(String[] roles) {
|
||||||
|
this.roles = roles;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer[] getLocations() {
|
||||||
|
return locations;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLocations(Integer[] locations) {
|
||||||
|
this.locations = locations;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String[] getPhoneNumbers() {
|
||||||
|
return phoneNumbers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPhoneNumbers(String[] phoneNumbers) {
|
||||||
|
this.phoneNumbers = phoneNumbers;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,133 @@
|
||||||
|
package com.baeldung.hibernate.arraymapping;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.hibernate.HibernateException;
|
||||||
|
import org.hibernate.Session;
|
||||||
|
import org.hibernate.Transaction;
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
|
||||||
|
public class ArrayMappingIntegrationTest {
|
||||||
|
|
||||||
|
private Session session;
|
||||||
|
private Transaction transaction;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
public void setup() throws IOException {
|
||||||
|
try {
|
||||||
|
session = HibernateSessionUtil.getSessionFactory().openSession();
|
||||||
|
transaction = session.beginTransaction();
|
||||||
|
|
||||||
|
bootstrapData();
|
||||||
|
|
||||||
|
} catch (HibernateException | IOException e) {
|
||||||
|
System.out.println("Can't connect to a PostgreSQL DB");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
public void cleanup() {
|
||||||
|
if (null != session) {
|
||||||
|
transaction.rollback();
|
||||||
|
session.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenArrayMapping_whenQueried_thenReturnArraysFromDB() throws HibernateException, IOException {
|
||||||
|
if (null != session) {
|
||||||
|
User user = session.find(User.class, 1L);
|
||||||
|
|
||||||
|
assertEquals("john", user.getName());
|
||||||
|
assertEquals("superuser", user.getRoles()[0]);
|
||||||
|
assertEquals("admin", user.getRoles()[1]);
|
||||||
|
assertEquals(100, user.getLocations()[0]);
|
||||||
|
assertEquals(389, user.getLocations()[1]);
|
||||||
|
assertEquals("7000000000", user.getPhoneNumbers()[0]);
|
||||||
|
assertEquals("8000000000", user.getPhoneNumbers()[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenArrayMapping_whenArraysAreInserted_thenPersistInDB() throws HibernateException, IOException {
|
||||||
|
if (null != session) {
|
||||||
|
transaction = session.beginTransaction();
|
||||||
|
|
||||||
|
User user = new User();
|
||||||
|
user.setId(2L);
|
||||||
|
user.setName("smith");
|
||||||
|
|
||||||
|
String[] roles = {"admin", "employee"};
|
||||||
|
user.setRoles(roles);
|
||||||
|
|
||||||
|
Integer[] locations = {190, 578};
|
||||||
|
user.setLocations(locations);
|
||||||
|
|
||||||
|
session.persist(user);
|
||||||
|
session.flush();
|
||||||
|
session.clear();
|
||||||
|
|
||||||
|
transaction.commit();
|
||||||
|
|
||||||
|
User userDBObj = session.find(User.class, 2L);
|
||||||
|
|
||||||
|
assertEquals("smith", userDBObj.getName());
|
||||||
|
assertEquals("admin", userDBObj.getRoles()[0]);
|
||||||
|
assertEquals(578, userDBObj.getLocations()[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenArrayMapping_whenArrayIsUpdated_thenPersistInDB() throws HibernateException, IOException {
|
||||||
|
if (null != session) {
|
||||||
|
transaction = session.beginTransaction();
|
||||||
|
|
||||||
|
User user = session.find(User.class, 1L);
|
||||||
|
|
||||||
|
String[] updatedRoles = {"superuser", "superadmin"};
|
||||||
|
String[] updatedPhoneNumbers = {"9000000000"};
|
||||||
|
|
||||||
|
user.setRoles(updatedRoles);
|
||||||
|
user.setPhoneNumbers(updatedPhoneNumbers);
|
||||||
|
|
||||||
|
session.persist(user);
|
||||||
|
session.flush();
|
||||||
|
session.clear();
|
||||||
|
|
||||||
|
User userDBObj = session.find(User.class, 1L);
|
||||||
|
|
||||||
|
assertEquals("john", userDBObj.getName());
|
||||||
|
assertEquals("superadmin", userDBObj.getRoles()[1]);
|
||||||
|
assertEquals("9000000000", userDBObj.getPhoneNumbers()[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void bootstrapData() {
|
||||||
|
session.createQuery("delete from User").executeUpdate();
|
||||||
|
|
||||||
|
User user = new User();
|
||||||
|
user.setId(1L);
|
||||||
|
user.setName("john");
|
||||||
|
|
||||||
|
String[] roles = {"superuser", "admin"};
|
||||||
|
user.setRoles(roles);
|
||||||
|
|
||||||
|
Integer[] locations = {100, 389};
|
||||||
|
user.setLocations(locations);
|
||||||
|
|
||||||
|
String[] phoneNumbers = {"7000000000", "8000000000"};
|
||||||
|
user.setPhoneNumbers(phoneNumbers);
|
||||||
|
|
||||||
|
session.persist(user);
|
||||||
|
session.flush();
|
||||||
|
session.clear();
|
||||||
|
|
||||||
|
transaction.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
hibernate.connection.driver_class=org.postgresql.Driver
|
||||||
|
hibernate.connection.url=jdbc:postgresql://localhost:5432/postgres
|
||||||
|
hibernate.connection.username=web
|
||||||
|
hibernate.connection.autocommit=true
|
||||||
|
jdbc.password=
|
||||||
|
|
||||||
|
hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
|
||||||
|
hibernate.show_sql=true
|
||||||
|
hibernate.hbm2ddl.auto=none
|
||||||
|
|
||||||
|
hibernate.c3p0.min_size=5
|
||||||
|
hibernate.c3p0.max_size=20
|
||||||
|
hibernate.c3p0.acquire_increment=5
|
||||||
|
hibernate.c3p0.timeout=1800
|
|
@ -68,6 +68,12 @@
|
||||||
<version>${assertj.version}</version>
|
<version>${assertj.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>${junit.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
package com.baeldung.jpa.IdGeneration;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.GenerationType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class User {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
// @GeneratedValue(strategy = GenerationType.SEQUENCE)
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
private long id;
|
||||||
|
private String username;
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
public long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUsername() {
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUsername(String username) {
|
||||||
|
this.username = username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPassword() {
|
||||||
|
return password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPassword(String password) {
|
||||||
|
this.password = password;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package com.baeldung.jpa.IdGeneration;
|
||||||
|
|
||||||
|
import javax.persistence.EntityManager;
|
||||||
|
import javax.transaction.Transactional;
|
||||||
|
|
||||||
|
public class UserService {
|
||||||
|
|
||||||
|
EntityManager entityManager;
|
||||||
|
|
||||||
|
public UserService(EntityManager entityManager) {
|
||||||
|
this.entityManager = entityManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public long saveUser(User user){
|
||||||
|
entityManager.persist(user);
|
||||||
|
return user.getId();
|
||||||
|
}
|
||||||
|
}
|
|
@ -97,4 +97,20 @@
|
||||||
<property name="hibernate.temp.use_jdbc_metadata_defaults" value="false"/>
|
<property name="hibernate.temp.use_jdbc_metadata_defaults" value="false"/>
|
||||||
</properties>
|
</properties>
|
||||||
</persistence-unit>
|
</persistence-unit>
|
||||||
|
|
||||||
|
<persistence-unit name="jpa-h2-id-generation">
|
||||||
|
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
|
||||||
|
<class>com.baeldung.jpa.IdGeneration.User</class>
|
||||||
|
<exclude-unlisted-classes>true</exclude-unlisted-classes>
|
||||||
|
<properties>
|
||||||
|
<property name="javax.persistence.jdbc.driver" value="org.h2.Driver"/>
|
||||||
|
<property name="javax.persistence.jdbc.url" value="jdbc:h2:mem:idGen"/>
|
||||||
|
<property name="javax.persistence.jdbc.user" value="sa"/>
|
||||||
|
<property name="javax.persistence.jdbc.password" value=""/>
|
||||||
|
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
|
||||||
|
<property name="hibernate.hbm2ddl.auto" value="create-drop"/>
|
||||||
|
<property name="hibernate.format_sql" value="true"/>
|
||||||
|
<property name="hibernate.temp.use_jdbc_metadata_defaults" value="false"/>
|
||||||
|
</properties>
|
||||||
|
</persistence-unit>
|
||||||
</persistence>
|
</persistence>
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
package com.baeldung.jpa.IdGeneration;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import javax.persistence.EntityManager;
|
||||||
|
import javax.persistence.EntityManagerFactory;
|
||||||
|
import javax.persistence.Persistence;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class IdGenerationIntegrationTest {
|
||||||
|
|
||||||
|
private static EntityManager entityManager;
|
||||||
|
private static UserService service;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void setup() {
|
||||||
|
EntityManagerFactory factory = Persistence.createEntityManagerFactory("jpa-h2-id-generation");
|
||||||
|
entityManager = factory.createEntityManager();
|
||||||
|
service = new UserService(entityManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenNewUserIsPersisted_thenEntityHasNoId() {
|
||||||
|
User user = new User();
|
||||||
|
user.setUsername("test");
|
||||||
|
user.setPassword(UUID.randomUUID().toString());
|
||||||
|
|
||||||
|
long index = service.saveUser(user);
|
||||||
|
Assert.assertEquals(0L, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenTransactionIsControlled_thenEntityHasId() {
|
||||||
|
User user = new User();
|
||||||
|
user.setUsername("test");
|
||||||
|
user.setPassword(UUID.randomUUID().toString());
|
||||||
|
|
||||||
|
entityManager.getTransaction().begin();
|
||||||
|
long index = service.saveUser(user);
|
||||||
|
entityManager.getTransaction().commit();
|
||||||
|
|
||||||
|
Assert.assertEquals(2L, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
package com.baeldung.attribute.override.entity;
|
||||||
|
|
||||||
|
import javax.persistence.Embeddable;
|
||||||
|
|
||||||
|
@Embeddable
|
||||||
|
public class Address {
|
||||||
|
private String name;
|
||||||
|
private String city;
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCity() {
|
||||||
|
return city;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCity(String city) {
|
||||||
|
this.city = city;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
package com.baeldung.attribute.override.entity;
|
||||||
|
|
||||||
|
import javax.persistence.Embeddable;
|
||||||
|
import javax.persistence.Embedded;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
|
||||||
|
@Embeddable
|
||||||
|
public class Brand {
|
||||||
|
private String name;
|
||||||
|
private LocalDate foundationDate;
|
||||||
|
@Embedded
|
||||||
|
private Address address;
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalDate getFoundationDate() {
|
||||||
|
return foundationDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFoundationDate(LocalDate foundationDate) {
|
||||||
|
this.foundationDate = foundationDate;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
package com.baeldung.attribute.override.entity;
|
||||||
|
|
||||||
|
import javax.persistence.AttributeOverride;
|
||||||
|
import javax.persistence.AttributeOverrides;
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.ElementCollection;
|
||||||
|
import javax.persistence.Embedded;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@AttributeOverride(name = "identifier", column = @Column(name = "VIN"))
|
||||||
|
public class Car extends Vehicle {
|
||||||
|
|
||||||
|
private String model;
|
||||||
|
private String name;
|
||||||
|
@Embedded
|
||||||
|
@AttributeOverrides({
|
||||||
|
@AttributeOverride(name = "name", column = @Column(name = "BRAND_NAME", length = 5)),
|
||||||
|
@AttributeOverride(name = "address.name", column = @Column(name = "ADDRESS_NAME"))
|
||||||
|
})
|
||||||
|
private Brand brand;
|
||||||
|
@ElementCollection
|
||||||
|
@AttributeOverrides({
|
||||||
|
@AttributeOverride(name = "key.name", column = @Column(name = "OWNER_NAME")),
|
||||||
|
@AttributeOverride(name = "key.surname", column = @Column(name = "OWNER_SURNAME")),
|
||||||
|
@AttributeOverride(name = "value.name", column = @Column(name = "ADDRESS_NAME")),
|
||||||
|
})
|
||||||
|
Map<Owner, Address> owners;
|
||||||
|
|
||||||
|
public String getModel() {
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setModel(String model) {
|
||||||
|
this.model = model;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Brand getBrand() {
|
||||||
|
return brand;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBrand(Brand brand) {
|
||||||
|
this.brand = brand;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
package com.baeldung.attribute.override.entity;
|
||||||
|
|
||||||
|
import javax.persistence.Embeddable;
|
||||||
|
|
||||||
|
@Embeddable
|
||||||
|
public class Owner {
|
||||||
|
private String name;
|
||||||
|
private String surname;
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSurname() {
|
||||||
|
return surname;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSurname(String surname) {
|
||||||
|
this.surname = surname;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
package com.baeldung.attribute.override.entity;
|
||||||
|
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.MappedSuperclass;
|
||||||
|
|
||||||
|
@MappedSuperclass
|
||||||
|
public class Vehicle {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue
|
||||||
|
private Integer id;
|
||||||
|
private String identifier;
|
||||||
|
private Integer numberOfWheels;
|
||||||
|
|
||||||
|
public Integer getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Integer id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getIdentifier() {
|
||||||
|
return identifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIdentifier(String identifier) {
|
||||||
|
this.identifier = identifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getNumberOfWheels() {
|
||||||
|
return numberOfWheels;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNumberOfWheels(Integer numberOfWheels) {
|
||||||
|
this.numberOfWheels = numberOfWheels;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
package com.baeldung.attribute.override.repository;
|
||||||
|
|
||||||
|
import com.baeldung.attribute.override.entity.Car;
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
|
||||||
|
public interface CarRepository extends JpaRepository<Car, Integer> {
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
package com.baeldung.attribute.override;
|
||||||
|
|
||||||
|
import com.baeldung.Application;
|
||||||
|
import com.baeldung.attribute.override.entity.Address;
|
||||||
|
import com.baeldung.attribute.override.entity.Brand;
|
||||||
|
import com.baeldung.attribute.override.entity.Car;
|
||||||
|
import com.baeldung.attribute.override.repository.CarRepository;
|
||||||
|
import org.assertj.core.api.Assertions;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
|
||||||
|
@RunWith(SpringRunner.class)
|
||||||
|
@SpringBootTest(classes = { Application.class })
|
||||||
|
public class AttributeOverrideIntegrationTest {
|
||||||
|
|
||||||
|
private static final LocalDate FORD_FOUNDATION_DATE = LocalDate.parse("1903-06-16");
|
||||||
|
@Autowired
|
||||||
|
CarRepository carRepository;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Transactional
|
||||||
|
public void whenInsertingCar_thenEmbeddedAndMappedFieldsArePopulated() {
|
||||||
|
|
||||||
|
Car fordMustang = createMustang();
|
||||||
|
|
||||||
|
carRepository.save(fordMustang);
|
||||||
|
Car actualCar = carRepository.getOne(fordMustang.getId());
|
||||||
|
|
||||||
|
Assertions.assertThat(actualCar).isEqualTo(fordMustang);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private Car createMustang() {
|
||||||
|
Address address = new Address();
|
||||||
|
address.setName("Ford United States");
|
||||||
|
address.setCity("Dearborn");
|
||||||
|
|
||||||
|
Brand ford = new Brand();
|
||||||
|
ford.setName("Ford");
|
||||||
|
ford.setFoundationDate(FORD_FOUNDATION_DATE);
|
||||||
|
|
||||||
|
Car fordMustang = new Car();
|
||||||
|
fordMustang.setIdentifier("WP1AB29P88LA47599");
|
||||||
|
fordMustang.setModel("Ford");
|
||||||
|
fordMustang.setName("My car");
|
||||||
|
fordMustang.setBrand(ford);
|
||||||
|
return fordMustang;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
package com.baeldung.softdelete;
|
||||||
|
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.GenerationType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.hibernate.annotations.Filter;
|
||||||
|
import org.hibernate.annotations.FilterDef;
|
||||||
|
import org.hibernate.annotations.ParamDef;
|
||||||
|
import org.hibernate.annotations.SQLDelete;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "tbl_products")
|
||||||
|
@SQLDelete(sql = "UPDATE tbl_products SET deleted = true WHERE id=?")
|
||||||
|
@FilterDef(name = "deletedProductFilter", parameters = @ParamDef(name = "isDeleted", type = "boolean"))
|
||||||
|
@Filter(name = "deletedProductFilter", condition = "deleted = :isDeleted")
|
||||||
|
public class Product implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
private double price;
|
||||||
|
|
||||||
|
private boolean deleted = Boolean.FALSE;
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getPrice() {
|
||||||
|
return price;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPrice(double price) {
|
||||||
|
this.price = price;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDeleted() {
|
||||||
|
return deleted;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDeleted(boolean deleted) {
|
||||||
|
this.deleted = deleted;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
package com.baeldung.softdelete;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/products")
|
||||||
|
public class ProductController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ProductService productService;
|
||||||
|
|
||||||
|
@PostMapping
|
||||||
|
public Product createOne(@RequestBody Product product) {
|
||||||
|
return productService.create(product);
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping("/{id}")
|
||||||
|
public void removeOne(@PathVariable("id") Long id) {
|
||||||
|
productService.remove(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping
|
||||||
|
public Iterable<Product> findAll(@RequestParam(value = "isDeleted", required = false, defaultValue = "false") boolean isDeleted) {
|
||||||
|
return productService.findAll(isDeleted);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
package com.baeldung.softdelete;
|
||||||
|
|
||||||
|
import org.springframework.data.repository.CrudRepository;
|
||||||
|
|
||||||
|
public interface ProductRepository extends CrudRepository<Product, Long>{
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
package com.baeldung.softdelete;
|
||||||
|
|
||||||
|
import javax.persistence.EntityManager;
|
||||||
|
|
||||||
|
import org.hibernate.Filter;
|
||||||
|
import org.hibernate.Session;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class ProductService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ProductRepository productRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private EntityManager entityManager;
|
||||||
|
|
||||||
|
public Product create(Product product) {
|
||||||
|
return productRepository.save(product);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void remove(Long id){
|
||||||
|
productRepository.deleteById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Iterable<Product> findAll(boolean isDeleted){
|
||||||
|
Session session = entityManager.unwrap(Session.class);
|
||||||
|
Filter filter = session.enableFilter("deletedProductFilter");
|
||||||
|
filter.setParameter("isDeleted", isDeleted);
|
||||||
|
Iterable<Product> products = productRepository.findAll();
|
||||||
|
session.disableFilter("deletedProductFilter");
|
||||||
|
return products;
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,10 +5,5 @@ spring.jpa.properties.hibernate.order_inserts=true
|
||||||
spring.jpa.properties.hibernate.order_updates=true
|
spring.jpa.properties.hibernate.order_updates=true
|
||||||
spring.jpa.properties.hibernate.generate_statistics=true
|
spring.jpa.properties.hibernate.generate_statistics=true
|
||||||
|
|
||||||
# JPA-Schema-Generation
|
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
|
||||||
# Use below configuration to generate database schema create commands based on the entity models
|
|
||||||
# and export them into the create.sql file
|
|
||||||
#spring.jpa.properties.javax.persistence.schema-generation.scripts.action=create
|
|
||||||
#spring.jpa.properties.javax.persistence.schema-generation.scripts.create-target=create.sql
|
|
||||||
#spring.jpa.properties.javax.persistence.schema-generation.scripts.create-source=metadata
|
|
||||||
#spring.jpa.properties.hibernate.format_sql=true
|
|
||||||
|
|
3
pom.xml
3
pom.xml
|
@ -623,6 +623,7 @@
|
||||||
<module>spring-boot-rest-2</module>
|
<module>spring-boot-rest-2</module>
|
||||||
|
|
||||||
<module>spring-caching</module>
|
<module>spring-caching</module>
|
||||||
|
<module>spring-caching-2</module>
|
||||||
|
|
||||||
<module>spring-cloud</module>
|
<module>spring-cloud</module>
|
||||||
<module>spring-cloud-bus</module>
|
<module>spring-cloud-bus</module>
|
||||||
|
@ -1079,6 +1080,7 @@
|
||||||
<module>spring-boot-rest-2</module>
|
<module>spring-boot-rest-2</module>
|
||||||
|
|
||||||
<module>spring-caching</module>
|
<module>spring-caching</module>
|
||||||
|
<module>spring-caching-2</module>
|
||||||
|
|
||||||
<module>spring-cloud</module>
|
<module>spring-cloud</module>
|
||||||
<module>spring-cloud-bus</module>
|
<module>spring-cloud-bus</module>
|
||||||
|
@ -1274,6 +1276,7 @@
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
|
<module>spring-boot-modules/spring-boot-cassandre</module>
|
||||||
<module>core-java-modules/core-java-9</module>
|
<module>core-java-modules/core-java-9</module>
|
||||||
<module>core-java-modules/core-java-9-improvements</module>
|
<module>core-java-modules/core-java-9-improvements</module>
|
||||||
<module>core-java-modules/core-java-9-jigsaw</module>
|
<module>core-java-modules/core-java-9-jigsaw</module>
|
||||||
|
|
|
@ -8,3 +8,4 @@ This module contains articles about Reactor Core.
|
||||||
- [Combining Publishers in Project Reactor](https://www.baeldung.com/reactor-combine-streams)
|
- [Combining Publishers in Project Reactor](https://www.baeldung.com/reactor-combine-streams)
|
||||||
- [Programmatically Creating Sequences with Project Reactor](https://www.baeldung.com/flux-sequences-reactor)
|
- [Programmatically Creating Sequences with Project Reactor](https://www.baeldung.com/flux-sequences-reactor)
|
||||||
- [How to Extract a Mono’s Content in Java](https://www.baeldung.com/java-string-from-mono)
|
- [How to Extract a Mono’s Content in Java](https://www.baeldung.com/java-string-from-mono)
|
||||||
|
- [How to Convert Mono<List<T\>> Into Flux<T\>](https://www.baeldung.com/java-mono-list-to-flux)
|
||||||
|
|
|
@ -1,10 +1,14 @@
|
||||||
package com.baeldung.mono;
|
package com.baeldung.mono;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import reactor.core.publisher.Flux;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
import reactor.test.StepVerifier;
|
||||||
|
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.time.temporal.ChronoUnit;
|
import java.time.temporal.ChronoUnit;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
@ -40,4 +44,40 @@ public class MonoUnitTest {
|
||||||
// blocking
|
// blocking
|
||||||
return Mono.just("Hello world!");
|
return Mono.just("Hello world!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenMonoProducesListOfElements_thenConvertToFluxofElements() {
|
||||||
|
|
||||||
|
Mono<List<String>> monoList = monoOfList();
|
||||||
|
|
||||||
|
StepVerifier.create(monoTofluxUsingFlatMapIterable(monoList))
|
||||||
|
.expectNext("one", "two", "three", "four")
|
||||||
|
.verifyComplete();
|
||||||
|
|
||||||
|
StepVerifier.create(monoTofluxUsingFlatMapMany(monoList))
|
||||||
|
.expectNext("one", "two", "three", "four")
|
||||||
|
.verifyComplete();
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> Flux<T> monoTofluxUsingFlatMapIterable(Mono<List<T>> monoList) {
|
||||||
|
return monoList
|
||||||
|
.flatMapIterable(list -> list)
|
||||||
|
.log();
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> Flux<T> monoTofluxUsingFlatMapMany(Mono<List<T>> monoList) {
|
||||||
|
return monoList
|
||||||
|
.flatMapMany(Flux::fromIterable)
|
||||||
|
.log();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Mono<List<String>> monoOfList() {
|
||||||
|
List<String> list = new ArrayList<>();
|
||||||
|
list.add("one");
|
||||||
|
list.add("two");
|
||||||
|
list.add("three");
|
||||||
|
list.add("four");
|
||||||
|
|
||||||
|
return Mono.just(list);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
# Cassandre trading bot example
|
||||||
|
|
||||||
|
This project is an example of a trading bot developed with Cassandre
|
||||||
|
|
||||||
|
## Running the examples
|
||||||
|
|
||||||
|
* `mvn test` - Run strategy backtesting
|
||||||
|
* `mvn spring-boot:run` - Run the bot
|
||||||
|
|
||||||
|
## Relevant Articles
|
||||||
|
- [Build a Trading Bot with Cassandre Spring Boot Starter](https://www.baeldung.com/build-a-trading-bot-with-cassandre-spring-boot-starter/)
|
|
@ -0,0 +1,68 @@
|
||||||
|
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
|
<version>2.4.5</version>
|
||||||
|
<relativePath /> <!-- lookup parent from repository -->
|
||||||
|
</parent>
|
||||||
|
<groupId>com.example</groupId>
|
||||||
|
<artifactId>demo</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<name>Cassandre trading bot tutorial</name>
|
||||||
|
<description>Cassandre trading bot tutorial</description>
|
||||||
|
<properties>
|
||||||
|
<java.version>11</java.version>
|
||||||
|
</properties>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Cassandre dependencies -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>tech.cassandre.trading.bot</groupId>
|
||||||
|
<artifactId>cassandre-trading-bot-spring-boot-starter</artifactId>
|
||||||
|
<version>4.2.1</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.knowm.xchange</groupId>
|
||||||
|
<artifactId>xchange-kucoin</artifactId>
|
||||||
|
<version>5.0.7</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.hsqldb</groupId>
|
||||||
|
<artifactId>hsqldb</artifactId>
|
||||||
|
<version>2.5.1</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<!-- Cassandre dependencies -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>tech.cassandre.trading.bot</groupId>
|
||||||
|
<artifactId>cassandre-trading-bot-spring-boot-starter-test</artifactId>
|
||||||
|
<version>4.2.1</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
<version>2.4.5</version>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,13 @@
|
||||||
|
package com.example.demo;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
public class DemoApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(DemoApplication.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,66 @@
|
||||||
|
package com.example.demo;
|
||||||
|
|
||||||
|
import static tech.cassandre.trading.bot.dto.position.PositionStatusDTO.CLOSED;
|
||||||
|
import static tech.cassandre.trading.bot.dto.position.PositionStatusDTO.OPENED;
|
||||||
|
import static tech.cassandre.trading.bot.dto.util.CurrencyDTO.BTC;
|
||||||
|
import static tech.cassandre.trading.bot.dto.util.CurrencyDTO.USDT;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import tech.cassandre.trading.bot.dto.market.TickerDTO;
|
||||||
|
import tech.cassandre.trading.bot.dto.position.PositionDTO;
|
||||||
|
import tech.cassandre.trading.bot.dto.position.PositionRulesDTO;
|
||||||
|
import tech.cassandre.trading.bot.dto.user.AccountDTO;
|
||||||
|
import tech.cassandre.trading.bot.dto.util.CurrencyPairDTO;
|
||||||
|
import tech.cassandre.trading.bot.strategy.BasicCassandreStrategy;
|
||||||
|
import tech.cassandre.trading.bot.strategy.CassandreStrategy;
|
||||||
|
|
||||||
|
@CassandreStrategy
|
||||||
|
public class MyFirstStrategy extends BasicCassandreStrategy {
|
||||||
|
|
||||||
|
private final Logger logger = LoggerFactory.getLogger(MyFirstStrategy.class);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<CurrencyPairDTO> getRequestedCurrencyPairs() {
|
||||||
|
return Set.of(new CurrencyPairDTO(BTC, USDT));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<AccountDTO> getTradeAccount(Set<AccountDTO> accounts) {
|
||||||
|
return accounts.stream()
|
||||||
|
.filter(a -> "trade".equals(a.getName()))
|
||||||
|
.findFirst();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTickerUpdate(TickerDTO ticker) {
|
||||||
|
logger.info("Received a new ticker : {}", ticker);
|
||||||
|
|
||||||
|
if (new BigDecimal("56000").compareTo(ticker.getLast()) == -1) {
|
||||||
|
|
||||||
|
if (canBuy(new CurrencyPairDTO(BTC, USDT), new BigDecimal("0.01"))) {
|
||||||
|
PositionRulesDTO rules = PositionRulesDTO.builder()
|
||||||
|
.stopGainPercentage(4f)
|
||||||
|
.stopLossPercentage(25f)
|
||||||
|
.build();
|
||||||
|
createLongPosition(new CurrencyPairDTO(BTC, USDT), new BigDecimal("0.01"), rules);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPositionStatusUpdate(PositionDTO position) {
|
||||||
|
if (position.getStatus() == OPENED) {
|
||||||
|
logger.info("> New position opened : {}", position.getPositionId());
|
||||||
|
}
|
||||||
|
if (position.getStatus() == CLOSED) {
|
||||||
|
logger.info("> Position closed : {}", position.getDescription());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
#
|
||||||
|
# Exchange configuration.
|
||||||
|
cassandre.trading.bot.exchange.name=kucoin
|
||||||
|
cassandre.trading.bot.exchange.username=kucoin.cassandre.test@gmail.com
|
||||||
|
cassandre.trading.bot.exchange.passphrase=cassandre
|
||||||
|
cassandre.trading.bot.exchange.key=6054ad25365ac6000689a998
|
||||||
|
cassandre.trading.bot.exchange.secret=af080d55-afe3-47c9-8ec1-4b479fbcc5e7
|
||||||
|
#
|
||||||
|
# Modes
|
||||||
|
cassandre.trading.bot.exchange.modes.sandbox=true
|
||||||
|
cassandre.trading.bot.exchange.modes.dry=false
|
||||||
|
#
|
||||||
|
# Exchange API calls rates (ms or standard ISO 8601 duration like 'PT5S').
|
||||||
|
cassandre.trading.bot.exchange.rates.account=2000
|
||||||
|
cassandre.trading.bot.exchange.rates.ticker=2000
|
||||||
|
cassandre.trading.bot.exchange.rates.trade=2000
|
||||||
|
#
|
||||||
|
# Database configuration.
|
||||||
|
cassandre.trading.bot.database.datasource.driver-class-name=org.hsqldb.jdbc.JDBCDriver
|
||||||
|
cassandre.trading.bot.database.datasource.url=jdbc:hsqldb:mem:cassandre
|
||||||
|
cassandre.trading.bot.database.datasource.username=sa
|
||||||
|
cassandre.trading.bot.database.datasource.password=
|
|
@ -0,0 +1,13 @@
|
||||||
|
package com.example.demo;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
class DemoApplicationTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void contextLoads() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
package com.example.demo;
|
||||||
|
|
||||||
|
import static org.awaitility.Awaitility.await;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
import static tech.cassandre.trading.bot.dto.position.PositionStatusDTO.OPENED;
|
||||||
|
import static tech.cassandre.trading.bot.dto.util.CurrencyDTO.USDT;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.DisplayName;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.context.annotation.Import;
|
||||||
|
|
||||||
|
import tech.cassandre.trading.bot.dto.util.CurrencyDTO;
|
||||||
|
import tech.cassandre.trading.bot.dto.util.GainDTO;
|
||||||
|
import tech.cassandre.trading.bot.test.mock.TickerFluxMock;
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
@Import(TickerFluxMock.class)
|
||||||
|
@DisplayName("Simple strategy test")
|
||||||
|
public class MyFirstStrategyUnitTest {
|
||||||
|
|
||||||
|
private final Logger logger = LoggerFactory.getLogger(MyFirstStrategyUnitTest.class);
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private MyFirstStrategy strategy;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private TickerFluxMock tickerFluxMock;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("Check gains")
|
||||||
|
public void whenTickersArrives_thenCheckGains() {
|
||||||
|
await().forever().until(() -> tickerFluxMock.isFluxDone());
|
||||||
|
|
||||||
|
final HashMap<CurrencyDTO, GainDTO> gains = strategy.getGains();
|
||||||
|
|
||||||
|
logger.info("Cumulated gains:");
|
||||||
|
gains.forEach((currency, gain) -> logger.info(currency + " : " + gain.getAmount()));
|
||||||
|
|
||||||
|
logger.info("Position still opened :");
|
||||||
|
strategy.getPositions()
|
||||||
|
.values()
|
||||||
|
.stream()
|
||||||
|
.filter(p -> p.getStatus().equals(OPENED))
|
||||||
|
.forEach(p -> logger.info(" - {} " + p.getDescription()));
|
||||||
|
|
||||||
|
assertTrue(gains.get(USDT).getPercentage() > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
#
|
||||||
|
# Exchange configuration.
|
||||||
|
cassandre.trading.bot.exchange.name=kucoin
|
||||||
|
cassandre.trading.bot.exchange.username=kucoin.cassandre.test@gmail.com
|
||||||
|
cassandre.trading.bot.exchange.passphrase=cassandre
|
||||||
|
cassandre.trading.bot.exchange.key=6054ad25365ac6000689a998
|
||||||
|
cassandre.trading.bot.exchange.secret=af080d55-afe3-47c9-8ec1-4b479fbcc5e7
|
||||||
|
#
|
||||||
|
# Modes
|
||||||
|
cassandre.trading.bot.exchange.modes.sandbox=true
|
||||||
|
cassandre.trading.bot.exchange.modes.dry=true
|
||||||
|
#
|
||||||
|
# Exchange API calls rates (ms or standard ISO 8601 duration like 'PT5S').
|
||||||
|
cassandre.trading.bot.exchange.rates.account=2000
|
||||||
|
cassandre.trading.bot.exchange.rates.ticker=2000
|
||||||
|
cassandre.trading.bot.exchange.rates.trade=2000
|
||||||
|
#
|
||||||
|
# Database configuration.
|
||||||
|
cassandre.trading.bot.database.datasource.driver-class-name=org.hsqldb.jdbc.JDBCDriver
|
||||||
|
cassandre.trading.bot.database.datasource.url=jdbc:hsqldb:mem:cassandre
|
||||||
|
cassandre.trading.bot.database.datasource.username=sa
|
||||||
|
cassandre.trading.bot.database.datasource.password=
|
|
@ -0,0 +1,89 @@
|
||||||
|
1612569600 38294.4 39195.5 40964.2 38217.5 3882.29460938 153897343.463150723
|
||||||
|
1612656000 39195.4 38807.6 39623.6 37341.4 2389.96820017 91972455.834535369
|
||||||
|
1612742400 38807.6 46373.5 46767.9 38010 4971.54731481 212132648.426718929
|
||||||
|
1612828800 46374.6 46434.8 48139.3 44961 4330.72854712 201891604.027160303
|
||||||
|
1612915200 46430 44812.2 47300 43687.5 4351.84907778 198189685.592028516
|
||||||
|
1613001600 44806.1 47941.5 48647.6 44005.8 4045.91883504 188171651.974437139
|
||||||
|
1613088000 47963.1 47310.7 48958.8 46181.2 3356.01832119 159561721.419695848
|
||||||
|
1613174400 47305.4 47152.6 48120.5 46225.5 2740.99221759 129227867.922246174
|
||||||
|
1613260800 47152.5 48591.9 49686.9 47026.3 3359.4690565 163299915.839307312
|
||||||
|
1613347200 48587.2 47904.4 49003.6 42841.6 3974.98461358 188990056.26923591
|
||||||
|
1613433600 47913.1 49147.7 50619.3 47023.9 3599.85370182 176084748.845657596
|
||||||
|
1613520000 49147.7 52118.1 52609.6 48931.1 3356.85082847 170893567.530348564
|
||||||
|
1613606400 52114.3 51568.9 52522.9 50906.4 2183.18379408 113272339.172174965
|
||||||
|
1613692800 51561.1 55890.5 56317.7 50727 3749.6920105 200656740.865959032
|
||||||
|
1613779200 55893.6 55851.5 57622.6 53463.3 3394.87226216 190744601.429330887
|
||||||
|
1613865600 55851.4 57423 58336.3 55489.6 2514.02340013 143658132.671448082
|
||||||
|
1613952000 57420.6 54096.6 57517.8 44160 6125.32442907 330513978.457310237
|
||||||
|
1614038400 54085.9 48908.3 54174.2 44900 8048.96505298 389277314.445372085
|
||||||
|
1614124800 48902.9 49685.2 51361.9 47003.2 4816.75027676 239303706.844272809
|
||||||
|
1614211200 49676.5 47082.7 52019.6 46624.4 3701.80236678 184044004.383578525
|
||||||
|
1614297600 47082 46289.6 48408.8 44135 5329.77125908 247604118.914146591
|
||||||
|
1614384000 46290.2 46114.4 48381.9 44836.5 2872.64640734 134946360.020429589
|
||||||
|
1614470400 46111.3 45141.6 46626.1 43004.3 3940.17863714 175990962.484551548
|
||||||
|
1614556800 45136.5 49590.3 49771.3 44958.9 3548.51026561 169389196.772247159
|
||||||
|
1614643200 49590.3 48441.2 50201.6 47052.8 2936.94454126 142575425.463057812
|
||||||
|
1614729600 48440.6 50345.5 52623.9 48100 3177.38943911 160801620.821885745
|
||||||
|
1614816000 50347.6 48374.5 51762.1 47505.7 3624.17683614 178873453.27515484
|
||||||
|
1614902400 48374.5 48758.9 49450 46189.8 3697.34556922 176318969.507294567
|
||||||
|
1614988800 48746.9 48871.9 49255.1 47001 1949.15311354 94201823.810314647
|
||||||
|
1615075200 48885 50930.4 51424.7 48885 2444.3584982 122962479.787996993
|
||||||
|
1615161600 50956.6 52377 52387.5 49287.5 2710.99151191 137751640.241286989
|
||||||
|
1615248000 52376.9 54867.6 54867.6 51833.8 3070.93581512 165487483.114064122
|
||||||
|
1615334400 54867.5 55865.5 57364 52911.4 4049.50553851 224565244.752334892
|
||||||
|
1615420800 55863.7 57781.1 58150 54238 3403.69441456 191915265.020541521
|
||||||
|
1615507200 57781 57238.5 58057.5 55013.7 4031.0376629 228810606.091302364
|
||||||
|
1615593600 57220.7 61180.9 61815.3 56059.3 4394.62318443 259602986.875738328
|
||||||
|
1615680000 61174.3 59000 61700 59000 3084.33952274 186155667.656432156
|
||||||
|
1615766400 59000 55607.1 60632.9 54525.6 5910.33518227 338468393.188725572
|
||||||
|
1615852800 55607.1 56880.3 56918.9 53240.3 7410.49057723 409052587.523700888
|
||||||
|
1615939200 56880.3 58875.8 58951.8 54147.5 5828.79026943 328135601.648660052
|
||||||
|
1616025600 58882.9 57648.9 60107.7 57000 5073.7458698 297279816.540519693
|
||||||
|
1616112000 57648.9 58024.2 59450.1 56071 3727.09434161 217005823.723994618
|
||||||
|
1616198400 58024.3 58113.5 59874.6 57825.6 2746.52973805 161565114.165299707
|
||||||
|
1616284800 58113.5 57350.2 58591.6 55501 3265.35649781 186845535.507151609
|
||||||
|
1616371200 57345.3 54096.1 58415.5 53667 4219.99501831 237141977.003568352
|
||||||
|
1616457600 54086.8 54348.4 55823.1 52986.3 4374.34046303 239135883.538398977
|
||||||
|
1616544000 54348.4 52307.4 57200 51499.6 6416.76024581 351202326.218690674
|
||||||
|
1616630400 52307.1 51301.7 53239.1 50455 7242.6466396 375950351.557038048
|
||||||
|
1616716800 51301.7 55032 55062.5 51225.3 4609.48192944 245299757.451540308
|
||||||
|
1616803200 55031.9 55820.4 56628.6 53967.5 3634.73588532 200758048.816804103
|
||||||
|
1616889600 55820.3 55772.9 56541 54666.6 3158.20452681 176119911.151714842
|
||||||
|
1616976000 55772.8 57628.9 58400.5 54926.5 4413.63121553 251384747.301649587
|
||||||
|
1617062400 57630.8 58754.6 59351.9 57072.8 3563.87315049 208118726.050535887
|
||||||
|
1617148800 58753.2 58745.9 59800 56357.5 4921.45848213 288469053.074870873
|
||||||
|
1617235200 58745.5 58735.7 59487.1 57879 3163.98213108 186078130.901422269
|
||||||
|
1617321600 58735.7 58963.6 60179.1 58460.7 2553.76427314 151446539.609794648
|
||||||
|
1617408000 58963.6 57058.3 59795 56721.2 2512.19109578 147434403.06515736
|
||||||
|
1617494400 57052.5 58201.4 58481.2 56432.6 2069.14670128 119228330.17272614
|
||||||
|
1617580800 58201.4 59116.2 59254.1 56501 3003.76043377 174821106.684799505
|
||||||
|
1617667200 59116.2 57988.3 59497.5 57304.8 2964.86183859 173169186.845682699
|
||||||
|
1617753600 57988.3 55958.2 58668.6 55439 5277.04906389 299996660.411940246
|
||||||
|
1617840000 55958.2 58076.7 58141 55700.6 3175.60482079 181817013.517575328
|
||||||
|
1617926400 58076.7 58131.6 58900 57666.9 3516.19104669 204849717.059779284
|
||||||
|
1618012800 58138.2 59770.2 61350 57902.1 5533.50675561 332014577.538990658
|
||||||
|
1618099200 59770.2 60007.6 60687.4 59247.6 3896.37426019 233158562.799039154
|
||||||
|
1618185600 60007.6 59863.4 61270.7 59417.4 4611.409014 277430208.743380477
|
||||||
|
1618272000 59863.4 63578.7 63759.7 59815 6906.310253 430518557.569547626
|
||||||
|
1618358400 63578.7 62958.7 64840 61000 7696.509177 487298143.928065301
|
||||||
|
1618444800 62954.4 63152.6 63772.1 62023.9 4709.82427144 296178401.81115496
|
||||||
|
1618531200 63152.6 61342.6 63509.7 59930.8 8295.32523869 510423835.691643255
|
||||||
|
1618617600 61342.7 59995.2 62497.8 59599.6 5367.42979289 328364887.709585395
|
||||||
|
1618704000 59995.3 56150.6 60409.5 49001 11485.97101449 637797282.448645379
|
||||||
|
1618790400 56152.7 55618.8 57583.4 54205.2 7721.306905 432634348.931871989
|
||||||
|
1618876800 55618.7 56427.8 57061.6 53328 8677.75606016 480164200.559836543
|
||||||
|
1618963200 56426.1 53793.6 56761.7 53602 6240.82191836 345339357.806167462
|
||||||
|
1619049600 53793.5 51696.4 55474.7 50400 8879.16016304 475394174.249706678
|
||||||
|
1619136000 51691.2 51102.7 52112.1 47502.1 8885.07060366 441295812.644904319
|
||||||
|
1619222400 51109.8 50033 51157.9 48676.5 4833.41744745 241336360.887795675
|
||||||
|
1619308800 50041.5 49086.9 50554.6 46966.2 4805.34664069 237153315.222670555
|
||||||
|
1619395200 49069 54000.2 54336.4 48775.8 6695.12934907 353727728.269533971
|
||||||
|
1619481600 53997.1 55014.3 55439 53240.8 4344.22291318 237020455.905144335
|
||||||
|
1619568000 55014.2 54833.2 56399.1 53808.3 4801.04618634 262912695.604761319
|
||||||
|
1619654400 54833.1 53558.4 55181.2 52340.1 4356.05177188 234153663.397444462
|
||||||
|
1619740800 53558.5 57697.3 57936.4 53042.6 5000.47557303 277531927.921795199
|
||||||
|
1619827200 57697.3 57794.7 58471.4 57006.3 3639.78966647 210179438.189007639
|
||||||
|
1619913600 57794.7 56568.5 57903.7 56044.3 3508.52428767 199206958.05741809
|
||||||
|
1620000000 56568.5 57159.7 58977.9 56451.3 4780.43387226 276554749.540429296
|
||||||
|
1620086400 57159.7 53196.3 57188.2 53083.3 7079.55804728 390469293.396018923
|
||||||
|
1620172800 53196.3 57834.5 57979.7 52888 4224.63060355 233779565.506303973
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
BTC 1
|
||||||
|
USDT 100000
|
||||||
|
ETH 10
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
package com.baeldung.filtersinterceptors;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
@SpringBootApplication(scanBasePackages = "com.baeldung.filtersinterceptors")
|
||||||
|
public class FilterInterceptorApp {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(FilterInterceptorApp.class, args);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package com.baeldung.filtersinterceptors;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
public class HelloConroller {
|
||||||
|
|
||||||
|
private Logger logger = LoggerFactory.getLogger(HelloConroller.class);
|
||||||
|
|
||||||
|
@GetMapping("/hello")
|
||||||
|
public String hello() {
|
||||||
|
logger.info("Hello from the controller");
|
||||||
|
return "hello";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
package com.baeldung.filtersinterceptors;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.servlet.Filter;
|
||||||
|
import javax.servlet.FilterChain;
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.ServletRequest;
|
||||||
|
import javax.servlet.ServletResponse;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class LogFilter implements Filter {
|
||||||
|
|
||||||
|
private Logger logger = LoggerFactory.getLogger(LogFilter.class);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
|
||||||
|
logger.info("Hello from: " + request.getLocalAddr());
|
||||||
|
chain.doFilter(request, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
package com.baeldung.filtersinterceptors;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.servlet.HandlerInterceptor;
|
||||||
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
|
||||||
|
public class LogInterceptor implements HandlerInterceptor {
|
||||||
|
|
||||||
|
private Logger logger = LoggerFactory.getLogger(LogInterceptor.class);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
||||||
|
logger.info("preHandle");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
|
||||||
|
logger.info("postHandle");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
|
||||||
|
logger.info("afterCompletion");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package com.baeldung.filtersinterceptors;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||||
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class WebMvcConfig implements WebMvcConfigurer {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addInterceptors(InterceptorRegistry registry) {
|
||||||
|
registry.addInterceptor(new LogInterceptor());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue