Merge remote-tracking branch 'eugenp/master'
This commit is contained in:
commit
b340cad28d
|
@ -4,7 +4,7 @@ before_install:
|
|||
- echo "MAVEN_OPTS='-Xmx2048M -Xss128M -XX:+CMSClassUnloadingEnabled -XX:+UseG1GC -XX:-UseGCOverheadLimit'" > ~/.mavenrc
|
||||
|
||||
install: skip
|
||||
script: travis_wait 60 mvn -q install -Pdefault-first,default-second
|
||||
script: travis_wait 60 mvn -q install -Pdefault-first,default-second -Dgib.enabled=true
|
||||
|
||||
sudo: required
|
||||
|
||||
|
|
|
@ -17,3 +17,4 @@
|
|||
- [Round Up to the Nearest Hundred](https://www.baeldung.com/java-round-up-nearest-hundred)
|
||||
- [Calculate Percentage in Java](https://www.baeldung.com/java-calculate-percentage)
|
||||
- [Converting Between Byte Arrays and Hexadecimal Strings in Java](https://www.baeldung.com/java-byte-arrays-hex-strings)
|
||||
- [Convert Latitude and Longitude to a 2D Point in Java](https://www.baeldung.com/java-convert-latitude-longitude)
|
||||
|
|
23
cdi/pom.xml
23
cdi/pom.xml
|
@ -14,6 +14,16 @@
|
|||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>javax.enterprise</groupId>
|
||||
<artifactId>cdi-api</artifactId>
|
||||
<version>${cdi-api.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jboss.weld.se</groupId>
|
||||
<artifactId>weld-se-core</artifactId>
|
||||
<version>${weld-se-core.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hamcrest</groupId>
|
||||
<artifactId>hamcrest-core</artifactId>
|
||||
|
@ -42,11 +52,6 @@
|
|||
<artifactId>aspectjweaver</artifactId>
|
||||
<version>${aspectjweaver.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jboss.weld.se</groupId>
|
||||
<artifactId>weld-se-core</artifactId>
|
||||
<version>${weld-se-core.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
|
@ -54,13 +59,13 @@
|
|||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<aspectjweaver.version>1.8.9</aspectjweaver.version>
|
||||
<weld-se-core.version>2.4.1.Final</weld-se-core.version>
|
||||
<cdi-api.version>2.0.SP1</cdi-api.version>
|
||||
<weld-se-core.version>3.0.5.Final</weld-se-core.version>
|
||||
<aspectjweaver.version>1.9.2</aspectjweaver.version>
|
||||
<hamcrest-core.version>1.3</hamcrest-core.version>
|
||||
<assertj-core.version>3.10.0</assertj-core.version>
|
||||
<junit.version>4.12</junit.version>
|
||||
<spring.version>5.1.2.RELEASE</spring.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
package com.baeldung.cdi.cdi2observers.application;
|
||||
|
||||
import com.baeldung.cdi.cdi2observers.events.ExampleEvent;
|
||||
import javax.enterprise.inject.se.SeContainer;
|
||||
import javax.enterprise.inject.se.SeContainerInitializer;
|
||||
|
||||
public class BootstrappingApplication {
|
||||
|
||||
public static void main(String... args) {
|
||||
SeContainerInitializer containerInitializer = SeContainerInitializer.newInstance();
|
||||
try (SeContainer container = containerInitializer.initialize()) {
|
||||
container.getBeanManager().fireEvent(new ExampleEvent("Welcome to Baeldung!"));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package com.baeldung.cdi.cdi2observers.events;
|
||||
|
||||
public class ExampleEvent {
|
||||
|
||||
private final String eventMessage;
|
||||
|
||||
public ExampleEvent(String eventMessage) {
|
||||
this.eventMessage = eventMessage;
|
||||
}
|
||||
|
||||
public String getEventMessage() {
|
||||
return eventMessage;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package com.baeldung.cdi.cdi2observers.events;
|
||||
|
||||
import javax.enterprise.event.Event;
|
||||
import javax.inject.Inject;
|
||||
|
||||
public class ExampleEventSource {
|
||||
|
||||
@Inject
|
||||
Event<ExampleEvent> exampleEvent;
|
||||
|
||||
public void fireEvent() {
|
||||
exampleEvent.fireAsync(new ExampleEvent("Welcome to Baeldung!"));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package com.baeldung.cdi.cdi2observers.observers;
|
||||
|
||||
import com.baeldung.cdi.cdi2observers.events.ExampleEvent;
|
||||
import javax.annotation.Priority;
|
||||
import javax.enterprise.event.Observes;
|
||||
|
||||
public class AnotherExampleEventObserver {
|
||||
|
||||
public String onEvent(@Observes @Priority(2) ExampleEvent event) {
|
||||
return event.getEventMessage();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package com.baeldung.cdi.cdi2observers.observers;
|
||||
|
||||
import com.baeldung.cdi.cdi2observers.events.ExampleEvent;
|
||||
import com.baeldung.cdi.cdi2observers.services.TextService;
|
||||
import javax.annotation.Priority;
|
||||
import javax.enterprise.event.Observes;
|
||||
|
||||
public class ExampleEventObserver {
|
||||
|
||||
public String onEvent(@Observes @Priority(1) ExampleEvent event, TextService textService) {
|
||||
return textService.parseText(event.getEventMessage());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package com.baeldung.cdi.cdi2observers.services;
|
||||
|
||||
public class TextService {
|
||||
|
||||
public String parseText(String text) {
|
||||
return text.toUpperCase();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package com.baeldung.cdi.cdi2observers.tests;
|
||||
|
||||
import com.baeldung.cdi.cdi2observers.services.TextService;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import org.junit.Test;
|
||||
|
||||
public class TextServiceUnitTest {
|
||||
|
||||
@Test
|
||||
public void givenTextServiceInstance_whenCalledparseText_thenCorrect() {
|
||||
TextService textService = new TextService();
|
||||
assertThat(textService.parseText("Baeldung")).isEqualTo("BAELDUNG");
|
||||
}
|
||||
}
|
|
@ -4,3 +4,4 @@
|
|||
- [Java 10 LocalVariable Type-Inference](http://www.baeldung.com/java-10-local-variable-type-inference)
|
||||
- [Guide to Java 10](http://www.baeldung.com/java-10-overview)
|
||||
- [Copy a List to Another List in Java](http://www.baeldung.com/java-copy-list-to-another)
|
||||
- [Deep Dive Into the New Java JIT Compiler – Graal](https://www.baeldung.com/graal-java-jit-compiler)
|
||||
|
|
|
@ -33,3 +33,4 @@
|
|||
- [An Overview of Regular Expressions Performance in Java](https://www.baeldung.com/java-regex-performance)
|
||||
- [Java Primitives versus Objects](https://www.baeldung.com/java-primitives-vs-objects)
|
||||
- [How to Use if/else Logic in Java 8 Streams](https://www.baeldung.com/java-8-streams-if-else-logic)
|
||||
- [How to Replace Many if Statements in Java](https://www.baeldung.com/java-replace-if-statements)
|
||||
|
|
|
@ -4,11 +4,13 @@ import java.lang.reflect.Array;
|
|||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.IntPredicate;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
|
@ -194,4 +196,16 @@ public class ArrayOperations {
|
|||
public static <T> T getRandomFromObjectArray(T[] array) {
|
||||
return array[new Random().nextInt(array.length)];
|
||||
}
|
||||
|
||||
public static Integer[] intersectionSimple(final Integer[] a, final Integer[] b){
|
||||
return Stream.of(a).filter(Arrays.asList(b)::contains).toArray(Integer[]::new);
|
||||
}
|
||||
|
||||
public static Integer[] intersectionSet(final Integer[] a, final Integer[] b){
|
||||
return Stream.of(a).filter(Arrays.asList(b)::contains).distinct().toArray(Integer[]::new);
|
||||
}
|
||||
|
||||
public static Integer[] intersectionMultiSet(final Integer[] a, final Integer[] b){
|
||||
return Stream.of(a).filter(new LinkedList<>(Arrays.asList(b))::remove).toArray(Integer[]::new);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
package com.baeldung.array.operations;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static com.baeldung.array.operations.ArrayOperations.intersectionMultiSet;
|
||||
import static com.baeldung.array.operations.ArrayOperations.intersectionSet;
|
||||
import static com.baeldung.array.operations.ArrayOperations.intersectionSimple;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class IntersectionUnitTest {
|
||||
private static final Integer[] a = { 1, 3, 2 };
|
||||
private static final Integer[] b = { 4, 3, 2, 4, 2, 3, 4, 4, 3 };
|
||||
private static final Integer[] c = { 1, 3, 2, 3, 3, 2 };
|
||||
|
||||
@Test
|
||||
void whenIntersectionSimpleIsUsed_thenCommonEntriesAreInTheResult() {
|
||||
assertThat(intersectionSimple(a, b)).isEqualTo(new Integer[] { 3, 2 });
|
||||
assertThat(intersectionSimple(b, a)).isEqualTo(new Integer[] { 3, 2, 2, 3, 3 });
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenIntersectionSimpleIsUsedWithAnArrayAndItself_thenTheResultIsTheIdentity() {
|
||||
assertThat(intersectionSimple(b, b)).isEqualTo(b);
|
||||
assertThat(intersectionSimple(a, a)).isEqualTo(a);
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenIntersectionSetIsUsed_thenCommonEntriesAreInTheResult() {
|
||||
assertThat(intersectionSet(b, a)).isEqualTo(new Integer[] { 3, 2 });
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenIntersectionSetIsUsed_thenTheNumberOfEntriesDoesNotChangeWithTheParameterOrder() {
|
||||
assertThat(intersectionSet(a, b)).isEqualTo(new Integer[] { 3, 2 });
|
||||
assertThat(intersectionSet(b, a)).isEqualTo(new Integer[] { 3, 2 });
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenIntersectionSetIsUsedWithAnArrayAndWithItself_andTheInputHasNoDuplicateEntries_ThenTheResultIsTheIdentity() {
|
||||
assertThat(intersectionSet(a, a)).isEqualTo(a);
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenIntersectionSetIsUsedWithAnArrayAndWithItself_andTheInputHasDuplicateEntries_ThenTheResultIsNotTheIdentity() {
|
||||
assertThat(intersectionSet(b, b)).isNotEqualTo(b);
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenMultiSetIsUsed_thenCommonEntriesAreInTheResult() {
|
||||
assertThat(intersectionMultiSet(b, a)).isEqualTo(new Integer[] { 3, 2 });
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenIntersectionMultiSetIsUsed_thenTheNumberOfEntriesDoesNotChangeWithTheParameterOrder() {
|
||||
assertThat(intersectionMultiSet(a, b)).isEqualTo(new Integer[] { 3, 2 });
|
||||
assertThat(intersectionMultiSet(b, a)).isEqualTo(new Integer[] { 3, 2 });
|
||||
assertThat(intersectionMultiSet(b, c)).isEqualTo(new Integer[] { 3, 2, 2, 3, 3 });
|
||||
assertThat(intersectionMultiSet(c, b)).isEqualTo(new Integer[] { 3, 2, 3, 3, 2 });
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenIntersectionMultiSetIsUsedWithAnArrayAndWithItself_ThenTheResultIsTheIdentity() {
|
||||
assertThat(intersectionMultiSet(b, b)).isEqualTo(b);
|
||||
assertThat(intersectionMultiSet(a, a)).isEqualTo(a);
|
||||
}
|
||||
}
|
|
@ -50,3 +50,4 @@
|
|||
- [Check If Two Lists are Equal in Java](http://www.baeldung.com/java-test-a-list-for-ordinality-and-equality)
|
||||
- [Java List Initialization in One Line](https://www.baeldung.com/java-init-list-one-line)
|
||||
- [ClassCastException: Arrays$ArrayList cannot be cast to ArrayList](https://www.baeldung.com/java-classcastexception-arrays-arraylist)
|
||||
- [A Guide to EnumMap](https://www.baeldung.com/java-enum-map)
|
||||
|
|
|
@ -34,3 +34,4 @@
|
|||
- [Read a File into an ArrayList](https://www.baeldung.com/java-file-to-arraylist)
|
||||
- [Guide to Java OutputStream](https://www.baeldung.com/java-outputstream)
|
||||
- [Reading a CSV File into an Array](https://www.baeldung.com/java-csv-file-array)
|
||||
- [Guide to BufferedReader](https://www.baeldung.com/java-buffered-reader)
|
||||
|
|
|
@ -56,4 +56,5 @@
|
|||
- [How to Separate Double into Integer and Decimal Parts](https://www.baeldung.com/java-separate-double-into-integer-decimal-parts)
|
||||
- [“Sneaky Throws” in Java](http://www.baeldung.com/java-sneaky-throws)
|
||||
- [Inheritance and Composition (Is-a vs Has-a relationship) in Java](http://www.baeldung.com/java-inheritance-composition)
|
||||
- [A Guide to Constructors in Java](https://www.baeldung.com/java-constructors)
|
||||
|
||||
|
|
|
@ -85,3 +85,6 @@
|
|||
- [A Guide to SimpleDateFormat](https://www.baeldung.com/java-simple-date-format)
|
||||
- [SSL Handshake Failures](https://www.baeldung.com/java-ssl-handshake-failures)
|
||||
- [Implementing a Binary Tree in Java](https://www.baeldung.com/java-binary-tree)
|
||||
- [Changing the Order in a Sum Operation Can Produce Different Results?](https://www.baeldung.com/java-floating-point-sum-order)
|
||||
- [Java – Try with Resources](https://www.baeldung.com/java-try-with-resources)
|
||||
- [Abstract Classes in Java](https://www.baeldung.com/java-abstract-class)
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
package com.baeldung.className;
|
||||
|
||||
public class RetrievingClassName {
|
||||
|
||||
public class InnerClass {
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,156 @@
|
|||
package com.baeldung.className;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
public class RetrievingClassNameUnitTest {
|
||||
|
||||
// Retrieving Simple Name
|
||||
@Test
|
||||
public void givenRetrievingClassName_whenGetSimpleName_thenRetrievingClassName() {
|
||||
assertEquals("RetrievingClassName", RetrievingClassName.class.getSimpleName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenPrimitiveInt_whenGetSimpleName_thenInt() {
|
||||
assertEquals("int", int.class.getSimpleName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenRetrievingClassNameArray_whenGetSimpleName_thenRetrievingClassNameWithBrackets() {
|
||||
assertEquals("RetrievingClassName[]", RetrievingClassName[].class.getSimpleName());
|
||||
assertEquals("RetrievingClassName[][]", RetrievingClassName[][].class.getSimpleName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenAnonymousClass_whenGetSimpleName_thenEmptyString() {
|
||||
assertEquals("", new RetrievingClassName() {}.getClass().getSimpleName());
|
||||
}
|
||||
|
||||
// Retrieving Other Names
|
||||
// - Primitive Types
|
||||
@Test
|
||||
public void givenPrimitiveInt_whenGetName_thenInt() {
|
||||
assertEquals("int", int.class.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenPrimitiveInt_whenGetTypeName_thenInt() {
|
||||
assertEquals("int", int.class.getTypeName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenPrimitiveInt_whenGetCanonicalName_thenInt() {
|
||||
assertEquals("int", int.class.getCanonicalName());
|
||||
}
|
||||
|
||||
// - Object Types
|
||||
@Test
|
||||
public void givenRetrievingClassName_whenGetName_thenCanonicalName() {
|
||||
assertEquals("com.baeldung.className.RetrievingClassName", RetrievingClassName.class.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenRetrievingClassName_whenGetTypeName_thenCanonicalName() {
|
||||
assertEquals("com.baeldung.className.RetrievingClassName", RetrievingClassName.class.getTypeName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenRetrievingClassName_whenGetCanonicalName_thenCanonicalName() {
|
||||
assertEquals("com.baeldung.className.RetrievingClassName", RetrievingClassName.class.getCanonicalName());
|
||||
}
|
||||
|
||||
// - Inner Classes
|
||||
@Test
|
||||
public void givenRetrievingClassNameInnerClass_whenGetName_thenCanonicalNameWithDollarSeparator() {
|
||||
assertEquals("com.baeldung.className.RetrievingClassName$InnerClass", RetrievingClassName.InnerClass.class.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenRetrievingClassNameInnerClass_whenGetTypeName_thenCanonicalNameWithDollarSeparator() {
|
||||
assertEquals("com.baeldung.className.RetrievingClassName$InnerClass", RetrievingClassName.InnerClass.class.getTypeName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenRetrievingClassNameInnerClass_whenGetCanonicalName_thenCanonicalName() {
|
||||
assertEquals("com.baeldung.className.RetrievingClassName.InnerClass", RetrievingClassName.InnerClass.class.getCanonicalName());
|
||||
}
|
||||
|
||||
// - Anonymous Classes
|
||||
@Test
|
||||
public void givenAnonymousClass_whenGetName_thenCallingClassCanonicalNameWithDollarSeparatorAndCountNumber() {
|
||||
// These are the second and third appearences of an anonymous class in RetrievingClassNameUnitTest, hence $2 and $3 expectations
|
||||
assertEquals("com.baeldung.className.RetrievingClassNameUnitTest$2", new RetrievingClassName() {}.getClass().getName());
|
||||
assertEquals("com.baeldung.className.RetrievingClassNameUnitTest$3", new RetrievingClassName() {}.getClass().getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenAnonymousClass_whenGetTypeName_thenCallingClassCanonicalNameWithDollarSeparatorAndCountNumber() {
|
||||
// These are the fourth and fifth appearences of an anonymous class in RetrievingClassNameUnitTest, hence $4 and $5 expectations
|
||||
assertEquals("com.baeldung.className.RetrievingClassNameUnitTest$4", new RetrievingClassName() {}.getClass().getTypeName());
|
||||
assertEquals("com.baeldung.className.RetrievingClassNameUnitTest$5", new RetrievingClassName() {}.getClass().getTypeName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenAnonymousClass_whenGetCanonicalName_thenNull() {
|
||||
assertNull(new RetrievingClassName() {}.getClass().getCanonicalName());
|
||||
}
|
||||
|
||||
// - Arrays
|
||||
@Test
|
||||
public void givenPrimitiveIntArray_whenGetName_thenOpeningBracketsAndPrimitiveIntLetter() {
|
||||
assertEquals("[I", int[].class.getName());
|
||||
assertEquals("[[I", int[][].class.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenRetrievingClassNameArray_whenGetName_thenOpeningBracketsLetterLAndRetrievingClassNameGetName() {
|
||||
assertEquals("[Lcom.baeldung.className.RetrievingClassName;", RetrievingClassName[].class.getName());
|
||||
assertEquals("[[Lcom.baeldung.className.RetrievingClassName;", RetrievingClassName[][].class.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenRetrievingClassNameInnerClassArray_whenGetName_thenOpeningBracketsLetterLAndRetrievingClassNameInnerClassGetName() {
|
||||
assertEquals("[Lcom.baeldung.className.RetrievingClassName$InnerClass;", RetrievingClassName.InnerClass[].class.getName());
|
||||
assertEquals("[[Lcom.baeldung.className.RetrievingClassName$InnerClass;", RetrievingClassName.InnerClass[][].class.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenPrimitiveIntArray_whenGetTypeName_thenPrimitiveIntGetTypeNameWithBrackets() {
|
||||
assertEquals("int[]", int[].class.getTypeName());
|
||||
assertEquals("int[][]", int[][].class.getTypeName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenRetrievingClassNameArray_whenGetTypeName_thenRetrievingClassNameGetTypeNameWithBrackets() {
|
||||
assertEquals("com.baeldung.className.RetrievingClassName[]", RetrievingClassName[].class.getTypeName());
|
||||
assertEquals("com.baeldung.className.RetrievingClassName[][]", RetrievingClassName[][].class.getTypeName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenRetrievingClassNameInnerClassArray_whenGetTypeName_thenRetrievingClassNameInnerClassGetTypeNameWithBrackets() {
|
||||
assertEquals("com.baeldung.className.RetrievingClassName$InnerClass[]", RetrievingClassName.InnerClass[].class.getTypeName());
|
||||
assertEquals("com.baeldung.className.RetrievingClassName$InnerClass[][]", RetrievingClassName.InnerClass[][].class.getTypeName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenPrimitiveIntArray_whenGetCanonicalName_thenPrimitiveIntGetCanonicalNameWithBrackets() {
|
||||
assertEquals("int[]", int[].class.getCanonicalName());
|
||||
assertEquals("int[][]", int[][].class.getCanonicalName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenRetrievingClassNameArray_whenGetCanonicalName_thenRetrievingClassNameGetCanonicalNameWithBrackets() {
|
||||
assertEquals("com.baeldung.className.RetrievingClassName[]", RetrievingClassName[].class.getCanonicalName());
|
||||
assertEquals("com.baeldung.className.RetrievingClassName[][]", RetrievingClassName[][].class.getCanonicalName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenRetrievingClassNameInnerClassArray_whenGetCanonicalName_thenRetrievingClassNameInnerClassGetCanonicalNameWithBrackets() {
|
||||
assertEquals("com.baeldung.className.RetrievingClassName.InnerClass[]", RetrievingClassName.InnerClass[].class.getCanonicalName());
|
||||
assertEquals("com.baeldung.className.RetrievingClassName.InnerClass[][]", RetrievingClassName.InnerClass[][].class.getCanonicalName());
|
||||
}
|
||||
|
||||
}
|
|
@ -24,3 +24,4 @@
|
|||
- [Add Hours To a Date In Java](http://www.baeldung.com/java-add-hours-date)
|
||||
- [Guide to DateTimeFormatter](https://www.baeldung.com/java-datetimeformatter)
|
||||
- [Format ZonedDateTime to String](https://www.baeldung.com/java-format-zoned-datetime-string)
|
||||
- [Convert Between java.time.Instant and java.sql.Timestamp](Convert Between java.time.Instant and java.sql.Timestamp)
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
package com.baeldung.string.checkinputs;
|
||||
|
||||
import java.util.Scanner;
|
||||
|
||||
public class CheckIntegerInput {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
try (Scanner scanner = new Scanner(System.in)) {
|
||||
System.out.println("Enter an integer : ");
|
||||
|
||||
if (scanner.hasNextInt()) {
|
||||
System.out.println("You entered : " + scanner.nextInt());
|
||||
} else {
|
||||
System.out.println("The input is not an integer");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -44,18 +44,18 @@ public class RemoveDuplicateFromString {
|
|||
}
|
||||
|
||||
String removeDuplicatesUsingSorting(String str) {
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if(!str.isEmpty()) {
|
||||
char[] chars = str.toCharArray();
|
||||
|
||||
Arrays.sort(chars);
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
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();
|
||||
}
|
||||
|
@ -90,6 +90,13 @@ public class RemoveDuplicateFromString {
|
|||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
String removeDuplicatesUsingDistinct(String str) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
str.chars().distinct().forEach(c -> sb.append((char) c));
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
package com.baeldung.string;
|
||||
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class StringReplaceAndRemoveUnitTest {
|
||||
|
||||
|
||||
@Test
|
||||
public void givenTestStrings_whenReplace_thenProcessedString() {
|
||||
|
||||
String master = "Hello World Baeldung!";
|
||||
String target = "Baeldung";
|
||||
String replacement = "Java";
|
||||
String processed = master.replace(target, replacement);
|
||||
assertTrue(processed.contains(replacement));
|
||||
assertFalse(processed.contains(target));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenTestStrings_whenReplaceAll_thenProcessedString() {
|
||||
|
||||
String master2 = "Welcome to Baeldung, Hello World Baeldung";
|
||||
String regexTarget= "(Baeldung)$";
|
||||
String replacement = "Java";
|
||||
String processed2 = master2.replaceAll(regexTarget, replacement);
|
||||
assertTrue(processed2.endsWith("Java"));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenTestStrings_whenStringBuilderMethods_thenProcessedString() {
|
||||
|
||||
String master = "Hello World Baeldung!";
|
||||
String target = "Baeldung";
|
||||
String replacement = "Java";
|
||||
|
||||
int startIndex = master.indexOf(target);
|
||||
int stopIndex = startIndex + target.length();
|
||||
|
||||
StringBuilder builder = new StringBuilder(master);
|
||||
|
||||
|
||||
builder.delete(startIndex, stopIndex);
|
||||
assertFalse(builder.toString().contains(target));
|
||||
|
||||
|
||||
builder.replace(startIndex, stopIndex, replacement);
|
||||
assertTrue(builder.toString().contains(replacement));
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void givenTestStrings_whenStringUtilsMethods_thenProcessedStrings() {
|
||||
|
||||
String master = "Hello World Baeldung!";
|
||||
String target = "Baeldung";
|
||||
String replacement = "Java";
|
||||
|
||||
String processed = StringUtils.replace(master, target, replacement);
|
||||
assertTrue(processed.contains(replacement));
|
||||
|
||||
String master2 = "Hello World Baeldung!";
|
||||
String target2 = "baeldung";
|
||||
String processed2 = StringUtils.replaceIgnoreCase(master2, target2, replacement);
|
||||
assertFalse(processed2.contains(target));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -8,6 +8,8 @@ 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
|
||||
|
@ -20,6 +22,8 @@ public class RemoveDuplicateFromStringUnitTest {
|
|||
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);
|
||||
}
|
||||
|
@ -28,6 +32,9 @@ public class RemoveDuplicateFromStringUnitTest {
|
|||
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);
|
||||
}
|
||||
|
@ -36,6 +43,9 @@ public class RemoveDuplicateFromStringUnitTest {
|
|||
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);
|
||||
}
|
||||
|
@ -44,6 +54,8 @@ public class RemoveDuplicateFromStringUnitTest {
|
|||
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);
|
||||
}
|
||||
|
@ -52,7 +64,19 @@ public class RemoveDuplicateFromStringUnitTest {
|
|||
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);
|
||||
}
|
||||
}
|
||||
|
|
109
jee-7/pom.xml
109
jee-7/pom.xml
|
@ -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>
|
||||
<artifactId>jee-7</artifactId>
|
||||
|
@ -121,6 +122,58 @@
|
|||
<artifactId>spring-security-taglibs</artifactId>
|
||||
<version>${org.springframework.security.version}</version>
|
||||
</dependency>
|
||||
<!-- Batch dependencies -->
|
||||
|
||||
<dependency>
|
||||
<groupId>org.jboss.spec.javax.batch</groupId>
|
||||
<artifactId>jboss-batch-api_1.0_spec</artifactId>
|
||||
<version>1.0.0.Final</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jberet</groupId>
|
||||
<artifactId>jberet-core</artifactId>
|
||||
<version>1.0.2.Final</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jberet</groupId>
|
||||
<artifactId>jberet-support</artifactId>
|
||||
<version>1.0.2.Final</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jboss.spec.javax.transaction</groupId>
|
||||
<artifactId>jboss-transaction-api_1.2_spec</artifactId>
|
||||
<version>1.0.0.Final</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jboss.marshalling</groupId>
|
||||
<artifactId>jboss-marshalling</artifactId>
|
||||
<version>1.4.2.Final</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jboss.weld</groupId>
|
||||
<artifactId>weld-core</artifactId>
|
||||
<version>2.1.1.Final</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jboss.weld.se</groupId>
|
||||
<artifactId>weld-se</artifactId>
|
||||
<version>2.1.1.Final</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jberet</groupId>
|
||||
<artifactId>jberet-se</artifactId>
|
||||
<version>1.0.2.Final</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<version>1.4.178</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.glassfish.jersey.containers</groupId>
|
||||
<artifactId>jersey-container-jetty-servlet</artifactId>
|
||||
<version>2.22.1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
@ -135,6 +188,42 @@
|
|||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<!--This plugin's configuration is used to store Eclipse m2e settings
|
||||
only. It has no influence on the Maven build itself. -->
|
||||
<plugin>
|
||||
<groupId>org.eclipse.m2e</groupId>
|
||||
<artifactId>lifecycle-mapping</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<configuration>
|
||||
<lifecycleMappingMetadata>
|
||||
<pluginExecutions>
|
||||
<pluginExecution>
|
||||
<pluginExecutionFilter>
|
||||
<groupId>
|
||||
org.apache.maven.plugins
|
||||
</groupId>
|
||||
<artifactId>
|
||||
maven-pmd-plugin
|
||||
</artifactId>
|
||||
<versionRange>
|
||||
[3.8,)
|
||||
</versionRange>
|
||||
<goals>
|
||||
<goal>check</goal>
|
||||
</goals>
|
||||
</pluginExecutionFilter>
|
||||
<action>
|
||||
<ignore></ignore>
|
||||
</action>
|
||||
</pluginExecution>
|
||||
</pluginExecutions>
|
||||
</lifecycleMappingMetadata>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
</build>
|
||||
|
||||
<dependencyManagement>
|
||||
|
@ -196,6 +285,12 @@
|
|||
<artifactId>wildfly-arquillian-container-managed</artifactId>
|
||||
<version>${wildfly.version}</version>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>sun.jdk</groupId>
|
||||
<artifactId>jconsole</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
@ -224,6 +319,12 @@
|
|||
<type>zip</type>
|
||||
<overWrite>false</overWrite>
|
||||
<outputDirectory>${project.build.directory}</outputDirectory>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>sun.jdk</groupId>
|
||||
<artifactId>jconsole</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</artifactItem>
|
||||
</artifactItems>
|
||||
</configuration>
|
||||
|
@ -275,6 +376,12 @@
|
|||
<artifactId>wildfly-arquillian-container-remote</artifactId>
|
||||
<version>${wildfly.version}</version>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>sun.jdk</groupId>
|
||||
<artifactId>jconsole</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</profile>
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
package com.baeldung.batch.understanding;
|
||||
|
||||
import javax.batch.api.chunk.listener.SkipReadListener;
|
||||
import javax.inject.Named;
|
||||
|
||||
@Named
|
||||
public class ChunkExceptionSkipReadListener implements SkipReadListener {
|
||||
@Override
|
||||
public void onSkipReadItem(Exception e) throws Exception {
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package com.baeldung.batch.understanding;
|
||||
|
||||
import javax.batch.api.chunk.AbstractCheckpointAlgorithm;
|
||||
import javax.inject.Named;
|
||||
|
||||
@Named
|
||||
public class CustomCheckPoint extends AbstractCheckpointAlgorithm {
|
||||
@Override
|
||||
public boolean isReadyToCheckpoint() throws Exception {
|
||||
return SimpleChunkItemReader.COUNT % 5 == 0;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package com.baeldung.batch.understanding;
|
||||
|
||||
import javax.batch.api.Decider;
|
||||
import javax.batch.runtime.StepExecution;
|
||||
import javax.inject.Named;
|
||||
|
||||
@Named
|
||||
public class DeciderJobSequence implements Decider {
|
||||
@Override
|
||||
public String decide(StepExecution[] ses) throws Exception {
|
||||
return "nothing";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package com.baeldung.batch.understanding;
|
||||
|
||||
import javax.batch.api.AbstractBatchlet;
|
||||
import javax.batch.api.BatchProperty;
|
||||
import javax.batch.runtime.BatchStatus;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
|
||||
@Named
|
||||
public class InjectSimpleBatchLet extends AbstractBatchlet {
|
||||
@Inject
|
||||
@BatchProperty(name = "name")
|
||||
private String nameString;
|
||||
|
||||
@Override
|
||||
public String process() throws Exception {
|
||||
System.out.println("Value passed in = " + nameString);
|
||||
return BatchStatus.COMPLETED.toString();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package com.baeldung.batch.understanding;
|
||||
|
||||
import javax.batch.api.AbstractBatchlet;
|
||||
import javax.batch.runtime.BatchStatus;
|
||||
import javax.inject.Named;
|
||||
|
||||
@Named
|
||||
public class SimpleBatchLet extends AbstractBatchlet {
|
||||
@Override
|
||||
public String process() throws Exception {
|
||||
return BatchStatus.FAILED.toString();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package com.baeldung.batch.understanding;
|
||||
|
||||
import javax.batch.api.chunk.ItemProcessor;
|
||||
import javax.inject.Named;
|
||||
|
||||
@Named
|
||||
public class SimpleChunkItemProcessor implements ItemProcessor {
|
||||
@Override
|
||||
public Integer processItem(Object t) {
|
||||
return ((Integer) t).intValue() % 2 == 0 ? null : ((Integer) t).intValue();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package com.baeldung.batch.understanding;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.StringTokenizer;
|
||||
import javax.batch.api.chunk.AbstractItemReader;
|
||||
import javax.inject.Named;
|
||||
|
||||
@Named
|
||||
public class SimpleChunkItemReader extends AbstractItemReader {
|
||||
private StringTokenizer tokens;
|
||||
public static int COUNT = 0;
|
||||
|
||||
@Override
|
||||
public Integer readItem() throws Exception {
|
||||
if (tokens.hasMoreTokens()) {
|
||||
COUNT++;
|
||||
String tempTokenize = tokens.nextToken();
|
||||
return Integer.valueOf(tempTokenize);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void open(Serializable checkpoint) throws Exception {
|
||||
tokens = new StringTokenizer("1,2,3,4,5,6,7,8,9,10", ",");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package com.baeldung.batch.understanding;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import javax.batch.api.chunk.AbstractItemReader;
|
||||
import javax.inject.Named;
|
||||
|
||||
@Named
|
||||
public class SimpleChunkItemReaderError extends AbstractItemReader {
|
||||
private StringTokenizer tokens;
|
||||
public static int COUNT = 0;
|
||||
|
||||
@Override
|
||||
public Integer readItem() throws Exception {
|
||||
if (tokens.hasMoreTokens()) {
|
||||
COUNT++;
|
||||
int token = Integer.valueOf(tokens.nextToken());
|
||||
if (token == 3) {
|
||||
throw new RuntimeException("Something happened");
|
||||
}
|
||||
return Integer.valueOf(token);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void open(Serializable checkpoint) throws Exception {
|
||||
tokens = new StringTokenizer("1,2,3,4,5,6,7,8,9,10", ",");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package com.baeldung.batch.understanding;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.batch.api.chunk.AbstractItemWriter;
|
||||
import javax.inject.Named;
|
||||
|
||||
@Named
|
||||
public class SimpleChunkWriter extends AbstractItemWriter {
|
||||
@Override
|
||||
public void writeItems(List<Object> items) throws Exception {
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package com.baeldung.batch.understanding.exception;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class MyInputRecord implements Serializable {
|
||||
private int id;
|
||||
|
||||
public MyInputRecord(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o)
|
||||
return true;
|
||||
if (o == null || getClass() != o.getClass())
|
||||
return false;
|
||||
|
||||
MyInputRecord that = (MyInputRecord) o;
|
||||
|
||||
return id == that.id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "MyInputRecord: " + id;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package com.baeldung.batch.understanding.exception;
|
||||
|
||||
import javax.batch.api.chunk.ItemProcessor;
|
||||
import javax.inject.Named;
|
||||
|
||||
@Named
|
||||
public class MyItemProcessor implements ItemProcessor {
|
||||
@Override
|
||||
public Object processItem(Object t) {
|
||||
if (((MyInputRecord) t).getId() == 6) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
return new MyOutputRecord(((MyInputRecord) t).getId());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
package com.baeldung.batch.understanding.exception;
|
||||
|
||||
import javax.batch.api.chunk.AbstractItemReader;
|
||||
import javax.inject.Named;
|
||||
import java.io.Serializable;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
@Named
|
||||
public class MyItemReader extends AbstractItemReader {
|
||||
private StringTokenizer tokens;
|
||||
private MyInputRecord lastElement;
|
||||
private boolean alreadyFailed;
|
||||
|
||||
@Override
|
||||
public void open(Serializable checkpoint) {
|
||||
tokens = new StringTokenizer("1,2,3,4,5,6,7,8,9,10", ",");
|
||||
if (checkpoint != null) {
|
||||
while (!Integer.valueOf(tokens.nextToken())
|
||||
.equals(((MyInputRecord) checkpoint).getId())) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object readItem() {
|
||||
if (tokens.hasMoreTokens()) {
|
||||
int token = Integer.valueOf(tokens.nextToken());
|
||||
if (token == 5 && !alreadyFailed) {
|
||||
alreadyFailed = true;
|
||||
throw new IllegalArgumentException("Could not read record");
|
||||
}
|
||||
lastElement = new MyInputRecord(token);
|
||||
return lastElement;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Serializable checkpointInfo() throws Exception {
|
||||
return lastElement;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
|
||||
package com.baeldung.batch.understanding.exception;
|
||||
|
||||
import javax.batch.api.chunk.AbstractItemWriter;
|
||||
import javax.inject.Named;
|
||||
import java.util.List;
|
||||
|
||||
@Named
|
||||
public class MyItemWriter extends AbstractItemWriter {
|
||||
private static int retries = 0;
|
||||
|
||||
@Override
|
||||
public void writeItems(List list) {
|
||||
if (retries <= 3 && list.contains(new MyOutputRecord(8))) {
|
||||
retries++;
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package com.baeldung.batch.understanding.exception;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class MyOutputRecord implements Serializable {
|
||||
private int id;
|
||||
|
||||
public MyOutputRecord(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
MyOutputRecord that = (MyOutputRecord) o;
|
||||
|
||||
return id == that.id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "MyOutputRecord: " + id;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package com.baeldung.batch.understanding.exception;
|
||||
|
||||
import javax.batch.api.chunk.listener.RetryProcessListener;
|
||||
import javax.inject.Named;
|
||||
|
||||
@Named
|
||||
public class MyRetryProcessorListener implements RetryProcessListener {
|
||||
@Override
|
||||
public void onRetryProcessException(Object item, Exception ex) throws Exception {
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package com.baeldung.batch.understanding.exception;
|
||||
|
||||
import javax.batch.api.chunk.listener.RetryReadListener;
|
||||
import javax.inject.Named;
|
||||
|
||||
@Named
|
||||
public class MyRetryReadListener implements RetryReadListener {
|
||||
@Override
|
||||
public void onRetryReadException(Exception ex) throws Exception {
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package com.baeldung.batch.understanding.exception;
|
||||
|
||||
import javax.batch.api.chunk.listener.RetryWriteListener;
|
||||
import javax.inject.Named;
|
||||
import java.util.List;
|
||||
|
||||
@Named
|
||||
public class MyRetryWriteListener implements RetryWriteListener {
|
||||
@Override
|
||||
public void onRetryWriteException(List<Object> items, Exception ex) throws Exception {
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package com.baeldung.batch.understanding.exception;
|
||||
|
||||
import javax.batch.api.chunk.listener.SkipProcessListener;
|
||||
import javax.inject.Named;
|
||||
|
||||
@Named
|
||||
public class MySkipProcessorListener implements SkipProcessListener {
|
||||
@Override
|
||||
public void onSkipProcessItem(Object t, Exception e) throws Exception {
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package com.baeldung.batch.understanding.exception;
|
||||
|
||||
import javax.batch.api.chunk.listener.SkipReadListener;
|
||||
import javax.inject.Named;
|
||||
|
||||
@Named
|
||||
public class MySkipReadListener implements SkipReadListener {
|
||||
@Override
|
||||
public void onSkipReadItem(Exception e) throws Exception {
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package com.baeldung.batch.understanding.exception;
|
||||
|
||||
import javax.batch.api.chunk.listener.SkipWriteListener;
|
||||
import javax.inject.Named;
|
||||
import java.util.List;
|
||||
|
||||
@Named
|
||||
public class MySkipWriteListener implements SkipWriteListener {
|
||||
@Override
|
||||
public void onSkipWriteItem(List list, Exception e) throws Exception {
|
||||
list.remove(new MyOutputRecord(2));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<job id="customCheckPoint" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/jobXML_1_0.xsd" version="1.0">
|
||||
<step id="firstChunkStep" >
|
||||
<chunk item-count="3" checkpoint-policy="custom">
|
||||
<reader ref="simpleChunkItemReader"/>
|
||||
<processor ref="simpleChunkItemProcessor"/>
|
||||
<writer ref="simpleChunkWriter"/>
|
||||
<checkpoint-algorithm ref="customCheckPoint"/>
|
||||
</chunk>
|
||||
</step>
|
||||
</job>
|
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<job id="decideJobSequence" xmlns="http://xmlns.jcp.org/xml/ns/javaee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/jobXML_1_0.xsd"
|
||||
version="1.0">
|
||||
<step id="firstBatchStepStep1" next="firstDecider">
|
||||
<batchlet ref="simpleBatchLet" />
|
||||
</step>
|
||||
<decision id="firstDecider" ref="deciderJobSequence">
|
||||
<next on="nothing" to="firstBatchStepStep3"/>
|
||||
</decision>
|
||||
<step id="firstBatchStepStep2">
|
||||
<batchlet ref="simpleBatchLet" />
|
||||
</step>
|
||||
<step id="firstBatchStepStep3">
|
||||
<batchlet ref="simpleBatchLet" />
|
||||
</step>
|
||||
</job>
|
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<job id="flowJobSequence" xmlns="http://xmlns.jcp.org/xml/ns/javaee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/jobXML_1_0.xsd"
|
||||
version="1.0">
|
||||
<flow id="flow1" next="firstBatchStepStep3">
|
||||
<step id="firstChunkStepStep1" next="firstBatchStepStep2">
|
||||
<chunk item-count="3">
|
||||
<reader ref="simpleChunkItemReader" />
|
||||
<processor ref="simpleChunkItemProcessor" />
|
||||
<writer ref="simpleChunkWriter" />
|
||||
</chunk>
|
||||
</step>
|
||||
<step id="firstBatchStepStep2">
|
||||
<batchlet ref="simpleBatchLet" />
|
||||
</step>
|
||||
</flow>
|
||||
<step id="firstBatchStepStep3">
|
||||
<batchlet ref="simpleBatchLet" />
|
||||
</step>
|
||||
</job>
|
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<job id="injectSimpleBatchLet" xmlns="http://xmlns.jcp.org/xml/ns/javaee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/jobXML_1_0.xsd"
|
||||
version="1.0">
|
||||
<step id="firstStep" >
|
||||
<batchlet ref="injectSimpleBatchLet">
|
||||
<properties>
|
||||
<property name="name" value="helloThere" />
|
||||
</properties>
|
||||
</batchlet>
|
||||
</step>
|
||||
</job>
|
|
@ -0,0 +1,24 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<job id="injectSimpleBatchLet"
|
||||
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/jobXML_1_0.xsd"
|
||||
version="1.0">
|
||||
<step id="firstStep">
|
||||
<batchlet ref="injectSimpleBatchLet">
|
||||
<properties>
|
||||
<property name="name" value="#{partitionPlan['name']}" />
|
||||
</properties>
|
||||
</batchlet>
|
||||
<partition>
|
||||
<plan partitions="2">
|
||||
<properties partition="0">
|
||||
<property name="name" value="firstPartition" />
|
||||
</properties>
|
||||
<properties partition="1">
|
||||
<property name="name" value="secondpPartition" />
|
||||
</properties>
|
||||
</plan>
|
||||
</partition>
|
||||
</step>
|
||||
</job>
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<job id="simpleBatchLet" xmlns="http://xmlns.jcp.org/xml/ns/javaee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/jobXML_1_0.xsd"
|
||||
version="1.0">
|
||||
<step id="firstStep" >
|
||||
<batchlet ref="simpleBatchLet"/>
|
||||
</step>
|
||||
</job>
|
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<job id="simpleChunk" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/jobXML_1_0.xsd" version="1.0">
|
||||
<step id="firstChunkStep" >
|
||||
<chunk item-count="3">
|
||||
<reader ref="simpleChunkItemReader"/>
|
||||
<processor ref="simpleChunkItemProcessor"/>
|
||||
<writer ref="simpleChunkWriter"/>
|
||||
</chunk>
|
||||
</step>
|
||||
</job>
|
|
@ -0,0 +1,24 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<job id="simpleErrorChunk"
|
||||
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/jobXML_1_0.xsd"
|
||||
version="1.0">
|
||||
<step id="firstErrorChunkStep" >
|
||||
<chunk item-count="3">
|
||||
<reader ref="simpleChunkItemReaderError"/>
|
||||
<processor ref="simpleChunkItemProcessor"/>
|
||||
<writer ref="simpleChunkWriter"/>
|
||||
</chunk>
|
||||
</step>
|
||||
<step id="firstErrorSkipChunkStep" >
|
||||
<chunk item-count="3" skip-limit="3">
|
||||
<reader ref="simpleChunkItemReaderError"/>
|
||||
<processor ref="simpleChunkItemProcessor"/>
|
||||
<writer ref="simpleChunkWriter"/>
|
||||
<skippable-exception-classes>
|
||||
<include class="java.lang.RuntimeException"/>
|
||||
</skippable-exception-classes>
|
||||
</chunk>
|
||||
</step>
|
||||
</job>
|
|
@ -0,0 +1,26 @@
|
|||
<job id="simpleErrorSkipChunk" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/jobXML_1_0.xsd" version="1.0">
|
||||
<step id="errorStep" >
|
||||
<listeners>
|
||||
<listener ref="mySkipReadListener"/>
|
||||
<listener ref="mySkipProcessorListener"/>
|
||||
<listener ref="mySkipWriteListener"/>
|
||||
<listener ref="myRetryReadListener"/>
|
||||
<listener ref="myRetryProcessorListener"/>
|
||||
<listener ref="myRetryWriteListener"/>
|
||||
</listeners>
|
||||
<chunk checkpoint-policy="item" item-count="3" skip-limit="3" retry-limit="3">
|
||||
<reader ref="myItemReader"/>
|
||||
<processor ref="myItemProcessor"/>
|
||||
<writer ref="myItemWriter"/>
|
||||
<skippable-exception-classes>
|
||||
<include class="java.lang.RuntimeException"/>
|
||||
<include class="java.lang.UnsupportedOperationException"/>
|
||||
</skippable-exception-classes>
|
||||
<retryable-exception-classes>
|
||||
<include class="java.lang.IllegalArgumentException"/>
|
||||
<include class="java.lang.UnsupportedOperationException"/>
|
||||
</retryable-exception-classes>
|
||||
</chunk>
|
||||
</step>
|
||||
</job>
|
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<job id="simpleJobSequence"
|
||||
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/jobXML_1_0.xsd"
|
||||
version="1.0">
|
||||
<step id="firstChunkStepStep1" next="firstBatchStepStep2">
|
||||
<chunk item-count="3">
|
||||
<reader ref="simpleChunkItemReader"/>
|
||||
<processor ref="simpleChunkItemProcessor"/>
|
||||
<writer ref="simpleChunkWriter"/>
|
||||
</chunk>
|
||||
</step>
|
||||
<step id="firstBatchStepStep2" >
|
||||
<batchlet ref="simpleBatchLet"/>
|
||||
</step>
|
||||
</job>
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<job id="splitJobSequence"
|
||||
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/jobXML_1_0.xsd"
|
||||
version="1.0">
|
||||
<split id="split1" next="splitJobSequenceStep3">
|
||||
<flow id="flow1">
|
||||
<step id="splitJobSequenceStep1">
|
||||
<batchlet ref="simpleBatchLet" />
|
||||
</step>
|
||||
</flow>
|
||||
<flow id="flow2">
|
||||
<step id="splitJobSequenceStep2">
|
||||
<batchlet ref="simpleBatchLet" />
|
||||
</step>
|
||||
</flow>
|
||||
</split>
|
||||
<step id="splitJobSequenceStep3">
|
||||
<batchlet ref="simpleBatchLet" />
|
||||
</step>
|
||||
</job>
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans
|
||||
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
|
||||
http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
|
||||
bean-discovery-mode="all">
|
||||
</beans>
|
|
@ -0,0 +1,79 @@
|
|||
package com.baeldung.batch.understanding;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.batch.runtime.BatchRuntime;
|
||||
import javax.batch.runtime.BatchStatus;
|
||||
import javax.batch.runtime.JobExecution;
|
||||
import javax.batch.runtime.Metric;
|
||||
|
||||
public class BatchTestHelper {
|
||||
private static final int MAX_TRIES = 40;
|
||||
private static final int THREAD_SLEEP = 1000;
|
||||
|
||||
private BatchTestHelper() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public static JobExecution keepTestAlive(JobExecution jobExecution) throws InterruptedException {
|
||||
int maxTries = 0;
|
||||
while (!jobExecution.getBatchStatus()
|
||||
.equals(BatchStatus.COMPLETED)) {
|
||||
if (maxTries < MAX_TRIES) {
|
||||
maxTries++;
|
||||
Thread.sleep(THREAD_SLEEP);
|
||||
jobExecution = BatchRuntime.getJobOperator()
|
||||
.getJobExecution(jobExecution.getExecutionId());
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
Thread.sleep(THREAD_SLEEP);
|
||||
return jobExecution;
|
||||
}
|
||||
|
||||
public static JobExecution keepTestFailed(JobExecution jobExecution) throws InterruptedException {
|
||||
int maxTries = 0;
|
||||
while (!jobExecution.getBatchStatus()
|
||||
.equals(BatchStatus.FAILED)) {
|
||||
if (maxTries < MAX_TRIES) {
|
||||
maxTries++;
|
||||
Thread.sleep(THREAD_SLEEP);
|
||||
jobExecution = BatchRuntime.getJobOperator()
|
||||
.getJobExecution(jobExecution.getExecutionId());
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
Thread.sleep(THREAD_SLEEP);
|
||||
|
||||
return jobExecution;
|
||||
}
|
||||
|
||||
public static JobExecution keepTestStopped(JobExecution jobExecution) throws InterruptedException {
|
||||
int maxTries = 0;
|
||||
while (!jobExecution.getBatchStatus()
|
||||
.equals(BatchStatus.STOPPED)) {
|
||||
if (maxTries < MAX_TRIES) {
|
||||
maxTries++;
|
||||
Thread.sleep(THREAD_SLEEP);
|
||||
jobExecution = BatchRuntime.getJobOperator()
|
||||
.getJobExecution(jobExecution.getExecutionId());
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
Thread.sleep(THREAD_SLEEP);
|
||||
return jobExecution;
|
||||
}
|
||||
|
||||
public static Map<Metric.MetricType, Long> getMetricsMap(Metric[] metrics) {
|
||||
Map<Metric.MetricType, Long> metricsMap = new HashMap<>();
|
||||
for (Metric metric : metrics) {
|
||||
metricsMap.put(metric.getType(), metric.getValue());
|
||||
}
|
||||
return metricsMap;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package com.baeldung.batch.understanding;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import javax.batch.operations.JobOperator;
|
||||
import javax.batch.runtime.BatchRuntime;
|
||||
import javax.batch.runtime.BatchStatus;
|
||||
import javax.batch.runtime.JobExecution;
|
||||
import javax.batch.runtime.Metric;
|
||||
import javax.batch.runtime.StepExecution;
|
||||
import com.baeldung.batch.understanding.BatchTestHelper;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class CustomCheckPointUnitTest {
|
||||
@Test
|
||||
public void givenChunk_whenCustomCheckPoint_thenCommitCount_3() throws Exception {
|
||||
JobOperator jobOperator = BatchRuntime.getJobOperator();
|
||||
Long executionId = jobOperator.start("customCheckPoint", new Properties());
|
||||
JobExecution jobExecution = jobOperator.getJobExecution(executionId);
|
||||
jobExecution = BatchTestHelper.keepTestAlive(jobExecution);
|
||||
for (StepExecution stepExecution : jobOperator.getStepExecutions(executionId)) {
|
||||
if (stepExecution.getStepName()
|
||||
.equals("firstChunkStep")) {
|
||||
Map<Metric.MetricType, Long> metricsMap = BatchTestHelper.getMetricsMap(stepExecution.getMetrics());
|
||||
assertEquals(3L, metricsMap.get(Metric.MetricType.COMMIT_COUNT)
|
||||
.longValue());
|
||||
}
|
||||
}
|
||||
assertEquals(jobExecution.getBatchStatus(), BatchStatus.COMPLETED);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
package com.baeldung.batch.understanding;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.batch.operations.JobOperator;
|
||||
import javax.batch.runtime.BatchRuntime;
|
||||
import javax.batch.runtime.BatchStatus;
|
||||
import javax.batch.runtime.JobExecution;
|
||||
import javax.batch.runtime.StepExecution;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class JobSequenceUnitTest {
|
||||
@Test
|
||||
public void givenTwoSteps_thenBatch_CompleteWithSuccess() throws Exception {
|
||||
JobOperator jobOperator = BatchRuntime.getJobOperator();
|
||||
Long executionId = jobOperator.start("simpleJobSequence", new Properties());
|
||||
JobExecution jobExecution = jobOperator.getJobExecution(executionId);
|
||||
jobExecution = BatchTestHelper.keepTestAlive(jobExecution);
|
||||
assertEquals(2 , jobOperator.getStepExecutions(executionId).size());
|
||||
assertEquals(jobExecution.getBatchStatus(), BatchStatus.COMPLETED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenFlow_thenBatch_CompleteWithSuccess() throws Exception {
|
||||
JobOperator jobOperator = BatchRuntime.getJobOperator();
|
||||
Long executionId = jobOperator.start("flowJobSequence", new Properties());
|
||||
JobExecution jobExecution = jobOperator.getJobExecution(executionId);
|
||||
jobExecution = BatchTestHelper.keepTestAlive(jobExecution);
|
||||
assertEquals(3 , jobOperator.getStepExecutions(executionId).size());
|
||||
assertEquals(jobExecution.getBatchStatus(), BatchStatus.COMPLETED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenDecider_thenBatch_CompleteWithSuccess() throws Exception {
|
||||
JobOperator jobOperator = BatchRuntime.getJobOperator();
|
||||
Long executionId = jobOperator.start("decideJobSequence", new Properties());
|
||||
JobExecution jobExecution = jobOperator.getJobExecution(executionId);
|
||||
jobExecution = BatchTestHelper.keepTestAlive(jobExecution);
|
||||
List<StepExecution> stepExecutions = jobOperator.getStepExecutions(executionId);
|
||||
List<String> executedSteps = new ArrayList<>();
|
||||
for (StepExecution stepExecution : stepExecutions) {
|
||||
executedSteps.add(stepExecution.getStepName());
|
||||
}
|
||||
assertEquals(2, jobOperator.getStepExecutions(executionId).size());
|
||||
assertArrayEquals(new String[] { "firstBatchStepStep1", "firstBatchStepStep3" }, executedSteps.toArray());
|
||||
assertEquals(jobExecution.getBatchStatus(), BatchStatus.COMPLETED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenSplit_thenBatch_CompletesWithSuccess() throws Exception {
|
||||
JobOperator jobOperator = BatchRuntime.getJobOperator();
|
||||
Long executionId = jobOperator.start("splitJobSequence", new Properties());
|
||||
JobExecution jobExecution = jobOperator.getJobExecution(executionId);
|
||||
jobExecution = BatchTestHelper.keepTestAlive(jobExecution);
|
||||
List<StepExecution> stepExecutions = jobOperator.getStepExecutions(executionId);
|
||||
List<String> executedSteps = new ArrayList<>();
|
||||
for (StepExecution stepExecution : stepExecutions) {
|
||||
executedSteps.add(stepExecution.getStepName());
|
||||
}
|
||||
assertEquals(3, stepExecutions.size());
|
||||
assertTrue(executedSteps.contains("splitJobSequenceStep1"));
|
||||
assertTrue(executedSteps.contains("splitJobSequenceStep2"));
|
||||
assertTrue(executedSteps.contains("splitJobSequenceStep3"));
|
||||
assertTrue(executedSteps.get(0).equals("splitJobSequenceStep1") || executedSteps.get(0).equals("splitJobSequenceStep2"));
|
||||
assertTrue(executedSteps.get(1).equals("splitJobSequenceStep1") || executedSteps.get(1).equals("splitJobSequenceStep2"));
|
||||
assertTrue(executedSteps.get(2).equals("splitJobSequenceStep3"));
|
||||
assertEquals(jobExecution.getBatchStatus(), BatchStatus.COMPLETED);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
package com.baeldung.batch.understanding;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.batch.operations.JobOperator;
|
||||
import javax.batch.runtime.BatchRuntime;
|
||||
import javax.batch.runtime.BatchStatus;
|
||||
import javax.batch.runtime.JobExecution;
|
||||
import javax.batch.runtime.Metric;
|
||||
import javax.batch.runtime.StepExecution;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class SimpleBatchLetUnitTest {
|
||||
@Test
|
||||
public void givenBatchLet_thenBatch_CompleteWithSuccess() throws Exception {
|
||||
JobOperator jobOperator = BatchRuntime.getJobOperator();
|
||||
Long executionId = jobOperator.start("simpleBatchLet", new Properties());
|
||||
JobExecution jobExecution = jobOperator.getJobExecution(executionId);
|
||||
jobExecution = BatchTestHelper.keepTestAlive(jobExecution);
|
||||
assertEquals(jobExecution.getBatchStatus(), BatchStatus.COMPLETED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenBatchLetProperty_thenBatch_CompleteWithSuccess() throws Exception {
|
||||
JobOperator jobOperator = BatchRuntime.getJobOperator();
|
||||
Long executionId = jobOperator.start("injectionSimpleBatchLet", new Properties());
|
||||
JobExecution jobExecution = jobOperator.getJobExecution(executionId);
|
||||
jobExecution = BatchTestHelper.keepTestAlive(jobExecution);
|
||||
assertEquals(jobExecution.getBatchStatus(), BatchStatus.COMPLETED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenBatchLetPartition_thenBatch_CompleteWithSuccess() throws Exception {
|
||||
JobOperator jobOperator = BatchRuntime.getJobOperator();
|
||||
Long executionId = jobOperator.start("partitionSimpleBatchLet", new Properties());
|
||||
JobExecution jobExecution = jobOperator.getJobExecution(executionId);
|
||||
jobExecution = BatchTestHelper.keepTestAlive(jobExecution);
|
||||
assertEquals(jobExecution.getBatchStatus(), BatchStatus.COMPLETED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenBatchLetStarted_whenStopped_thenBatchStopped() throws Exception {
|
||||
JobOperator jobOperator = BatchRuntime.getJobOperator();
|
||||
Long executionId = jobOperator.start("simpleBatchLet", new Properties());
|
||||
JobExecution jobExecution = jobOperator.getJobExecution(executionId);
|
||||
jobOperator.stop(executionId);
|
||||
jobExecution = BatchTestHelper.keepTestStopped(jobExecution);
|
||||
assertEquals(jobExecution.getBatchStatus(), BatchStatus.STOPPED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenBatchLetStopped_whenRestarted_thenBatchCompletesSuccess() throws Exception {
|
||||
JobOperator jobOperator = BatchRuntime.getJobOperator();
|
||||
Long executionId = jobOperator.start("simpleBatchLet", new Properties());
|
||||
JobExecution jobExecution = jobOperator.getJobExecution(executionId);
|
||||
jobOperator.stop(executionId);
|
||||
jobExecution = BatchTestHelper.keepTestStopped(jobExecution);
|
||||
assertEquals(jobExecution.getBatchStatus(), BatchStatus.STOPPED);
|
||||
executionId = jobOperator.restart(jobExecution.getExecutionId(), new Properties());
|
||||
jobExecution = BatchTestHelper.keepTestAlive(jobOperator.getJobExecution(executionId));
|
||||
assertEquals(jobExecution.getBatchStatus(), BatchStatus.COMPLETED);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
package com.baeldung.batch.understanding;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.batch.operations.JobOperator;
|
||||
import javax.batch.runtime.BatchRuntime;
|
||||
import javax.batch.runtime.BatchStatus;
|
||||
import javax.batch.runtime.JobExecution;
|
||||
import javax.batch.runtime.Metric;
|
||||
import javax.batch.runtime.StepExecution;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class SimpleChunkUnitTest {
|
||||
@Test
|
||||
public void givenChunk_thenBatch_CompletesWithSucess() throws Exception {
|
||||
JobOperator jobOperator = BatchRuntime.getJobOperator();
|
||||
Long executionId = jobOperator.start("simpleChunk", new Properties());
|
||||
JobExecution jobExecution = jobOperator.getJobExecution(executionId);
|
||||
jobExecution = BatchTestHelper.keepTestAlive(jobExecution);
|
||||
List<StepExecution> stepExecutions = jobOperator.getStepExecutions(executionId);
|
||||
for (StepExecution stepExecution : stepExecutions) {
|
||||
if (stepExecution.getStepName()
|
||||
.equals("firstChunkStep")) {
|
||||
Map<Metric.MetricType, Long> metricsMap = BatchTestHelper.getMetricsMap(stepExecution.getMetrics());
|
||||
assertEquals(10L, metricsMap.get(Metric.MetricType.READ_COUNT)
|
||||
.longValue());
|
||||
assertEquals(10L / 2L, metricsMap.get(Metric.MetricType.WRITE_COUNT)
|
||||
.longValue());
|
||||
assertEquals(10L / 3 + (10L % 3 > 0 ? 1 : 0), metricsMap.get(Metric.MetricType.COMMIT_COUNT)
|
||||
.longValue());
|
||||
}
|
||||
}
|
||||
assertEquals(jobExecution.getBatchStatus(), BatchStatus.COMPLETED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenChunk__thenBatch_fetchInformation() throws Exception {
|
||||
JobOperator jobOperator = BatchRuntime.getJobOperator();
|
||||
Long executionId = jobOperator.start("simpleChunk", new Properties());
|
||||
JobExecution jobExecution = jobOperator.getJobExecution(executionId);
|
||||
jobExecution = BatchTestHelper.keepTestAlive(jobExecution);
|
||||
// job name contains simpleBatchLet which is the name of the file
|
||||
assertTrue(jobOperator.getJobNames().contains("simpleChunk"));
|
||||
// job parameters are empty
|
||||
assertTrue(jobOperator.getParameters(executionId).isEmpty());
|
||||
// step execution information
|
||||
List<StepExecution> stepExecutions = jobOperator.getStepExecutions(executionId);
|
||||
assertEquals("firstChunkStep", stepExecutions.get(0).getStepName());
|
||||
// finding out batch status
|
||||
assertEquals(BatchStatus.COMPLETED, stepExecutions.get(0).getBatchStatus());
|
||||
Map<Metric.MetricType, Long> metricTest = BatchTestHelper.getMetricsMap(stepExecutions.get(0).getMetrics());
|
||||
assertEquals(10L, metricTest.get(Metric.MetricType.READ_COUNT).longValue());
|
||||
assertEquals(5L, metricTest.get(Metric.MetricType.FILTER_COUNT).longValue());
|
||||
assertEquals(4L, metricTest.get(Metric.MetricType.COMMIT_COUNT).longValue());
|
||||
assertEquals(5L, metricTest.get(Metric.MetricType.WRITE_COUNT).longValue());
|
||||
assertEquals(0L, metricTest.get(Metric.MetricType.READ_SKIP_COUNT).longValue());
|
||||
assertEquals(0L, metricTest.get(Metric.MetricType.WRITE_SKIP_COUNT).longValue());
|
||||
assertEquals(0L, metricTest.get(Metric.MetricType.PROCESS_SKIP_COUNT).longValue());
|
||||
assertEquals(0L, metricTest.get(Metric.MetricType.ROLLBACK_COUNT).longValue());
|
||||
assertEquals(jobExecution.getBatchStatus(), BatchStatus.COMPLETED);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
package com.baeldung.batch.understanding;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import javax.batch.operations.JobOperator;
|
||||
import javax.batch.runtime.BatchRuntime;
|
||||
import javax.batch.runtime.BatchStatus;
|
||||
import javax.batch.runtime.JobExecution;
|
||||
import javax.batch.runtime.Metric.MetricType;
|
||||
import javax.batch.runtime.StepExecution;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class SimpleErrorChunkUnitTest {
|
||||
|
||||
@Test
|
||||
public void givenChunkError_thenBatch_CompletesWithFailed() throws Exception {
|
||||
JobOperator jobOperator = BatchRuntime.getJobOperator();
|
||||
Long executionId = jobOperator.start("simpleErrorChunk", new Properties());
|
||||
JobExecution jobExecution = jobOperator.getJobExecution(executionId);
|
||||
jobExecution = BatchTestHelper.keepTestFailed(jobExecution);
|
||||
System.out.println(jobExecution.getBatchStatus());
|
||||
assertEquals(jobExecution.getBatchStatus(), BatchStatus.FAILED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenChunkError_thenErrorSkipped_CompletesWithSuccess() throws Exception {
|
||||
JobOperator jobOperator = BatchRuntime.getJobOperator();
|
||||
Long executionId = jobOperator.start("simpleErrorSkipChunk", new Properties());
|
||||
JobExecution jobExecution = jobOperator.getJobExecution(executionId);
|
||||
jobExecution = BatchTestHelper.keepTestAlive(jobExecution);
|
||||
List<StepExecution> stepExecutions = jobOperator.getStepExecutions(executionId);
|
||||
for (StepExecution stepExecution : stepExecutions) {
|
||||
if (stepExecution.getStepName()
|
||||
.equals("errorStep")) {
|
||||
Map<MetricType, Long> metricsMap = BatchTestHelper.getMetricsMap(stepExecution.getMetrics());
|
||||
long skipCount = metricsMap.get(MetricType.PROCESS_SKIP_COUNT)
|
||||
.longValue();
|
||||
assertTrue("Skip count=" + skipCount, skipCount == 1l || skipCount == 2l);
|
||||
}
|
||||
}
|
||||
assertEquals(jobExecution.getBatchStatus(), BatchStatus.COMPLETED);
|
||||
}
|
||||
}
|
|
@ -87,6 +87,13 @@
|
|||
<artifactId>h2</artifactId>
|
||||
<version>${h2database.version}</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/io.arrow-kt/arrow-core -->
|
||||
<dependency>
|
||||
<groupId>io.arrow-kt</groupId>
|
||||
<artifactId>arrow-core</artifactId>
|
||||
<version>0.7.3</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
package com.baeldung.kotlin.arrow
|
||||
|
||||
import arrow.core.Either
|
||||
import arrow.core.filterOrElse
|
||||
import kotlin.math.sqrt
|
||||
|
||||
class FunctionalErrorHandlingWithEither {
|
||||
|
||||
sealed class ComputeProblem {
|
||||
object OddNumber : ComputeProblem()
|
||||
object NotANumber : ComputeProblem()
|
||||
}
|
||||
|
||||
fun parseInput(s : String) : Either<ComputeProblem, Int> = Either.cond(s.toIntOrNull() != null, {-> s.toInt()}, {->ComputeProblem.NotANumber} )
|
||||
|
||||
fun isEven(x : Int) : Boolean = x % 2 == 0
|
||||
|
||||
fun biggestDivisor(x: Int) : Int = biggestDivisor(x, 2)
|
||||
|
||||
fun biggestDivisor(x : Int, y : Int) : Int {
|
||||
if(x == y){
|
||||
return 1;
|
||||
}
|
||||
if(x % y == 0){
|
||||
return x / y;
|
||||
}
|
||||
return biggestDivisor(x, y+1)
|
||||
}
|
||||
|
||||
fun isSquareNumber(x : Int) : Boolean {
|
||||
val sqrt: Double = sqrt(x.toDouble())
|
||||
return sqrt % 1.0 == 0.0
|
||||
}
|
||||
|
||||
fun computeWithEither(input : String) : Either<ComputeProblem, Boolean> {
|
||||
return parseInput(input)
|
||||
.filterOrElse(::isEven) {->ComputeProblem.OddNumber}
|
||||
.map (::biggestDivisor)
|
||||
.map (::isSquareNumber)
|
||||
}
|
||||
|
||||
fun computeWithEitherClient(input : String) {
|
||||
val computeWithEither = computeWithEither(input)
|
||||
|
||||
when(computeWithEither){
|
||||
is Either.Right -> "The greatest divisor is square number: ${computeWithEither.b}"
|
||||
is Either.Left -> when(computeWithEither.a){
|
||||
is ComputeProblem.NotANumber -> "Wrong input! Not a number!"
|
||||
is ComputeProblem.OddNumber -> "It is an odd number!"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
package com.baeldung.kotlin.arrow
|
||||
|
||||
import arrow.core.None
|
||||
import arrow.core.Option
|
||||
import arrow.core.Some
|
||||
import kotlin.math.sqrt
|
||||
|
||||
class FunctionalErrorHandlingWithOption {
|
||||
|
||||
fun parseInput(s : String) : Option<Int> = Option.fromNullable(s.toIntOrNull())
|
||||
|
||||
fun isEven(x : Int) : Boolean = x % 2 == 0
|
||||
|
||||
fun biggestDivisor(x: Int) : Int = biggestDivisor(x, 2)
|
||||
|
||||
fun biggestDivisor(x : Int, y : Int) : Int {
|
||||
if(x == y){
|
||||
return 1;
|
||||
}
|
||||
if(x % y == 0){
|
||||
return x / y;
|
||||
}
|
||||
return biggestDivisor(x, y+1)
|
||||
}
|
||||
|
||||
fun isSquareNumber(x : Int) : Boolean {
|
||||
val sqrt: Double = sqrt(x.toDouble())
|
||||
return sqrt % 1.0 == 0.0
|
||||
}
|
||||
|
||||
fun computeWithOption(input : String) : Option<Boolean> {
|
||||
return parseInput(input)
|
||||
.filter(::isEven)
|
||||
.map(::biggestDivisor)
|
||||
.map(::isSquareNumber)
|
||||
}
|
||||
|
||||
fun computeWithOptionClient(input : String) : String{
|
||||
val computeOption = computeWithOption(input)
|
||||
|
||||
return when(computeOption){
|
||||
is None -> "Not an even number!"
|
||||
is Some -> "The greatest divisor is square number: ${computeOption.t}"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,143 @@
|
|||
package com.baeldung.kotlin.arrow
|
||||
|
||||
import arrow.core.*
|
||||
import org.junit.Assert
|
||||
import org.junit.Test
|
||||
|
||||
class FunctionalDataTypes {
|
||||
|
||||
@Test
|
||||
fun whenIdCreated_thanValueIsPresent(){
|
||||
val id = Id("foo")
|
||||
val justId = Id.just("foo");
|
||||
|
||||
Assert.assertEquals("foo", id.extract())
|
||||
Assert.assertEquals(justId, id)
|
||||
}
|
||||
|
||||
fun length(s : String) : Int = s.length
|
||||
|
||||
fun isBigEnough(i : Int) : Boolean = i > 10
|
||||
|
||||
@Test
|
||||
fun whenIdCreated_thanMapIsAssociative(){
|
||||
val foo = Id("foo")
|
||||
|
||||
val map1 = foo.map(::length)
|
||||
.map(::isBigEnough)
|
||||
val map2 = foo.map { s -> isBigEnough(length(s)) }
|
||||
|
||||
Assert.assertEquals(map1, map2)
|
||||
}
|
||||
|
||||
fun lengthId(s : String) : Id<Int> = Id.just(length(s))
|
||||
|
||||
fun isBigEnoughId(i : Int) : Id<Boolean> = Id.just(isBigEnough(i))
|
||||
|
||||
@Test
|
||||
fun whenIdCreated_thanFlatMapIsAssociative(){
|
||||
val bar = Id("bar")
|
||||
|
||||
val flatMap = bar.flatMap(::lengthId)
|
||||
.flatMap(::isBigEnoughId)
|
||||
val flatMap1 = bar.flatMap { s -> lengthId(s).flatMap(::isBigEnoughId) }
|
||||
|
||||
Assert.assertEquals(flatMap, flatMap1)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenOptionCreated_thanValueIsPresent(){
|
||||
val factory = Option.just(42)
|
||||
val constructor = Option(42)
|
||||
val emptyOptional = Option.empty<Integer>()
|
||||
val fromNullable = Option.fromNullable(null)
|
||||
|
||||
Assert.assertEquals(42, factory.getOrElse { -1 })
|
||||
Assert.assertEquals(factory, constructor)
|
||||
Assert.assertEquals(emptyOptional, fromNullable)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenOptionCreated_thanConstructorDifferFromFactory(){
|
||||
val constructor : Option<String?> = Option(null)
|
||||
val fromNullable : Option<String?> = Option.fromNullable(null)
|
||||
|
||||
try{
|
||||
constructor.map { s -> s!!.length }
|
||||
Assert.fail()
|
||||
} catch (e : KotlinNullPointerException){
|
||||
fromNullable.map { s->s!!.length }
|
||||
}
|
||||
Assert.assertNotEquals(constructor, fromNullable)
|
||||
}
|
||||
|
||||
fun wrapper(x : Integer?) : Option<Int> = if (x == null) Option.just(-1) else Option.just(x.toInt())
|
||||
|
||||
@Test
|
||||
fun whenOptionFromNullableCreated_thanItBreaksLeftIdentity(){
|
||||
val optionFromNull = Option.fromNullable(null)
|
||||
|
||||
Assert.assertNotEquals(optionFromNull.flatMap(::wrapper), wrapper(null))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenEitherCreated_thanOneValueIsPresent(){
|
||||
val rightOnly : Either<String,Int> = Either.right(42)
|
||||
val leftOnly : Either<String,Int> = Either.left("foo")
|
||||
|
||||
Assert.assertTrue(rightOnly.isRight())
|
||||
Assert.assertTrue(leftOnly.isLeft())
|
||||
Assert.assertEquals(42, rightOnly.getOrElse { -1 })
|
||||
Assert.assertEquals(-1, leftOnly.getOrElse { -1 })
|
||||
|
||||
Assert.assertEquals(0, rightOnly.map { it % 2 }.getOrElse { -1 })
|
||||
Assert.assertEquals(-1, leftOnly.map { it % 2 }.getOrElse { -1 })
|
||||
Assert.assertTrue(rightOnly.flatMap { Either.Right(it % 2) }.isRight())
|
||||
Assert.assertTrue(leftOnly.flatMap { Either.Right(it % 2) }.isLeft())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenEvalNowUsed_thenMapEvaluatedLazily(){
|
||||
val now = Eval.now(1)
|
||||
Assert.assertEquals(1, now.value())
|
||||
|
||||
var counter : Int = 0
|
||||
val map = now.map { x -> counter++; x+1 }
|
||||
Assert.assertEquals(0, counter)
|
||||
|
||||
val value = map.value()
|
||||
Assert.assertEquals(2, value)
|
||||
Assert.assertEquals(1, counter)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenEvalLaterUsed_theResultIsMemoized(){
|
||||
var counter : Int = 0
|
||||
val later = Eval.later { counter++; counter }
|
||||
Assert.assertEquals(0, counter)
|
||||
|
||||
val firstValue = later.value()
|
||||
Assert.assertEquals(1, firstValue)
|
||||
Assert.assertEquals(1, counter)
|
||||
|
||||
val secondValue = later.value()
|
||||
Assert.assertEquals(1, secondValue)
|
||||
Assert.assertEquals(1, counter)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenEvalAlwaysUsed_theResultIsNotMemoized(){
|
||||
var counter : Int = 0
|
||||
val later = Eval.always { counter++; counter }
|
||||
Assert.assertEquals(0, counter)
|
||||
|
||||
val firstValue = later.value()
|
||||
Assert.assertEquals(1, firstValue)
|
||||
Assert.assertEquals(1, counter)
|
||||
|
||||
val secondValue = later.value()
|
||||
Assert.assertEquals(2, secondValue)
|
||||
Assert.assertEquals(2, counter)
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
package com.baeldung.kotlin.arrow
|
||||
|
||||
import arrow.core.Either
|
||||
import com.baeldung.kotlin.arrow.FunctionalErrorHandlingWithEither.ComputeProblem.NotANumber
|
||||
import com.baeldung.kotlin.arrow.FunctionalErrorHandlingWithEither.ComputeProblem.OddNumber
|
||||
import org.junit.Assert
|
||||
import org.junit.Test
|
||||
|
||||
class FunctionalErrorHandlingWithEitherTest {
|
||||
|
||||
val operator = FunctionalErrorHandlingWithEither()
|
||||
|
||||
@Test
|
||||
fun givenInvalidInput_whenComputeInvoked_NotANumberIsPresent(){
|
||||
val computeWithEither = operator.computeWithEither("bar")
|
||||
|
||||
Assert.assertTrue(computeWithEither.isLeft())
|
||||
when(computeWithEither){
|
||||
is Either.Left -> when(computeWithEither.a){
|
||||
NotANumber -> "Ok."
|
||||
else -> Assert.fail()
|
||||
}
|
||||
else -> Assert.fail()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenOddNumberInput_whenComputeInvoked_OddNumberIsPresent(){
|
||||
val computeWithEither = operator.computeWithEither("121")
|
||||
|
||||
Assert.assertTrue(computeWithEither.isLeft())
|
||||
when(computeWithEither){
|
||||
is Either.Left -> when(computeWithEither.a){
|
||||
OddNumber -> "Ok."
|
||||
else -> Assert.fail()
|
||||
}
|
||||
else -> Assert.fail()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenEvenNumberWithoutSquare_whenComputeInvoked_OddNumberIsPresent(){
|
||||
val computeWithEither = operator.computeWithEither("100")
|
||||
|
||||
Assert.assertTrue(computeWithEither.isRight())
|
||||
when(computeWithEither){
|
||||
is Either.Right -> when(computeWithEither.b){
|
||||
false -> "Ok."
|
||||
else -> Assert.fail()
|
||||
}
|
||||
else -> Assert.fail()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenEvenNumberWithSquare_whenComputeInvoked_OddNumberIsPresent(){
|
||||
val computeWithEither = operator.computeWithEither("98")
|
||||
|
||||
Assert.assertTrue(computeWithEither.isRight())
|
||||
when(computeWithEither){
|
||||
is Either.Right -> when(computeWithEither.b){
|
||||
true -> "Ok."
|
||||
else -> Assert.fail()
|
||||
}
|
||||
else -> Assert.fail()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package com.baeldung.kotlin.arrow
|
||||
|
||||
import org.junit.Assert
|
||||
import org.junit.Test
|
||||
|
||||
class FunctionalErrorHandlingWithOptionTest {
|
||||
|
||||
val operator = FunctionalErrorHandlingWithOption()
|
||||
|
||||
@Test
|
||||
fun givenInvalidInput_thenErrorMessageIsPresent(){
|
||||
val useComputeOption = operator.computeWithOptionClient("foo")
|
||||
Assert.assertEquals("Not an even number!", useComputeOption)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenOddNumberInput_thenErrorMessageIsPresent(){
|
||||
val useComputeOption = operator.computeWithOptionClient("539")
|
||||
Assert.assertEquals("Not an even number!",useComputeOption)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenEvenNumberInputWithNonSquareNum_thenFalseMessageIsPresent(){
|
||||
val useComputeOption = operator.computeWithOptionClient("100")
|
||||
Assert.assertEquals("The greatest divisor is square number: false",useComputeOption)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenEvenNumberInputWithSquareNum_thenTrueMessageIsPresent(){
|
||||
val useComputeOption = operator.computeWithOptionClient("242")
|
||||
Assert.assertEquals("The greatest divisor is square number: true",useComputeOption)
|
||||
}
|
||||
|
||||
}
|
|
@ -720,11 +720,11 @@
|
|||
</dependencies>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<!-- <repository>
|
||||
<id>maven2-repository.dev.java.net</id>
|
||||
<name>Java.net repository</name>
|
||||
<url>http://download.java.net/maven/2</url>
|
||||
</repository>
|
||||
</repository> -->
|
||||
<repository>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.baeldung</groupId>
|
||||
|
@ -43,6 +44,12 @@
|
|||
<artifactId>disruptor</artifactId>
|
||||
<version>${disruptor.version}</version>
|
||||
</dependency>
|
||||
<!-- Webflux for reactive logging example -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-webflux</artifactId>
|
||||
<version>${spring-boot.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
|
@ -50,6 +57,7 @@
|
|||
<log4j-api.version>2.7</log4j-api.version>
|
||||
<log4j-core.version>2.7</log4j-core.version>
|
||||
<disruptor.version>3.3.6</disruptor.version>
|
||||
<spring-boot.version>2.1.0.RELEASE</spring-boot.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,21 @@
|
|||
package com.baeldung.webFluxLogging;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
public class WebFluxLoggingExample {
|
||||
|
||||
public static void main(String[] args) {
|
||||
Flux<Integer> reactiveStream = Flux.range(1, 5).log();
|
||||
|
||||
reactiveStream.subscribe();
|
||||
|
||||
reactiveStream = Flux.range(1, 5).log().take(3);
|
||||
|
||||
reactiveStream.subscribe();
|
||||
|
||||
reactiveStream = Flux.range(1, 5).take(3).log();
|
||||
|
||||
reactiveStream.subscribe();
|
||||
}
|
||||
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
## Relevant articles:
|
|
@ -77,7 +77,8 @@
|
|||
<rest-assured.version>3.1.0</rest-assured.version>
|
||||
<!-- plugins -->
|
||||
<thin.version>1.0.11.RELEASE</thin.version>
|
||||
<spring-boot.version>2.1.0.RELEASE</spring-boot.version>
|
||||
<oauth-auto.version>2.1.0.RELEASE</oauth-auto.version>
|
||||
<spring-boot.version>2.0.5.RELEASE</spring-boot.version>
|
||||
</properties>
|
||||
</project>
|
||||
|
||||
|
||||
|
|
|
@ -12,3 +12,4 @@
|
|||
- [The DAO Pattern in Java](http://www.baeldung.com/java-dao-pattern)
|
||||
- [Interpreter Design Pattern in Java](http://www.baeldung.com/java-interpreter-pattern)
|
||||
- [State Design Pattern in Java](https://www.baeldung.com/java-state-design-pattern)
|
||||
- [The Decorator Pattern in Java](https://www.baeldung.com/java-decorator-pattern)
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
package com.baeldung.jpa.entitygraph;
|
||||
|
||||
import com.baeldung.jpa.entitygraph.model.Post;
|
||||
import com.baeldung.jpa.entitygraph.repo.PostRepository;
|
||||
|
||||
public class MainApp {
|
||||
|
||||
public static void main(String... args) {
|
||||
Long postId = 1L;
|
||||
Post post = null;
|
||||
PostRepository postRepository = new PostRepository();
|
||||
|
||||
//Using EntityManager.find().
|
||||
post = postRepository.find(postId);
|
||||
post = postRepository.findWithEntityGraph(postId);
|
||||
post = postRepository.findWithEntityGraph2(postId);
|
||||
|
||||
//Using JPQL: Query and TypedQuery
|
||||
post = postRepository.findUsingJpql(postId);
|
||||
|
||||
//Using Criteria API
|
||||
post = postRepository.findUsingCriteria(postId);
|
||||
|
||||
postRepository.clean();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
package com.baeldung.jpa.entitygraph.model;
|
||||
|
||||
import javax.persistence.*;
|
||||
|
||||
@Entity
|
||||
public class Comment {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
private String reply;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn
|
||||
private Post post;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn
|
||||
private User user;
|
||||
//...
|
||||
|
||||
public Comment() {
|
||||
}
|
||||
|
||||
public Comment(String reply, Post post, User user) {
|
||||
this.reply = reply;
|
||||
this.post = post;
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getReply() {
|
||||
return reply;
|
||||
}
|
||||
|
||||
public void setReply(String reply) {
|
||||
this.reply = reply;
|
||||
}
|
||||
|
||||
public Post getPost() {
|
||||
return post;
|
||||
}
|
||||
|
||||
public void setPost(Post post) {
|
||||
this.post = post;
|
||||
}
|
||||
|
||||
public User getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
public void setUser(User user) {
|
||||
this.user = user;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
package com.baeldung.jpa.entitygraph.model;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@NamedEntityGraph(
|
||||
name = "post-entity-graph",
|
||||
attributeNodes = {
|
||||
@NamedAttributeNode("subject"),
|
||||
@NamedAttributeNode("user"),
|
||||
@NamedAttributeNode("comments"),
|
||||
}
|
||||
)
|
||||
@NamedEntityGraph(
|
||||
name = "post-entity-graph-with-comment-users",
|
||||
attributeNodes = {
|
||||
@NamedAttributeNode("subject"),
|
||||
@NamedAttributeNode("user"),
|
||||
@NamedAttributeNode(value = "comments", subgraph = "comments-subgraph"),
|
||||
},
|
||||
subgraphs = {
|
||||
@NamedSubgraph(
|
||||
name = "comments-subgraph",
|
||||
attributeNodes = {
|
||||
@NamedAttributeNode("user")
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
@Entity
|
||||
public class Post {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
private String subject;
|
||||
@OneToMany(mappedBy = "post")
|
||||
private List<Comment> comments = new ArrayList<>();
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn
|
||||
private User user;
|
||||
//...
|
||||
|
||||
public Post() {
|
||||
}
|
||||
|
||||
public Post(String subject, User user) {
|
||||
this.subject = subject;
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getSubject() {
|
||||
return subject;
|
||||
}
|
||||
|
||||
public void setSubject(String subject) {
|
||||
this.subject = subject;
|
||||
}
|
||||
|
||||
public List<Comment> getComments() {
|
||||
return comments;
|
||||
}
|
||||
|
||||
public void setComments(List<Comment> comments) {
|
||||
this.comments = comments;
|
||||
}
|
||||
|
||||
public User getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
public void setUser(User user) {
|
||||
this.user = user;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
package com.baeldung.jpa.entitygraph.model;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
|
||||
@Entity
|
||||
public class User {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
private String name;
|
||||
private String email;
|
||||
|
||||
//...
|
||||
|
||||
public User() {
|
||||
}
|
||||
|
||||
public User(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
package com.baeldung.jpa.entitygraph.repo;
|
||||
|
||||
import com.baeldung.jpa.entitygraph.model.Post;
|
||||
|
||||
import javax.persistence.*;
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Root;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class PostRepository {
|
||||
private EntityManagerFactory emf = null;
|
||||
|
||||
|
||||
public PostRepository() {
|
||||
Map properties = new HashMap();
|
||||
properties.put("hibernate.show_sql", "true");
|
||||
properties.put("hibernate.format_sql", "true");
|
||||
emf = Persistence.createEntityManagerFactory("entity-graph-pu", properties);
|
||||
}
|
||||
|
||||
public Post find(Long id) {
|
||||
EntityManager entityManager = emf.createEntityManager();
|
||||
|
||||
Post post = entityManager.find(Post.class, id);
|
||||
|
||||
entityManager.close();
|
||||
return post;
|
||||
}
|
||||
|
||||
public Post findWithEntityGraph(Long id) {
|
||||
EntityManager entityManager = emf.createEntityManager();
|
||||
|
||||
EntityGraph entityGraph = entityManager.getEntityGraph("post-entity-graph");
|
||||
Map<String, Object> properties = new HashMap<>();
|
||||
properties.put("javax.persistence.fetchgraph", entityGraph);
|
||||
Post post = entityManager.find(Post.class, id, properties);
|
||||
|
||||
entityManager.close();
|
||||
return post;
|
||||
}
|
||||
|
||||
public Post findWithEntityGraph2(Long id) {
|
||||
EntityManager entityManager = emf.createEntityManager();
|
||||
|
||||
EntityGraph<Post> entityGraph = entityManager.createEntityGraph(Post.class);
|
||||
entityGraph.addAttributeNodes("subject");
|
||||
entityGraph.addAttributeNodes("user");
|
||||
entityGraph.addSubgraph("comments")
|
||||
.addAttributeNodes("user");
|
||||
|
||||
Map<String, Object> properties = new HashMap<>();
|
||||
properties.put("javax.persistence.fetchgraph", entityGraph);
|
||||
Post post = entityManager.find(Post.class, id, properties);
|
||||
|
||||
entityManager.close();
|
||||
return post;
|
||||
}
|
||||
|
||||
public Post findUsingJpql(Long id) {
|
||||
EntityManager entityManager = emf.createEntityManager();
|
||||
|
||||
EntityGraph entityGraph = entityManager.getEntityGraph("post-entity-graph-with-comment-users");
|
||||
Post post = entityManager.createQuery("Select p from Post p where p.id=:id", Post.class)
|
||||
.setParameter("id", id)
|
||||
.setHint("javax.persistence.fetchgraph", entityGraph)
|
||||
.getSingleResult();
|
||||
|
||||
entityManager.close();
|
||||
return post;
|
||||
}
|
||||
|
||||
public Post findUsingCriteria(Long id) {
|
||||
EntityManager entityManager = emf.createEntityManager();
|
||||
|
||||
EntityGraph entityGraph = entityManager.getEntityGraph("post-entity-graph-with-comment-users");
|
||||
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
|
||||
CriteriaQuery<Post> criteriaQuery = criteriaBuilder.createQuery(Post.class);
|
||||
Root<Post> root = criteriaQuery.from(Post.class);
|
||||
criteriaQuery.where(criteriaBuilder.equal(root.<Long>get("id"), id));
|
||||
TypedQuery<Post> typedQuery = entityManager.createQuery(criteriaQuery);
|
||||
typedQuery.setHint("javax.persistence.loadgraph", entityGraph);
|
||||
Post post = typedQuery.getSingleResult();
|
||||
|
||||
entityManager.close();
|
||||
return post;
|
||||
}
|
||||
|
||||
public void clean() {
|
||||
emf.close();
|
||||
}
|
||||
}
|
|
@ -49,4 +49,21 @@
|
|||
</properties>
|
||||
</persistence-unit>
|
||||
|
||||
<persistence-unit name="entity-graph-pu" transaction-type="RESOURCE_LOCAL">
|
||||
<class>com.baeldung.jpa.entitygraph.model.Post</class>
|
||||
<class>com.baeldung.jpa.entitygraph.model.User</class>
|
||||
<class>com.baeldung.jpa.entitygraph.model.Comment</class>
|
||||
<exclude-unlisted-classes>true</exclude-unlisted-classes>
|
||||
<properties>
|
||||
|
||||
<!--H2-->
|
||||
<property name="javax.persistence.jdbc.driver" value="org.h2.Driver"/>
|
||||
<property name="javax.persistence.jdbc.url"
|
||||
value="jdbc:h2:mem:entitygraphdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE"/>
|
||||
|
||||
<property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/>
|
||||
<property name="javax.persistence.sql-load-script-source" value="data-init.sql"/>
|
||||
</properties>
|
||||
</persistence-unit>
|
||||
|
||||
</persistence>
|
|
@ -0,0 +1,8 @@
|
|||
INSERT INTO `USER` (`ID`,`NAME`,`EMAIL`) VALUES (1,'user1','user1@test.com');
|
||||
INSERT INTO `USER` (`ID`,`NAME`,`EMAIL`) VALUES (2,'user2','user2@test.com');
|
||||
INSERT INTO `USER` (`ID`,`NAME`,`EMAIL`) VALUES (3,'user3','user3@test.com');
|
||||
|
||||
INSERT INTO `POST` (`ID`,`SUBJECT`,`USER_ID`) VALUES (1,'JPA Entity Graph In Action',1);
|
||||
|
||||
INSERT INTO `COMMENT` (`ID`,`REPLY`,`POST_ID`,`USER_ID`) VALUES (1,'Nice !!',1,2);
|
||||
INSERT INTO `COMMENT` (`ID`,`REPLY`,`POST_ID`,`USER_ID`) VALUES (2,'Cool !!',1,3);
|
|
@ -0,0 +1,68 @@
|
|||
package com.baeldung.jpa.entitygraph.repo;
|
||||
|
||||
import com.baeldung.jpa.entitygraph.model.Comment;
|
||||
import com.baeldung.jpa.entitygraph.model.Post;
|
||||
import com.baeldung.jpa.entitygraph.model.User;
|
||||
import org.hibernate.LazyInitializationException;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class PostRepositoryIntegrationTest {
|
||||
|
||||
private static PostRepository postRepository = null;
|
||||
|
||||
@BeforeClass
|
||||
public static void once() {
|
||||
postRepository = new PostRepository();
|
||||
}
|
||||
|
||||
@Test(expected = LazyInitializationException.class)
|
||||
public void find() {
|
||||
Post post = postRepository.find(1L);
|
||||
assertNotNull(post.getUser());
|
||||
String email = post.getUser().getEmail();
|
||||
assertNull(email);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findWithEntityGraph() {
|
||||
Post post = postRepository.findWithEntityGraph(1L);
|
||||
assertNotNull(post.getUser());
|
||||
String email = post.getUser().getEmail();
|
||||
assertNotNull(email);
|
||||
}
|
||||
|
||||
@Test(expected = LazyInitializationException.class)
|
||||
public void findWithEntityGraph_Comment_Without_User() {
|
||||
Post post = postRepository.findWithEntityGraph(1L);
|
||||
assertNotNull(post.getUser());
|
||||
String email = post.getUser().getEmail();
|
||||
assertNotNull(email);
|
||||
assertNotNull(post.getComments());
|
||||
assertEquals(post.getComments().size(), 2);
|
||||
Comment comment = post.getComments().get(0);
|
||||
assertNotNull(comment);
|
||||
User user = comment.getUser();
|
||||
user.getEmail();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findWithEntityGraph2_Comment_With_User() {
|
||||
Post post = postRepository.findWithEntityGraph2(1L);
|
||||
assertNotNull(post.getComments());
|
||||
assertEquals(post.getComments().size(), 2);
|
||||
Comment comment = post.getComments().get(0);
|
||||
assertNotNull(comment);
|
||||
User user = comment.getUser();
|
||||
assertNotNull(user);
|
||||
assertEquals(user.getEmail(), "user2@test.com");
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void destroy() {
|
||||
postRepository.clean();
|
||||
}
|
||||
}
|
|
@ -4,3 +4,4 @@
|
|||
- [Configuring Separate Spring DataSource for Tests](http://www.baeldung.com/spring-testing-separate-data-source)
|
||||
- [Quick Guide on data.sql and schema.sql Files in Spring Boot](http://www.baeldung.com/spring-boot-data-sql-and-schema-sql)
|
||||
- [Configuring a Tomcat Connection Pool in Spring Boot](https://www.baeldung.com/spring-boot-tomcat-connection-pool)
|
||||
- [Hibernate Field Naming with Spring Boot](https://www.baeldung.com/hibernate-field-naming-spring-boot)
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
- [Query Entities by Dates and Times with Spring Data JPA](https://www.baeldung.com/spring-data-jpa-query-by-date)
|
||||
- [DDD Aggregates and @DomainEvents](https://www.baeldung.com/spring-data-ddd)
|
||||
- [Spring Data – CrudRepository save() Method](https://www.baeldung.com/spring-data-crud-repository-save)
|
||||
- [Limiting Query Results with JPA and Spring Data JPA](https://www.baeldung.com/jpa-limit-query-results)
|
||||
|
||||
### Eclipse Config
|
||||
After importing the project into Eclipse, you may see the following error:
|
||||
|
|
|
@ -12,3 +12,4 @@
|
|||
- [Spring Data MongoDB: Projections and Aggregations](http://www.baeldung.com/spring-data-mongodb-projections-aggregations)
|
||||
- [Spring Data Annotations](http://www.baeldung.com/spring-data-annotations)
|
||||
- [Spring Data MongoDB Transactions](https://www.baeldung.com/spring-data-mongodb-transactions )
|
||||
- [ZonedDateTime with Spring Data MongoDB](https://www.baeldung.com/spring-data-mongodb-zoneddatetime)
|
||||
|
|
840
pom.xml
840
pom.xml
|
@ -466,6 +466,7 @@
|
|||
<module>spring-5-reactive-client</module>
|
||||
<module>spring-5-mvc</module>
|
||||
<module>spring-5-security</module>
|
||||
<module>spring-5-security-oauth</module>
|
||||
<module>spring-5-reactive-oauth</module>
|
||||
<module>spring-activiti</module>
|
||||
<module>spring-akka</module>
|
||||
|
@ -738,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>
|
||||
|
@ -768,6 +809,7 @@
|
|||
<module>spring-5-reactive-client</module>
|
||||
<module>spring-5-reactive-security</module>
|
||||
<module>spring-5-security</module>
|
||||
<module>spring-5-security-oauth</module>
|
||||
<module>spring-activiti</module>
|
||||
<module>spring-akka</module>
|
||||
<module>spring-all</module>
|
||||
|
@ -894,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>
|
||||
|
||||
|
@ -994,6 +1463,7 @@
|
|||
<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>
|
||||
|
@ -1198,374 +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-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>
|
||||
|
||||
|
@ -1635,7 +1737,7 @@
|
|||
<gib.skipTestsForNotImpactedModules>true</gib.skipTestsForNotImpactedModules>
|
||||
<gib.failOnMissingGitDir>false</gib.failOnMissingGitDir>
|
||||
<gib.failOnError>false</gib.failOnError>
|
||||
<!-- <gib.enabled>false</gib.enabled> -->
|
||||
<gib.enabled>false</gib.enabled>
|
||||
|
||||
<junit.version>4.12</junit.version>
|
||||
<org.hamcrest.version>1.3</org.hamcrest.version>
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
### Relevant Articles:
|
||||
|
||||
- [Spring Security OAuth Login with WebFlux](https://www.baeldung.com/spring-oauth-login-webflux)
|
|
@ -8,8 +8,8 @@ import org.springframework.http.server.reactive.HttpHandler;
|
|||
import org.springframework.http.server.reactive.ReactorHttpHandlerAdapter;
|
||||
import org.springframework.web.reactive.config.EnableWebFlux;
|
||||
import org.springframework.web.server.adapter.WebHttpHandlerBuilder;
|
||||
import reactor.netty.DisposableServer;
|
||||
import reactor.netty.http.server.HttpServer;
|
||||
import reactor.ipc.netty.NettyContext;
|
||||
import reactor.ipc.netty.http.server.HttpServer;
|
||||
|
||||
@ComponentScan(basePackages = {"com.baeldung.reactive.security"})
|
||||
@EnableWebFlux
|
||||
|
@ -18,16 +18,17 @@ public class SpringSecurity5Application {
|
|||
public static void main(String[] args) {
|
||||
try (AnnotationConfigApplicationContext context =
|
||||
new AnnotationConfigApplicationContext(SpringSecurity5Application.class)) {
|
||||
context.getBean(DisposableServer.class).onDispose().block();
|
||||
context.getBean(NettyContext.class).onClose().block();
|
||||
}
|
||||
}
|
||||
|
||||
@Bean
|
||||
public DisposableServer nettyContext(ApplicationContext context) {
|
||||
public NettyContext nettyContext(ApplicationContext context) {
|
||||
HttpHandler handler = WebHttpHandlerBuilder.applicationContext(context)
|
||||
.build();
|
||||
ReactorHttpHandlerAdapter adapter = new ReactorHttpHandlerAdapter(handler);
|
||||
return HttpServer.create().host("localhost").port(8080).handle(adapter).bind().block();
|
||||
HttpServer httpServer = HttpServer.create("localhost", 8080);
|
||||
return httpServer.newHandler(adapter).block();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -10,8 +10,8 @@ import org.springframework.web.reactive.function.server.RouterFunctions;
|
|||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.netty.DisposableServer;
|
||||
import reactor.netty.http.server.HttpServer;
|
||||
import reactor.ipc.netty.NettyContext;
|
||||
import reactor.ipc.netty.http.server.HttpServer;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
|
@ -19,11 +19,11 @@ import static org.springframework.web.reactive.function.server.RequestPredicates
|
|||
import static org.springframework.web.reactive.function.server.RequestPredicates.POST;
|
||||
|
||||
public class Spring5ReactiveServerClientIntegrationTest {
|
||||
private static DisposableServer nettyServer;
|
||||
private static NettyContext nettyContext;
|
||||
|
||||
@BeforeAll
|
||||
public static void setUp() throws Exception {
|
||||
HttpServer server = HttpServer.create().host("localhost").port(8080);
|
||||
HttpServer server = HttpServer.create("localhost", 8080);
|
||||
RouterFunction<?> route = RouterFunctions.route(POST("/task/process"), request -> ServerResponse.ok()
|
||||
.body(request.bodyToFlux(Task.class)
|
||||
.map(ll -> new Task("TaskName", 1)), Task.class))
|
||||
|
@ -31,12 +31,13 @@ public class Spring5ReactiveServerClientIntegrationTest {
|
|||
.body(Mono.just("server is alive"), String.class)));
|
||||
HttpHandler httpHandler = RouterFunctions.toHttpHandler(route);
|
||||
ReactorHttpHandlerAdapter adapter = new ReactorHttpHandlerAdapter(httpHandler);
|
||||
nettyServer = server.handle(adapter).bind().block();
|
||||
nettyContext = server.newHandler(adapter)
|
||||
.block();
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
public static void shutDown() {
|
||||
nettyServer.dispose();
|
||||
nettyContext.dispose();
|
||||
}
|
||||
|
||||
// @Test
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
## Relevant articles:
|
||||
|
||||
- [Spring Security 5 -OAuth2 Login](http://www.baeldung.com/spring-security-5-oauth2-login)
|
||||
- [Extracting Principal and Authorities using Spring Security OAuth](https://www.baeldung.com/spring-security-oauth-principal-authorities-extractor)
|
|
@ -0,0 +1,73 @@
|
|||
<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>
|
||||
<artifactId>spring-5-security-oauth</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
<name>spring-5-security-oauth</name>
|
||||
<description>spring 5 security oauth sample project</description>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-boot-2</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../parent-boot-2</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-security</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-thymeleaf</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.thymeleaf.extras</groupId>
|
||||
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- oauth2 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.security.oauth.boot</groupId>
|
||||
<artifactId>spring-security-oauth2-autoconfigure</artifactId>
|
||||
<version>${oauth-auto.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-oauth2-client</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-oauth2-jose</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<oauth-auto.version>2.0.1.RELEASE</oauth-auto.version>
|
||||
<start-class>com.baeldung.oauth2.SpringOAuthApplication</start-class>
|
||||
</properties>
|
||||
|
||||
</project>
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue