Merge branch 'master' into JAVA-5223

This commit is contained in:
freelansam 2021-05-17 22:37:02 +05:30 committed by GitHub
commit 8cc6444700
130 changed files with 4012 additions and 106 deletions

View File

@ -50,6 +50,11 @@
<version>${junit.jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons-lang3.version}</version>
</dependency>
</dependencies>
<build>
@ -73,6 +78,7 @@
<junit.jupiter.version>5.7.0</junit.jupiter.version>
<assertj.version>3.17.2</assertj.version>
<mockserver.version>5.11.1</mockserver.version>
<commons-lang3.version>3.12.0</commons-lang3.version>
</properties>
</project>

View File

@ -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);
}
}

View File

@ -45,4 +45,4 @@
<providermodule.version>1.0</providermodule.version>
</properties>
</project>
</project>

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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.
}
}

View File

@ -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.
}
}

View File

@ -0,0 +1,8 @@
package com.baeldung.interfacevsabstractclass;
import java.io.File;
public interface Sender {
void send(File fileToBeSent);
}

View File

@ -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();
}

View File

@ -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
}
}

View File

@ -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);
}
}

View File

@ -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();
}
}

View File

@ -17,9 +17,9 @@ import static org.junit.Assert.assertTrue;
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_MD5_HASH = "6cb91af4ed4c60c11613b75cd1fc6116";
static String FILE_MD5_HASH = "c959feb066b37f5c4f0e0f45bbbb4f86";
@Test
public void givenJavaIO_whenDownloadingFile_thenDownloadShouldBeCorrect() throws NoSuchAlgorithmException, IOException {

View File

@ -27,6 +27,17 @@
<version>${lombok.version}</version>
<scope>provided</scope>
</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 -->
<dependency>
<groupId>org.assertj</groupId>
@ -44,11 +55,30 @@
<filtering>true</filtering>
</resource>
</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>
<properties>
<lombok.version>1.18.20</lombok.version>
<!-- testing -->
<assertj.version>3.6.1</assertj.version>
<jmh.version>1.29</jmh.version>
</properties>
</project>

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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());
}
}

View File

@ -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())
);
}
}

View File

@ -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())
);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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");
}
}

View File

@ -1,18 +1,17 @@
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 org.junit.BeforeClass;
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 {
private static Validator validator;
@ -24,41 +23,67 @@ public class InvoiceUnitTest extends LocaleAwareUnitTest {
}
@Test
public void whenPriceIntegerDigitLessThanThreeWithDecimalValue_thenShouldGiveConstraintViolations() {
Invoice invoice = new Invoice(new BigDecimal(10.21), "Book purchased");
public void whenLessThanThreeIntegerDigits_thenShouldNotGiveConstraintViolations() {
Invoice invoice = new Invoice(new BigDecimal("10.21"), "Book purchased");
Set<ConstraintViolation<Invoice>> violations = validator.validate(invoice);
assertThat(violations.size()).isEqualTo(1);
violations.forEach(action -> assertThat(action.getMessage()).isEqualTo("numeric value out of bounds (<3 digits>.<2 digits> expected)"));
assertThat(violations).isEmpty();
}
@Test
public void whenPriceIntegerDigitLessThanThreeWithIntegerValue_thenShouldNotGiveConstraintViolations() {
Invoice invoice = new Invoice(new BigDecimal(10), "Book purchased");
public void whenThreeIntegerDigits_thenShouldNotGiveConstraintViolations() {
Invoice invoice = new Invoice(new BigDecimal("102.21"), "Book purchased");
Set<ConstraintViolation<Invoice>> violations = validator.validate(invoice);
assertThat(violations.size()).isEqualTo(0);
assertThat(violations).isEmpty();
}
@Test
public void whenPriceIntegerDigitGreaterThanThree_thenShouldGiveConstraintViolations() {
Invoice invoice = new Invoice(new BigDecimal(1021.21), "Book purchased");
public void whenMoreThanThreeIntegerDigits_thenShouldGiveConstraintViolations() {
Invoice invoice = new Invoice(new BigDecimal("1021.21"), "Book purchased");
Set<ConstraintViolation<Invoice>> violations = validator.validate(invoice);
assertThat(violations.size()).isEqualTo(1);
violations.forEach(action -> assertThat(action.getMessage()).isEqualTo("numeric value out of bounds (<3 digits>.<2 digits> expected)"));
assertThat(violations).hasSize(1);
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
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);
assertThat(violations.size()).isEqualTo(1);
violations.forEach(action -> assertThat(action.getMessage()).isEqualTo("must be greater than 0.0"));
assertThat(violations).hasSize(1);
assertThat(violations)
.extracting("message")
.containsOnly("must be greater than 0.0");
}
@Test
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);
assertThat(violations.size()).isEqualTo(0);
assertThat(violations).isEmpty();
}
}

View File

@ -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)
- [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)

View File

@ -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

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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));
}
}

View File

@ -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"
});
}
}

View File

@ -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"
});
}
}

View File

@ -8,5 +8,6 @@ This module contains articles about HTTP libraries.
- [Decode an OkHttp JSON Response](https://www.baeldung.com/okhttp-json-response)
- [Retrofit 2 Dynamic URL](https://www.baeldung.com/retrofit-dynamic-url)
- [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)

View File

@ -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");
}
}

View File

@ -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());
}
}

View File

@ -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());
}
}
}

View File

@ -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();
}
}

View File

@ -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>

View File

@ -0,0 +1 @@
Copy File Example

View File

@ -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());
}
}

View File

@ -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>

View File

@ -0,0 +1 @@
Copy File Example

View File

@ -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());
}
}

View File

@ -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>

View File

@ -0,0 +1 @@
Copy File Example

View File

@ -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());
}
}

View File

@ -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>

View File

@ -0,0 +1 @@
logs/

View File

@ -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>

View File

@ -16,6 +16,7 @@
<modules>
<!-- <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-exec-plugin</module>
<module>maven-integration-test</module>
@ -30,6 +31,7 @@
<module>version-collision</module>
<module>version-overriding-plugins</module>
<module>versions-maven-plugin</module>
<module>maven-printing-plugins</module>
</modules>
</project>
</project>

View File

@ -19,7 +19,6 @@
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.1.3.RELEASE</version>
</dependency>
<dependency>
<groupId>io.mantisrx</groupId>
@ -35,36 +34,31 @@
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.10.2</version>
</dependency>
<dependency>
<groupId>net.andreinc.mockneat</groupId>
<artifactId>mockneat</artifactId>
<version>0.3.8</version>
<version>0.4.2</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webflux</artifactId>
<version>5.0.9.RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.projectreactor.netty</groupId>
<artifactId>reactor-netty</artifactId>
<version>0.9.12.RELEASE</version>
<scope>test</scope>
</dependency>
</dependencies>
<repositories>
<repository>
<id>SpringLibReleaseRepo</id>
<url>https://repo.spring.io/libs-release/</url>
<id>jcenter</id>
<url>https://jcenter.bintray.com/</url>
</repository>
</repositories>

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<project
xmlns="http://maven.apache.org/POM/4.0.0"
<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>

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<project
xmlns="http://maven.apache.org/POM/4.0.0"
<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>

View File

@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>parent-java</artifactId>
<version>0.0.1-SNAPSHOT</version>

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<project
xmlns="http://maven.apache.org/POM/4.0.0"
<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>

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<project
xmlns="http://maven.apache.org/POM/4.0.0"
<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>

View File

