[BAEL-9712] - Fixed conflicts
This commit is contained in:
commit
e9fa7851a5
|
@ -4,7 +4,7 @@ before_install:
|
|||
- echo "MAVEN_OPTS='-Xmx2048M -Xss128M -XX:+CMSClassUnloadingEnabled -XX:+UseG1GC -XX:-UseGCOverheadLimit'" > ~/.mavenrc
|
||||
|
||||
install: skip
|
||||
script: travis_wait 60 mvn -q install -Pdefault-first,default-second
|
||||
script: travis_wait 60 mvn -q install -Pdefault-first,default-second -Dgib.enabled=true
|
||||
|
||||
sudo: required
|
||||
|
||||
|
|
|
@ -17,3 +17,4 @@
|
|||
- [Round Up to the Nearest Hundred](https://www.baeldung.com/java-round-up-nearest-hundred)
|
||||
- [Calculate Percentage in Java](https://www.baeldung.com/java-calculate-percentage)
|
||||
- [Converting Between Byte Arrays and Hexadecimal Strings in Java](https://www.baeldung.com/java-byte-arrays-hex-strings)
|
||||
- [Convert Latitude and Longitude to a 2D Point in Java](https://www.baeldung.com/java-convert-latitude-longitude)
|
||||
|
|
|
@ -4,3 +4,4 @@
|
|||
- [Java 10 LocalVariable Type-Inference](http://www.baeldung.com/java-10-local-variable-type-inference)
|
||||
- [Guide to Java 10](http://www.baeldung.com/java-10-overview)
|
||||
- [Copy a List to Another List in Java](http://www.baeldung.com/java-copy-list-to-another)
|
||||
- [Deep Dive Into the New Java JIT Compiler – Graal](https://www.baeldung.com/graal-java-jit-compiler)
|
||||
|
|
|
@ -33,3 +33,4 @@
|
|||
- [An Overview of Regular Expressions Performance in Java](https://www.baeldung.com/java-regex-performance)
|
||||
- [Java Primitives versus Objects](https://www.baeldung.com/java-primitives-vs-objects)
|
||||
- [How to Use if/else Logic in Java 8 Streams](https://www.baeldung.com/java-8-streams-if-else-logic)
|
||||
- [How to Replace Many if Statements in Java](https://www.baeldung.com/java-replace-if-statements)
|
||||
|
|
|
@ -4,11 +4,13 @@ import java.lang.reflect.Array;
|
|||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.IntPredicate;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
|
@ -194,4 +196,16 @@ public class ArrayOperations {
|
|||
public static <T> T getRandomFromObjectArray(T[] array) {
|
||||
return array[new Random().nextInt(array.length)];
|
||||
}
|
||||
|
||||
public static Integer[] intersectionSimple(final Integer[] a, final Integer[] b){
|
||||
return Stream.of(a).filter(Arrays.asList(b)::contains).toArray(Integer[]::new);
|
||||
}
|
||||
|
||||
public static Integer[] intersectionSet(final Integer[] a, final Integer[] b){
|
||||
return Stream.of(a).filter(Arrays.asList(b)::contains).distinct().toArray(Integer[]::new);
|
||||
}
|
||||
|
||||
public static Integer[] intersectionMultiSet(final Integer[] a, final Integer[] b){
|
||||
return Stream.of(a).filter(new LinkedList<>(Arrays.asList(b))::remove).toArray(Integer[]::new);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
package com.baeldung.array.operations;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static com.baeldung.array.operations.ArrayOperations.intersectionMultiSet;
|
||||
import static com.baeldung.array.operations.ArrayOperations.intersectionSet;
|
||||
import static com.baeldung.array.operations.ArrayOperations.intersectionSimple;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class IntersectionUnitTest {
|
||||
private static final Integer[] a = { 1, 3, 2 };
|
||||
private static final Integer[] b = { 4, 3, 2, 4, 2, 3, 4, 4, 3 };
|
||||
private static final Integer[] c = { 1, 3, 2, 3, 3, 2 };
|
||||
|
||||
@Test
|
||||
void whenIntersectionSimpleIsUsed_thenCommonEntriesAreInTheResult() {
|
||||
assertThat(intersectionSimple(a, b)).isEqualTo(new Integer[] { 3, 2 });
|
||||
assertThat(intersectionSimple(b, a)).isEqualTo(new Integer[] { 3, 2, 2, 3, 3 });
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenIntersectionSimpleIsUsedWithAnArrayAndItself_thenTheResultIsTheIdentity() {
|
||||
assertThat(intersectionSimple(b, b)).isEqualTo(b);
|
||||
assertThat(intersectionSimple(a, a)).isEqualTo(a);
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenIntersectionSetIsUsed_thenCommonEntriesAreInTheResult() {
|
||||
assertThat(intersectionSet(b, a)).isEqualTo(new Integer[] { 3, 2 });
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenIntersectionSetIsUsed_thenTheNumberOfEntriesDoesNotChangeWithTheParameterOrder() {
|
||||
assertThat(intersectionSet(a, b)).isEqualTo(new Integer[] { 3, 2 });
|
||||
assertThat(intersectionSet(b, a)).isEqualTo(new Integer[] { 3, 2 });
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenIntersectionSetIsUsedWithAnArrayAndWithItself_andTheInputHasNoDuplicateEntries_ThenTheResultIsTheIdentity() {
|
||||
assertThat(intersectionSet(a, a)).isEqualTo(a);
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenIntersectionSetIsUsedWithAnArrayAndWithItself_andTheInputHasDuplicateEntries_ThenTheResultIsNotTheIdentity() {
|
||||
assertThat(intersectionSet(b, b)).isNotEqualTo(b);
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenMultiSetIsUsed_thenCommonEntriesAreInTheResult() {
|
||||
assertThat(intersectionMultiSet(b, a)).isEqualTo(new Integer[] { 3, 2 });
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenIntersectionMultiSetIsUsed_thenTheNumberOfEntriesDoesNotChangeWithTheParameterOrder() {
|
||||
assertThat(intersectionMultiSet(a, b)).isEqualTo(new Integer[] { 3, 2 });
|
||||
assertThat(intersectionMultiSet(b, a)).isEqualTo(new Integer[] { 3, 2 });
|
||||
assertThat(intersectionMultiSet(b, c)).isEqualTo(new Integer[] { 3, 2, 2, 3, 3 });
|
||||
assertThat(intersectionMultiSet(c, b)).isEqualTo(new Integer[] { 3, 2, 3, 3, 2 });
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenIntersectionMultiSetIsUsedWithAnArrayAndWithItself_ThenTheResultIsTheIdentity() {
|
||||
assertThat(intersectionMultiSet(b, b)).isEqualTo(b);
|
||||
assertThat(intersectionMultiSet(a, a)).isEqualTo(a);
|
||||
}
|
||||
}
|
|
@ -50,3 +50,4 @@
|
|||
- [Check If Two Lists are Equal in Java](http://www.baeldung.com/java-test-a-list-for-ordinality-and-equality)
|
||||
- [Java List Initialization in One Line](https://www.baeldung.com/java-init-list-one-line)
|
||||
- [ClassCastException: Arrays$ArrayList cannot be cast to ArrayList](https://www.baeldung.com/java-classcastexception-arrays-arraylist)
|
||||
- [A Guide to EnumMap](https://www.baeldung.com/java-enum-map)
|
||||
|
|
|
@ -34,3 +34,4 @@
|
|||
- [Read a File into an ArrayList](https://www.baeldung.com/java-file-to-arraylist)
|
||||
- [Guide to Java OutputStream](https://www.baeldung.com/java-outputstream)
|
||||
- [Reading a CSV File into an Array](https://www.baeldung.com/java-csv-file-array)
|
||||
- [Guide to BufferedReader](https://www.baeldung.com/java-buffered-reader)
|
||||
|
|
|
@ -56,4 +56,5 @@
|
|||
- [How to Separate Double into Integer and Decimal Parts](https://www.baeldung.com/java-separate-double-into-integer-decimal-parts)
|
||||
- [“Sneaky Throws” in Java](http://www.baeldung.com/java-sneaky-throws)
|
||||
- [Inheritance and Composition (Is-a vs Has-a relationship) in Java](http://www.baeldung.com/java-inheritance-composition)
|
||||
- [A Guide to Constructors in Java](https://www.baeldung.com/java-constructors)
|
||||
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
package com.baeldung.constructors;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
class BankAccount {
|
||||
String name;
|
||||
LocalDateTime opened;
|
||||
double balance;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%s, %s, %f", this.name, this.opened.toString(), this.balance);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public LocalDateTime getOpened() {
|
||||
return opened;
|
||||
}
|
||||
|
||||
public double getBalance() {
|
||||
return this.balance;
|
||||
}
|
||||
}
|
||||
|
||||
class BankAccountEmptyConstructor extends BankAccount {
|
||||
public BankAccountEmptyConstructor() {
|
||||
this.name = "";
|
||||
this.opened = LocalDateTime.now();
|
||||
this.balance = 0.0d;
|
||||
}
|
||||
}
|
||||
|
||||
class BankAccountParameterizedConstructor extends BankAccount {
|
||||
public BankAccountParameterizedConstructor(String name, LocalDateTime opened, double balance) {
|
||||
this.name = name;
|
||||
this.opened = opened;
|
||||
this.balance = balance;
|
||||
}
|
||||
}
|
||||
|
||||
class BankAccountCopyConstructor extends BankAccount {
|
||||
public BankAccountCopyConstructor(String name, LocalDateTime opened, double balance) {
|
||||
this.name = name;
|
||||
this.opened = opened;
|
||||
this.balance = balance;
|
||||
}
|
||||
|
||||
public BankAccountCopyConstructor(BankAccount other) {
|
||||
this.name = other.name;
|
||||
this.opened = LocalDateTime.now();
|
||||
this.balance = 0.0f;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package com.baeldung.constructors;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
class Transaction {
|
||||
final BankAccountEmptyConstructor bankAccount;
|
||||
final LocalDateTime date;
|
||||
final double amount;
|
||||
|
||||
public Transaction(BankAccountEmptyConstructor account, LocalDateTime date, double amount) {
|
||||
this.bankAccount = account;
|
||||
this.date = date;
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compilation Error :'(, all final variables must be explicitly initialised.
|
||||
* public Transaction() {
|
||||
* }
|
||||
*/
|
||||
|
||||
public void invalidMethod() {
|
||||
// this.amount = 102.03; // Results in a compiler error. You cannot change the value of a final variable.
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
package com.baeldung.constructors;
|
||||
|
||||
import com.baeldung.constructors.*;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.Month;
|
||||
|
||||
import org.junit.Test;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatCode;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
|
||||
public class ConstructorUnitTest {
|
||||
final static Logger LOGGER = Logger.getLogger(ConstructorUnitTest.class.getName());
|
||||
|
||||
@Test
|
||||
public void givenNoExplicitContructor_whenUsed_thenFails() {
|
||||
BankAccount account = new BankAccount();
|
||||
assertThatThrownBy(() -> { account.toString(); }).isInstanceOf(Exception.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenNoArgumentConstructor_whenUsed_thenSucceeds() {
|
||||
BankAccountEmptyConstructor account = new BankAccountEmptyConstructor();
|
||||
assertThatCode(() -> {
|
||||
account.toString();
|
||||
}).doesNotThrowAnyException();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenParameterisedConstructor_whenUsed_thenSucceeds() {
|
||||
LocalDateTime opened = LocalDateTime.of(2018, Month.JUNE, 29, 06, 30, 00);
|
||||
BankAccountParameterizedConstructor account =
|
||||
new BankAccountParameterizedConstructor("Tom", opened, 1000.0f);
|
||||
|
||||
assertThatCode(() -> {
|
||||
account.toString();
|
||||
}).doesNotThrowAnyException();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenCopyContructor_whenUser_thenMaintainsLogic() {
|
||||
LocalDateTime opened = LocalDateTime.of(2018, Month.JUNE, 29, 06, 30, 00);
|
||||
BankAccountCopyConstructor account = new BankAccountCopyConstructor("Tim", opened, 1000.0f);
|
||||
BankAccountCopyConstructor newAccount = new BankAccountCopyConstructor(account);
|
||||
|
||||
assertThat(account.getName()).isEqualTo(newAccount.getName());
|
||||
assertThat(account.getOpened()).isNotEqualTo(newAccount.getOpened());
|
||||
|
||||
assertThat(newAccount.getBalance()).isEqualTo(0.0f);
|
||||
}
|
||||
}
|
|
@ -85,3 +85,6 @@
|
|||
- [A Guide to SimpleDateFormat](https://www.baeldung.com/java-simple-date-format)
|
||||
- [SSL Handshake Failures](https://www.baeldung.com/java-ssl-handshake-failures)
|
||||
- [Implementing a Binary Tree in Java](https://www.baeldung.com/java-binary-tree)
|
||||
- [Changing the Order in a Sum Operation Can Produce Different Results?](https://www.baeldung.com/java-floating-point-sum-order)
|
||||
- [Java – Try with Resources](https://www.baeldung.com/java-try-with-resources)
|
||||
- [Abstract Classes in Java](https://www.baeldung.com/java-abstract-class)
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
package com.baeldung.className;
|
||||
|
||||
public class RetrievingClassName {
|
||||
|
||||
public class InnerClass {
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,156 @@
|
|||
package com.baeldung.className;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
public class RetrievingClassNameUnitTest {
|
||||
|
||||
// Retrieving Simple Name
|
||||
@Test
|
||||
public void givenRetrievingClassName_whenGetSimpleName_thenRetrievingClassName() {
|
||||
assertEquals("RetrievingClassName", RetrievingClassName.class.getSimpleName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenPrimitiveInt_whenGetSimpleName_thenInt() {
|
||||
assertEquals("int", int.class.getSimpleName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenRetrievingClassNameArray_whenGetSimpleName_thenRetrievingClassNameWithBrackets() {
|
||||
assertEquals("RetrievingClassName[]", RetrievingClassName[].class.getSimpleName());
|
||||
assertEquals("RetrievingClassName[][]", RetrievingClassName[][].class.getSimpleName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenAnonymousClass_whenGetSimpleName_thenEmptyString() {
|
||||
assertEquals("", new RetrievingClassName() {}.getClass().getSimpleName());
|
||||
}
|
||||
|
||||
// Retrieving Other Names
|
||||
// - Primitive Types
|
||||
@Test
|
||||
public void givenPrimitiveInt_whenGetName_thenInt() {
|
||||
assertEquals("int", int.class.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenPrimitiveInt_whenGetTypeName_thenInt() {
|
||||
assertEquals("int", int.class.getTypeName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenPrimitiveInt_whenGetCanonicalName_thenInt() {
|
||||
assertEquals("int", int.class.getCanonicalName());
|
||||
}
|
||||
|
||||
// - Object Types
|
||||
@Test
|
||||
public void givenRetrievingClassName_whenGetName_thenCanonicalName() {
|
||||
assertEquals("com.baeldung.className.RetrievingClassName", RetrievingClassName.class.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenRetrievingClassName_whenGetTypeName_thenCanonicalName() {
|
||||
assertEquals("com.baeldung.className.RetrievingClassName", RetrievingClassName.class.getTypeName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenRetrievingClassName_whenGetCanonicalName_thenCanonicalName() {
|
||||
assertEquals("com.baeldung.className.RetrievingClassName", RetrievingClassName.class.getCanonicalName());
|
||||
}
|
||||
|
||||
// - Inner Classes
|
||||
@Test
|
||||
public void givenRetrievingClassNameInnerClass_whenGetName_thenCanonicalNameWithDollarSeparator() {
|
||||
assertEquals("com.baeldung.className.RetrievingClassName$InnerClass", RetrievingClassName.InnerClass.class.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenRetrievingClassNameInnerClass_whenGetTypeName_thenCanonicalNameWithDollarSeparator() {
|
||||
assertEquals("com.baeldung.className.RetrievingClassName$InnerClass", RetrievingClassName.InnerClass.class.getTypeName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenRetrievingClassNameInnerClass_whenGetCanonicalName_thenCanonicalName() {
|
||||
assertEquals("com.baeldung.className.RetrievingClassName.InnerClass", RetrievingClassName.InnerClass.class.getCanonicalName());
|
||||
}
|
||||
|
||||
// - Anonymous Classes
|
||||
@Test
|
||||
public void givenAnonymousClass_whenGetName_thenCallingClassCanonicalNameWithDollarSeparatorAndCountNumber() {
|
||||
// These are the second and third appearences of an anonymous class in RetrievingClassNameUnitTest, hence $2 and $3 expectations
|
||||
assertEquals("com.baeldung.className.RetrievingClassNameUnitTest$2", new RetrievingClassName() {}.getClass().getName());
|
||||
assertEquals("com.baeldung.className.RetrievingClassNameUnitTest$3", new RetrievingClassName() {}.getClass().getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenAnonymousClass_whenGetTypeName_thenCallingClassCanonicalNameWithDollarSeparatorAndCountNumber() {
|
||||
// These are the fourth and fifth appearences of an anonymous class in RetrievingClassNameUnitTest, hence $4 and $5 expectations
|
||||
assertEquals("com.baeldung.className.RetrievingClassNameUnitTest$4", new RetrievingClassName() {}.getClass().getTypeName());
|
||||
assertEquals("com.baeldung.className.RetrievingClassNameUnitTest$5", new RetrievingClassName() {}.getClass().getTypeName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenAnonymousClass_whenGetCanonicalName_thenNull() {
|
||||
assertNull(new RetrievingClassName() {}.getClass().getCanonicalName());
|
||||
}
|
||||
|
||||
// - Arrays
|
||||
@Test
|
||||
public void givenPrimitiveIntArray_whenGetName_thenOpeningBracketsAndPrimitiveIntLetter() {
|
||||
assertEquals("[I", int[].class.getName());
|
||||
assertEquals("[[I", int[][].class.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenRetrievingClassNameArray_whenGetName_thenOpeningBracketsLetterLAndRetrievingClassNameGetName() {
|
||||
assertEquals("[Lcom.baeldung.className.RetrievingClassName;", RetrievingClassName[].class.getName());
|
||||
assertEquals("[[Lcom.baeldung.className.RetrievingClassName;", RetrievingClassName[][].class.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenRetrievingClassNameInnerClassArray_whenGetName_thenOpeningBracketsLetterLAndRetrievingClassNameInnerClassGetName() {
|
||||
assertEquals("[Lcom.baeldung.className.RetrievingClassName$InnerClass;", RetrievingClassName.InnerClass[].class.getName());
|
||||
assertEquals("[[Lcom.baeldung.className.RetrievingClassName$InnerClass;", RetrievingClassName.InnerClass[][].class.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenPrimitiveIntArray_whenGetTypeName_thenPrimitiveIntGetTypeNameWithBrackets() {
|
||||
assertEquals("int[]", int[].class.getTypeName());
|
||||
assertEquals("int[][]", int[][].class.getTypeName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenRetrievingClassNameArray_whenGetTypeName_thenRetrievingClassNameGetTypeNameWithBrackets() {
|
||||
assertEquals("com.baeldung.className.RetrievingClassName[]", RetrievingClassName[].class.getTypeName());
|
||||
assertEquals("com.baeldung.className.RetrievingClassName[][]", RetrievingClassName[][].class.getTypeName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenRetrievingClassNameInnerClassArray_whenGetTypeName_thenRetrievingClassNameInnerClassGetTypeNameWithBrackets() {
|
||||
assertEquals("com.baeldung.className.RetrievingClassName$InnerClass[]", RetrievingClassName.InnerClass[].class.getTypeName());
|
||||
assertEquals("com.baeldung.className.RetrievingClassName$InnerClass[][]", RetrievingClassName.InnerClass[][].class.getTypeName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenPrimitiveIntArray_whenGetCanonicalName_thenPrimitiveIntGetCanonicalNameWithBrackets() {
|
||||
assertEquals("int[]", int[].class.getCanonicalName());
|
||||
assertEquals("int[][]", int[][].class.getCanonicalName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenRetrievingClassNameArray_whenGetCanonicalName_thenRetrievingClassNameGetCanonicalNameWithBrackets() {
|
||||
assertEquals("com.baeldung.className.RetrievingClassName[]", RetrievingClassName[].class.getCanonicalName());
|
||||
assertEquals("com.baeldung.className.RetrievingClassName[][]", RetrievingClassName[][].class.getCanonicalName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenRetrievingClassNameInnerClassArray_whenGetCanonicalName_thenRetrievingClassNameInnerClassGetCanonicalNameWithBrackets() {
|
||||
assertEquals("com.baeldung.className.RetrievingClassName.InnerClass[]", RetrievingClassName.InnerClass[].class.getCanonicalName());
|
||||
assertEquals("com.baeldung.className.RetrievingClassName.InnerClass[][]", RetrievingClassName.InnerClass[][].class.getCanonicalName());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
package com.baeldung.string;
|
||||
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class StringReplaceAndRemoveUnitTest {
|
||||
|
||||
|
||||
@Test
|
||||
public void givenTestStrings_whenReplace_thenProcessedString() {
|
||||
|
||||
String master = "Hello World Baeldung!";
|
||||
String target = "Baeldung";
|
||||
String replacement = "Java";
|
||||
String processed = master.replace(target, replacement);
|
||||
assertTrue(processed.contains(replacement));
|
||||
assertFalse(processed.contains(target));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenTestStrings_whenReplaceAll_thenProcessedString() {
|
||||
|
||||
String master2 = "Welcome to Baeldung, Hello World Baeldung";
|
||||
String regexTarget= "(Baeldung)$";
|
||||
String replacement = "Java";
|
||||
String processed2 = master2.replaceAll(regexTarget, replacement);
|
||||
assertTrue(processed2.endsWith("Java"));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenTestStrings_whenStringBuilderMethods_thenProcessedString() {
|
||||
|
||||
String master = "Hello World Baeldung!";
|
||||
String target = "Baeldung";
|
||||
String replacement = "Java";
|
||||
|
||||
int startIndex = master.indexOf(target);
|
||||
int stopIndex = startIndex + target.length();
|
||||
|
||||
StringBuilder builder = new StringBuilder(master);
|
||||
|
||||
|
||||
builder.delete(startIndex, stopIndex);
|
||||
assertFalse(builder.toString().contains(target));
|
||||
|
||||
|
||||
builder.replace(startIndex, stopIndex, replacement);
|
||||
assertTrue(builder.toString().contains(replacement));
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void givenTestStrings_whenStringUtilsMethods_thenProcessedStrings() {
|
||||
|
||||
String master = "Hello World Baeldung!";
|
||||
String target = "Baeldung";
|
||||
String replacement = "Java";
|
||||
|
||||
String processed = StringUtils.replace(master, target, replacement);
|
||||
assertTrue(processed.contains(replacement));
|
||||
|
||||
String master2 = "Hello World Baeldung!";
|
||||
String target2 = "baeldung";
|
||||
String processed2 = StringUtils.replaceIgnoreCase(master2, target2, replacement);
|
||||
assertFalse(processed2.contains(target));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -71,9 +71,8 @@
|
|||
</build>
|
||||
|
||||
<properties>
|
||||
<io.grpc.version>1.5.0</io.grpc.version>
|
||||
<os-maven-plugin.version>1.5.0.Final</os-maven-plugin.version>
|
||||
<protobuf-maven-plugin.version>0.5.0</protobuf-maven-plugin.version>
|
||||
<io.grpc.version>1.16.1</io.grpc.version>
|
||||
<os-maven-plugin.version>1.6.1</os-maven-plugin.version>
|
||||
<protobuf-maven-plugin.version>0.6.1</protobuf-maven-plugin.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
|
|
|
@ -10,7 +10,7 @@ import io.grpc.ManagedChannelBuilder;
|
|||
public class GrpcClient {
|
||||
public static void main(String[] args) throws InterruptedException {
|
||||
ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 8080)
|
||||
.usePlaintext(true)
|
||||
.usePlaintext()
|
||||
.build();
|
||||
|
||||
HelloServiceGrpc.HelloServiceBlockingStub stub
|
||||
|
|
|
@ -24,3 +24,4 @@
|
|||
- [Add Hours To a Date In Java](http://www.baeldung.com/java-add-hours-date)
|
||||
- [Guide to DateTimeFormatter](https://www.baeldung.com/java-datetimeformatter)
|
||||
- [Format ZonedDateTime to String](https://www.baeldung.com/java-format-zoned-datetime-string)
|
||||
- [Convert Between java.time.Instant and java.sql.Timestamp](Convert Between java.time.Instant and java.sql.Timestamp)
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
package com.baeldung.timestamp;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
public class StringToTimestampConverterUnitTest {
|
||||
|
||||
@Test
|
||||
public void givenDatePattern_whenParsing_thenTimestampIsCorrect() {
|
||||
String pattern = "MMM dd, yyyy HH:mm:ss.SSSSSSSS";
|
||||
String timestampAsString = "Nov 12, 2018 13:02:56.12345678";
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
|
||||
LocalDateTime localDateTime = LocalDateTime.from(formatter.parse(timestampAsString));
|
||||
|
||||
Timestamp timestamp = Timestamp.valueOf(localDateTime);
|
||||
Assert.assertEquals("2018-11-12 13:02:56.12345678", timestamp.toString());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package com.baeldung.timestamp;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
public class TimestampToStringConverterTest {
|
||||
|
||||
@Test
|
||||
public void givenDatePattern_whenFormatting_thenResultingStringIsCorrect() {
|
||||
Timestamp timestamp = Timestamp.valueOf("2018-12-12 01:02:03.123456789");
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
|
||||
|
||||
String timestampAsString = formatter.format(timestamp.toLocalDateTime());
|
||||
Assert.assertEquals("2018-12-12T01:02:03.123456789", timestampAsString);
|
||||
}
|
||||
}
|
|
@ -36,3 +36,4 @@
|
|||
- [String Performance Hints](https://www.baeldung.com/java-string-performance)
|
||||
- [Using indexOf to Find All Occurrences of a Word in a String](https://www.baeldung.com/java-indexOf-find-string-occurrences)
|
||||
- [Java Base64 Encoding and Decoding](https://www.baeldung.com/java-base64-encode-and-decode)
|
||||
- [Generate a Secure Random Password in Java](https://www.baeldung.com/java-generate-secure-password)
|
||||
|
|
|
@ -0,0 +1,102 @@
|
|||
package com.baeldung.stringduplicates;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class RemoveDuplicateFromString {
|
||||
|
||||
|
||||
String removeDuplicatesUsingCharArray(String str) {
|
||||
|
||||
char[] chars = str.toCharArray();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
int repeatedCtr;
|
||||
for (int i = 0; i < chars.length; i++) {
|
||||
repeatedCtr = 0;
|
||||
for (int j = i + 1; j < chars.length; j++) {
|
||||
if (chars[i] == chars[j]) {
|
||||
repeatedCtr++;
|
||||
}
|
||||
}
|
||||
if (repeatedCtr == 0) {
|
||||
sb.append(chars[i]);
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
String removeDuplicatesUsinglinkedHashSet(String str) {
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
Set<Character> linkedHashSet = new LinkedHashSet<>();
|
||||
|
||||
for (int i = 0; i < str.length(); i++) {
|
||||
linkedHashSet.add(str.charAt(i));
|
||||
}
|
||||
|
||||
for (Character c : linkedHashSet) {
|
||||
sb.append(c);
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
String removeDuplicatesUsingSorting(String str) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if(!str.isEmpty()) {
|
||||
char[] chars = str.toCharArray();
|
||||
Arrays.sort(chars);
|
||||
|
||||
sb.append(chars[0]);
|
||||
for (int i = 1; i < chars.length; i++) {
|
||||
if (chars[i] != chars[i - 1]) {
|
||||
sb.append(chars[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
String removeDuplicatesUsingHashSet(String str) {
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
Set<Character> hashSet = new HashSet<>();
|
||||
|
||||
for (int i = 0; i < str.length(); i++) {
|
||||
hashSet.add(str.charAt(i));
|
||||
}
|
||||
|
||||
for (Character c : hashSet) {
|
||||
sb.append(c);
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
String removeDuplicatesUsingIndexOf(String str) {
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
int idx;
|
||||
for (int i = 0; i < str.length(); i++) {
|
||||
char c = str.charAt(i);
|
||||
idx = str.indexOf(c, i + 1);
|
||||
if (idx == -1) {
|
||||
sb.append(c);
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
String removeDuplicatesUsingDistinct(String str) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
str.chars().distinct().forEach(c -> sb.append((char) c));
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
package com.baeldung.string;
|
||||
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class StringReplaceAndRemoveUnitTest {
|
||||
|
||||
|
||||
@Test
|
||||
public void givenTestStrings_whenReplace_thenProcessedString() {
|
||||
|
||||
String master = "Hello World Baeldung!";
|
||||
String target = "Baeldung";
|
||||
String replacement = "Java";
|
||||
String processed = master.replace(target, replacement);
|
||||
assertTrue(processed.contains(replacement));
|
||||
assertFalse(processed.contains(target));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenTestStrings_whenReplaceAll_thenProcessedString() {
|
||||
|
||||
String master2 = "Welcome to Baeldung, Hello World Baeldung";
|
||||
String regexTarget= "(Baeldung)$";
|
||||
String replacement = "Java";
|
||||
String processed2 = master2.replaceAll(regexTarget, replacement);
|
||||
assertTrue(processed2.endsWith("Java"));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenTestStrings_whenStringBuilderMethods_thenProcessedString() {
|
||||
|
||||
String master = "Hello World Baeldung!";
|
||||
String target = "Baeldung";
|
||||
String replacement = "Java";
|
||||
|
||||
int startIndex = master.indexOf(target);
|
||||
int stopIndex = startIndex + target.length();
|
||||
|
||||
StringBuilder builder = new StringBuilder(master);
|
||||
|
||||
|
||||
builder.delete(startIndex, stopIndex);
|
||||
assertFalse(builder.toString().contains(target));
|
||||
|
||||
|
||||
builder.replace(startIndex, stopIndex, replacement);
|
||||
assertTrue(builder.toString().contains(replacement));
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void givenTestStrings_whenStringUtilsMethods_thenProcessedStrings() {
|
||||
|
||||
String master = "Hello World Baeldung!";
|
||||
String target = "Baeldung";
|
||||
String replacement = "Java";
|
||||
|
||||
String processed = StringUtils.replace(master, target, replacement);
|
||||
assertTrue(processed.contains(replacement));
|
||||
|
||||
String master2 = "Hello World Baeldung!";
|
||||
String target2 = "baeldung";
|
||||
String processed2 = StringUtils.replaceIgnoreCase(master2, target2, replacement);
|
||||
assertFalse(processed2.contains(target));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
package com.baeldung.stringduplicates;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
public class RemoveDuplicateFromStringUnitTest {
|
||||
|
||||
private final static String STR1 = "racecar";
|
||||
private final static String STR2 = "J2ee programming";
|
||||
private final static String STR_EMPTY = "";
|
||||
|
||||
private RemoveDuplicateFromString removeDuplicateFromString;
|
||||
|
||||
@Before
|
||||
public void executedBeforeEach() {
|
||||
removeDuplicateFromString = new RemoveDuplicateFromString();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void whenUsingCharArray_DuplicatesShouldBeRemovedWithoutKeepingStringOrder() {
|
||||
String str1 = removeDuplicateFromString.removeDuplicatesUsingCharArray(STR1);
|
||||
String str2 = removeDuplicateFromString.removeDuplicatesUsingCharArray(STR2);
|
||||
String strEmpty = removeDuplicateFromString.removeDuplicatesUsingCharArray(STR_EMPTY);
|
||||
Assert.assertEquals("", strEmpty);
|
||||
Assert.assertEquals("ecar", str1);
|
||||
Assert.assertEquals("J2e poraming", str2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenUsingLinkedHashSet_DuplicatesShouldBeRemovedAndItKeepStringOrder() {
|
||||
String str1 = removeDuplicateFromString.removeDuplicatesUsinglinkedHashSet(STR1);
|
||||
String str2 = removeDuplicateFromString.removeDuplicatesUsinglinkedHashSet(STR2);
|
||||
|
||||
String strEmpty = removeDuplicateFromString.removeDuplicatesUsinglinkedHashSet(STR_EMPTY);
|
||||
Assert.assertEquals("", strEmpty);
|
||||
Assert.assertEquals("race", str1);
|
||||
Assert.assertEquals("J2e progamin", str2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenUsingSorting_DuplicatesShouldBeRemovedWithoutKeepingStringOrder() {
|
||||
String str1 = removeDuplicateFromString.removeDuplicatesUsingSorting(STR1);
|
||||
String str2 = removeDuplicateFromString.removeDuplicatesUsingSorting(STR2);
|
||||
|
||||
String strEmpty = removeDuplicateFromString.removeDuplicatesUsingSorting(STR_EMPTY);
|
||||
Assert.assertEquals("", strEmpty);
|
||||
Assert.assertEquals("acer", str1);
|
||||
Assert.assertEquals(" 2Jaegimnopr", str2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenUsingHashSet_DuplicatesShouldBeRemovedWithoutKeepingStringOrder() {
|
||||
String str1 = removeDuplicateFromString.removeDuplicatesUsingHashSet(STR1);
|
||||
String str2 = removeDuplicateFromString.removeDuplicatesUsingHashSet(STR2);
|
||||
String strEmpty = removeDuplicateFromString.removeDuplicatesUsingHashSet(STR_EMPTY);
|
||||
Assert.assertEquals("", strEmpty);
|
||||
Assert.assertEquals("arce", str1);
|
||||
Assert.assertEquals(" pa2regiJmno", str2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenUsingIndexOf_DuplicatesShouldBeRemovedWithoutKeepingStringOrder() {
|
||||
String str1 = removeDuplicateFromString.removeDuplicatesUsingIndexOf(STR1);
|
||||
String str2 = removeDuplicateFromString.removeDuplicatesUsingIndexOf(STR2);
|
||||
String strEmpty = removeDuplicateFromString.removeDuplicatesUsingIndexOf(STR_EMPTY);
|
||||
Assert.assertEquals("", strEmpty);
|
||||
Assert.assertEquals("ecar", str1);
|
||||
Assert.assertEquals("J2e poraming", str2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenUsingJava8_DuplicatesShouldBeRemovedAndItKeepStringOrder() {
|
||||
String str1 = removeDuplicateFromString.removeDuplicatesUsingDistinct(STR1);
|
||||
String str2 = removeDuplicateFromString.removeDuplicatesUsingDistinct(STR2);
|
||||
String strEmpty = removeDuplicateFromString.removeDuplicatesUsingDistinct(STR_EMPTY);
|
||||
Assert.assertEquals("", strEmpty);
|
||||
Assert.assertEquals("race", str1);
|
||||
Assert.assertEquals("J2e progamin", str2);
|
||||
}
|
||||
}
|
|
@ -87,6 +87,13 @@
|
|||
<artifactId>h2</artifactId>
|
||||
<version>${h2database.version}</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/io.arrow-kt/arrow-core -->
|
||||
<dependency>
|
||||
<groupId>io.arrow-kt</groupId>
|
||||
<artifactId>arrow-core</artifactId>
|
||||
<version>0.7.3</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
package com.baeldung.kotlin.arrow
|
||||
|
||||
import arrow.core.Either
|
||||
import arrow.core.filterOrElse
|
||||
import kotlin.math.sqrt
|
||||
|
||||
class FunctionalErrorHandlingWithEither {
|
||||
|
||||
sealed class ComputeProblem {
|
||||
object OddNumber : ComputeProblem()
|
||||
object NotANumber : ComputeProblem()
|
||||
}
|
||||
|
||||
fun parseInput(s : String) : Either<ComputeProblem, Int> = Either.cond(s.toIntOrNull() != null, {-> s.toInt()}, {->ComputeProblem.NotANumber} )
|
||||
|
||||
fun isEven(x : Int) : Boolean = x % 2 == 0
|
||||
|
||||
fun biggestDivisor(x: Int) : Int = biggestDivisor(x, 2)
|
||||
|
||||
fun biggestDivisor(x : Int, y : Int) : Int {
|
||||
if(x == y){
|
||||
return 1;
|
||||
}
|
||||
if(x % y == 0){
|
||||
return x / y;
|
||||
}
|
||||
return biggestDivisor(x, y+1)
|
||||
}
|
||||
|
||||
fun isSquareNumber(x : Int) : Boolean {
|
||||
val sqrt: Double = sqrt(x.toDouble())
|
||||
return sqrt % 1.0 == 0.0
|
||||
}
|
||||
|
||||
fun computeWithEither(input : String) : Either<ComputeProblem, Boolean> {
|
||||
return parseInput(input)
|
||||
.filterOrElse(::isEven) {->ComputeProblem.OddNumber}
|
||||
.map (::biggestDivisor)
|
||||
.map (::isSquareNumber)
|
||||
}
|
||||
|
||||
fun computeWithEitherClient(input : String) {
|
||||
val computeWithEither = computeWithEither(input)
|
||||
|
||||
when(computeWithEither){
|
||||
is Either.Right -> "The greatest divisor is square number: ${computeWithEither.b}"
|
||||
is Either.Left -> when(computeWithEither.a){
|
||||
is ComputeProblem.NotANumber -> "Wrong input! Not a number!"
|
||||
is ComputeProblem.OddNumber -> "It is an odd number!"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
package com.baeldung.kotlin.arrow
|
||||
|
||||
import arrow.core.None
|
||||
import arrow.core.Option
|
||||
import arrow.core.Some
|
||||
import kotlin.math.sqrt
|
||||
|
||||
class FunctionalErrorHandlingWithOption {
|
||||
|
||||
fun parseInput(s : String) : Option<Int> = Option.fromNullable(s.toIntOrNull())
|
||||
|
||||
fun isEven(x : Int) : Boolean = x % 2 == 0
|
||||
|
||||
fun biggestDivisor(x: Int) : Int = biggestDivisor(x, 2)
|
||||
|
||||
fun biggestDivisor(x : Int, y : Int) : Int {
|
||||
if(x == y){
|
||||
return 1;
|
||||
}
|
||||
if(x % y == 0){
|
||||
return x / y;
|
||||
}
|
||||
return biggestDivisor(x, y+1)
|
||||
}
|
||||
|
||||
fun isSquareNumber(x : Int) : Boolean {
|
||||
val sqrt: Double = sqrt(x.toDouble())
|
||||
return sqrt % 1.0 == 0.0
|
||||
}
|
||||
|
||||
fun computeWithOption(input : String) : Option<Boolean> {
|
||||
return parseInput(input)
|
||||
.filter(::isEven)
|
||||
.map(::biggestDivisor)
|
||||
.map(::isSquareNumber)
|
||||
}
|
||||
|
||||
fun computeWithOptionClient(input : String) : String{
|
||||
val computeOption = computeWithOption(input)
|
||||
|
||||
return when(computeOption){
|
||||
is None -> "Not an even number!"
|
||||
is Some -> "The greatest divisor is square number: ${computeOption.t}"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,143 @@
|
|||
package com.baeldung.kotlin.arrow
|
||||
|
||||
import arrow.core.*
|
||||
import org.junit.Assert
|
||||
import org.junit.Test
|
||||
|
||||
class FunctionalDataTypes {
|
||||
|
||||
@Test
|
||||
fun whenIdCreated_thanValueIsPresent(){
|
||||
val id = Id("foo")
|
||||
val justId = Id.just("foo");
|
||||
|
||||
Assert.assertEquals("foo", id.extract())
|
||||
Assert.assertEquals(justId, id)
|
||||
}
|
||||
|
||||
fun length(s : String) : Int = s.length
|
||||
|
||||
fun isBigEnough(i : Int) : Boolean = i > 10
|
||||
|
||||
@Test
|
||||
fun whenIdCreated_thanMapIsAssociative(){
|
||||
val foo = Id("foo")
|
||||
|
||||
val map1 = foo.map(::length)
|
||||
.map(::isBigEnough)
|
||||
val map2 = foo.map { s -> isBigEnough(length(s)) }
|
||||
|
||||
Assert.assertEquals(map1, map2)
|
||||
}
|
||||
|
||||
fun lengthId(s : String) : Id<Int> = Id.just(length(s))
|
||||
|
||||
fun isBigEnoughId(i : Int) : Id<Boolean> = Id.just(isBigEnough(i))
|
||||
|
||||
@Test
|
||||
fun whenIdCreated_thanFlatMapIsAssociative(){
|
||||
val bar = Id("bar")
|
||||
|
||||
val flatMap = bar.flatMap(::lengthId)
|
||||
.flatMap(::isBigEnoughId)
|
||||
val flatMap1 = bar.flatMap { s -> lengthId(s).flatMap(::isBigEnoughId) }
|
||||
|
||||
Assert.assertEquals(flatMap, flatMap1)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenOptionCreated_thanValueIsPresent(){
|
||||
val factory = Option.just(42)
|
||||
val constructor = Option(42)
|
||||
val emptyOptional = Option.empty<Integer>()
|
||||
val fromNullable = Option.fromNullable(null)
|
||||
|
||||
Assert.assertEquals(42, factory.getOrElse { -1 })
|
||||
Assert.assertEquals(factory, constructor)
|
||||
Assert.assertEquals(emptyOptional, fromNullable)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenOptionCreated_thanConstructorDifferFromFactory(){
|
||||
val constructor : Option<String?> = Option(null)
|
||||
val fromNullable : Option<String?> = Option.fromNullable(null)
|
||||
|
||||
try{
|
||||
constructor.map { s -> s!!.length }
|
||||
Assert.fail()
|
||||
} catch (e : KotlinNullPointerException){
|
||||
fromNullable.map { s->s!!.length }
|
||||
}
|
||||
Assert.assertNotEquals(constructor, fromNullable)
|
||||
}
|
||||
|
||||
fun wrapper(x : Integer?) : Option<Int> = if (x == null) Option.just(-1) else Option.just(x.toInt())
|
||||
|
||||
@Test
|
||||
fun whenOptionFromNullableCreated_thanItBreaksLeftIdentity(){
|
||||
val optionFromNull = Option.fromNullable(null)
|
||||
|
||||
Assert.assertNotEquals(optionFromNull.flatMap(::wrapper), wrapper(null))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenEitherCreated_thanOneValueIsPresent(){
|
||||
val rightOnly : Either<String,Int> = Either.right(42)
|
||||
val leftOnly : Either<String,Int> = Either.left("foo")
|
||||
|
||||
Assert.assertTrue(rightOnly.isRight())
|
||||
Assert.assertTrue(leftOnly.isLeft())
|
||||
Assert.assertEquals(42, rightOnly.getOrElse { -1 })
|
||||
Assert.assertEquals(-1, leftOnly.getOrElse { -1 })
|
||||
|
||||
Assert.assertEquals(0, rightOnly.map { it % 2 }.getOrElse { -1 })
|
||||
Assert.assertEquals(-1, leftOnly.map { it % 2 }.getOrElse { -1 })
|
||||
Assert.assertTrue(rightOnly.flatMap { Either.Right(it % 2) }.isRight())
|
||||
Assert.assertTrue(leftOnly.flatMap { Either.Right(it % 2) }.isLeft())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenEvalNowUsed_thenMapEvaluatedLazily(){
|
||||
val now = Eval.now(1)
|
||||
Assert.assertEquals(1, now.value())
|
||||
|
||||
var counter : Int = 0
|
||||
val map = now.map { x -> counter++; x+1 }
|
||||
Assert.assertEquals(0, counter)
|
||||
|
||||
val value = map.value()
|
||||
Assert.assertEquals(2, value)
|
||||
Assert.assertEquals(1, counter)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenEvalLaterUsed_theResultIsMemoized(){
|
||||
var counter : Int = 0
|
||||
val later = Eval.later { counter++; counter }
|
||||
Assert.assertEquals(0, counter)
|
||||
|
||||
val firstValue = later.value()
|
||||
Assert.assertEquals(1, firstValue)
|
||||
Assert.assertEquals(1, counter)
|
||||
|
||||
val secondValue = later.value()
|
||||
Assert.assertEquals(1, secondValue)
|
||||
Assert.assertEquals(1, counter)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenEvalAlwaysUsed_theResultIsNotMemoized(){
|
||||
var counter : Int = 0
|
||||
val later = Eval.always { counter++; counter }
|
||||
Assert.assertEquals(0, counter)
|
||||
|
||||
val firstValue = later.value()
|
||||
Assert.assertEquals(1, firstValue)
|
||||
Assert.assertEquals(1, counter)
|
||||
|
||||
val secondValue = later.value()
|
||||
Assert.assertEquals(2, secondValue)
|
||||
Assert.assertEquals(2, counter)
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
package com.baeldung.kotlin.arrow
|
||||
|
||||
import arrow.core.Either
|
||||
import com.baeldung.kotlin.arrow.FunctionalErrorHandlingWithEither.ComputeProblem.NotANumber
|
||||
import com.baeldung.kotlin.arrow.FunctionalErrorHandlingWithEither.ComputeProblem.OddNumber
|
||||
import org.junit.Assert
|
||||
import org.junit.Test
|
||||
|
||||
class FunctionalErrorHandlingWithEitherTest {
|
||||
|
||||
val operator = FunctionalErrorHandlingWithEither()
|
||||
|
||||
@Test
|
||||
fun givenInvalidInput_whenComputeInvoked_NotANumberIsPresent(){
|
||||
val computeWithEither = operator.computeWithEither("bar")
|
||||
|
||||
Assert.assertTrue(computeWithEither.isLeft())
|
||||
when(computeWithEither){
|
||||
is Either.Left -> when(computeWithEither.a){
|
||||
NotANumber -> "Ok."
|
||||
else -> Assert.fail()
|
||||
}
|
||||
else -> Assert.fail()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenOddNumberInput_whenComputeInvoked_OddNumberIsPresent(){
|
||||
val computeWithEither = operator.computeWithEither("121")
|
||||
|
||||
Assert.assertTrue(computeWithEither.isLeft())
|
||||
when(computeWithEither){
|
||||
is Either.Left -> when(computeWithEither.a){
|
||||
OddNumber -> "Ok."
|
||||
else -> Assert.fail()
|
||||
}
|
||||
else -> Assert.fail()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenEvenNumberWithoutSquare_whenComputeInvoked_OddNumberIsPresent(){
|
||||
val computeWithEither = operator.computeWithEither("100")
|
||||
|
||||
Assert.assertTrue(computeWithEither.isRight())
|
||||
when(computeWithEither){
|
||||
is Either.Right -> when(computeWithEither.b){
|
||||
false -> "Ok."
|
||||
else -> Assert.fail()
|
||||
}
|
||||
else -> Assert.fail()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenEvenNumberWithSquare_whenComputeInvoked_OddNumberIsPresent(){
|
||||
val computeWithEither = operator.computeWithEither("98")
|
||||
|
||||
Assert.assertTrue(computeWithEither.isRight())
|
||||
when(computeWithEither){
|
||||
is Either.Right -> when(computeWithEither.b){
|
||||
true -> "Ok."
|
||||
else -> Assert.fail()
|
||||
}
|
||||
else -> Assert.fail()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package com.baeldung.kotlin.arrow
|
||||
|
||||
import org.junit.Assert
|
||||
import org.junit.Test
|
||||
|
||||
class FunctionalErrorHandlingWithOptionTest {
|
||||
|
||||
val operator = FunctionalErrorHandlingWithOption()
|
||||
|
||||
@Test
|
||||
fun givenInvalidInput_thenErrorMessageIsPresent(){
|
||||
val useComputeOption = operator.computeWithOptionClient("foo")
|
||||
Assert.assertEquals("Not an even number!", useComputeOption)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenOddNumberInput_thenErrorMessageIsPresent(){
|
||||
val useComputeOption = operator.computeWithOptionClient("539")
|
||||
Assert.assertEquals("Not an even number!",useComputeOption)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenEvenNumberInputWithNonSquareNum_thenFalseMessageIsPresent(){
|
||||
val useComputeOption = operator.computeWithOptionClient("100")
|
||||
Assert.assertEquals("The greatest divisor is square number: false",useComputeOption)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenEvenNumberInputWithSquareNum_thenTrueMessageIsPresent(){
|
||||
val useComputeOption = operator.computeWithOptionClient("242")
|
||||
Assert.assertEquals("The greatest divisor is square number: true",useComputeOption)
|
||||
}
|
||||
|
||||
}
|
|
@ -720,11 +720,11 @@
|
|||
</dependencies>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<!-- <repository>
|
||||
<id>maven2-repository.dev.java.net</id>
|
||||
<name>Java.net repository</name>
|
||||
<url>http://download.java.net/maven/2</url>
|
||||
</repository>
|
||||
</repository> -->
|
||||
<repository>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<?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"
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.baeldung</groupId>
|
||||
|
@ -43,6 +44,12 @@
|
|||
<artifactId>disruptor</artifactId>
|
||||
<version>${disruptor.version}</version>
|
||||
</dependency>
|
||||
<!-- Webflux for reactive logging example -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-webflux</artifactId>
|
||||
<version>${spring-boot.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
|
@ -50,6 +57,7 @@
|
|||
<log4j-api.version>2.7</log4j-api.version>
|
||||
<log4j-core.version>2.7</log4j-core.version>
|
||||
<disruptor.version>3.3.6</disruptor.version>
|
||||
<spring-boot.version>2.1.0.RELEASE</spring-boot.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,21 @@
|
|||
package com.baeldung.webFluxLogging;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
public class WebFluxLoggingExample {
|
||||
|
||||
public static void main(String[] args) {
|
||||
Flux<Integer> reactiveStream = Flux.range(1, 5).log();
|
||||
|
||||
reactiveStream.subscribe();
|
||||
|
||||
reactiveStream = Flux.range(1, 5).log().take(3);
|
||||
|
||||
reactiveStream.subscribe();
|
||||
|
||||
reactiveStream = Flux.range(1, 5).take(3).log();
|
||||
|
||||
reactiveStream.subscribe();
|
||||
}
|
||||
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
## Relevant articles:
|
|
@ -77,7 +77,8 @@
|
|||
<rest-assured.version>3.1.0</rest-assured.version>
|
||||
<!-- plugins -->
|
||||
<thin.version>1.0.11.RELEASE</thin.version>
|
||||
<spring-boot.version>2.1.0.RELEASE</spring-boot.version>
|
||||
<oauth-auto.version>2.1.0.RELEASE</oauth-auto.version>
|
||||
<spring-boot.version>2.0.5.RELEASE</spring-boot.version>
|
||||
</properties>
|
||||
</project>
|
||||
|
||||
|
||||
|
|
|
@ -12,3 +12,4 @@
|
|||
- [The DAO Pattern in Java](http://www.baeldung.com/java-dao-pattern)
|
||||
- [Interpreter Design Pattern in Java](http://www.baeldung.com/java-interpreter-pattern)
|
||||
- [State Design Pattern in Java](https://www.baeldung.com/java-state-design-pattern)
|
||||
- [The Decorator Pattern in Java](https://www.baeldung.com/java-decorator-pattern)
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
package com.baeldung.jpa.entitygraph;
|
||||
|
||||
import com.baeldung.jpa.entitygraph.model.Post;
|
||||
import com.baeldung.jpa.entitygraph.repo.PostRepository;
|
||||
|
||||
public class MainApp {
|
||||
|
||||
public static void main(String... args) {
|
||||
Long postId = 1L;
|
||||
Post post = null;
|
||||
PostRepository postRepository = new PostRepository();
|
||||
|
||||
//Using EntityManager.find().
|
||||
post = postRepository.find(postId);
|
||||
post = postRepository.findWithEntityGraph(postId);
|
||||
post = postRepository.findWithEntityGraph2(postId);
|
||||
|
||||
//Using JPQL: Query and TypedQuery
|
||||
post = postRepository.findUsingJpql(postId);
|
||||
|
||||
//Using Criteria API
|
||||
post = postRepository.findUsingCriteria(postId);
|
||||
|
||||
postRepository.clean();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
package com.baeldung.jpa.entitygraph.model;
|
||||
|
||||
import javax.persistence.*;
|
||||
|
||||
@Entity
|
||||
public class Comment {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
private String reply;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn
|
||||
private Post post;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn
|
||||
private User user;
|
||||
//...
|
||||
|
||||
public Comment() {
|
||||
}
|
||||
|
||||
public Comment(String reply, Post post, User user) {
|
||||
this.reply = reply;
|
||||
this.post = post;
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getReply() {
|
||||
return reply;
|
||||
}
|
||||
|
||||
public void setReply(String reply) {
|
||||
this.reply = reply;
|
||||
}
|
||||
|
||||
public Post getPost() {
|
||||
return post;
|
||||
}
|
||||
|
||||
public void setPost(Post post) {
|
||||
this.post = post;
|
||||
}
|
||||
|
||||
public User getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
public void setUser(User user) {
|
||||
this.user = user;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
package com.baeldung.jpa.entitygraph.model;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@NamedEntityGraph(
|
||||
name = "post-entity-graph",
|
||||
attributeNodes = {
|
||||
@NamedAttributeNode("subject"),
|
||||
@NamedAttributeNode("user"),
|
||||
@NamedAttributeNode("comments"),
|
||||
}
|
||||
)
|
||||
@NamedEntityGraph(
|
||||
name = "post-entity-graph-with-comment-users",
|
||||
attributeNodes = {
|
||||
@NamedAttributeNode("subject"),
|
||||
@NamedAttributeNode("user"),
|
||||
@NamedAttributeNode(value = "comments", subgraph = "comments-subgraph"),
|
||||
},
|
||||
subgraphs = {
|
||||
@NamedSubgraph(
|
||||
name = "comments-subgraph",
|
||||
attributeNodes = {
|
||||
@NamedAttributeNode("user")
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
@Entity
|
||||
public class Post {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
private String subject;
|
||||
@OneToMany(mappedBy = "post")
|
||||
private List<Comment> comments = new ArrayList<>();
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn
|
||||
private User user;
|
||||
//...
|
||||
|
||||
public Post() {
|
||||
}
|
||||
|
||||
public Post(String subject, User user) {
|
||||
this.subject = subject;
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getSubject() {
|
||||
return subject;
|
||||
}
|
||||
|
||||
public void setSubject(String subject) {
|
||||
this.subject = subject;
|
||||
}
|
||||
|
||||
public List<Comment> getComments() {
|
||||
return comments;
|
||||
}
|
||||
|
||||
public void setComments(List<Comment> comments) {
|
||||
this.comments = comments;
|
||||
}
|
||||
|
||||
public User getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
public void setUser(User user) {
|
||||
this.user = user;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
package com.baeldung.jpa.entitygraph.model;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
|
||||
@Entity
|
||||
public class User {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
private String name;
|
||||
private String email;
|
||||
|
||||
//...
|
||||
|
||||
public User() {
|
||||
}
|
||||
|
||||
public User(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
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 getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
package com.baeldung.jpa.entitygraph.repo;
|
||||
|
||||
import com.baeldung.jpa.entitygraph.model.Post;
|
||||
|
||||
import javax.persistence.*;
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Root;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class PostRepository {
|
||||
private EntityManagerFactory emf = null;
|
||||
|
||||
|
||||
public PostRepository() {
|
||||
Map properties = new HashMap();
|
||||
properties.put("hibernate.show_sql", "true");
|
||||
properties.put("hibernate.format_sql", "true");
|
||||
emf = Persistence.createEntityManagerFactory("entity-graph-pu", properties);
|
||||
}
|
||||
|
||||
public Post find(Long id) {
|
||||
EntityManager entityManager = emf.createEntityManager();
|
||||
|
||||
Post post = entityManager.find(Post.class, id);
|
||||
|
||||
entityManager.close();
|
||||
return post;
|
||||
}
|
||||
|
||||
public Post findWithEntityGraph(Long id) {
|
||||
EntityManager entityManager = emf.createEntityManager();
|
||||
|
||||
EntityGraph entityGraph = entityManager.getEntityGraph("post-entity-graph");
|
||||
Map<String, Object> properties = new HashMap<>();
|
||||
properties.put("javax.persistence.fetchgraph", entityGraph);
|
||||
Post post = entityManager.find(Post.class, id, properties);
|
||||
|
||||
entityManager.close();
|
||||
return post;
|
||||
}
|
||||
|
||||
public Post findWithEntityGraph2(Long id) {
|
||||
EntityManager entityManager = emf.createEntityManager();
|
||||
|
||||
EntityGraph<Post> entityGraph = entityManager.createEntityGraph(Post.class);
|
||||
entityGraph.addAttributeNodes("subject");
|
||||
entityGraph.addAttributeNodes("user");
|
||||
entityGraph.addSubgraph("comments")
|
||||
.addAttributeNodes("user");
|
||||
|
||||
Map<String, Object> properties = new HashMap<>();
|
||||
properties.put("javax.persistence.fetchgraph", entityGraph);
|
||||
Post post = entityManager.find(Post.class, id, properties);
|
||||
|
||||
entityManager.close();
|
||||
return post;
|
||||
}
|
||||
|
||||
public Post findUsingJpql(Long id) {
|
||||
EntityManager entityManager = emf.createEntityManager();
|
||||
|
||||
EntityGraph entityGraph = entityManager.getEntityGraph("post-entity-graph-with-comment-users");
|
||||
Post post = entityManager.createQuery("Select p from Post p where p.id=:id", Post.class)
|
||||
.setParameter("id", id)
|
||||
.setHint("javax.persistence.fetchgraph", entityGraph)
|
||||
.getSingleResult();
|
||||
|
||||
entityManager.close();
|
||||
return post;
|
||||
}
|
||||
|
||||
public Post findUsingCriteria(Long id) {
|
||||
EntityManager entityManager = emf.createEntityManager();
|
||||
|
||||
EntityGraph entityGraph = entityManager.getEntityGraph("post-entity-graph-with-comment-users");
|
||||
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
|
||||
CriteriaQuery<Post> criteriaQuery = criteriaBuilder.createQuery(Post.class);
|
||||
Root<Post> root = criteriaQuery.from(Post.class);
|
||||
criteriaQuery.where(criteriaBuilder.equal(root.<Long>get("id"), id));
|
||||
TypedQuery<Post> typedQuery = entityManager.createQuery(criteriaQuery);
|
||||
typedQuery.setHint("javax.persistence.loadgraph", entityGraph);
|
||||
Post post = typedQuery.getSingleResult();
|
||||
|
||||
entityManager.close();
|
||||
return post;
|
||||
}
|
||||
|
||||
public void clean() {
|
||||
emf.close();
|
||||
}
|
||||
}
|
|
@ -3,13 +3,12 @@ package com.baeldung.jpa.stringcast;
|
|||
import javax.persistence.*;
|
||||
|
||||
@SqlResultSetMapping(name = "textQueryMapping", classes = {
|
||||
@ConstructorResult(targetClass = DummyEntity.class, columns = {
|
||||
@ConstructorResult(targetClass = Message.class, columns = {
|
||||
@ColumnResult(name = "text")
|
||||
})
|
||||
})
|
||||
@Entity
|
||||
@Table(name = "dummy")
|
||||
public class DummyEntity {
|
||||
public class Message {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
|
@ -17,11 +16,11 @@ public class DummyEntity {
|
|||
|
||||
private String text;
|
||||
|
||||
public DummyEntity() {
|
||||
public Message() {
|
||||
|
||||
}
|
||||
|
||||
public DummyEntity(String text) {
|
||||
public Message(String text) {
|
||||
this.text = text;
|
||||
}
|
||||
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
<persistence-unit name="jpa-h2">
|
||||
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
|
||||
<class>com.baeldung.jpa.stringcast.DummyEntity</class>
|
||||
<class>com.baeldung.jpa.stringcast.Message</class>
|
||||
<properties>
|
||||
<property name="javax.persistence.jdbc.driver" value="org.h2.Driver"/>
|
||||
<property name="javax.persistence.jdbc.url" value="jdbc:h2:mem:test"/>
|
||||
|
@ -49,4 +49,21 @@
|
|||
</properties>
|
||||
</persistence-unit>
|
||||
|
||||
<persistence-unit name="entity-graph-pu" transaction-type="RESOURCE_LOCAL">
|
||||
<class>com.baeldung.jpa.entitygraph.model.Post</class>
|
||||
<class>com.baeldung.jpa.entitygraph.model.User</class>
|
||||
<class>com.baeldung.jpa.entitygraph.model.Comment</class>
|
||||
<exclude-unlisted-classes>true</exclude-unlisted-classes>
|
||||
<properties>
|
||||
|
||||
<!--H2-->
|
||||
<property name="javax.persistence.jdbc.driver" value="org.h2.Driver"/>
|
||||
<property name="javax.persistence.jdbc.url"
|
||||
value="jdbc:h2:mem:entitygraphdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE"/>
|
||||
|
||||
<property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/>
|
||||
<property name="javax.persistence.sql-load-script-source" value="data-init.sql"/>
|
||||
</properties>
|
||||
</persistence-unit>
|
||||
|
||||
</persistence>
|
|
@ -0,0 +1,8 @@
|
|||
INSERT INTO `USER` (`ID`,`NAME`,`EMAIL`) VALUES (1,'user1','user1@test.com');
|
||||
INSERT INTO `USER` (`ID`,`NAME`,`EMAIL`) VALUES (2,'user2','user2@test.com');
|
||||
INSERT INTO `USER` (`ID`,`NAME`,`EMAIL`) VALUES (3,'user3','user3@test.com');
|
||||
|
||||
INSERT INTO `POST` (`ID`,`SUBJECT`,`USER_ID`) VALUES (1,'JPA Entity Graph In Action',1);
|
||||
|
||||
INSERT INTO `COMMENT` (`ID`,`REPLY`,`POST_ID`,`USER_ID`) VALUES (1,'Nice !!',1,2);
|
||||
INSERT INTO `COMMENT` (`ID`,`REPLY`,`POST_ID`,`USER_ID`) VALUES (2,'Cool !!',1,3);
|
|
@ -0,0 +1,68 @@
|
|||
package com.baeldung.jpa.entitygraph.repo;
|
||||
|
||||
import com.baeldung.jpa.entitygraph.model.Comment;
|
||||
import com.baeldung.jpa.entitygraph.model.Post;
|
||||
import com.baeldung.jpa.entitygraph.model.User;
|
||||
import org.hibernate.LazyInitializationException;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class PostRepositoryIntegrationTest {
|
||||
|
||||
private static PostRepository postRepository = null;
|
||||
|
||||
@BeforeClass
|
||||
public static void once() {
|
||||
postRepository = new PostRepository();
|
||||
}
|
||||
|
||||
@Test(expected = LazyInitializationException.class)
|
||||
public void find() {
|
||||
Post post = postRepository.find(1L);
|
||||
assertNotNull(post.getUser());
|
||||
String email = post.getUser().getEmail();
|
||||
assertNull(email);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findWithEntityGraph() {
|
||||
Post post = postRepository.findWithEntityGraph(1L);
|
||||
assertNotNull(post.getUser());
|
||||
String email = post.getUser().getEmail();
|
||||
assertNotNull(email);
|
||||
}
|
||||
|
||||
@Test(expected = LazyInitializationException.class)
|
||||
public void findWithEntityGraph_Comment_Without_User() {
|
||||
Post post = postRepository.findWithEntityGraph(1L);
|
||||
assertNotNull(post.getUser());
|
||||
String email = post.getUser().getEmail();
|
||||
assertNotNull(email);
|
||||
assertNotNull(post.getComments());
|
||||
assertEquals(post.getComments().size(), 2);
|
||||
Comment comment = post.getComments().get(0);
|
||||
assertNotNull(comment);
|
||||
User user = comment.getUser();
|
||||
user.getEmail();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findWithEntityGraph2_Comment_With_User() {
|
||||
Post post = postRepository.findWithEntityGraph2(1L);
|
||||
assertNotNull(post.getComments());
|
||||
assertEquals(post.getComments().size(), 2);
|
||||
Comment comment = post.getComments().get(0);
|
||||
assertNotNull(comment);
|
||||
User user = comment.getUser();
|
||||
assertNotNull(user);
|
||||
assertEquals(user.getEmail(), "user2@test.com");
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void destroy() {
|
||||
postRepository.clean();
|
||||
}
|
||||
}
|
|
@ -3,10 +3,7 @@ package com.baeldung.jpa.stringcast;
|
|||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import javax.persistence.EntityTransaction;
|
||||
import javax.persistence.Persistence;
|
||||
import javax.persistence.*;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
@ -22,18 +19,18 @@ public class SpringCastUnitTest {
|
|||
em = emFactory.createEntityManager();
|
||||
|
||||
// insert an object into the db
|
||||
DummyEntity dummyEntity = new DummyEntity();
|
||||
dummyEntity.setText("text");
|
||||
Message message = new Message();
|
||||
message.setText("text");
|
||||
|
||||
EntityTransaction tr = em.getTransaction();
|
||||
tr.begin();
|
||||
em.persist(dummyEntity);
|
||||
em.persist(message);
|
||||
tr.commit();
|
||||
}
|
||||
|
||||
@Test(expected = ClassCastException.class)
|
||||
public void givenExecutorNoCastCheck_whenQueryReturnsOneColumn_thenClassCastThrown() {
|
||||
List<String[]> results = QueryExecutor.executeNativeQueryNoCastCheck("select text from dummy", em);
|
||||
List<String[]> results = QueryExecutor.executeNativeQueryNoCastCheck("select text from message", em);
|
||||
|
||||
// fails
|
||||
for (String[] row : results) {
|
||||
|
@ -43,13 +40,13 @@ public class SpringCastUnitTest {
|
|||
|
||||
@Test
|
||||
public void givenExecutorWithCastCheck_whenQueryReturnsOneColumn_thenNoClassCastThrown() {
|
||||
List<String[]> results = QueryExecutor.executeNativeQueryWithCastCheck("select text from dummy", em);
|
||||
List<String[]> results = QueryExecutor.executeNativeQueryWithCastCheck("select text from message", em);
|
||||
assertEquals("text", results.get(0)[0]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenExecutorGeneric_whenQueryReturnsOneColumn_thenNoClassCastThrown() {
|
||||
List<DummyEntity> results = QueryExecutor.executeNativeQueryGeneric("select text from dummy", "textQueryMapping", em);
|
||||
List<Message> results = QueryExecutor.executeNativeQueryGeneric("select text from message", "textQueryMapping", em);
|
||||
assertEquals("text", results.get(0).getText());
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
<persistence-unit name="jpa-h2">
|
||||
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
|
||||
<class>com.baeldung.jpa.stringcast.DummyEntity</class>
|
||||
<class>com.baeldung.jpa.stringcast.Message</class>
|
||||
<properties>
|
||||
<property name="javax.persistence.jdbc.driver" value="org.h2.Driver" />
|
||||
<property name="javax.persistence.jdbc.url" value="jdbc:h2:mem:test" />
|
||||
|
|
|
@ -4,3 +4,4 @@
|
|||
- [Configuring Separate Spring DataSource for Tests](http://www.baeldung.com/spring-testing-separate-data-source)
|
||||
- [Quick Guide on data.sql and schema.sql Files in Spring Boot](http://www.baeldung.com/spring-boot-data-sql-and-schema-sql)
|
||||
- [Configuring a Tomcat Connection Pool in Spring Boot](https://www.baeldung.com/spring-boot-tomcat-connection-pool)
|
||||
- [Hibernate Field Naming with Spring Boot](https://www.baeldung.com/hibernate-field-naming-spring-boot)
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
- [Query Entities by Dates and Times with Spring Data JPA](https://www.baeldung.com/spring-data-jpa-query-by-date)
|
||||
- [DDD Aggregates and @DomainEvents](https://www.baeldung.com/spring-data-ddd)
|
||||
- [Spring Data – CrudRepository save() Method](https://www.baeldung.com/spring-data-crud-repository-save)
|
||||
- [Limiting Query Results with JPA and Spring Data JPA](https://www.baeldung.com/jpa-limit-query-results)
|
||||
|
||||
### Eclipse Config
|
||||
After importing the project into Eclipse, you may see the following error:
|
||||
|
|
|
@ -12,3 +12,4 @@
|
|||
- [Spring Data MongoDB: Projections and Aggregations](http://www.baeldung.com/spring-data-mongodb-projections-aggregations)
|
||||
- [Spring Data Annotations](http://www.baeldung.com/spring-data-annotations)
|
||||
- [Spring Data MongoDB Transactions](https://www.baeldung.com/spring-data-mongodb-transactions )
|
||||
- [ZonedDateTime with Spring Data MongoDB](https://www.baeldung.com/spring-data-mongodb-zoneddatetime)
|
||||
|
|
838
pom.xml
838
pom.xml
|
@ -739,6 +739,46 @@
|
|||
<module>helidon</module>
|
||||
</modules>
|
||||
|
||||
</profile>
|
||||
|
||||
<profile>
|
||||
<id>default-third</id>
|
||||
<build>
|
||||
<plugins>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>${maven-surefire-plugin.version}</version>
|
||||
<configuration>
|
||||
<forkCount>3</forkCount>
|
||||
<reuseForks>true</reuseForks>
|
||||
<excludes>
|
||||
<exclude>**/*IntegrationTest.java</exclude>
|
||||
<exclude>**/*IntTest.java</exclude>
|
||||
<exclude>**/*LongRunningUnitTest.java</exclude>
|
||||
<exclude>**/*ManualTest.java</exclude>
|
||||
<exclude>**/*JdbcTest.java</exclude>
|
||||
<exclude>**/*LiveTest.java</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<modules>
|
||||
<module>parent-boot-1</module>
|
||||
<module>parent-boot-2</module>
|
||||
<module>parent-spring-4</module>
|
||||
<module>parent-spring-5</module>
|
||||
<module>parent-java</module>
|
||||
<module>parent-kotlin</module>
|
||||
|
||||
<module>testing-modules/gatling</module>
|
||||
<!-- <module>geotools</module> --> <!-- the opengeo is down -->
|
||||
</modules>
|
||||
|
||||
</profile>
|
||||
|
||||
<profile>
|
||||
|
@ -896,6 +936,433 @@
|
|||
|
||||
</profile>
|
||||
|
||||
<profile>
|
||||
<id>integration-lite-first</id>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<excludes>
|
||||
<exclude>**/*ManualTest.java</exclude>
|
||||
<exclude>**/*LiveTest.java</exclude>
|
||||
</excludes>
|
||||
<includes>
|
||||
<include>**/*IntegrationTest.java</include>
|
||||
<include>**/*IntTest.java</include>
|
||||
</includes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<modules>
|
||||
<module>parent-boot-1</module>
|
||||
<module>parent-boot-2</module>
|
||||
<module>parent-spring-4</module>
|
||||
<module>parent-spring-5</module>
|
||||
<module>parent-java</module>
|
||||
<module>parent-kotlin</module>
|
||||
|
||||
<module>asm</module>
|
||||
<module>atomix</module>
|
||||
<module>aws</module>
|
||||
<module>aws-lambda</module>
|
||||
<module>akka-streams</module>
|
||||
<module>algorithms-genetic</module>
|
||||
<module>algorithms-miscellaneous-1</module>
|
||||
<module>algorithms-miscellaneous-2</module>
|
||||
<module>algorithms-sorting</module>
|
||||
<module>annotations</module>
|
||||
<module>apache-cxf</module>
|
||||
<module>apache-fop</module>
|
||||
<module>apache-poi</module>
|
||||
<module>apache-tika</module>
|
||||
<module>apache-thrift</module>
|
||||
<module>apache-curator</module>
|
||||
<module>apache-zookeeper</module>
|
||||
<module>apache-opennlp</module>
|
||||
<module>autovalue</module>
|
||||
<module>axon</module>
|
||||
<module>azure</module>
|
||||
<module>apache-velocity</module>
|
||||
<module>apache-solrj</module>
|
||||
<module>apache-meecrowave</module>
|
||||
<module>antlr</module>
|
||||
|
||||
<module>bootique</module>
|
||||
|
||||
<module>cdi</module>
|
||||
<module>core-java-collections</module>
|
||||
<module>core-java-io</module>
|
||||
<module>core-java-8</module>
|
||||
<module>core-groovy</module>
|
||||
<module>couchbase</module>
|
||||
|
||||
<module>dozer</module>
|
||||
<module>disruptor</module>
|
||||
<module>drools</module>
|
||||
<module>deeplearning4j</module>
|
||||
|
||||
<module>ethereum</module>
|
||||
|
||||
<module>feign</module>
|
||||
<module>flips</module>
|
||||
|
||||
<module>google-cloud</module>
|
||||
<module>gson</module>
|
||||
<module>guava</module>
|
||||
<module>guava-collections</module>
|
||||
<module>guava-modules/guava-18</module>
|
||||
<module>guava-modules/guava-19</module>
|
||||
<module>guava-modules/guava-21</module>
|
||||
<module>guice</module>
|
||||
|
||||
<module>hazelcast</module>
|
||||
<module>hystrix</module>
|
||||
<module>httpclient</module>
|
||||
|
||||
<module>image-processing</module>
|
||||
<module>immutables</module>
|
||||
|
||||
<module>jackson</module>
|
||||
<module>java-strings</module>
|
||||
<!--<module>core-java-9</module> --> <!-- Commented because we have still not upgraded to java 9 -->
|
||||
<module>java-collections-conversions</module>
|
||||
<module>java-collections-maps</module>
|
||||
<module>java-streams</module>
|
||||
<module>java-lite</module>
|
||||
<module>java-numbers</module>
|
||||
<module>java-rmi</module>
|
||||
<module>java-vavr-stream</module>
|
||||
<module>javax-servlets</module>
|
||||
<module>javaxval</module>
|
||||
<module>jaxb</module>
|
||||
<module>javafx</module>
|
||||
<module>jgroups</module>
|
||||
<module>jee-7</module>
|
||||
<module>jee-7-security</module>
|
||||
<module>jjwt</module>
|
||||
<module>jsf</module>
|
||||
<module>json-path</module>
|
||||
<module>json</module>
|
||||
<module>jsoup</module>
|
||||
<module>jta</module>
|
||||
<module>jws</module>
|
||||
<module>jersey</module>
|
||||
<module>java-spi</module>
|
||||
<module>java-ee-8-security-api</module>
|
||||
|
||||
<module>libraries-data</module>
|
||||
<module>linkrest</module>
|
||||
<module>logging-modules/log-mdc</module>
|
||||
<module>logging-modules/log4j</module>
|
||||
<module>logging-modules/logback</module>
|
||||
<module>lombok</module>
|
||||
<module>lucene</module>
|
||||
|
||||
<module>mapstruct</module>
|
||||
<module>maven</module>
|
||||
<module>mesos-marathon</module>
|
||||
<module>msf4j</module>
|
||||
<module>mustache</module>
|
||||
<module>mvn-wrapper</module>
|
||||
<module>mybatis</module>
|
||||
<module>metrics</module>
|
||||
<module>maven-archetype</module>
|
||||
|
||||
<module>noexception</module>
|
||||
|
||||
<module>osgi</module>
|
||||
<module>orika</module>
|
||||
|
||||
<module>patterns</module>
|
||||
<module>pdf</module>
|
||||
<module>protobuffer</module>
|
||||
<module>performance-tests</module>
|
||||
|
||||
<module>persistence-modules/java-jdbi</module>
|
||||
<module>persistence-modules/redis</module>
|
||||
<module>persistence-modules/orientdb</module>
|
||||
<module>persistence-modules/querydsl</module>
|
||||
<module>persistence-modules/apache-cayenne</module>
|
||||
<module>persistence-modules/solr</module>
|
||||
<module>persistence-modules/spring-data-dynamodb</module>
|
||||
<module>persistence-modules/spring-data-keyvalue</module>
|
||||
<module>persistence-modules/spring-data-neo4j</module>
|
||||
<module>persistence-modules/spring-data-solr</module>
|
||||
<module>persistence-modules/spring-hibernate-5</module>
|
||||
<module>persistence-modules/spring-data-eclipselink</module>
|
||||
<module>persistence-modules/spring-jpa</module>
|
||||
<module>persistence-modules/spring-hibernate-3</module>
|
||||
<module>persistence-modules/spring-data-gemfire</module>
|
||||
<module>persistence-modules/spring-boot-persistence</module>
|
||||
<module>persistence-modules/liquibase</module>
|
||||
<module>persistence-modules/java-cockroachdb</module>
|
||||
<module>persistence-modules/deltaspike</module>
|
||||
<module>persistence-modules/hbase</module>
|
||||
<module>persistence-modules/influxdb</module>
|
||||
<module>persistence-modules/spring-hibernate4</module>
|
||||
|
||||
<module>reactor-core</module>
|
||||
<module>resteasy</module>
|
||||
<module>rxjava</module>
|
||||
<module>rxjava-2</module>
|
||||
<module>rabbitmq</module>
|
||||
|
||||
<!-- very long running - temporarily disabled -->
|
||||
<!--
|
||||
<module>persistence-modules/spring-data-mongodb</module>
|
||||
-->
|
||||
|
||||
</modules>
|
||||
|
||||
</profile>
|
||||
|
||||
<profile>
|
||||
<id>integration-lite-second</id>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<excludes>
|
||||
<exclude>**/*ManualTest.java</exclude>
|
||||
<exclude>**/*LiveTest.java</exclude>
|
||||
</excludes>
|
||||
<includes>
|
||||
<include>**/*IntegrationTest.java</include>
|
||||
<include>**/*IntTest.java</include>
|
||||
</includes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<modules>
|
||||
<module>parent-boot-1</module>
|
||||
<module>parent-boot-2</module>
|
||||
<module>parent-spring-4</module>
|
||||
<module>parent-spring-5</module>
|
||||
<module>parent-java</module>
|
||||
<module>parent-kotlin</module>
|
||||
|
||||
<module>spring-4</module>
|
||||
<module>spring-5-reactive</module>
|
||||
<module>spring-5-reactive-security</module>
|
||||
<module>spring-5-reactive-client</module>
|
||||
<module>spring-5-mvc</module>
|
||||
<module>spring-5-security</module>
|
||||
<module>spring-5-security-oauth</module>
|
||||
<module>spring-activiti</module>
|
||||
<module>spring-akka</module>
|
||||
<module>spring-amqp</module>
|
||||
<module>spring-all</module>
|
||||
<module>spring-apache-camel</module>
|
||||
<module>spring-batch</module>
|
||||
<module>spring-bom</module>
|
||||
|
||||
<module>spring-boot-keycloak</module>
|
||||
<module>spring-boot-bootstrap</module>
|
||||
<module>spring-boot-admin</module>
|
||||
<module>spring-boot-camel</module>
|
||||
<module>spring-boot-security</module>
|
||||
<module>spring-boot-mvc</module>
|
||||
<module>spring-boot-logging-log4j2</module>
|
||||
<module>spring-boot-disable-console-logging</module>
|
||||
|
||||
<module>spring-cloud-data-flow</module>
|
||||
<module>spring-cloud</module>
|
||||
<module>spring-cloud-bus</module>
|
||||
<module>spring-core</module>
|
||||
<module>spring-cucumber</module>
|
||||
<module>spring-ejb</module>
|
||||
<module>spring-aop</module>
|
||||
|
||||
<module>spring-data-rest</module>
|
||||
<module>spring-dispatcher-servlet</module>
|
||||
<module>spring-exceptions</module>
|
||||
<module>spring-freemarker</module>
|
||||
|
||||
<module>spring-integration</module>
|
||||
<module>spring-jenkins-pipeline</module>
|
||||
<module>spring-jersey</module>
|
||||
|
||||
<module>spring-jms</module>
|
||||
<module>spring-jooq</module>
|
||||
<module>spring-kafka</module>
|
||||
<module>spring-katharsis</module>
|
||||
<module>spring-ldap</module>
|
||||
<module>spring-mockito</module>
|
||||
<module>spring-mvc-forms-jsp</module>
|
||||
<module>spring-mvc-forms-thymeleaf</module>
|
||||
<module>spring-mvc-java</module>
|
||||
<module>spring-mvc-velocity</module>
|
||||
<module>spring-mvc-webflow</module>
|
||||
<module>spring-mvc-xml</module>
|
||||
<module>spring-mvc-kotlin</module>
|
||||
<module>spring-protobuf</module>
|
||||
<module>spring-quartz</module>
|
||||
<module>spring-rest-angular</module>
|
||||
<module>spring-rest-full</module>
|
||||
<module>spring-rest-query-language</module>
|
||||
<module>spring-rest</module>
|
||||
<module>spring-resttemplate</module>
|
||||
<module>spring-rest-simple</module>
|
||||
<module>spring-security-acl</module>
|
||||
<module>spring-security-cache-control</module>
|
||||
<module>spring-security-client/spring-security-jsp-authentication</module>
|
||||
<module>spring-security-client/spring-security-jsp-authorize</module>
|
||||
<module>spring-security-client/spring-security-jsp-config</module>
|
||||
<module>spring-security-client/spring-security-mvc</module>
|
||||
<module>spring-security-client/spring-security-thymeleaf-authentication</module>
|
||||
<module>spring-security-client/spring-security-thymeleaf-authorize</module>
|
||||
<module>spring-security-client/spring-security-thymeleaf-config</module>
|
||||
<module>spring-security-core</module>
|
||||
<module>spring-security-mvc-boot</module>
|
||||
<module>spring-security-mvc-digest-auth</module>
|
||||
<module>spring-security-mvc-ldap</module>
|
||||
<module>spring-security-mvc-login</module>
|
||||
<module>spring-security-mvc-persisted-remember-me</module>
|
||||
<module>spring-security-mvc-session</module>
|
||||
<module>spring-security-mvc-socket</module>
|
||||
<module>spring-security-openid</module>
|
||||
<!--<module>spring-security-react</module> -->
|
||||
<module>spring-security-rest-basic-auth</module>
|
||||
<module>spring-security-rest-custom</module>
|
||||
<module>spring-security-rest</module>
|
||||
<module>spring-security-sso</module>
|
||||
<module>spring-security-x509</module>
|
||||
<module>spring-session</module>
|
||||
<module>spring-sleuth</module>
|
||||
<module>spring-social-login</module>
|
||||
<module>spring-spel</module>
|
||||
<module>spring-state-machine</module>
|
||||
<module>spring-thymeleaf</module>
|
||||
<module>spring-userservice</module>
|
||||
<module>spring-zuul</module>
|
||||
<module>spring-remoting</module>
|
||||
<module>spring-reactor</module>
|
||||
<module>spring-vertx</module>
|
||||
<module>spring-vault</module>
|
||||
<module>spring-jinq</module>
|
||||
<module>spring-rest-embedded-tomcat</module>
|
||||
|
||||
<module>spring-static-resources</module>
|
||||
<module>spring-swagger-codegen</module>
|
||||
<module>spring-drools</module>
|
||||
<module>spring-boot-property-exp</module>
|
||||
<module>spring-security-thymeleaf</module>
|
||||
<module>spring-boot-ctx-fluent</module>
|
||||
<module>spring-webflux-amqp</module>
|
||||
|
||||
<!-- very long running - temporarily disabled -->
|
||||
<!--
|
||||
<module>spring-amqp-simple</module>
|
||||
<module>spring-5-data-reactive</module>
|
||||
-->
|
||||
|
||||
</modules>
|
||||
|
||||
</profile>
|
||||
|
||||
<profile>
|
||||
<id>integration-lite-third</id>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<excludes>
|
||||
<exclude>**/*ManualTest.java</exclude>
|
||||
<exclude>**/*LiveTest.java</exclude>
|
||||
</excludes>
|
||||
<includes>
|
||||
<include>**/*IntegrationTest.java</include>
|
||||
<include>**/*IntTest.java</include>
|
||||
</includes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<modules>
|
||||
<module>parent-boot-1</module>
|
||||
<module>parent-boot-2</module>
|
||||
<module>parent-spring-4</module>
|
||||
<module>parent-spring-5</module>
|
||||
<module>parent-java</module>
|
||||
<module>parent-kotlin</module>
|
||||
|
||||
<module>spark-java</module>
|
||||
<module>saas</module>
|
||||
<module>struts-2</module>
|
||||
|
||||
<module>testing-modules/selenium-junit-testng</module>
|
||||
<module>testing-modules/groovy-spock</module>
|
||||
<module>testing-modules/mockito</module>
|
||||
<module>testing-modules/mockito-2</module>
|
||||
<module>testing-modules/mocks</module>
|
||||
<module>testing-modules/rest-assured</module>
|
||||
<module>testing-modules/rest-testing</module>
|
||||
<module>testing-modules/junit-5</module>
|
||||
<module>testing-modules/junit5-migration</module>
|
||||
<module>testing-modules/testing</module>
|
||||
<module>testing-modules/testng</module>
|
||||
<module>testing-modules/mockserver</module>
|
||||
<module>testing-modules/test-containers</module>
|
||||
<module>twilio</module>
|
||||
|
||||
<module>undertow</module>
|
||||
|
||||
<module>video-tutorials</module>
|
||||
<module>vaadin</module>
|
||||
<module>vertx-and-rxjava</module>
|
||||
<module>vraptor</module>
|
||||
<module>vertx</module>
|
||||
<module>vavr</module>
|
||||
|
||||
<module>xmlunit-2</module>
|
||||
<module>xml</module>
|
||||
|
||||
<!-- problematic -->
|
||||
<!--
|
||||
<module>persistence-modules/java-cassandra</module>
|
||||
<module>persistence-modules/spring-data-cassandra</module>
|
||||
<module>logging-modules/log4j2</module>
|
||||
<module>persistence-modules/spring-data-couchbase-2</module>
|
||||
<module>persistence-modules/spring-data-redis</module>
|
||||
|
||||
<module>jmeter</module>
|
||||
-->
|
||||
|
||||
<!-- heavy -->
|
||||
<!--
|
||||
<module>libraries</module>
|
||||
<module>geotools</module>
|
||||
<module>jhipster/jhipster-monolithic</module>
|
||||
<module>testing-modules/gatling</module>
|
||||
<module>spring-boot</module>
|
||||
<module>spring-boot-ops</module>
|
||||
<module>spring-5</module>
|
||||
<module>core-kotlin</module>
|
||||
<module>core-java</module>
|
||||
<module>google-web-toolkit</module>
|
||||
<module>spring-security-mvc-custom</module>
|
||||
<module>core-java-concurrency</module>
|
||||
-->
|
||||
|
||||
<!-- 30:32 min -->
|
||||
</modules>
|
||||
|
||||
</profile>
|
||||
|
||||
<profile>
|
||||
<id>integration</id>
|
||||
|
||||
|
@ -1201,375 +1668,6 @@
|
|||
|
||||
</profile>
|
||||
|
||||
<profile>
|
||||
<id>integration-lite-test</id>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<excludes>
|
||||
<exclude>**/*ManualTest.java</exclude>
|
||||
<exclude>**/*LiveTest.java</exclude>
|
||||
</excludes>
|
||||
<includes>
|
||||
<include>**/*IntegrationTest.java</include>
|
||||
<include>**/*IntTest.java</include>
|
||||
</includes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<modules>
|
||||
<module>parent-boot-1</module>
|
||||
<module>parent-boot-2</module>
|
||||
<module>parent-spring-4</module>
|
||||
<module>parent-spring-5</module>
|
||||
<module>parent-java</module>
|
||||
<module>parent-kotlin</module>
|
||||
|
||||
<module>spring-4</module>
|
||||
</modules>
|
||||
|
||||
</profile>
|
||||
|
||||
<profile>
|
||||
<id>integration-lite</id>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<excludes>
|
||||
<exclude>**/*ManualTest.java</exclude>
|
||||
<exclude>**/*LiveTest.java</exclude>
|
||||
</excludes>
|
||||
<includes>
|
||||
<include>**/*IntegrationTest.java</include>
|
||||
<include>**/*IntTest.java</include>
|
||||
</includes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<modules>
|
||||
<module>parent-boot-1</module>
|
||||
<module>parent-boot-2</module>
|
||||
<module>parent-spring-4</module>
|
||||
<module>parent-spring-5</module>
|
||||
<module>parent-java</module>
|
||||
<module>parent-kotlin</module>
|
||||
<module>asm</module>
|
||||
<module>atomix</module>
|
||||
<module>persistence-modules/apache-cayenne</module>
|
||||
<module>aws</module>
|
||||
<module>aws-lambda</module>
|
||||
<module>akka-streams</module>
|
||||
<module>algorithms-genetic</module>
|
||||
<module>algorithms-miscellaneous-1</module>
|
||||
<module>algorithms-miscellaneous-2</module>
|
||||
<module>algorithms-sorting</module>
|
||||
<module>annotations</module>
|
||||
<module>apache-cxf</module>
|
||||
<module>apache-fop</module>
|
||||
<module>apache-poi</module>
|
||||
<module>apache-tika</module>
|
||||
<module>apache-thrift</module>
|
||||
<module>apache-curator</module>
|
||||
<module>apache-zookeeper</module>
|
||||
<module>apache-opennlp</module>
|
||||
<module>autovalue</module>
|
||||
<module>axon</module>
|
||||
<module>azure</module>
|
||||
<module>bootique</module>
|
||||
<module>cdi</module>
|
||||
<module>java-strings</module>
|
||||
<!--<module>core-java-9</module> --> <!-- Commented because we have still not upgraded to java 9 -->
|
||||
<module>core-java-collections</module>
|
||||
<module>java-collections-conversions</module>
|
||||
<module>java-collections-maps</module>
|
||||
<module>core-java-io</module>
|
||||
<module>core-java-8</module>
|
||||
<module>java-streams</module>
|
||||
<module>core-groovy</module>
|
||||
|
||||
<module>couchbase</module>
|
||||
<module>persistence-modules/deltaspike</module>
|
||||
<module>dozer</module>
|
||||
<module>ethereum</module>
|
||||
<module>feign</module>
|
||||
<module>flips</module>
|
||||
<module>testing-modules/groovy-spock</module>
|
||||
<module>google-cloud</module>
|
||||
<module>gson</module>
|
||||
<module>guava</module>
|
||||
<module>guava-collections</module>
|
||||
<module>guava-modules/guava-18</module>
|
||||
<module>guava-modules/guava-19</module>
|
||||
<module>guava-modules/guava-21</module>
|
||||
<module>guice</module>
|
||||
<module>disruptor</module>
|
||||
<module>spring-static-resources</module>
|
||||
<module>hazelcast</module>
|
||||
<module>persistence-modules/hbase</module>
|
||||
|
||||
<module>hystrix</module>
|
||||
<module>image-processing</module>
|
||||
<module>immutables</module>
|
||||
<module>persistence-modules/influxdb</module>
|
||||
<module>jackson</module>
|
||||
<module>vavr</module>
|
||||
<module>java-lite</module>
|
||||
<module>java-numbers</module>
|
||||
<module>java-rmi</module>
|
||||
<module>java-vavr-stream</module>
|
||||
<module>javax-servlets</module>
|
||||
<module>javaxval</module>
|
||||
<module>jaxb</module>
|
||||
<module>javafx</module>
|
||||
<module>jgroups</module>
|
||||
<module>jee-7</module>
|
||||
<module>jee-7-security</module>
|
||||
<module>jjwt</module>
|
||||
<module>jsf</module>
|
||||
<module>json-path</module>
|
||||
<module>json</module>
|
||||
<module>jsoup</module>
|
||||
<module>jta</module>
|
||||
<module>testing-modules/junit-5</module>
|
||||
<module>testing-modules/junit5-migration</module>
|
||||
<module>jws</module>
|
||||
<module>libraries-data</module>
|
||||
<module>linkrest</module>
|
||||
<module>logging-modules/log-mdc</module>
|
||||
<module>logging-modules/log4j</module>
|
||||
|
||||
<module>logging-modules/logback</module>
|
||||
<module>lombok</module>
|
||||
<module>mapstruct</module>
|
||||
|
||||
<module>maven</module>
|
||||
<module>mesos-marathon</module>
|
||||
<module>msf4j</module>
|
||||
<module>testing-modules/mockito</module>
|
||||
<module>testing-modules/mockito-2</module>
|
||||
<module>testing-modules/mocks</module>
|
||||
<module>mustache</module>
|
||||
<module>mvn-wrapper</module>
|
||||
<module>noexception</module>
|
||||
<module>persistence-modules/orientdb</module>
|
||||
<module>osgi</module>
|
||||
<module>orika</module>
|
||||
<module>patterns</module>
|
||||
<module>pdf</module>
|
||||
<module>protobuffer</module>
|
||||
<module>persistence-modules/querydsl</module>
|
||||
<module>reactor-core</module>
|
||||
<module>persistence-modules/redis</module>
|
||||
<module>testing-modules/rest-assured</module>
|
||||
<module>testing-modules/rest-testing</module>
|
||||
<module>resteasy</module>
|
||||
<module>rxjava</module>
|
||||
<module>rxjava-2</module>
|
||||
<module>spring-swagger-codegen</module>
|
||||
<module>testing-modules/selenium-junit-testng</module>
|
||||
<module>persistence-modules/solr</module>
|
||||
<module>spark-java</module>
|
||||
<module>spring-4</module>
|
||||
<module>spring-5-data-reactive</module>
|
||||
<module>spring-5-reactive</module>
|
||||
<module>spring-5-reactive-security</module>
|
||||
<module>spring-5-reactive-client</module>
|
||||
<module>spring-5-mvc</module>
|
||||
<module>spring-5-security</module>
|
||||
<module>spring-5-security-oauth</module>
|
||||
<module>spring-activiti</module>
|
||||
<module>spring-akka</module>
|
||||
<module>spring-amqp</module>
|
||||
<module>spring-all</module>
|
||||
<module>spring-amqp-simple</module>
|
||||
<module>spring-apache-camel</module>
|
||||
<module>spring-batch</module>
|
||||
<module>spring-bom</module>
|
||||
<module>spring-boot-keycloak</module>
|
||||
<module>spring-boot-bootstrap</module>
|
||||
<module>spring-boot-admin</module>
|
||||
<module>spring-boot-camel</module>
|
||||
<module>persistence-modules/spring-boot-persistence</module>
|
||||
<module>spring-boot-security</module>
|
||||
<module>spring-boot-mvc</module>
|
||||
<module>spring-boot-logging-log4j2</module>
|
||||
<module>spring-boot-disable-console-logging</module>
|
||||
<module>spring-cloud-data-flow</module>
|
||||
<module>spring-cloud</module>
|
||||
<module>spring-cloud-bus</module>
|
||||
<module>spring-core</module>
|
||||
<module>spring-cucumber</module>
|
||||
<module>spring-ejb</module>
|
||||
<module>spring-aop</module>
|
||||
|
||||
<module>persistence-modules/spring-data-dynamodb</module>
|
||||
<module>persistence-modules/spring-data-keyvalue</module>
|
||||
<module>persistence-modules/spring-data-mongodb</module>
|
||||
<module>persistence-modules/spring-data-neo4j</module>
|
||||
|
||||
<module>spring-data-rest</module>
|
||||
<module>persistence-modules/spring-data-solr</module>
|
||||
<module>spring-dispatcher-servlet</module>
|
||||
<module>spring-exceptions</module>
|
||||
<module>spring-freemarker</module>
|
||||
<module>persistence-modules/spring-hibernate-3</module>
|
||||
|
||||
<module>persistence-modules/spring-hibernate-5</module>
|
||||
<module>persistence-modules/spring-data-eclipselink</module>
|
||||
<module>spring-integration</module>
|
||||
<module>spring-jenkins-pipeline</module>
|
||||
<module>spring-jersey</module>
|
||||
|
||||
<module>spring-jms</module>
|
||||
<module>spring-jooq</module>
|
||||
<module>persistence-modules/spring-jpa</module>
|
||||
<module>spring-kafka</module>
|
||||
<module>spring-katharsis</module>
|
||||
<module>spring-ldap</module>
|
||||
<module>spring-mockito</module>
|
||||
<module>spring-mvc-forms-jsp</module>
|
||||
<module>spring-mvc-forms-thymeleaf</module>
|
||||
<module>spring-mvc-java</module>
|
||||
<module>spring-mvc-velocity</module>
|
||||
<module>spring-mvc-webflow</module>
|
||||
<module>spring-mvc-xml</module>
|
||||
<module>spring-mvc-kotlin</module>
|
||||
<module>spring-protobuf</module>
|
||||
<module>spring-quartz</module>
|
||||
<module>spring-rest-angular</module>
|
||||
<module>spring-rest-full</module>
|
||||
<module>spring-rest-query-language</module>
|
||||
<module>spring-rest</module>
|
||||
<module>spring-resttemplate</module>
|
||||
<module>spring-rest-simple</module>
|
||||
<module>spring-security-acl</module>
|
||||
<module>spring-security-cache-control</module>
|
||||
<module>spring-security-client/spring-security-jsp-authentication</module>
|
||||
<module>spring-security-client/spring-security-jsp-authorize</module>
|
||||
<module>spring-security-client/spring-security-jsp-config</module>
|
||||
<module>spring-security-client/spring-security-mvc</module>
|
||||
<module>spring-security-client/spring-security-thymeleaf-authentication</module>
|
||||
<module>spring-security-client/spring-security-thymeleaf-authorize</module>
|
||||
<module>spring-security-client/spring-security-thymeleaf-config</module>
|
||||
<module>spring-security-core</module>
|
||||
<module>spring-security-mvc-boot</module>
|
||||
<module>spring-security-mvc-digest-auth</module>
|
||||
<module>spring-security-mvc-ldap</module>
|
||||
<module>spring-security-mvc-login</module>
|
||||
<module>spring-security-mvc-persisted-remember-me</module>
|
||||
<module>spring-security-mvc-session</module>
|
||||
<module>spring-security-mvc-socket</module>
|
||||
<module>spring-security-openid</module>
|
||||
<!--<module>spring-security-react</module> -->
|
||||
<module>spring-security-rest-basic-auth</module>
|
||||
<module>spring-security-rest-custom</module>
|
||||
<module>spring-security-rest</module>
|
||||
<module>spring-security-sso</module>
|
||||
<module>spring-security-x509</module>
|
||||
<module>spring-session</module>
|
||||
<module>spring-sleuth</module>
|
||||
<module>spring-social-login</module>
|
||||
<module>spring-spel</module>
|
||||
<module>spring-state-machine</module>
|
||||
<module>spring-thymeleaf</module>
|
||||
<module>spring-userservice</module>
|
||||
<module>spring-zuul</module>
|
||||
<module>spring-remoting</module>
|
||||
<module>spring-reactor</module>
|
||||
<module>spring-vertx</module>
|
||||
<module>spring-vault</module>
|
||||
<module>spring-jinq</module>
|
||||
<module>spring-rest-embedded-tomcat</module>
|
||||
<module>testing-modules/testing</module>
|
||||
<module>testing-modules/testng</module>
|
||||
<module>video-tutorials</module>
|
||||
|
||||
<module>xmlunit-2</module>
|
||||
<module>struts-2</module>
|
||||
<module>apache-velocity</module>
|
||||
<module>apache-solrj</module>
|
||||
<module>rabbitmq</module>
|
||||
|
||||
<module>persistence-modules/spring-data-gemfire</module>
|
||||
<module>mybatis</module>
|
||||
<module>spring-drools</module>
|
||||
<module>drools</module>
|
||||
<module>persistence-modules/liquibase</module>
|
||||
<module>spring-boot-property-exp</module>
|
||||
<module>testing-modules/mockserver</module>
|
||||
<module>testing-modules/test-containers</module>
|
||||
<module>undertow</module>
|
||||
<module>vaadin</module>
|
||||
<module>vertx-and-rxjava</module>
|
||||
<module>saas</module>
|
||||
<module>deeplearning4j</module>
|
||||
<module>lucene</module>
|
||||
<module>vraptor</module>
|
||||
<module>persistence-modules/java-cockroachdb</module>
|
||||
<module>spring-security-thymeleaf</module>
|
||||
<module>persistence-modules/java-jdbi</module>
|
||||
<module>jersey</module>
|
||||
<module>java-spi</module>
|
||||
<module>performance-tests</module>
|
||||
<module>twilio</module>
|
||||
<module>spring-boot-ctx-fluent</module>
|
||||
<module>java-ee-8-security-api</module>
|
||||
<module>spring-webflux-amqp</module>
|
||||
<module>antlr</module>
|
||||
<module>maven-archetype</module>
|
||||
<module>apache-meecrowave</module>
|
||||
|
||||
<module>persistence-modules/spring-hibernate4</module>
|
||||
<module>xml</module>
|
||||
<module>vertx</module>
|
||||
<module>metrics</module>
|
||||
<module>httpclient</module>
|
||||
|
||||
<!-- problematic -->
|
||||
<!--
|
||||
<module>ejb</module>
|
||||
<module>persistence-modules/java-cassandra</module>
|
||||
<module>persistence-modules/spring-data-cassandra</module>
|
||||
<module>logging-modules/log4j2</module>
|
||||
<module>persistence-modules/spring-data-couchbase-2</module>
|
||||
<module>persistence-modules/spring-data-redis</module>
|
||||
|
||||
<module>jmeter</module>
|
||||
-->
|
||||
|
||||
<!-- heavy -->
|
||||
<!--
|
||||
<module>libraries</module>
|
||||
<module>geotools</module>
|
||||
<module>jhipster/jhipster-monolithic</module>
|
||||
<module>testing-modules/gatling</module>
|
||||
<module>spring-boot</module>
|
||||
<module>spring-boot-ops</module>
|
||||
<module>spring-5</module>
|
||||
<module>core-kotlin</module>
|
||||
<module>core-java</module>
|
||||
<module>google-web-toolkit</module>
|
||||
<module>spring-security-mvc-custom</module>
|
||||
<module>core-java-concurrency</module>
|
||||
-->
|
||||
|
||||
<!-- 30:32 min -->
|
||||
</modules>
|
||||
|
||||
</profile>
|
||||
|
||||
<profile>
|
||||
<id>integration-heavy</id>
|
||||
|
||||
|
@ -1639,7 +1737,7 @@
|
|||
<gib.skipTestsForNotImpactedModules>true</gib.skipTestsForNotImpactedModules>
|
||||
<gib.failOnMissingGitDir>false</gib.failOnMissingGitDir>
|
||||
<gib.failOnError>false</gib.failOnError>
|
||||
<!-- <gib.enabled>false</gib.enabled> -->
|
||||
<gib.enabled>false</gib.enabled>
|
||||
|
||||
<junit.version>4.12</junit.version>
|
||||
<org.hamcrest.version>1.3</org.hamcrest.version>
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
### Relevant Articles:
|
||||
|
||||
- [Spring Security OAuth Login with WebFlux](https://www.baeldung.com/spring-oauth-login-webflux)
|
|
@ -8,8 +8,8 @@ import org.springframework.http.server.reactive.HttpHandler;
|
|||
import org.springframework.http.server.reactive.ReactorHttpHandlerAdapter;
|
||||
import org.springframework.web.reactive.config.EnableWebFlux;
|
||||
import org.springframework.web.server.adapter.WebHttpHandlerBuilder;
|
||||
import reactor.netty.DisposableServer;
|
||||
import reactor.netty.http.server.HttpServer;
|
||||
import reactor.ipc.netty.NettyContext;
|
||||
import reactor.ipc.netty.http.server.HttpServer;
|
||||
|
||||
@ComponentScan(basePackages = {"com.baeldung.reactive.security"})
|
||||
@EnableWebFlux
|
||||
|
@ -18,16 +18,17 @@ public class SpringSecurity5Application {
|
|||
public static void main(String[] args) {
|
||||
try (AnnotationConfigApplicationContext context =
|
||||
new AnnotationConfigApplicationContext(SpringSecurity5Application.class)) {
|
||||
context.getBean(DisposableServer.class).onDispose().block();
|
||||
context.getBean(NettyContext.class).onClose().block();
|
||||
}
|
||||
}
|
||||
|
||||
@Bean
|
||||
public DisposableServer nettyContext(ApplicationContext context) {
|
||||
public NettyContext nettyContext(ApplicationContext context) {
|
||||
HttpHandler handler = WebHttpHandlerBuilder.applicationContext(context)
|
||||
.build();
|
||||
ReactorHttpHandlerAdapter adapter = new ReactorHttpHandlerAdapter(handler);
|
||||
return HttpServer.create().host("localhost").port(8080).handle(adapter).bind().block();
|
||||
HttpServer httpServer = HttpServer.create("localhost", 8080);
|
||||
return httpServer.newHandler(adapter).block();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -10,8 +10,8 @@ import org.springframework.web.reactive.function.server.RouterFunctions;
|
|||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.netty.DisposableServer;
|
||||
import reactor.netty.http.server.HttpServer;
|
||||
import reactor.ipc.netty.NettyContext;
|
||||
import reactor.ipc.netty.http.server.HttpServer;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
|
@ -19,11 +19,11 @@ import static org.springframework.web.reactive.function.server.RequestPredicates
|
|||
import static org.springframework.web.reactive.function.server.RequestPredicates.POST;
|
||||
|
||||
public class Spring5ReactiveServerClientIntegrationTest {
|
||||
private static DisposableServer nettyServer;
|
||||
private static NettyContext nettyContext;
|
||||
|
||||
@BeforeAll
|
||||
public static void setUp() throws Exception {
|
||||
HttpServer server = HttpServer.create().host("localhost").port(8080);
|
||||
HttpServer server = HttpServer.create("localhost", 8080);
|
||||
RouterFunction<?> route = RouterFunctions.route(POST("/task/process"), request -> ServerResponse.ok()
|
||||
.body(request.bodyToFlux(Task.class)
|
||||
.map(ll -> new Task("TaskName", 1)), Task.class))
|
||||
|
@ -31,12 +31,13 @@ public class Spring5ReactiveServerClientIntegrationTest {
|
|||
.body(Mono.just("server is alive"), String.class)));
|
||||
HttpHandler httpHandler = RouterFunctions.toHttpHandler(route);
|
||||
ReactorHttpHandlerAdapter adapter = new ReactorHttpHandlerAdapter(httpHandler);
|
||||
nettyServer = server.handle(adapter).bind().block();
|
||||
nettyContext = server.newHandler(adapter)
|
||||
.block();
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
public static void shutDown() {
|
||||
nettyServer.dispose();
|
||||
nettyContext.dispose();
|
||||
}
|
||||
|
||||
// @Test
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.thymeleaf.extras</groupId>
|
||||
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
|
||||
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- oauth2 -->
|
||||
|
@ -65,4 +65,8 @@
|
|||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<oauth-auto.version>2.0.5.RELEASE</oauth-auto.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
|
|
|
@ -12,7 +12,7 @@ import org.springframework.core.env.Environment;
|
|||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||
import org.springframework.security.config.oauth2.client.CommonOAuth2Provider;
|
||||
import org.springframework.security.oauth2.client.endpoint.DefaultAuthorizationCodeTokenResponseClient;
|
||||
import org.springframework.security.oauth2.client.endpoint.NimbusAuthorizationCodeTokenResponseClient;
|
||||
import org.springframework.security.oauth2.client.endpoint.OAuth2AccessTokenResponseClient;
|
||||
import org.springframework.security.oauth2.client.endpoint.OAuth2AuthorizationCodeGrantRequest;
|
||||
import org.springframework.security.oauth2.client.registration.ClientRegistration;
|
||||
|
@ -54,7 +54,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
|||
|
||||
@Bean
|
||||
public OAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> accessTokenResponseClient() {
|
||||
return new DefaultAuthorizationCodeTokenResponseClient();
|
||||
return new NimbusAuthorizationCodeTokenResponseClient();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -31,9 +31,8 @@
|
|||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.thymeleaf.extras</groupId>
|
||||
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
|
||||
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
|
|
|
@ -33,3 +33,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring
|
|||
- [Spring Cache – Creating a Custom KeyGenerator](http://www.baeldung.com/spring-cache-custom-keygenerator)
|
||||
- [Spring @Primary Annotation](http://www.baeldung.com/spring-primary)
|
||||
- [Spring Events](https://www.baeldung.com/spring-events)
|
||||
- [Spring Null-Safety Annotations](https://www.baeldung.com/spring-null-safety-annotations)
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>spring-amqp-simple</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<name>Spring AMQP Simple App</name>
|
||||
|
||||
<parent>
|
||||
<artifactId>parent-boot-1</artifactId>
|
||||
|
|
|
@ -79,6 +79,11 @@
|
|||
<artifactId>graphql-java-tools</artifactId>
|
||||
<version>${graphql-java-tools.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.graphql-java</groupId>
|
||||
<artifactId>graphiql-spring-boot-starter</artifactId>
|
||||
<version>${graphiql-spring-boot-starter.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
|
@ -249,8 +254,9 @@
|
|||
<togglz.version>2.4.1.Final</togglz.version>
|
||||
<rome.version>1.9.0</rome.version>
|
||||
<chaos.monkey.version>2.0.0</chaos.monkey.version>
|
||||
<graphql-spring-boot-starter.version>3.6.0</graphql-spring-boot-starter.version>
|
||||
<graphql-java-tools.version>3.2.0</graphql-java-tools.version>
|
||||
<graphql-spring-boot-starter.version>5.0.2</graphql-spring-boot-starter.version>
|
||||
<graphiql-spring-boot-starter.version>5.0.2</graphiql-spring-boot-starter.version>
|
||||
<graphql-java-tools.version>5.2.4</graphql-java-tools.version>
|
||||
<guava.version>18.0</guava.version>
|
||||
<git-commit-id-plugin.version>2.2.4</git-commit-id-plugin.version>
|
||||
</properties>
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
org.springframework.boot.diagnostics.FailureAnalyzer=com.baeldung.failureanalyzer.MyBeanNotOfRequiredTypeFailureAnalyzer
|
|
@ -0,0 +1,47 @@
|
|||
package com.baeldung.failureanalyzer;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
|
||||
import com.baeldung.failureanalyzer.utils.ListAppender;
|
||||
|
||||
import ch.qos.logback.classic.spi.ILoggingEvent;
|
||||
|
||||
public class FailureAnalyzerAppIntegrationTest {
|
||||
|
||||
private static final String EXPECTED_ANALYSIS_DESCRIPTION_TITLE = "Description:";
|
||||
private static final String EXPECTED_ANALYSIS_DESCRIPTION_CONTENT = "The bean myDAO could not be injected as com.baeldung.failureanalyzer.MyDAO because it is of type com.baeldung.failureanalyzer.MySecondDAO";
|
||||
private static final String EXPECTED_ANALYSIS_ACTION_TITLE = "Action:";
|
||||
private static final String EXPECTED_ANALYSIS_ACTION_CONTENT = "Consider creating a bean with name myDAO of type com.baeldung.failureanalyzer.MyDAO";
|
||||
|
||||
@BeforeEach
|
||||
public void clearLogList() {
|
||||
ListAppender.clearEventList();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenBeanCreationErrorInContext_whenContextLoaded_thenFailureAnalyzerLogsReport() {
|
||||
try {
|
||||
SpringApplication.run(FailureAnalyzerApplication.class);
|
||||
} catch (BeanCreationException e) {
|
||||
Collection<String> allLoggedEntries = ListAppender.getEvents()
|
||||
.stream()
|
||||
.map(ILoggingEvent::getFormattedMessage)
|
||||
.collect(Collectors.toList());
|
||||
assertThat(allLoggedEntries).anyMatch(entry -> entry.contains(EXPECTED_ANALYSIS_DESCRIPTION_TITLE))
|
||||
.anyMatch(entry -> entry.contains(EXPECTED_ANALYSIS_DESCRIPTION_CONTENT))
|
||||
.anyMatch(entry -> entry.contains(EXPECTED_ANALYSIS_ACTION_TITLE))
|
||||
.anyMatch(entry -> entry.contains(EXPECTED_ANALYSIS_ACTION_CONTENT));
|
||||
return;
|
||||
}
|
||||
throw new IllegalStateException("Context load should be failing due to a BeanCreationException!");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package com.baeldung.failureanalyzer.utils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import ch.qos.logback.classic.spi.ILoggingEvent;
|
||||
import ch.qos.logback.core.AppenderBase;
|
||||
|
||||
public class ListAppender extends AppenderBase<ILoggingEvent> {
|
||||
|
||||
static private List<ILoggingEvent> events = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
protected void append(ILoggingEvent eventObject) {
|
||||
events.add(eventObject);
|
||||
}
|
||||
|
||||
public static List<ILoggingEvent> getEvents() {
|
||||
return events;
|
||||
}
|
||||
|
||||
public static void clearEventList() {
|
||||
events.clear();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<include
|
||||
resource="org/springframework/boot/logging/logback/base.xml" />
|
||||
<appender name="LISTAPPENDER"
|
||||
class="com.baeldung.failureanalyzer.utils.ListAppender">
|
||||
</appender>
|
||||
<logger
|
||||
name="org.springframework.boot.diagnostics.LoggingFailureAnalysisReporter">
|
||||
<appender-ref ref="LISTAPPENDER" />
|
||||
</logger>
|
||||
<root level="info">
|
||||
<appender-ref ref="CONSOLE" />
|
||||
</root>
|
||||
</configuration>
|
|
@ -30,3 +30,4 @@
|
|||
- [Introduction to Netflix Archaius with Spring Cloud](https://www.baeldung.com/netflix-archaius-spring-cloud-integration)
|
||||
- [An Intro to Spring Cloud Vault](https://www.baeldung.com/spring-cloud-vault)
|
||||
- [Netflix Archaius with Various Database Configurations](https://www.baeldung.com/netflix-archaius-database-configurations)
|
||||
- [Rate Limiting in Spring Cloud Netflix Zuul](https://www.baeldung.com/spring-cloud-zuul-rate-limit)
|
||||
|
|
|
@ -20,3 +20,4 @@ To view the running application, visit [http://localhost:8080](http://localhost:
|
|||
- [List of In-Memory Databases](http://www.baeldung.com/java-in-memory-databases)
|
||||
- [Projections and Excerpts in Spring Data REST](http://www.baeldung.com/spring-data-rest-projections-excerpts)
|
||||
- [Spring Data REST Events with @RepositoryEventHandler](http://www.baeldung.com/spring-data-rest-events)
|
||||
- [Customizing HTTP Endpoints in Spring Data REST](https://www.baeldung.com/spring-data-rest-customize-http-endpoints)
|
||||
|
|
|
@ -42,4 +42,8 @@
|
|||
<finalName>${project.artifactId}</finalName>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<spring-boot.version>2.1.0.RELEASE</spring-boot.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
package com.baeldung.subflows.discardflow;
|
||||
|
||||
import java.util.Collection;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.integration.annotation.Gateway;
|
||||
import org.springframework.integration.annotation.IntegrationComponentScan;
|
||||
import org.springframework.integration.annotation.MessagingGateway;
|
||||
import org.springframework.integration.channel.QueueChannel;
|
||||
import org.springframework.integration.config.EnableIntegration;
|
||||
import org.springframework.integration.dsl.IntegrationFlow;
|
||||
|
||||
@EnableIntegration
|
||||
@IntegrationComponentScan
|
||||
public class FilterExample {
|
||||
@MessagingGateway
|
||||
public interface NumbersClassifier {
|
||||
@Gateway(requestChannel = "classify.input")
|
||||
void classify(Collection<Integer> numbers);
|
||||
}
|
||||
|
||||
@Bean
|
||||
QueueChannel multipleofThreeChannel() {
|
||||
return new QueueChannel();
|
||||
}
|
||||
|
||||
@Bean
|
||||
QueueChannel remainderIsOneChannel() {
|
||||
return new QueueChannel();
|
||||
}
|
||||
|
||||
@Bean
|
||||
QueueChannel remainderIsTwoChannel() {
|
||||
return new QueueChannel();
|
||||
}
|
||||
boolean isMultipleOfThree(Integer number) {
|
||||
return number % 3 == 0;
|
||||
}
|
||||
|
||||
boolean isRemainderOne(Integer number) {
|
||||
return number % 3 == 1;
|
||||
}
|
||||
|
||||
boolean isRemainderTwo(Integer number) {
|
||||
return number % 3 == 2;
|
||||
}
|
||||
@Bean
|
||||
public IntegrationFlow classify() {
|
||||
return flow -> flow.split()
|
||||
.<Integer> filter(this::isMultipleOfThree, notMultiple -> notMultiple
|
||||
.discardFlow(oneflow -> oneflow
|
||||
.<Integer> filter(this::isRemainderOne,
|
||||
twoflow -> twoflow .discardChannel("remainderIsTwoChannel"))
|
||||
.channel("remainderIsOneChannel")))
|
||||
.channel("multipleofThreeChannel");
|
||||
}
|
||||
|
||||
}
|
|
@ -1,15 +1,13 @@
|
|||
package com.baeldung.subflows.publishsubscribechannel;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.integration.annotation.Gateway;
|
||||
import org.springframework.integration.annotation.IntegrationComponentScan;
|
||||
import org.springframework.integration.annotation.MessagingGateway;
|
||||
import org.springframework.integration.channel.DirectChannel;
|
||||
|
||||
import org.springframework.integration.channel.QueueChannel;
|
||||
import org.springframework.integration.config.EnableIntegration;
|
||||
import org.springframework.integration.dsl.IntegrationFlow;
|
||||
|
||||
|
@ -18,46 +16,45 @@ import org.springframework.integration.dsl.IntegrationFlow;
|
|||
public class PublishSubscibeChannelExample {
|
||||
@MessagingGateway
|
||||
public interface NumbersClassifier {
|
||||
@Gateway(requestChannel = "flow.input")
|
||||
void flow(Collection<Integer> numbers);
|
||||
@Gateway(requestChannel = "classify.input")
|
||||
void classify(Collection<Integer> numbers);
|
||||
}
|
||||
|
||||
@Bean
|
||||
DirectChannel multipleof3Channel() {
|
||||
return new DirectChannel();
|
||||
QueueChannel multipleofThreeChannel() {
|
||||
return new QueueChannel();
|
||||
}
|
||||
|
||||
@Bean
|
||||
DirectChannel remainderIs1Channel() {
|
||||
return new DirectChannel();
|
||||
QueueChannel remainderIsOneChannel() {
|
||||
return new QueueChannel();
|
||||
}
|
||||
|
||||
@Bean
|
||||
DirectChannel remainderIs2Channel() {
|
||||
return new DirectChannel();
|
||||
QueueChannel remainderIsTwoChannel() {
|
||||
return new QueueChannel();
|
||||
}
|
||||
boolean isMultipleOfThree(Integer number) {
|
||||
return number % 3 == 0;
|
||||
}
|
||||
|
||||
boolean isRemainderOne(Integer number) {
|
||||
return number % 3 == 1;
|
||||
}
|
||||
|
||||
boolean isRemainderTwo(Integer number) {
|
||||
return number % 3 == 2;
|
||||
}
|
||||
@Bean
|
||||
public IntegrationFlow flow() {
|
||||
public IntegrationFlow classify() {
|
||||
return flow -> flow.split()
|
||||
.publishSubscribeChannel(s -> s.subscribe(f -> f.<Integer> filter(p -> p % 3 == 0)
|
||||
.channel("multipleof3Channel"))
|
||||
.subscribe(f -> f.<Integer> filter(p -> p % 3 == 1)
|
||||
.channel("remainderIs1Channel"))
|
||||
.subscribe(f -> f.<Integer> filter(p -> p % 3 == 2)
|
||||
.channel("remainderIs2Channel")));
|
||||
.publishSubscribeChannel(subscription -> subscription.subscribe(subflow -> subflow.<Integer> filter(this::isMultipleOfThree)
|
||||
.channel("multipleofThreeChannel"))
|
||||
.subscribe(subflow -> subflow.<Integer> filter(this::isRemainderOne)
|
||||
.channel("remainderIsOneChannel"))
|
||||
.subscribe(subflow -> subflow.<Integer> filter(this::isRemainderTwo)
|
||||
.channel("remainderIsTwoChannel")));
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
final ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext(PublishSubscibeChannelExample.class);
|
||||
DirectChannel multipleof3Channel = ctx.getBean("multipleof3Channel", DirectChannel.class);
|
||||
multipleof3Channel.subscribe(x -> System.out.println("multipleof3Channel: " + x));
|
||||
DirectChannel remainderIs1Channel = ctx.getBean("remainderIs1Channel", DirectChannel.class);
|
||||
remainderIs1Channel.subscribe(x -> System.out.println("remainderIs1Channel: " + x));
|
||||
DirectChannel remainderIs2Channel = ctx.getBean("remainderIs2Channel", DirectChannel.class);
|
||||
remainderIs2Channel.subscribe(x -> System.out.println("remainderIs2Channel: " + x));
|
||||
ctx.getBean(NumbersClassifier.class)
|
||||
.flow(Arrays.asList(1, 2, 3, 4, 5, 6));
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,15 +1,12 @@
|
|||
package com.baeldung.subflows.routeToRecipients;
|
||||
package com.baeldung.subflows.routetorecipients;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.integration.annotation.Gateway;
|
||||
import org.springframework.integration.annotation.IntegrationComponentScan;
|
||||
import org.springframework.integration.annotation.MessagingGateway;
|
||||
import org.springframework.integration.channel.DirectChannel;
|
||||
import org.springframework.integration.channel.QueueChannel;
|
||||
import org.springframework.integration.config.EnableIntegration;
|
||||
import org.springframework.integration.dsl.IntegrationFlow;
|
||||
|
||||
|
@ -18,44 +15,46 @@ import org.springframework.integration.dsl.IntegrationFlow;
|
|||
public class RouteToRecipientsExample {
|
||||
@MessagingGateway
|
||||
public interface NumbersClassifier {
|
||||
@Gateway(requestChannel = "flow.input")
|
||||
void flow(Collection<Integer> numbers);
|
||||
@Gateway(requestChannel = "classify.input")
|
||||
void classify(Collection<Integer> numbers);
|
||||
}
|
||||
|
||||
@Bean
|
||||
DirectChannel multipleof3Channel() {
|
||||
return new DirectChannel();
|
||||
QueueChannel multipleofThreeChannel() {
|
||||
return new QueueChannel();
|
||||
}
|
||||
|
||||
@Bean
|
||||
DirectChannel remainderIs1Channel() {
|
||||
return new DirectChannel();
|
||||
QueueChannel remainderIsOneChannel() {
|
||||
return new QueueChannel();
|
||||
}
|
||||
|
||||
@Bean
|
||||
DirectChannel remainderIs2Channel() {
|
||||
return new DirectChannel();
|
||||
QueueChannel remainderIsTwoChannel() {
|
||||
return new QueueChannel();
|
||||
}
|
||||
boolean isMultipleOfThree(Integer number) {
|
||||
return number % 3 == 0;
|
||||
}
|
||||
|
||||
boolean isRemainderOne(Integer number) {
|
||||
return number % 3 == 1;
|
||||
}
|
||||
|
||||
boolean isRemainderTwo(Integer number) {
|
||||
return number % 3 == 2;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public IntegrationFlow flow() {
|
||||
public IntegrationFlow classify() {
|
||||
return flow -> flow.split()
|
||||
.routeToRecipients(r -> r.<Integer> recipient("multipleof3Channel", p -> p % 3 == 0)// filter
|
||||
.<Integer> recipient("remainderIs1Channel", p -> p % 3 == 1)
|
||||
.recipientFlow(sf -> sf.<Integer> filter(p -> p % 3 == 2)
|
||||
.channel("remainderIs2Channel")));
|
||||
.routeToRecipients(route -> route
|
||||
.recipientFlow(subflow -> subflow
|
||||
.<Integer> filter(this::isMultipleOfThree)
|
||||
.channel("multipleofThreeChannel"))
|
||||
.<Integer> recipient("remainderIsOneChannel",this::isRemainderOne)
|
||||
.<Integer> recipient("remainderIsTwoChannel",this::isRemainderTwo));
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
final ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext(RouteToRecipientsExample.class);
|
||||
DirectChannel multipleof3Channel = ctx.getBean("multipleof3Channel", DirectChannel.class);
|
||||
multipleof3Channel.subscribe(x -> System.out.println("multipleof3Channel: " + x));
|
||||
DirectChannel remainderIs1Channel = ctx.getBean("remainderIs1Channel", DirectChannel.class);
|
||||
remainderIs1Channel.subscribe(x -> System.out.println("remainderIs1Channel: " + x));
|
||||
DirectChannel remainderIs2Channel = ctx.getBean("remainderIs2Channel", DirectChannel.class);
|
||||
remainderIs2Channel.subscribe(x -> System.out.println("remainderIs2Channel: " + x));
|
||||
ctx.getBean(NumbersClassifier.class)
|
||||
.flow(Arrays.asList(1, 2, 3, 4, 5, 6));
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,15 +1,13 @@
|
|||
package com.baeldung.subflows.separateflows;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.integration.annotation.Gateway;
|
||||
import org.springframework.integration.annotation.IntegrationComponentScan;
|
||||
import org.springframework.integration.annotation.MessagingGateway;
|
||||
import org.springframework.integration.channel.DirectChannel;
|
||||
|
||||
import org.springframework.integration.channel.QueueChannel;
|
||||
import org.springframework.integration.config.EnableIntegration;
|
||||
import org.springframework.integration.dsl.IntegrationFlow;
|
||||
|
||||
|
@ -18,66 +16,62 @@ import org.springframework.integration.dsl.IntegrationFlow;
|
|||
public class SeparateFlowsExample {
|
||||
@MessagingGateway
|
||||
public interface NumbersClassifier {
|
||||
@Gateway(requestChannel = "multipleof3Flow.input")
|
||||
void multipleof3(Collection<Integer> is);
|
||||
@Gateway(requestChannel = "multipleOfThreeFlow.input")
|
||||
void multipleofThree(Collection<Integer> numbers);
|
||||
|
||||
@Gateway(requestChannel = "remainderIs1Flow.input")
|
||||
void remainderIs1(Collection<Integer> is);
|
||||
@Gateway(requestChannel = "remainderIsOneFlow.input")
|
||||
void remainderIsOne(Collection<Integer> numbers);
|
||||
|
||||
@Gateway(requestChannel = "remainderIs2Flow.input")
|
||||
void remainderIs2(Collection<Integer> numbers);
|
||||
@Gateway(requestChannel = "remainderIsTwoFlow.input")
|
||||
void remainderIsTwo(Collection<Integer> numbers);
|
||||
}
|
||||
|
||||
@Bean
|
||||
DirectChannel multipleof3Channel() {
|
||||
return new DirectChannel();
|
||||
QueueChannel multipleOfThreeChannel() {
|
||||
return new QueueChannel();
|
||||
}
|
||||
|
||||
@Bean
|
||||
DirectChannel remainderIs1Channel() {
|
||||
return new DirectChannel();
|
||||
QueueChannel remainderIsOneChannel() {
|
||||
return new QueueChannel();
|
||||
}
|
||||
|
||||
@Bean
|
||||
DirectChannel remainderIs2Channel() {
|
||||
return new DirectChannel();
|
||||
QueueChannel remainderIsTwoChannel() {
|
||||
return new QueueChannel();
|
||||
}
|
||||
|
||||
boolean isMultipleOfThree(Integer number) {
|
||||
return number % 3 == 0;
|
||||
}
|
||||
|
||||
boolean isRemainderOne(Integer number) {
|
||||
return number % 3 == 1;
|
||||
}
|
||||
|
||||
boolean isRemainderTwo(Integer number) {
|
||||
return number % 3 == 2;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public IntegrationFlow multipleof3Flow() {
|
||||
return f -> f.split()
|
||||
.<Integer> filter(p -> p % 3 == 0)
|
||||
.channel("multipleof3Channel");
|
||||
public IntegrationFlow multipleOfThreeFlow() {
|
||||
return flow -> flow.split()
|
||||
.<Integer> filter(this::isMultipleOfThree)
|
||||
.channel("multipleOfThreeChannel");
|
||||
}
|
||||
|
||||
@Bean
|
||||
public IntegrationFlow remainderIs1Flow() {
|
||||
return f -> f.split()
|
||||
.<Integer> filter(p -> p % 3 == 1)
|
||||
.channel("remainderIs1Channel");
|
||||
public IntegrationFlow remainderIsOneFlow() {
|
||||
return flow -> flow.split()
|
||||
.<Integer> filter(this::isRemainderOne)
|
||||
.channel("remainderIsOneChannel");
|
||||
}
|
||||
|
||||
@Bean
|
||||
public IntegrationFlow remainderIs2Flow() {
|
||||
return f -> f.split()
|
||||
.<Integer> filter(p -> p % 3 == 2)
|
||||
.channel("remainderIs2Channel");
|
||||
public IntegrationFlow remainderIsTwoFlow() {
|
||||
return flow -> flow.split()
|
||||
.<Integer> filter(this::isRemainderTwo)
|
||||
.channel("remainderIsTwoChannel");
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
final ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext(SeparateFlowsExample.class);
|
||||
DirectChannel multipleof3Channel = ctx.getBean("multipleof3Channel", DirectChannel.class);
|
||||
multipleof3Channel.subscribe(x -> System.out.println("multipleof3Channel: " + x));
|
||||
DirectChannel remainderIs1Channel = ctx.getBean("remainderIs1Channel", DirectChannel.class);
|
||||
remainderIs1Channel.subscribe(x -> System.out.println("remainderIs1Channel: " + x));
|
||||
DirectChannel remainderIs2Channel = ctx.getBean("remainderIs2Channel", DirectChannel.class);
|
||||
remainderIs2Channel.subscribe(x -> System.out.println("remainderIs2Channel: " + x));
|
||||
ctx.getBean(NumbersClassifier.class)
|
||||
.multipleof3(Arrays.asList(1, 2, 3, 4, 5, 6));
|
||||
ctx.getBean(NumbersClassifier.class)
|
||||
.remainderIs1(Arrays.asList(1, 2, 3, 4, 5, 6));
|
||||
ctx.getBean(NumbersClassifier.class)
|
||||
.remainderIs2(Arrays.asList(1, 2, 3, 4, 5, 6));
|
||||
ctx.close();
|
||||
}
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
package com.baeldung.subflows.subflowchannel;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.integration.annotation.Gateway;
|
||||
import org.springframework.integration.annotation.IntegrationComponentScan;
|
||||
import org.springframework.integration.annotation.MessagingGateway;
|
||||
import org.springframework.integration.channel.DirectChannel;
|
||||
import org.springframework.integration.config.EnableIntegration;
|
||||
import org.springframework.integration.dsl.IntegrationFlow;
|
||||
|
||||
@EnableIntegration
|
||||
@IntegrationComponentScan
|
||||
public class FilterExample {
|
||||
@MessagingGateway
|
||||
public interface NumbersClassifier {
|
||||
@Gateway(requestChannel = "flow.input")
|
||||
void flow(Collection<Integer> numbers);
|
||||
}
|
||||
|
||||
@Bean
|
||||
DirectChannel multipleof3Channel() {
|
||||
return new DirectChannel();
|
||||
}
|
||||
|
||||
@Bean
|
||||
DirectChannel remainderIs1Channel() {
|
||||
return new DirectChannel();
|
||||
}
|
||||
|
||||
@Bean
|
||||
DirectChannel remainderIs2Channel() {
|
||||
return new DirectChannel();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public IntegrationFlow flow() {
|
||||
return flow -> flow.split()
|
||||
.<Integer> filter(x -> x % 3 == 0, sf -> sf.discardFlow(subf -> subf.<Integer> filter(x -> x % 3 == 1, ssf -> ssf.discardChannel("remainderIs2Channel"))
|
||||
.channel("remainderIs1Channel")))
|
||||
.channel("multipleof3Channel");
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
final ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext(FilterExample.class);
|
||||
DirectChannel multipleof3Channel = ctx.getBean("multipleof3Channel", DirectChannel.class);
|
||||
multipleof3Channel.subscribe(x -> System.out.println("multipleof3Channel: " + x));
|
||||
DirectChannel remainderIs1Channel = ctx.getBean("remainderIs1Channel", DirectChannel.class);
|
||||
remainderIs1Channel.subscribe(x -> System.out.println("remainderIs1Channel: " + x));
|
||||
DirectChannel remainderIs2Channel = ctx.getBean("remainderIs2Channel", DirectChannel.class);
|
||||
remainderIs2Channel.subscribe(x -> System.out.println("remainderIs2Channel: " + x));
|
||||
ctx.getBean(NumbersClassifier.class)
|
||||
.flow(Arrays.asList(1, 2, 3, 4, 5, 6));
|
||||
ctx.close();
|
||||
}
|
||||
}
|
|
@ -1,15 +1,11 @@
|
|||
package com.baeldung.subflows.subflowmapping;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.integration.annotation.Gateway;
|
||||
import org.springframework.integration.annotation.IntegrationComponentScan;
|
||||
import org.springframework.integration.annotation.MessagingGateway;
|
||||
import org.springframework.integration.channel.DirectChannel;
|
||||
import org.springframework.integration.channel.QueueChannel;
|
||||
import org.springframework.integration.config.EnableIntegration;
|
||||
import org.springframework.integration.dsl.IntegrationFlow;
|
||||
|
||||
|
@ -18,44 +14,49 @@ import org.springframework.integration.dsl.IntegrationFlow;
|
|||
public class RouterExample {
|
||||
@MessagingGateway
|
||||
public interface NumbersClassifier {
|
||||
@Gateway(requestChannel = "flow.input")
|
||||
void flow(Collection<Integer> numbers);
|
||||
@Gateway(requestChannel = "classify.input")
|
||||
void classify(Collection<Integer> numbers);
|
||||
}
|
||||
|
||||
@Bean
|
||||
DirectChannel multipleof3Channel() {
|
||||
return new DirectChannel();
|
||||
QueueChannel multipleofThreeChannel() {
|
||||
return new QueueChannel();
|
||||
}
|
||||
|
||||
@Bean
|
||||
DirectChannel remainderIs1Channel() {
|
||||
return new DirectChannel();
|
||||
QueueChannel remainderIsOneChannel() {
|
||||
return new QueueChannel();
|
||||
}
|
||||
|
||||
@Bean
|
||||
DirectChannel remainderIs2Channel() {
|
||||
return new DirectChannel();
|
||||
QueueChannel remainderIsTwoChannel() {
|
||||
return new QueueChannel();
|
||||
}
|
||||
|
||||
boolean isMultipleOfThree(Integer number) {
|
||||
return number % 3 == 0;
|
||||
}
|
||||
|
||||
boolean isRemainderOne(Integer number) {
|
||||
return number % 3 == 1;
|
||||
}
|
||||
|
||||
boolean isRemainderTwo(Integer number) {
|
||||
return number % 3 == 2;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public IntegrationFlow flow() {
|
||||
return f -> f.split()
|
||||
.<Integer, Integer> route(p -> p % 3, m -> m.channelMapping(0, "multipleof3Channel")
|
||||
.subFlowMapping(1, sf -> sf.channel("remainderIs1Channel"))
|
||||
.subFlowMapping(2, sf -> sf.<Integer> handle((p, h) -> p)))
|
||||
.channel("remainderIs2Channel");
|
||||
public IntegrationFlow classify() {
|
||||
return flow -> flow.split()
|
||||
.<Integer, Integer> route(number -> number % 3,
|
||||
mapping -> mapping
|
||||
.channelMapping(0, "multipleofThreeChannel")
|
||||
.subFlowMapping(1, subflow -> subflow.channel("remainderIsOneChannel"))
|
||||
.subFlowMapping(2, subflow -> subflow
|
||||
.<Integer> handle((payload, headers) -> {
|
||||
// do extra work on the payload
|
||||
return payload;
|
||||
}))).channel("remainderIsTwoChannel");
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
final ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext(RouterExample.class);
|
||||
DirectChannel multipleof3Channel = ctx.getBean("multipleof3Channel", DirectChannel.class);
|
||||
multipleof3Channel.subscribe(x -> System.out.println("multipleof3Channel: " + x));
|
||||
DirectChannel remainderIs1Channel = ctx.getBean("remainderIs1Channel", DirectChannel.class);
|
||||
remainderIs1Channel.subscribe(x -> System.out.println("remainderIs1Channel: " + x));
|
||||
DirectChannel remainderIs2Channel = ctx.getBean("remainderIs2Channel", DirectChannel.class);
|
||||
remainderIs2Channel.subscribe(x -> System.out.println("remainderIs2Channel: " + x));
|
||||
ctx.getBean(NumbersClassifier.class)
|
||||
.flow(Arrays.asList(1, 2, 3, 4, 5, 6));
|
||||
ctx.close();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
package com.baeldung.subflows.discardflow;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.integration.channel.QueueChannel;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import com.baeldung.subflows.discardflow.FilterExample.NumbersClassifier;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = { FilterExample.class })
|
||||
public class FilterUnitTest {
|
||||
@Autowired
|
||||
private QueueChannel multipleofThreeChannel;
|
||||
|
||||
@Autowired
|
||||
private QueueChannel remainderIsOneChannel;
|
||||
|
||||
@Autowired
|
||||
private QueueChannel remainderIsTwoChannel;
|
||||
|
||||
@Autowired
|
||||
private NumbersClassifier numbersClassifier;
|
||||
|
||||
@Test
|
||||
public void whenSendMessagesToFlow_thenNumbersAreClassified() {
|
||||
|
||||
numbersClassifier.classify(Arrays.asList(1, 2, 3, 4, 5, 6));
|
||||
|
||||
Message<?> outMessage = multipleofThreeChannel.receive(0);
|
||||
|
||||
assertEquals(outMessage.getPayload(), 3);
|
||||
|
||||
outMessage = multipleofThreeChannel.receive(0);
|
||||
|
||||
assertEquals(outMessage.getPayload(), 6);
|
||||
|
||||
outMessage = remainderIsOneChannel.receive(0);
|
||||
|
||||
assertEquals(outMessage.getPayload(), 1);
|
||||
outMessage = remainderIsOneChannel.receive(0);
|
||||
|
||||
assertEquals(outMessage.getPayload(), 4);
|
||||
|
||||
outMessage = remainderIsTwoChannel.receive(0);
|
||||
|
||||
assertEquals(outMessage.getPayload(), 2);
|
||||
|
||||
outMessage = remainderIsTwoChannel.receive(0);
|
||||
|
||||
assertEquals(outMessage.getPayload(), 5);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
package com.baeldung.subflows.publishsubscribechannel;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.integration.channel.QueueChannel;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import com.baeldung.subflows.publishsubscribechannel.PublishSubscibeChannelExample.NumbersClassifier;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = { PublishSubscibeChannelExample.class })
|
||||
public class PublishSubscribeChannelUnitTest {
|
||||
@Autowired
|
||||
private QueueChannel multipleofThreeChannel;
|
||||
|
||||
@Autowired
|
||||
private QueueChannel remainderIsOneChannel;
|
||||
|
||||
@Autowired
|
||||
private QueueChannel remainderIsTwoChannel;
|
||||
|
||||
@Autowired
|
||||
private NumbersClassifier numbersClassifier;
|
||||
|
||||
@Test
|
||||
public void whenSendMessagesToFlow_thenNumbersAreClassified() {
|
||||
|
||||
numbersClassifier.classify(Arrays.asList(1, 2, 3, 4, 5, 6));
|
||||
|
||||
Message<?> outMessage = multipleofThreeChannel.receive(0);
|
||||
|
||||
assertEquals(outMessage.getPayload(), 3);
|
||||
|
||||
outMessage = multipleofThreeChannel.receive(0);
|
||||
|
||||
assertEquals(outMessage.getPayload(), 6);
|
||||
|
||||
outMessage = remainderIsOneChannel.receive(0);
|
||||
|
||||
assertEquals(outMessage.getPayload(), 1);
|
||||
outMessage = remainderIsOneChannel.receive(0);
|
||||
|
||||
assertEquals(outMessage.getPayload(), 4);
|
||||
|
||||
outMessage = remainderIsTwoChannel.receive(0);
|
||||
|
||||
assertEquals(outMessage.getPayload(), 2);
|
||||
|
||||
outMessage = remainderIsTwoChannel.receive(0);
|
||||
|
||||
assertEquals(outMessage.getPayload(), 5);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
package com.baeldung.subflows.routetorecipients;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.integration.channel.QueueChannel;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import com.baeldung.subflows.routetorecipients.RouteToRecipientsExample;
|
||||
import com.baeldung.subflows.routetorecipients.RouteToRecipientsExample.NumbersClassifier;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = { RouteToRecipientsExample.class })
|
||||
public class RouteToRecipientsUnitTest {
|
||||
@Autowired
|
||||
private QueueChannel multipleofThreeChannel;
|
||||
|
||||
@Autowired
|
||||
private QueueChannel remainderIsOneChannel;
|
||||
|
||||
@Autowired
|
||||
private QueueChannel remainderIsTwoChannel;
|
||||
|
||||
@Autowired
|
||||
private NumbersClassifier numbersClassifier;
|
||||
|
||||
@Test
|
||||
public void whenSendMessagesToFlow_thenNumbersAreClassified() {
|
||||
|
||||
numbersClassifier.classify(Arrays.asList(1, 2, 3, 4, 5, 6));
|
||||
|
||||
Message<?> outMessage = multipleofThreeChannel.receive(0);
|
||||
|
||||
assertEquals(outMessage.getPayload(), 3);
|
||||
|
||||
outMessage = multipleofThreeChannel.receive(0);
|
||||
|
||||
assertEquals(outMessage.getPayload(), 6);
|
||||
|
||||
outMessage = remainderIsOneChannel.receive(0);
|
||||
|
||||
assertEquals(outMessage.getPayload(), 1);
|
||||
outMessage = remainderIsOneChannel.receive(0);
|
||||
|
||||
assertEquals(outMessage.getPayload(), 4);
|
||||
|
||||
outMessage = remainderIsTwoChannel.receive(0);
|
||||
|
||||
assertEquals(outMessage.getPayload(), 2);
|
||||
|
||||
outMessage = remainderIsTwoChannel.receive(0);
|
||||
|
||||
assertEquals(outMessage.getPayload(), 5);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
package com.baeldung.subflows.separateflows;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.integration.channel.QueueChannel;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import com.baeldung.subflows.separateflows.SeparateFlowsExample.NumbersClassifier;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = { SeparateFlowsExample.class })
|
||||
public class SeparateFlowsUnitTest {
|
||||
@Autowired
|
||||
private QueueChannel multipleOfThreeChannel;
|
||||
@Autowired
|
||||
private QueueChannel remainderIsOneChannel;
|
||||
@Autowired
|
||||
private QueueChannel remainderIsTwoChannel;
|
||||
|
||||
@Autowired
|
||||
private NumbersClassifier numbersClassifier;
|
||||
|
||||
@Test
|
||||
public void whenSendMessagesToMultipleOf3Flow_thenOutputMultiplesOf3() {
|
||||
|
||||
numbersClassifier.multipleofThree(Arrays.asList(1, 2, 3, 4, 5, 6));
|
||||
|
||||
Message<?> outMessage = multipleOfThreeChannel.receive(0);
|
||||
|
||||
assertEquals(outMessage.getPayload(), 3);
|
||||
|
||||
outMessage = multipleOfThreeChannel.receive(0);
|
||||
|
||||
assertEquals(outMessage.getPayload(), 6);
|
||||
outMessage = multipleOfThreeChannel.receive(0);
|
||||
assertNull(outMessage);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenSendMessagesToRemainderIs1Flow_thenOutputRemainderIs1() {
|
||||
|
||||
numbersClassifier.remainderIsOne(Arrays.asList(1, 2, 3, 4, 5, 6));
|
||||
|
||||
Message<?> outMessage = remainderIsOneChannel.receive(0);
|
||||
|
||||
assertEquals(outMessage.getPayload(), 1);
|
||||
|
||||
outMessage = remainderIsOneChannel.receive(0);
|
||||
|
||||
assertEquals(outMessage.getPayload(), 4);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenSendMessagesToRemainderIs2Flow_thenOutputRemainderIs2() {
|
||||
|
||||
numbersClassifier.remainderIsTwo(Arrays.asList(1, 2, 3, 4, 5, 6));
|
||||
|
||||
Message<?> outMessage = remainderIsTwoChannel.receive(0);
|
||||
|
||||
assertEquals(outMessage.getPayload(), 2);
|
||||
|
||||
outMessage = remainderIsTwoChannel.receive(0);
|
||||
|
||||
assertEquals(outMessage.getPayload(), 5);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
package com.baeldung.subflows.subflowmapping;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.integration.channel.QueueChannel;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import com.baeldung.subflows.subflowmapping.RouterExample.NumbersClassifier;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = { RouterExample.class })
|
||||
public class RouterUnitTest {
|
||||
@Autowired
|
||||
private QueueChannel multipleofThreeChannel;
|
||||
|
||||
@Autowired
|
||||
private QueueChannel remainderIsOneChannel;
|
||||
|
||||
@Autowired
|
||||
private QueueChannel remainderIsTwoChannel;
|
||||
|
||||
@Autowired
|
||||
private NumbersClassifier numbersClassifier;
|
||||
|
||||
@Test
|
||||
public void whenSendMessagesToFlow_thenNumbersAreClassified() {
|
||||
|
||||
numbersClassifier.classify(Arrays.asList(1, 2, 3, 4, 5, 6));
|
||||
|
||||
Message<?> outMessage = multipleofThreeChannel.receive(0);
|
||||
|
||||
assertEquals(outMessage.getPayload(), 3);
|
||||
|
||||
outMessage = multipleofThreeChannel.receive(0);
|
||||
|
||||
assertEquals(outMessage.getPayload(), 6);
|
||||
|
||||
outMessage = remainderIsOneChannel.receive(0);
|
||||
|
||||
assertEquals(outMessage.getPayload(), 1);
|
||||
outMessage = remainderIsOneChannel.receive(0);
|
||||
|
||||
assertEquals(outMessage.getPayload(), 4);
|
||||
|
||||
outMessage = remainderIsTwoChannel.receive(0);
|
||||
|
||||
assertEquals(outMessage.getPayload(), 2);
|
||||
|
||||
outMessage = remainderIsTwoChannel.receive(0);
|
||||
|
||||
assertEquals(outMessage.getPayload(), 5);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -3,12 +3,14 @@ package org.baeldung;
|
|||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import com.baeldung.SpringJenkinsPipelineApplication;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = SpringJenkinsPipelineApplication.class)
|
||||
@DirtiesContext
|
||||
public class SpringContextIntegrationTest {
|
||||
|
||||
@Test
|
||||
|
|
|
@ -5,3 +5,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring
|
|||
|
||||
### Relevant Articles:
|
||||
- [Uploading MultipartFile with Spring RestTemplate](http://www.baeldung.com/spring-rest-template-multipart-upload)
|
||||
- [Mocking a RestTemplate in Spring](https://www.baeldung.com/spring-mock-rest-template)
|
||||
|
|
|
@ -23,3 +23,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring
|
|||
- [Using the Spring RestTemplate Interceptor](http://www.baeldung.com/spring-rest-template-interceptor)
|
||||
- [Get and Post Lists of Objects with RestTemplate](http://www.baeldung.com/spring-rest-template-list)
|
||||
- [How to Set a Header on a Response with Spring 5](http://www.baeldung.com/spring-response-header)
|
||||
- [Spring’s RequestBody and ResponseBody Annotations](https://www.baeldung.com/spring-request-response-body)
|
||||
|
|
|
@ -58,9 +58,9 @@ public class TestRestTemplateBasicLiveTest {
|
|||
|
||||
@Test
|
||||
public void givenRestTemplateWrapperWithCredentials_whenSendGetForEntity_thenStatusOk() {
|
||||
RestTemplateBuilder restTemplateBuilder = new RestTemplateBuilder().basicAuthentication("user", "passwd");
|
||||
RestTemplateBuilder restTemplateBuilder = new RestTemplateBuilder();
|
||||
restTemplateBuilder.configure(restTemplate);
|
||||
TestRestTemplate testRestTemplate = new TestRestTemplate(restTemplateBuilder);
|
||||
TestRestTemplate testRestTemplate = new TestRestTemplate(restTemplateBuilder, "user", "passwd");
|
||||
ResponseEntity<String> response = testRestTemplate.getForEntity(URL_SECURED_BY_AUTHENTICATION,
|
||||
String.class);
|
||||
assertThat(response.getStatusCode(), equalTo(HttpStatus.OK));
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.thymeleaf.extras</groupId>
|
||||
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
|
||||
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
|
||||
<properties>
|
||||
<rest-assured.version>3.1.0</rest-assured.version>
|
||||
<oauth.version>2.3.3.RELEASE</oauth.version>
|
||||
<oauth-auto.version>2.0.1.RELEASE</oauth-auto.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -20,9 +20,9 @@
|
|||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.security.oauth.boot</groupId>
|
||||
<artifactId>spring-security-oauth2-autoconfigure</artifactId>
|
||||
<version>${oauth-auto.version}</version>
|
||||
<groupId>org.springframework.security.oauth</groupId>
|
||||
<artifactId>spring-security-oauth2</artifactId>
|
||||
<version>${oauth.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
|
||||
<dependency>
|
||||
<groupId>org.thymeleaf.extras</groupId>
|
||||
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
|
||||
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
|
||||
<dependency>
|
||||
<groupId>org.thymeleaf.extras</groupId>
|
||||
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
|
||||
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.thymeleaf.extras</groupId>
|
||||
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
|
||||
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
|
|
@ -0,0 +1,148 @@
|
|||
<?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">
|
||||
<parent>
|
||||
<artifactId>parent-modules</artifactId>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>load-testing-bakeoff</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<encoding>UTF-8</encoding>
|
||||
<scala.version>2.11.12</scala.version> <!--2.11.12 --> <!--2.12.6 -->
|
||||
<gatling.version>2.2.5</gatling.version> <!--2.2.5 --> <!--2.3.1 -->
|
||||
<scala-maven-plugin.version>3.2.2</scala-maven-plugin.version> <!--3.2.2 --> <!--3.3.2 -->
|
||||
<gatling-maven-plugin.version>2.2.1</gatling-maven-plugin.version> <!--2.2.1 --> <!--2.2.4 -->
|
||||
<jmeter.version>5.0</jmeter.version>
|
||||
<grinder.version>3.11</grinder.version>
|
||||
<spring.boot.version>2.0.5.RELEASE</spring.boot.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.gatling</groupId>
|
||||
<artifactId>gatling-app</artifactId>
|
||||
<version>${gatling.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.gatling</groupId>
|
||||
<artifactId>gatling-recorder</artifactId>
|
||||
<version>${gatling.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.gatling.highcharts</groupId>
|
||||
<artifactId>gatling-charts-highcharts</artifactId>
|
||||
<version>${gatling.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.scala-lang</groupId>
|
||||
<artifactId>scala-library</artifactId>
|
||||
<version>${scala.version}</version>
|
||||
</dependency>
|
||||
<!--<dependency>-->
|
||||
<!--<groupId>net.sf.grinder</groupId>-->
|
||||
<!--<artifactId>grinder</artifactId>-->
|
||||
<!--<version>${grinder.version}</version>-->
|
||||
<!--</dependency>-->
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>2.9.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
<version>${spring.boot.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
<version>${spring.boot.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
<version>${spring.boot.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<version>${spring.boot.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<version>1.4.197</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.2</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<!--<testSourceDirectory>src/test/scala</testSourceDirectory>-->
|
||||
<!--<pluginManagement>-->
|
||||
<!--<plugins>-->
|
||||
<!--<plugin>-->
|
||||
<!--<groupId>net.alchim31.maven</groupId>-->
|
||||
<!--<artifactId>scala-maven-plugin</artifactId>-->
|
||||
<!--<version>${scala-maven-plugin.version}</version>-->
|
||||
<!--</plugin>-->
|
||||
<!--</plugins>-->
|
||||
<!--</pluginManagement>-->
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<version>2.0.5.RELEASE</version>
|
||||
</plugin>
|
||||
<!--<plugin>-->
|
||||
<!--<groupId>net.alchim31.maven</groupId>-->
|
||||
<!--<artifactId>scala-maven-plugin</artifactId>-->
|
||||
<!--<executions>-->
|
||||
<!--<execution>-->
|
||||
<!--<goals>-->
|
||||
<!--<goal>testCompile</goal>-->
|
||||
<!--</goals>-->
|
||||
<!--<configuration>-->
|
||||
<!--<args>-->
|
||||
<!--<!–<arg>-Ybackend:GenBCode</arg> –>-->
|
||||
<!--<arg>-Ydelambdafy:method</arg>-->
|
||||
<!--<arg>-target:jvm-1.8</arg>-->
|
||||
<!--<arg>-deprecation</arg>-->
|
||||
<!--<arg>-feature</arg>-->
|
||||
<!--<arg>-unchecked</arg>-->
|
||||
<!--<arg>-language:implicitConversions</arg>-->
|
||||
<!--<arg>-language:postfixOps</arg>-->
|
||||
<!--</args>-->
|
||||
<!--</configuration>-->
|
||||
<!--</execution>-->
|
||||
<!--</executions>-->
|
||||
<!--</plugin>-->
|
||||
<!--<plugin>-->
|
||||
<!--<groupId>io.gatling</groupId>-->
|
||||
<!--<artifactId>gatling-maven-plugin</artifactId>-->
|
||||
<!--<version>${gatling-maven-plugin.version}</version>-->
|
||||
<!--<executions>-->
|
||||
<!--<execution>-->
|
||||
<!--<phase>test</phase>-->
|
||||
<!--<goals>-->
|
||||
<!--<goal>execute</goal>-->
|
||||
<!--</goals>-->
|
||||
<!--</execution>-->
|
||||
<!--</executions>-->
|
||||
<!--</plugin>-->
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
|
@ -0,0 +1,12 @@
|
|||
package com.baeldung.loadtesting;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class Application {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
package com.baeldung.loadtesting;
|
||||
|
||||
import com.baeldung.loadtesting.model.CustomerRewardsAccount;
|
||||
import com.baeldung.loadtesting.model.Transaction;
|
||||
import com.baeldung.loadtesting.repository.CustomerRewardsRepository;
|
||||
import com.baeldung.loadtesting.repository.TransactionRepository;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@RestController
|
||||
public class RewardsController {
|
||||
|
||||
@Autowired
|
||||
private CustomerRewardsRepository customerRewardsRepository;
|
||||
|
||||
@Autowired
|
||||
private TransactionRepository transactionRepository;
|
||||
|
||||
@PostMapping(path="/transactions/add")
|
||||
public @ResponseBody Transaction saveTransactions(@RequestBody Transaction trnsctn){
|
||||
trnsctn.setTransactionDate(Calendar.getInstance().getTime());
|
||||
Transaction result = transactionRepository.save(trnsctn);
|
||||
return result;
|
||||
}
|
||||
|
||||
@GetMapping(path="/transactions/findAll/{rewardId}")
|
||||
public @ResponseBody Iterable<Transaction> getTransactions(@PathVariable Integer rewardId){
|
||||
return transactionRepository.findByCustomerRewardsId(rewardId);
|
||||
}
|
||||
|
||||
@PostMapping(path="/rewards/add")
|
||||
public @ResponseBody CustomerRewardsAccount addRewardsAcount(@RequestBody CustomerRewardsAccount body) {
|
||||
Optional<CustomerRewardsAccount> acct = customerRewardsRepository.findByCustomerId(body.getCustomerId());
|
||||
return !acct.isPresent() ? customerRewardsRepository.save(body) : acct.get();
|
||||
}
|
||||
|
||||
@GetMapping(path="/rewards/find/{customerId}")
|
||||
public @ResponseBody
|
||||
Optional<CustomerRewardsAccount> find(@PathVariable Integer customerId) {
|
||||
return customerRewardsRepository.findByCustomerId(customerId);
|
||||
}
|
||||
|
||||
@GetMapping(path="/rewards/all")
|
||||
public @ResponseBody List<CustomerRewardsAccount> findAll() {
|
||||
return customerRewardsRepository.findAll();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package com.baeldung.loadtesting;
|
||||
|
||||
import com.baeldung.loadtesting.model.Transaction;
|
||||
import com.baeldung.loadtesting.repository.TransactionRepository;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@RestController
|
||||
@Deprecated
|
||||
public class TransactionController {
|
||||
|
||||
@Autowired
|
||||
private TransactionRepository transactionRepository;
|
||||
|
||||
@PostMapping(path="/addTransaction")
|
||||
public @ResponseBody
|
||||
String saveTransactions(@RequestBody Transaction trnsctn){
|
||||
transactionRepository.save(trnsctn);
|
||||
return "Saved Transaction.";
|
||||
}
|
||||
|
||||
@GetMapping(path="/findAll/{rewardId}")
|
||||
public @ResponseBody Iterable<Transaction> getTransactions(@RequestParam Integer id){
|
||||
return transactionRepository.findByCustomerRewardsId(id);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package com.baeldung.loadtesting.model;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Entity
|
||||
@Data
|
||||
public class CustomerRewardsAccount {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy= GenerationType.AUTO)
|
||||
private Integer id;
|
||||
private Integer customerId;
|
||||
|
||||
public Integer getCustomerId(){
|
||||
return this.customerId;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package com.baeldung.loadtesting.model;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import java.util.Date;
|
||||
import java.util.Calendar;
|
||||
|
||||
@Entity
|
||||
@Data
|
||||
public class Transaction {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy= GenerationType.AUTO)
|
||||
private Integer id;
|
||||
private Integer customerRewardsId;
|
||||
private Integer customerId;
|
||||
private Date transactionDate;
|
||||
|
||||
public Transaction(){
|
||||
transactionDate = Calendar.getInstance().getTime();
|
||||
}
|
||||
|
||||
public void setTransactionDate(Date transactionDate){
|
||||
this.transactionDate = transactionDate;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package com.baeldung.loadtesting.repository;
|
||||
|
||||
import com.baeldung.loadtesting.model.CustomerRewardsAccount;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public interface CustomerRewardsRepository extends JpaRepository<CustomerRewardsAccount, Integer> {
|
||||
|
||||
Optional<CustomerRewardsAccount> findByCustomerId(Integer customerId);
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package com.baeldung.loadtesting.repository;
|
||||
|
||||
import com.baeldung.loadtesting.model.Transaction;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface TransactionRepository extends JpaRepository<Transaction, Integer> {
|
||||
|
||||
List<Transaction> findByCustomerRewardsId(Integer rewardsId);
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
package com.baeldung
|
||||
|
||||
import scala.util._
|
||||
import io.gatling.core.Predef._
|
||||
import io.gatling.http.Predef._
|
||||
import scala.concurrent.duration._
|
||||
|
||||
class RewardsScenario extends Simulation {
|
||||
|
||||
def randCustId() = Random.nextInt(99)
|
||||
|
||||
val httpProtocol = http.baseUrl("http://localhost:8080")
|
||||
.acceptHeader("text/html,application/json;q=0.9,*/*;q=0.8")
|
||||
.doNotTrackHeader("1")
|
||||
.acceptLanguageHeader("en-US,en;q=0.5")
|
||||
.acceptEncodingHeader("gzip, deflate")
|
||||
.userAgentHeader("Mozilla/5.0 (Windows NT 5.1; rv:31.0) Gecko/20100101 Firefox/31.0")
|
||||
|
||||
val scn = scenario("RewardsScenario")
|
||||
.repeat(10){
|
||||
exec(http("transactions_add")
|
||||
.post("/transactions/add/")
|
||||
.body(StringBody("""{ "customerRewardsId":null,"customerId":""""+ randCustId() + """","transactionDate":null }""")).asJson
|
||||
.check(jsonPath("$.id").saveAs("txnId"))
|
||||
.check(jsonPath("$.transactionDate").saveAs("txtDate"))
|
||||
.check(jsonPath("$.customerId").saveAs("custId")))
|
||||
.pause(1)
|
||||
|
||||
.exec(http("get_reward")
|
||||
.get("/rewards/find/${custId}")
|
||||
.check(jsonPath("$.id").saveAs("rwdId")))
|
||||
.pause(1)
|
||||
|
||||
.doIf("${rwdId.isUndefined()}"){
|
||||
exec(http("rewards_add")
|
||||
.post("/rewards/add")
|
||||
.body(StringBody("""{ "customerId": "${custId}" }""")).asJson
|
||||
.check(jsonPath("$.id").saveAs("rwdId")))
|
||||
}
|
||||
|
||||
.exec(http("transactions_add")
|
||||
.post("/transactions/add/")
|
||||
.body(StringBody("""{ "customerRewardsId":"${rwdId}","customerId":"${custId}","transactionDate":"${txtDate}" }""")).asJson)
|
||||
.pause(1)
|
||||
|
||||
.exec(http("get_reward")
|
||||
.get("/transactions/findAll/${rwdId}"))
|
||||
}
|
||||
setUp(
|
||||
scn.inject(atOnceUsers(100))
|
||||
).protocols(httpProtocol)
|
||||
}
|
|
@ -0,0 +1,293 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<jmeterTestPlan version="1.2" properties="5.0" jmeter="5.0 r1840935">
|
||||
<hashTree>
|
||||
<TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Test Plan" enabled="true">
|
||||
<stringProp name="TestPlan.comments"></stringProp>
|
||||
<boolProp name="TestPlan.functional_mode">false</boolProp>
|
||||
<boolProp name="TestPlan.tearDown_on_shutdown">true</boolProp>
|
||||
<boolProp name="TestPlan.serialize_threadgroups">false</boolProp>
|
||||
<elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
|
||||
<collectionProp name="Arguments.arguments"/>
|
||||
</elementProp>
|
||||
<stringProp name="TestPlan.user_define_classpath"></stringProp>
|
||||
</TestPlan>
|
||||
<hashTree>
|
||||
<ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Thread Group" enabled="true">
|
||||
<stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
|
||||
<elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller" enabled="true">
|
||||
<boolProp name="LoopController.continue_forever">false</boolProp>
|
||||
<stringProp name="LoopController.loops">10</stringProp>
|
||||
</elementProp>
|
||||
<stringProp name="ThreadGroup.num_threads">100</stringProp>
|
||||
<stringProp name="ThreadGroup.ramp_time">0</stringProp>
|
||||
<boolProp name="ThreadGroup.scheduler">false</boolProp>
|
||||
<stringProp name="ThreadGroup.duration"></stringProp>
|
||||
<stringProp name="ThreadGroup.delay"></stringProp>
|
||||
</ThreadGroup>
|
||||
<hashTree>
|
||||
<LoopController guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller" enabled="true">
|
||||
<boolProp name="LoopController.continue_forever">true</boolProp>
|
||||
<stringProp name="LoopController.loops">1</stringProp>
|
||||
</LoopController>
|
||||
<hashTree>
|
||||
<HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="HTTP Header Manager" enabled="true">
|
||||
<collectionProp name="HeaderManager.headers">
|
||||
<elementProp name="" elementType="Header">
|
||||
<stringProp name="Header.name">Content-Type</stringProp>
|
||||
<stringProp name="Header.value">application/json</stringProp>
|
||||
</elementProp>
|
||||
</collectionProp>
|
||||
</HeaderManager>
|
||||
<hashTree/>
|
||||
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Add Transaction" enabled="true">
|
||||
<boolProp name="HTTPSampler.postBodyRaw">true</boolProp>
|
||||
<elementProp name="HTTPsampler.Arguments" elementType="Arguments">
|
||||
<collectionProp name="Arguments.arguments">
|
||||
<elementProp name="" elementType="HTTPArgument">
|
||||
<boolProp name="HTTPArgument.always_encode">false</boolProp>
|
||||
<stringProp name="Argument.value">{"customerRewardsId":null,"customerId":${random},"transactionDate":null}</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
</collectionProp>
|
||||
</elementProp>
|
||||
<stringProp name="HTTPSampler.domain">localhost</stringProp>
|
||||
<stringProp name="HTTPSampler.port">8080</stringProp>
|
||||
<stringProp name="HTTPSampler.protocol">http</stringProp>
|
||||
<stringProp name="HTTPSampler.contentEncoding"></stringProp>
|
||||
<stringProp name="HTTPSampler.path">/transactions/add</stringProp>
|
||||
<stringProp name="HTTPSampler.method">POST</stringProp>
|
||||
<boolProp name="HTTPSampler.follow_redirects">true</boolProp>
|
||||
<boolProp name="HTTPSampler.auto_redirects">false</boolProp>
|
||||
<boolProp name="HTTPSampler.use_keepalive">true</boolProp>
|
||||
<boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
|
||||
<stringProp name="HTTPSampler.embedded_url_re"></stringProp>
|
||||
<stringProp name="HTTPSampler.connect_timeout"></stringProp>
|
||||
<stringProp name="HTTPSampler.response_timeout"></stringProp>
|
||||
</HTTPSamplerProxy>
|
||||
<hashTree>
|
||||
<JSONPostProcessor guiclass="JSONPostProcessorGui" testclass="JSONPostProcessor" testname="Transaction Id Extractor" enabled="true">
|
||||
<stringProp name="JSONPostProcessor.referenceNames">txnId</stringProp>
|
||||
<stringProp name="JSONPostProcessor.jsonPathExprs">$.id</stringProp>
|
||||
<stringProp name="JSONPostProcessor.match_numbers">1</stringProp>
|
||||
<stringProp name="Sample.scope">all</stringProp>
|
||||
<stringProp name="JSONPostProcessor.defaultValues">foo</stringProp>
|
||||
</JSONPostProcessor>
|
||||
<hashTree/>
|
||||
<JSONPostProcessor guiclass="JSONPostProcessorGui" testclass="JSONPostProcessor" testname="Transaction Date Extractor" enabled="true">
|
||||
<stringProp name="JSONPostProcessor.referenceNames">txnDate</stringProp>
|
||||
<stringProp name="JSONPostProcessor.jsonPathExprs">$.transactionDate</stringProp>
|
||||
<stringProp name="JSONPostProcessor.match_numbers">1</stringProp>
|
||||
<stringProp name="JSONPostProcessor.defaultValues">Never</stringProp>
|
||||
</JSONPostProcessor>
|
||||
<hashTree/>
|
||||
<JSONPostProcessor guiclass="JSONPostProcessorGui" testclass="JSONPostProcessor" testname="Customer Id Extractor" enabled="true">
|
||||
<stringProp name="JSONPostProcessor.referenceNames">custId</stringProp>
|
||||
<stringProp name="JSONPostProcessor.jsonPathExprs">$.customerId</stringProp>
|
||||
<stringProp name="JSONPostProcessor.match_numbers">1</stringProp>
|
||||
<stringProp name="Sample.scope">all</stringProp>
|
||||
<stringProp name="JSONPostProcessor.defaultValues">bob</stringProp>
|
||||
</JSONPostProcessor>
|
||||
<hashTree/>
|
||||
</hashTree>
|
||||
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Find Reward Account" enabled="true">
|
||||
<elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
|
||||
<collectionProp name="Arguments.arguments"/>
|
||||
</elementProp>
|
||||
<stringProp name="HTTPSampler.domain">localhost</stringProp>
|
||||
<stringProp name="HTTPSampler.port">8080</stringProp>
|
||||
<stringProp name="HTTPSampler.protocol"></stringProp>
|
||||
<stringProp name="HTTPSampler.contentEncoding"></stringProp>
|
||||
<stringProp name="HTTPSampler.path">/rewards/find/${custId}</stringProp>
|
||||
<stringProp name="HTTPSampler.method">GET</stringProp>
|
||||
<boolProp name="HTTPSampler.follow_redirects">true</boolProp>
|
||||
<boolProp name="HTTPSampler.auto_redirects">false</boolProp>
|
||||
<boolProp name="HTTPSampler.use_keepalive">true</boolProp>
|
||||
<boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
|
||||
<stringProp name="HTTPSampler.embedded_url_re"></stringProp>
|
||||
<stringProp name="HTTPSampler.connect_timeout"></stringProp>
|
||||
<stringProp name="HTTPSampler.response_timeout"></stringProp>
|
||||
</HTTPSamplerProxy>
|
||||
<hashTree>
|
||||
<JSONPostProcessor guiclass="JSONPostProcessorGui" testclass="JSONPostProcessor" testname="JSON Extractor" enabled="true">
|
||||
<stringProp name="JSONPostProcessor.referenceNames">rwdId</stringProp>
|
||||
<stringProp name="JSONPostProcessor.jsonPathExprs">$.id</stringProp>
|
||||
<stringProp name="JSONPostProcessor.match_numbers">1</stringProp>
|
||||
<stringProp name="JSONPostProcessor.defaultValues">0</stringProp>
|
||||
<stringProp name="Sample.scope">all</stringProp>
|
||||
</JSONPostProcessor>
|
||||
<hashTree/>
|
||||
</hashTree>
|
||||
<IfController guiclass="IfControllerPanel" testclass="IfController" testname="If Reward Account Does Not Exist" enabled="true">
|
||||
<stringProp name="IfController.condition">${rwdId} == 0</stringProp>
|
||||
<boolProp name="IfController.evaluateAll">true</boolProp>
|
||||
</IfController>
|
||||
<hashTree>
|
||||
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Add Reward" enabled="true">
|
||||
<boolProp name="HTTPSampler.postBodyRaw">true</boolProp>
|
||||
<elementProp name="HTTPsampler.Arguments" elementType="Arguments">
|
||||
<collectionProp name="Arguments.arguments">
|
||||
<elementProp name="" elementType="HTTPArgument">
|
||||
<boolProp name="HTTPArgument.always_encode">false</boolProp>
|
||||
<stringProp name="Argument.value">{"customerId":${custId}}</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
</collectionProp>
|
||||
</elementProp>
|
||||
<stringProp name="HTTPSampler.domain">localhost</stringProp>
|
||||
<stringProp name="HTTPSampler.port">8080</stringProp>
|
||||
<stringProp name="HTTPSampler.protocol"></stringProp>
|
||||
<stringProp name="HTTPSampler.contentEncoding"></stringProp>
|
||||
<stringProp name="HTTPSampler.path">/rewards/add</stringProp>
|
||||
<stringProp name="HTTPSampler.method">POST</stringProp>
|
||||
<boolProp name="HTTPSampler.follow_redirects">true</boolProp>
|
||||
<boolProp name="HTTPSampler.auto_redirects">false</boolProp>
|
||||
<boolProp name="HTTPSampler.use_keepalive">true</boolProp>
|
||||
<boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
|
||||
<stringProp name="HTTPSampler.embedded_url_re"></stringProp>
|
||||
<stringProp name="HTTPSampler.connect_timeout"></stringProp>
|
||||
<stringProp name="HTTPSampler.response_timeout"></stringProp>
|
||||
</HTTPSamplerProxy>
|
||||
<hashTree>
|
||||
<JSONPostProcessor guiclass="JSONPostProcessorGui" testclass="JSONPostProcessor" testname="JSON Extractor" enabled="true">
|
||||
<stringProp name="JSONPostProcessor.referenceNames">rwdId</stringProp>
|
||||
<stringProp name="JSONPostProcessor.jsonPathExprs">$.id</stringProp>
|
||||
<stringProp name="JSONPostProcessor.match_numbers">1</stringProp>
|
||||
<stringProp name="JSONPostProcessor.defaultValues">bar</stringProp>
|
||||
<stringProp name="Sample.scope">all</stringProp>
|
||||
</JSONPostProcessor>
|
||||
<hashTree/>
|
||||
</hashTree>
|
||||
</hashTree>
|
||||
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Update Transaction" enabled="true">
|
||||
<boolProp name="HTTPSampler.postBodyRaw">true</boolProp>
|
||||
<elementProp name="HTTPsampler.Arguments" elementType="Arguments">
|
||||
<collectionProp name="Arguments.arguments">
|
||||
<elementProp name="" elementType="HTTPArgument">
|
||||
<boolProp name="HTTPArgument.always_encode">false</boolProp>
|
||||
<stringProp name="Argument.value">{"id":${txnId},"customerRewardsId":${rwdId},"customerId":${custId},"transactionDate":"${txnDate}"}</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
</collectionProp>
|
||||
</elementProp>
|
||||
<stringProp name="HTTPSampler.domain">localhost</stringProp>
|
||||
<stringProp name="HTTPSampler.port">8080</stringProp>
|
||||
<stringProp name="HTTPSampler.protocol"></stringProp>
|
||||
<stringProp name="HTTPSampler.contentEncoding"></stringProp>
|
||||
<stringProp name="HTTPSampler.path">/transactions/add</stringProp>
|
||||
<stringProp name="HTTPSampler.method">POST</stringProp>
|
||||
<boolProp name="HTTPSampler.follow_redirects">true</boolProp>
|
||||
<boolProp name="HTTPSampler.auto_redirects">false</boolProp>
|
||||
<boolProp name="HTTPSampler.use_keepalive">true</boolProp>
|
||||
<boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
|
||||
<stringProp name="HTTPSampler.embedded_url_re"></stringProp>
|
||||
<stringProp name="HTTPSampler.connect_timeout"></stringProp>
|
||||
<stringProp name="HTTPSampler.response_timeout"></stringProp>
|
||||
</HTTPSamplerProxy>
|
||||
<hashTree/>
|
||||
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Find All Transactions" enabled="true">
|
||||
<elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
|
||||
<collectionProp name="Arguments.arguments"/>
|
||||
</elementProp>
|
||||
<stringProp name="HTTPSampler.domain">localhost</stringProp>
|
||||
<stringProp name="HTTPSampler.port">8080</stringProp>
|
||||
<stringProp name="HTTPSampler.protocol"></stringProp>
|
||||
<stringProp name="HTTPSampler.contentEncoding"></stringProp>
|
||||
<stringProp name="HTTPSampler.path">/transactions/findAll/${rwdId}</stringProp>
|
||||
<stringProp name="HTTPSampler.method">GET</stringProp>
|
||||
<boolProp name="HTTPSampler.follow_redirects">true</boolProp>
|
||||
<boolProp name="HTTPSampler.auto_redirects">false</boolProp>
|
||||
<boolProp name="HTTPSampler.use_keepalive">true</boolProp>
|
||||
<boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
|
||||
<stringProp name="HTTPSampler.embedded_url_re"></stringProp>
|
||||
<stringProp name="HTTPSampler.connect_timeout"></stringProp>
|
||||
<stringProp name="HTTPSampler.response_timeout"></stringProp>
|
||||
</HTTPSamplerProxy>
|
||||
<hashTree/>
|
||||
</hashTree>
|
||||
<RandomVariableConfig guiclass="TestBeanGUI" testclass="RandomVariableConfig" testname="Random Variable" enabled="true">
|
||||
<stringProp name="maximumValue">10000</stringProp>
|
||||
<stringProp name="minimumValue">1</stringProp>
|
||||
<stringProp name="outputFormat"></stringProp>
|
||||
<boolProp name="perThread">false</boolProp>
|
||||
<stringProp name="randomSeed">67</stringProp>
|
||||
<stringProp name="variableName">random</stringProp>
|
||||
</RandomVariableConfig>
|
||||
<hashTree/>
|
||||
<ResultCollector guiclass="ViewResultsFullVisualizer" testclass="ResultCollector" testname="View Results Tree" enabled="true">
|
||||
<boolProp name="ResultCollector.error_logging">false</boolProp>
|
||||
<objProp>
|
||||
<name>saveConfig</name>
|
||||
<value class="SampleSaveConfiguration">
|
||||
<time>true</time>
|
||||
<latency>true</latency>
|
||||
<timestamp>true</timestamp>
|
||||
<success>true</success>
|
||||
<label>true</label>
|
||||
<code>true</code>
|
||||
<message>true</message>
|
||||
<threadName>true</threadName>
|
||||
<dataType>true</dataType>
|
||||
<encoding>false</encoding>
|
||||
<assertions>true</assertions>
|
||||
<subresults>true</subresults>
|
||||
<responseData>false</responseData>
|
||||
<samplerData>false</samplerData>
|
||||
<xml>false</xml>
|
||||
<fieldNames>true</fieldNames>
|
||||
<responseHeaders>false</responseHeaders>
|
||||
<requestHeaders>false</requestHeaders>
|
||||
<responseDataOnError>false</responseDataOnError>
|
||||
<saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage>
|
||||
<assertionsResultsToSave>0</assertionsResultsToSave>
|
||||
<bytes>true</bytes>
|
||||
<sentBytes>true</sentBytes>
|
||||
<url>true</url>
|
||||
<threadCounts>true</threadCounts>
|
||||
<idleTime>true</idleTime>
|
||||
<connectTime>true</connectTime>
|
||||
</value>
|
||||
</objProp>
|
||||
<stringProp name="filename"></stringProp>
|
||||
</ResultCollector>
|
||||
<hashTree/>
|
||||
<ResultCollector guiclass="SummaryReport" testclass="ResultCollector" testname="Summary Report" enabled="true">
|
||||
<boolProp name="ResultCollector.error_logging">false</boolProp>
|
||||
<objProp>
|
||||
<name>saveConfig</name>
|
||||
<value class="SampleSaveConfiguration">
|
||||
<time>true</time>
|
||||
<latency>true</latency>
|
||||
<timestamp>true</timestamp>
|
||||
<success>true</success>
|
||||
<label>true</label>
|
||||
<code>true</code>
|
||||
<message>true</message>
|
||||
<threadName>true</threadName>
|
||||
<dataType>true</dataType>
|
||||
<encoding>false</encoding>
|
||||
<assertions>true</assertions>
|
||||
<subresults>true</subresults>
|
||||
<responseData>false</responseData>
|
||||
<samplerData>false</samplerData>
|
||||
<xml>false</xml>
|
||||
<fieldNames>true</fieldNames>
|
||||
<responseHeaders>false</responseHeaders>
|
||||
<requestHeaders>false</requestHeaders>
|
||||
<responseDataOnError>false</responseDataOnError>
|
||||
<saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage>
|
||||
<assertionsResultsToSave>0</assertionsResultsToSave>
|
||||
<bytes>true</bytes>
|
||||
<sentBytes>true</sentBytes>
|
||||
<url>true</url>
|
||||
<threadCounts>true</threadCounts>
|
||||
<idleTime>true</idleTime>
|
||||
<connectTime>true</connectTime>
|
||||
</value>
|
||||
</objProp>
|
||||
<stringProp name="filename"></stringProp>
|
||||
</ResultCollector>
|
||||
<hashTree/>
|
||||
</hashTree>
|
||||
</hashTree>
|
||||
</hashTree>
|
||||
</jmeterTestPlan>
|
|
@ -0,0 +1,5 @@
|
|||
grinder.script = grinder.py
|
||||
grinder.threads = 100
|
||||
grinder.processes = 1
|
||||
grinder.runs = 10
|
||||
grinder.logDirectory = /logs
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue