[BAEL-9712] - Fixed conflicts

This commit is contained in:
amit2103 2018-11-25 00:18:37 +05:30
commit e9fa7851a5
101 changed files with 3504 additions and 709 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,9 @@
package com.baeldung.className;
public class RetrievingClassName {
public class InnerClass {
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1 +0,0 @@
## Relevant articles:

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

View File

@ -0,0 +1,3 @@
### Relevant Articles:
- [Spring Security OAuth Login with WebFlux](https://www.baeldung.com/spring-oauth-login-webflux)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1 @@
org.springframework.boot.diagnostics.FailureAnalyzer=com.baeldung.failureanalyzer.MyBeanNotOfRequiredTypeFailureAnalyzer

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -42,4 +42,8 @@
<finalName>${project.artifactId}</finalName>
</build>
<properties>
<spring-boot.version>2.1.0.RELEASE</spring-boot.version>
</properties>
</project>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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)
- [Springs RequestBody and ResponseBody Annotations](https://www.baeldung.com/spring-request-response-body)

View File

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

View File

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

View File

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

View File

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

View File

@ -37,7 +37,7 @@
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
</dependency>
</dependencies>

View File

@ -38,7 +38,7 @@
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
</dependency>
</dependencies>

View File

@ -43,7 +43,7 @@
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
</dependency>
</dependencies>

View File

@ -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>-->
<!--&lt;!&ndash;<arg>-Ybackend:GenBCode</arg> &ndash;&gt;-->
<!--<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>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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">{&quot;customerRewardsId&quot;:null,&quot;customerId&quot;:${random},&quot;transactionDate&quot;: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">{&quot;customerId&quot;:${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">{&quot;id&quot;:${txnId},&quot;customerRewardsId&quot;:${rwdId},&quot;customerId&quot;:${custId},&quot;transactionDate&quot;:&quot;${txnDate}&quot;}</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>

View File

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