@ -26,6 +26,11 @@
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>annotations</artifactId>
<version>${findbugs.annotations.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
@ -41,6 +46,7 @@
<properties>
<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>
</properties>

View File

@ -1,12 +1,12 @@
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 void accept(@NotNull Object param) {
public void accept(@NonNull Object param) {
System.out.println(param.toString());
}
@ -14,7 +14,7 @@ public class FindBugsAnnotations {
System.out.println("Printing " + param);
}
@NotNull
@NonNull
public Object process() throws Exception {
Object result = doSomething();
if (result == null) {

View File

@ -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)
- [Mapping LOB Data in Hibernate](https://www.baeldung.com/hibernate-lob)
- [FetchMode in Hibernate](https://www.baeldung.com/hibernate-fetchmode)
- [Mapping PostgreSQL Array With Hibernate](https://www.baeldung.com/java-hibernate-map-postgresql-array)

View File

@ -13,11 +13,22 @@
</parent>
<dependencies>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>${postgresql.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>com.vladmihalcea</groupId>
<artifactId>hibernate-types-52</artifactId>
<version>${hibernate-types.version}</version>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
@ -64,7 +75,9 @@
</dependencies>
<properties>
<postgresql.version>42.2.20</postgresql.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>
<hibernate-validator.version>6.0.16.Final</hibernate-validator.version>
<org.glassfish.javax.el.version>3.0.1-b11</org.glassfish.javax.el.version>

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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();
}
}

View File

@ -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

View File

@ -68,6 +68,12 @@
<version>${assertj.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>

View File

@ -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;
}
}

View File

@ -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();
}
}

View File

@ -97,4 +97,20 @@
<property name="hibernate.temp.use_jdbc_metadata_defaults" value="false"/>
</properties>
</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>

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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> {
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -0,0 +1,7 @@
package com.baeldung.softdelete;
import org.springframework.data.repository.CrudRepository;
public interface ProductRepository extends CrudRepository<Product, Long>{
}

View File

@ -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;
}
}

View File

@ -5,10 +5,5 @@ spring.jpa.properties.hibernate.order_inserts=true
spring.jpa.properties.hibernate.order_updates=true
spring.jpa.properties.hibernate.generate_statistics=true
# JPA-Schema-Generation
# 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
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect

View File

@ -623,6 +623,7 @@
<module>spring-boot-rest-2</module>
<module>spring-caching</module>
<module>spring-caching-2</module>
<module>spring-cloud</module>
<module>spring-cloud-bus</module>
@ -1079,6 +1080,7 @@
<module>spring-boot-rest-2</module>
<module>spring-caching</module>
<module>spring-caching-2</module>
<module>spring-cloud</module>
<module>spring-cloud-bus</module>
@ -1274,6 +1276,7 @@
</build>
<modules>
<module>spring-boot-modules/spring-boot-cassandre</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-jigsaw</module>

View File

@ -8,3 +8,4 @@ This module contains articles about Reactor Core.
- [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)
- [How to Extract a Monos 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)

View File

@ -1,10 +1,14 @@
package com.baeldung.mono;
import org.junit.Test;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import static org.junit.Assert.assertEquals;
@ -40,4 +44,40 @@ public class MonoUnitTest {
// blocking
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);
}
}

View File

@ -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/)

View File

@ -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>

View File

@ -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);
}
}

View File

@ -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());
}
}
}

View File

@ -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=

View File

@ -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() {
}
}

View File

@ -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);
}
}

View File

@ -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=

View File

@ -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
1 1612569600 38294.4 39195.5 40964.2 38217.5 3882.29460938 153897343.463150723
2 1612656000 39195.4 38807.6 39623.6 37341.4 2389.96820017 91972455.834535369
3 1612742400 38807.6 46373.5 46767.9 38010 4971.54731481 212132648.426718929
4 1612828800 46374.6 46434.8 48139.3 44961 4330.72854712 201891604.027160303
5 1612915200 46430 44812.2 47300 43687.5 4351.84907778 198189685.592028516
6 1613001600 44806.1 47941.5 48647.6 44005.8 4045.91883504 188171651.974437139
7 1613088000 47963.1 47310.7 48958.8 46181.2 3356.01832119 159561721.419695848
8 1613174400 47305.4 47152.6 48120.5 46225.5 2740.99221759 129227867.922246174
9 1613260800 47152.5 48591.9 49686.9 47026.3 3359.4690565 163299915.839307312
10 1613347200 48587.2 47904.4 49003.6 42841.6 3974.98461358 188990056.26923591
11 1613433600 47913.1 49147.7 50619.3 47023.9 3599.85370182 176084748.845657596
12 1613520000 49147.7 52118.1 52609.6 48931.1 3356.85082847 170893567.530348564
13 1613606400 52114.3 51568.9 52522.9 50906.4 2183.18379408 113272339.172174965
14 1613692800 51561.1 55890.5 56317.7 50727 3749.6920105 200656740.865959032
15 1613779200 55893.6 55851.5 57622.6 53463.3 3394.87226216 190744601.429330887
16 1613865600 55851.4 57423 58336.3 55489.6 2514.02340013 143658132.671448082
17 1613952000 57420.6 54096.6 57517.8 44160 6125.32442907 330513978.457310237
18 1614038400 54085.9 48908.3 54174.2 44900 8048.96505298 389277314.445372085
19 1614124800 48902.9 49685.2 51361.9 47003.2 4816.75027676 239303706.844272809
20 1614211200 49676.5 47082.7 52019.6 46624.4 3701.80236678 184044004.383578525
21 1614297600 47082 46289.6 48408.8 44135 5329.77125908 247604118.914146591
22 1614384000 46290.2 46114.4 48381.9 44836.5 2872.64640734 134946360.020429589
23 1614470400 46111.3 45141.6 46626.1 43004.3 3940.17863714 175990962.484551548
24 1614556800 45136.5 49590.3 49771.3 44958.9 3548.51026561 169389196.772247159
25 1614643200 49590.3 48441.2 50201.6 47052.8 2936.94454126 142575425.463057812
26 1614729600 48440.6 50345.5 52623.9 48100 3177.38943911 160801620.821885745
27 1614816000 50347.6 48374.5 51762.1 47505.7 3624.17683614 178873453.27515484
28 1614902400 48374.5 48758.9 49450 46189.8 3697.34556922 176318969.507294567
29 1614988800 48746.9 48871.9 49255.1 47001 1949.15311354 94201823.810314647
30 1615075200 48885 50930.4 51424.7 48885 2444.3584982 122962479.787996993
31 1615161600 50956.6 52377 52387.5 49287.5 2710.99151191 137751640.241286989
32 1615248000 52376.9 54867.6 54867.6 51833.8 3070.93581512 165487483.114064122
33 1615334400 54867.5 55865.5 57364 52911.4 4049.50553851 224565244.752334892
34 1615420800 55863.7 57781.1 58150 54238 3403.69441456 191915265.020541521
35 1615507200 57781 57238.5 58057.5 55013.7 4031.0376629 228810606.091302364
36 1615593600 57220.7 61180.9 61815.3 56059.3 4394.62318443 259602986.875738328
37 1615680000 61174.3 59000 61700 59000 3084.33952274 186155667.656432156
38 1615766400 59000 55607.1 60632.9 54525.6 5910.33518227 338468393.188725572
39 1615852800 55607.1 56880.3 56918.9 53240.3 7410.49057723 409052587.523700888
40 1615939200 56880.3 58875.8 58951.8 54147.5 5828.79026943 328135601.648660052
41 1616025600 58882.9 57648.9 60107.7 57000 5073.7458698 297279816.540519693
42 1616112000 57648.9 58024.2 59450.1 56071 3727.09434161 217005823.723994618
43 1616198400 58024.3 58113.5 59874.6 57825.6 2746.52973805 161565114.165299707
44 1616284800 58113.5 57350.2 58591.6 55501 3265.35649781 186845535.507151609
45 1616371200 57345.3 54096.1 58415.5 53667 4219.99501831 237141977.003568352
46 1616457600 54086.8 54348.4 55823.1 52986.3 4374.34046303 239135883.538398977
47 1616544000 54348.4 52307.4 57200 51499.6 6416.76024581 351202326.218690674
48 1616630400 52307.1 51301.7 53239.1 50455 7242.6466396 375950351.557038048
49 1616716800 51301.7 55032 55062.5 51225.3 4609.48192944 245299757.451540308
50 1616803200 55031.9 55820.4 56628.6 53967.5 3634.73588532 200758048.816804103
51 1616889600 55820.3 55772.9 56541 54666.6 3158.20452681 176119911.151714842
52 1616976000 55772.8 57628.9 58400.5 54926.5 4413.63121553 251384747.301649587
53 1617062400 57630.8 58754.6 59351.9 57072.8 3563.87315049 208118726.050535887
54 1617148800 58753.2 58745.9 59800 56357.5 4921.45848213 288469053.074870873
55 1617235200 58745.5 58735.7 59487.1 57879 3163.98213108 186078130.901422269
56 1617321600 58735.7 58963.6 60179.1 58460.7 2553.76427314 151446539.609794648
57 1617408000 58963.6 57058.3 59795 56721.2 2512.19109578 147434403.06515736
58 1617494400 57052.5 58201.4 58481.2 56432.6 2069.14670128 119228330.17272614
59 1617580800 58201.4 59116.2 59254.1 56501 3003.76043377 174821106.684799505
60 1617667200 59116.2 57988.3 59497.5 57304.8 2964.86183859 173169186.845682699
61 1617753600 57988.3 55958.2 58668.6 55439 5277.04906389 299996660.411940246
62 1617840000 55958.2 58076.7 58141 55700.6 3175.60482079 181817013.517575328
63 1617926400 58076.7 58131.6 58900 57666.9 3516.19104669 204849717.059779284
64 1618012800 58138.2 59770.2 61350 57902.1 5533.50675561 332014577.538990658
65 1618099200 59770.2 60007.6 60687.4 59247.6 3896.37426019 233158562.799039154
66 1618185600 60007.6 59863.4 61270.7 59417.4 4611.409014 277430208.743380477
67 1618272000 59863.4 63578.7 63759.7 59815 6906.310253 430518557.569547626
68 1618358400 63578.7 62958.7 64840 61000 7696.509177 487298143.928065301
69 1618444800 62954.4 63152.6 63772.1 62023.9 4709.82427144 296178401.81115496
70 1618531200 63152.6 61342.6 63509.7 59930.8 8295.32523869 510423835.691643255
71 1618617600 61342.7 59995.2 62497.8 59599.6 5367.42979289 328364887.709585395
72 1618704000 59995.3 56150.6 60409.5 49001 11485.97101449 637797282.448645379
73 1618790400 56152.7 55618.8 57583.4 54205.2 7721.306905 432634348.931871989
74 1618876800 55618.7 56427.8 57061.6 53328 8677.75606016 480164200.559836543
75 1618963200 56426.1 53793.6 56761.7 53602 6240.82191836 345339357.806167462
76 1619049600 53793.5 51696.4 55474.7 50400 8879.16016304 475394174.249706678
77 1619136000 51691.2 51102.7 52112.1 47502.1 8885.07060366 441295812.644904319
78 1619222400 51109.8 50033 51157.9 48676.5 4833.41744745 241336360.887795675
79 1619308800 50041.5 49086.9 50554.6 46966.2 4805.34664069 237153315.222670555
80 1619395200 49069 54000.2 54336.4 48775.8 6695.12934907 353727728.269533971
81 1619481600 53997.1 55014.3 55439 53240.8 4344.22291318 237020455.905144335
82 1619568000 55014.2 54833.2 56399.1 53808.3 4801.04618634 262912695.604761319
83 1619654400 54833.1 53558.4 55181.2 52340.1 4356.05177188 234153663.397444462
84 1619740800 53558.5 57697.3 57936.4 53042.6 5000.47557303 277531927.921795199
85 1619827200 57697.3 57794.7 58471.4 57006.3 3639.78966647 210179438.189007639
86 1619913600 57794.7 56568.5 57903.7 56044.3 3508.52428767 199206958.05741809
87 1620000000 56568.5 57159.7 58977.9 56451.3 4780.43387226 276554749.540429296
88 1620086400 57159.7 53196.3 57188.2 53083.3 7079.55804728 390469293.396018923
89 1620172800 53196.3 57834.5 57979.7 52888 4224.63060355 233779565.506303973

View File

@ -0,0 +1,3 @@
BTC 1
USDT 100000
ETH 10
1 BTC 1
2 USDT 100000
3 ETH 10

View File

@ -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);
}
}

View File

@ -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";
}
}

View File

@ -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);
}
}

View File

@ -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");
}
}

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