commit
6a8dc98ba3
@ -3,7 +3,7 @@
|
||||
This module contains articles about Apache CXF
|
||||
|
||||
## Relevant Articles:
|
||||
- [Introduction to Apache CXF Aegis Data Binding](https://www.baeldung.com/aegis-data-binding-in-apache-cxf)
|
||||
|
||||
- [Apache CXF Support for RESTful Web Services](https://www.baeldung.com/apache-cxf-rest-api)
|
||||
- [A Guide to Apache CXF with Spring](https://www.baeldung.com/apache-cxf-with-spring)
|
||||
- [Introduction to Apache CXF](https://www.baeldung.com/introduction-to-apache-cxf)
|
||||
|
3
apache-cxf/cxf-aegis/README.md
Normal file
3
apache-cxf/cxf-aegis/README.md
Normal file
@ -0,0 +1,3 @@
|
||||
### Relevant Articles:
|
||||
|
||||
- [Introduction to Apache CXF Aegis Data Binding](https://www.baeldung.com/aegis-data-binding-in-apache-cxf)
|
@ -10,8 +10,8 @@ import java.util.Map;
|
||||
|
||||
public class AppSyncClientHelper {
|
||||
|
||||
static String apiUrl = "https://m4i3b6icrrb7livfbypfspiifi.appsync-api.us-east-2.amazonaws.com";
|
||||
static String apiKey = "da2-bm4rpatkkrc5jfyhvvq7itjeke";
|
||||
static String apiUrl = "<INSERT API URL HERE>";
|
||||
static String apiKey = "<INSERT API KEY HERE>";
|
||||
static String API_KEY_HEADER = "x-api-key";
|
||||
|
||||
public static WebClient.ResponseSpec getResponseBodySpec(Map<String, Object> requestBody) {
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.baeldung.awsappsync;
|
||||
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
@ -10,6 +11,7 @@ import java.util.Map;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
@SpringBootTest
|
||||
@Disabled
|
||||
class AwsAppSyncApplicationTests {
|
||||
|
||||
@Test
|
||||
|
@ -16,10 +16,6 @@
|
||||
<relativePath>../../parent-boot-2</relativePath>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<spring-boot.version>2.2.6.RELEASE</spring-boot.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
|
@ -13,4 +13,5 @@ This module contains articles about core Groovy concepts
|
||||
- [Metaprogramming in Groovy](https://www.baeldung.com/groovy-metaprogramming)
|
||||
- [A Quick Guide to Working with Web Services in Groovy](https://www.baeldung.com/groovy-web-services)
|
||||
- [Categories in Groovy](https://www.baeldung.com/groovy-categories)
|
||||
- [How to Determine the Data Type in Groovy](https://www.baeldung.com/groovy-determine-data-type)
|
||||
- [[<-- Prev]](/core-groovy)
|
||||
|
@ -8,3 +8,4 @@ This module contains articles about Java 14.
|
||||
- [Java Text Blocks](https://www.baeldung.com/java-text-blocks)
|
||||
- [Pattern Matching for instanceof in Java 14](https://www.baeldung.com/java-pattern-matching-instanceof)
|
||||
- [Helpful NullPointerExceptions in Java 14](https://www.baeldung.com/java-14-nullpointerexception)
|
||||
- [Foreign Memory Access API in Java 14](https://www.baeldung.com/java-foreign-memory-access)
|
||||
|
@ -9,3 +9,4 @@ This module contains articles about the improvements to core Java features intro
|
||||
- [Java 9 Stream API Improvements](https://www.baeldung.com/java-9-stream-api)
|
||||
- [Java 9 java.util.Objects Additions](https://www.baeldung.com/java-9-objects-new)
|
||||
- [Java 9 CompletableFuture API Improvements](https://www.baeldung.com/java-9-completablefuture)
|
||||
- [Java InputStream to Byte Array and ByteBuffer](https://www.baeldung.com/convert-input-stream-to-array-of-bytes)
|
||||
|
@ -33,6 +33,11 @@
|
||||
<artifactId>guava</artifactId>
|
||||
<version>${guava.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>${commons-io.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.platform</groupId>
|
||||
<artifactId>junit-platform-runner</artifactId>
|
||||
|
@ -0,0 +1,57 @@
|
||||
package com.baeldung.java9.io.conversion;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.google.common.io.ByteSource;
|
||||
import com.google.common.io.ByteStreams;
|
||||
|
||||
public class InputStreamToByteArrayUnitTest {
|
||||
|
||||
@Test
|
||||
public final void givenUsingPlainJavaOnFixedSizeStream_whenConvertingAnInputStreamToAByteArray_thenCorrect() throws IOException {
|
||||
final InputStream initialStream = new ByteArrayInputStream(new byte[] { 0, 1, 2 });
|
||||
final byte[] targetArray = new byte[initialStream.available()];
|
||||
initialStream.read(targetArray);
|
||||
}
|
||||
|
||||
@Test
|
||||
public final void givenUsingPlainJavaOnUnknownSizeStream_whenConvertingAnInputStreamToAByteArray_thenCorrect() throws IOException {
|
||||
final InputStream is = new ByteArrayInputStream(new byte[] { 0, 1, 2 });
|
||||
|
||||
final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||
int nRead;
|
||||
final byte[] data = new byte[1024];
|
||||
while ((nRead = is.read(data, 0, data.length)) != -1) {
|
||||
buffer.write(data, 0, nRead);
|
||||
}
|
||||
|
||||
buffer.flush();
|
||||
final byte[] byteArray = buffer.toByteArray();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenUsingPlainJava9_whenConvertingAnInputStreamToAByteArray_thenCorrect() throws IOException {
|
||||
final InputStream is = new ByteArrayInputStream(new byte[] { 0, 1, 2 });
|
||||
|
||||
byte[] data = is.readAllBytes();
|
||||
}
|
||||
|
||||
@Test
|
||||
public final void givenUsingGuava_whenConvertingAnInputStreamToAByteArray_thenCorrect() throws IOException {
|
||||
final InputStream initialStream = ByteSource.wrap(new byte[] { 0, 1, 2 })
|
||||
.openStream();
|
||||
final byte[] targetArray = ByteStreams.toByteArray(initialStream);
|
||||
}
|
||||
|
||||
@Test
|
||||
public final void givenUsingCommonsIO_whenConvertingAnInputStreamToAByteArray_thenCorrect() throws IOException {
|
||||
final InputStream initialStream = new ByteArrayInputStream(new byte[] { 0, 1, 2 });
|
||||
final byte[] targetArray = IOUtils.toByteArray(initialStream);
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package com.baeldung.inputstreamtobytes;
|
||||
package com.baeldung.java9.io.conversion;
|
||||
|
||||
import com.google.common.io.ByteSource;
|
||||
import com.google.common.io.ByteStreams;
|
@ -11,4 +11,5 @@ This module contains articles about advanced topics about multithreading with co
|
||||
- [Guide to Work Stealing in Java](https://www.baeldung.com/java-work-stealing)
|
||||
- [Asynchronous Programming in Java](https://www.baeldung.com/java-asynchronous-programming)
|
||||
- [Java Thread Deadlock and Livelock](https://www.baeldung.com/java-deadlock-livelock)
|
||||
- [Guide to AtomicStampedReference in Java](https://www.baeldung.com/java-atomicstampedreference)
|
||||
- [[<-- previous]](/core-java-modules/core-java-concurrency-advanced-2)
|
||||
|
@ -0,0 +1,83 @@
|
||||
package com.baeldung.exchanger;
|
||||
|
||||
import java.util.Queue;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.Exchanger;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import org.junit.Test;
|
||||
|
||||
import static java.util.concurrent.CompletableFuture.runAsync;
|
||||
|
||||
|
||||
|
||||
public class ExchangerPipeLineManualTest {
|
||||
|
||||
private static final int BUFFER_SIZE = 100;
|
||||
|
||||
@Test
|
||||
public void givenData_whenPassedThrough_thenCorrect() throws InterruptedException, ExecutionException {
|
||||
|
||||
Exchanger<Queue<String>> readerExchanger = new Exchanger<>();
|
||||
Exchanger<Queue<String>> writerExchanger = new Exchanger<>();
|
||||
int counter = 0;
|
||||
|
||||
Runnable reader = () -> {
|
||||
Queue<String> readerBuffer = new ConcurrentLinkedQueue<>();
|
||||
while (true) {
|
||||
readerBuffer.add(UUID.randomUUID().toString());
|
||||
if (readerBuffer.size() >= BUFFER_SIZE) {
|
||||
try {
|
||||
readerBuffer = readerExchanger.exchange(readerBuffer);
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Runnable processor = () -> {
|
||||
Queue<String> processorBuffer = new ConcurrentLinkedQueue<>();
|
||||
Queue<String> writerBuffer = new ConcurrentLinkedQueue<>();
|
||||
try {
|
||||
processorBuffer = readerExchanger.exchange(processorBuffer);
|
||||
while (true) {
|
||||
writerBuffer.add(processorBuffer.poll());
|
||||
if (processorBuffer.isEmpty()) {
|
||||
try {
|
||||
processorBuffer = readerExchanger.exchange(processorBuffer);
|
||||
writerBuffer = writerExchanger.exchange(writerBuffer);
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
};
|
||||
|
||||
Runnable writer = () -> {
|
||||
Queue<String> writerBuffer = new ConcurrentLinkedQueue<>();
|
||||
try {
|
||||
writerBuffer = writerExchanger.exchange(writerBuffer);
|
||||
while (true) {
|
||||
System.out.println(writerBuffer.poll());
|
||||
if (writerBuffer.isEmpty()) {
|
||||
writerBuffer = writerExchanger.exchange(writerBuffer);
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
};
|
||||
|
||||
CompletableFuture.allOf(runAsync(reader), runAsync(processor), runAsync(writer)).get();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
package com.baeldung.exchanger;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Exchanger;
|
||||
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import org.junit.Test;
|
||||
|
||||
import static java.util.concurrent.CompletableFuture.runAsync;
|
||||
|
||||
public class ExchangerUnitTest {
|
||||
|
||||
|
||||
@Test
|
||||
public void givenThreads_whenMessageExchanged_thenCorrect() {
|
||||
Exchanger<String> exchanger = new Exchanger<>();
|
||||
|
||||
Runnable taskA = () -> {
|
||||
try {
|
||||
String message = exchanger.exchange("from A");
|
||||
assertEquals("from B", message);
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
};
|
||||
|
||||
Runnable taskB = () -> {
|
||||
try {
|
||||
String message = exchanger.exchange("from B");
|
||||
assertEquals("from A", message);
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
};
|
||||
|
||||
CompletableFuture.allOf(runAsync(taskA), runAsync(taskB)).join();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenThread_WhenExchangedMessage_thenCorrect() throws InterruptedException, ExecutionException {
|
||||
Exchanger<String> exchanger = new Exchanger<>();
|
||||
|
||||
Runnable runner = () -> {
|
||||
try {
|
||||
String message = exchanger.exchange("from runner");
|
||||
assertEquals("to runner", message);
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
};
|
||||
|
||||
CompletableFuture<Void> result = CompletableFuture.runAsync(runner);
|
||||
String msg = exchanger.exchange("to runner");
|
||||
assertEquals("from runner", msg);
|
||||
result.join();
|
||||
}
|
||||
|
||||
}
|
@ -23,7 +23,12 @@
|
||||
<artifactId>jmh-generator-annprocess</artifactId>
|
||||
<version>${jmh.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
<artifactId>assertj-core</artifactId>
|
||||
<version>${assertj.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<sourceDirectory>src</sourceDirectory>
|
||||
@ -42,6 +47,8 @@
|
||||
<properties>
|
||||
<jmh.version>1.21</jmh.version>
|
||||
<guava.version>28.2-jre</guava.version>
|
||||
<!-- testing -->
|
||||
<assertj.version>3.6.1</assertj.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
@ -0,0 +1,66 @@
|
||||
package com.baeldung.concurrent.queue;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.junit.FixMethodOrder;
|
||||
import org.junit.Test;
|
||||
|
||||
@FixMethodOrder
|
||||
public class TestConcurrentLinkedQueue {
|
||||
|
||||
@Test
|
||||
public void givenThereIsExistingCollection_WhenAddedIntoQueue_ThenShouldContainElements() {
|
||||
Collection<Integer> elements = Arrays.asList(1, 2, 3, 4, 5);
|
||||
ConcurrentLinkedQueue<Integer> concurrentLinkedQueue = new ConcurrentLinkedQueue<>(elements);
|
||||
assertThat(concurrentLinkedQueue).containsExactly(1, 2, 3, 4, 5);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenQueueIsEmpty_WhenAccessingTheQueue_ThenQueueReturnsNull() throws InterruptedException {
|
||||
ExecutorService executorService = Executors.newFixedThreadPool(1);
|
||||
ConcurrentLinkedQueue<Integer> concurrentLinkedQueue = new ConcurrentLinkedQueue<>();
|
||||
executorService.submit(() -> assertNull("Retrieve object is null", concurrentLinkedQueue.poll()));
|
||||
TimeUnit.SECONDS.sleep(1);
|
||||
executorService.awaitTermination(1, TimeUnit.SECONDS);
|
||||
executorService.shutdown();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenProducerOffersElementInQueue_WhenConsumerPollsQueue_ThenItRetrievesElement() throws Exception {
|
||||
int element = 1;
|
||||
|
||||
ExecutorService executorService = Executors.newFixedThreadPool(2);
|
||||
ConcurrentLinkedQueue<Integer> concurrentLinkedQueue = new ConcurrentLinkedQueue<>();
|
||||
Runnable offerTask = () -> concurrentLinkedQueue.offer(element);
|
||||
|
||||
Callable<Integer> pollTask = () -> {
|
||||
while (concurrentLinkedQueue.peek() != null) {
|
||||
return concurrentLinkedQueue.poll()
|
||||
.intValue();
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
executorService.submit(offerTask);
|
||||
TimeUnit.SECONDS.sleep(1);
|
||||
|
||||
Future<Integer> returnedElement = executorService.submit(pollTask);
|
||||
assertThat(returnedElement.get()
|
||||
.intValue(), is(equalTo(element)));
|
||||
executorService.awaitTermination(1, TimeUnit.SECONDS);
|
||||
executorService.shutdown();
|
||||
}
|
||||
}
|
@ -0,0 +1,81 @@
|
||||
package com.baeldung.concurrent.queue;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.junit.FixMethodOrder;
|
||||
import org.junit.Test;
|
||||
|
||||
@FixMethodOrder
|
||||
public class TestLinkedBlockingQueue {
|
||||
|
||||
@Test
|
||||
public void givenThereIsExistingCollection_WhenAddedIntoQueue_ThenShouldContainElements() {
|
||||
Collection<Integer> elements = Arrays.asList(1, 2, 3, 4, 5);
|
||||
LinkedBlockingQueue<Integer> linkedBlockingQueue = new LinkedBlockingQueue<>(elements);
|
||||
assertThat(linkedBlockingQueue).containsExactly(1, 2, 3, 4, 5);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenQueueIsEmpty_WhenAccessingTheQueue_ThenThreadBlocks() throws InterruptedException {
|
||||
ExecutorService executorService = Executors.newFixedThreadPool(1);
|
||||
LinkedBlockingQueue<Integer> linkedBlockingQueue = new LinkedBlockingQueue<>();
|
||||
executorService.submit(() -> {
|
||||
try {
|
||||
linkedBlockingQueue.take();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
TimeUnit.SECONDS.sleep(1);
|
||||
executorService.awaitTermination(1, TimeUnit.SECONDS);
|
||||
executorService.shutdown();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenProducerPutsElementInQueue_WhenConsumerAccessQueue_ThenItRetrieve() {
|
||||
int element = 10;
|
||||
ExecutorService executorService = Executors.newFixedThreadPool(2);
|
||||
LinkedBlockingQueue<Integer> linkedBlockingQueue = new LinkedBlockingQueue<>();
|
||||
Runnable putTask = () -> {
|
||||
try {
|
||||
linkedBlockingQueue.put(element);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
};
|
||||
|
||||
Callable<Integer> takeTask = () -> {
|
||||
try {
|
||||
return linkedBlockingQueue.take();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
executorService.submit(putTask);
|
||||
Future<Integer> returnElement = executorService.submit(takeTask);
|
||||
try {
|
||||
TimeUnit.SECONDS.sleep(1);
|
||||
assertThat(returnElement.get()
|
||||
.intValue(), is(equalTo(element)));
|
||||
executorService.awaitTermination(1, TimeUnit.SECONDS);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
executorService.shutdown();
|
||||
}
|
||||
}
|
@ -9,3 +9,6 @@ This module contains articles about core java exceptions
|
||||
- [java.net.UnknownHostException: Invalid Hostname for Server](https://www.baeldung.com/java-unknownhostexception)
|
||||
- [How to Handle Java SocketException](https://www.baeldung.com/java-socketexception)
|
||||
- [Java Suppressed Exceptions](https://www.baeldung.com/java-suppressed-exceptions)
|
||||
- [Java – Try with Resources](https://www.baeldung.com/java-try-with-resources)
|
||||
- [Java Global Exception Handler](https://www.baeldung.com/java-global-exception-handler)
|
||||
- [How to Find an Exception’s Root Cause in Java](https://www.baeldung.com/java-exception-root-cause)
|
||||
|
@ -23,6 +23,11 @@
|
||||
<version>${assertj-core.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>${commons.lang3.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<description> </description>
|
||||
@ -30,6 +35,7 @@
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<commons.lang3.version>3.10</commons.lang3.version>
|
||||
<!-- testing -->
|
||||
<assertj-core.version>3.10.0</assertj-core.version>
|
||||
</properties>
|
||||
|
@ -1,4 +1,4 @@
|
||||
package com.baeldung.exceptions.globalexceptionhandler;
|
||||
package com.baeldung.globalexceptionhandler;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
@ -1,4 +1,4 @@
|
||||
package com.baeldung.exceptions.globalexceptionhandler;
|
||||
package com.baeldung.globalexceptionhandler;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
@ -1,4 +1,4 @@
|
||||
package com.baeldung.exceptions.globalexceptionhandler;
|
||||
package com.baeldung.globalexceptionhandler;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
@ -1,4 +1,4 @@
|
||||
package com.baeldung.exceptions.globalexceptionhandler;
|
||||
package com.baeldung.globalexceptionhandler;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
@ -1,4 +1,4 @@
|
||||
package com.baeldung.exceptions.globalexceptionhandler;
|
||||
package com.baeldung.globalexceptionhandler;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
@ -1,4 +1,4 @@
|
||||
package com.baeldung.exceptions.globalexceptionhandler;
|
||||
package com.baeldung.globalexceptionhandler;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
@ -1,4 +1,4 @@
|
||||
package com.baeldung.exceptions.globalexceptionhandler;
|
||||
package com.baeldung.globalexceptionhandler;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
@ -1,4 +1,4 @@
|
||||
package com.baeldung.exceptions.globalexceptionhandler;
|
||||
package com.baeldung.globalexceptionhandler;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
@ -1,4 +1,4 @@
|
||||
package com.baeldung.exceptions.globalexceptionhandler;
|
||||
package com.baeldung.globalexceptionhandler;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
@ -1,4 +1,4 @@
|
||||
package com.baeldung.exceptions.globalexceptionhandler;
|
||||
package com.baeldung.globalexceptionhandler;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
@ -1,4 +1,4 @@
|
||||
package com.baeldung.exceptions.globalexceptionhandler;
|
||||
package com.baeldung.globalexceptionhandler;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
@ -1,4 +1,4 @@
|
||||
package com.baeldung.exceptions.globalexceptionhandler;
|
||||
package com.baeldung.globalexceptionhandler;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.ParseException;
|
@ -1,4 +1,4 @@
|
||||
package com.baeldung.exceptions.globalexceptionhandler;
|
||||
package com.baeldung.globalexceptionhandler;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
@ -1,4 +1,4 @@
|
||||
package com.baeldung.exceptions.rootcausefinder;
|
||||
package com.baeldung.rootcausefinder;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.Period;
|
@ -1,4 +1,4 @@
|
||||
package com.baeldung.exceptions.globalexceptionhandler;
|
||||
package com.baeldung.globalexceptionhandler;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
@ -1,7 +1,7 @@
|
||||
package com.baeldung.exceptions.rootcausefinder;
|
||||
package com.baeldung.rootcausefinder;
|
||||
|
||||
import com.baeldung.exceptions.rootcausefinder.RootCauseFinder.CalculationException;
|
||||
import com.baeldung.exceptions.rootcausefinder.RootCauseFinder.DateOutOfRangeException;
|
||||
import com.baeldung.rootcausefinder.RootCauseFinder.CalculationException;
|
||||
import com.baeldung.rootcausefinder.RootCauseFinder.DateOutOfRangeException;
|
||||
import com.google.common.base.Throwables;
|
||||
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
@ -11,8 +11,7 @@ import java.time.LocalDate;
|
||||
import java.time.format.DateTimeParseException;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
|
||||
import static com.baeldung.exceptions.rootcausefinder.RootCauseFinder.AgeCalculator;
|
||||
import static com.baeldung.exceptions.rootcausefinder.RootCauseFinder.findCauseUsingPlainJava;
|
||||
import static com.baeldung.rootcausefinder.RootCauseFinder.AgeCalculator;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
/**
|
||||
@ -38,7 +37,7 @@ public class RootCauseFinderUnitTest {
|
||||
try {
|
||||
AgeCalculator.calculateAge("010102");
|
||||
} catch (CalculationException ex) {
|
||||
assertTrue(findCauseUsingPlainJava(ex) instanceof DateTimeParseException);
|
||||
assertTrue(RootCauseFinder.findCauseUsingPlainJava(ex) instanceof DateTimeParseException);
|
||||
}
|
||||
}
|
||||
|
||||
@ -47,7 +46,7 @@ public class RootCauseFinderUnitTest {
|
||||
try {
|
||||
AgeCalculator.calculateAge("2020-04-04");
|
||||
} catch (CalculationException ex) {
|
||||
assertTrue(findCauseUsingPlainJava(ex) instanceof DateOutOfRangeException);
|
||||
assertTrue(RootCauseFinder.findCauseUsingPlainJava(ex) instanceof DateOutOfRangeException);
|
||||
}
|
||||
}
|
||||
|
||||
@ -56,7 +55,7 @@ public class RootCauseFinderUnitTest {
|
||||
try {
|
||||
AgeCalculator.calculateAge(null);
|
||||
} catch (Exception ex) {
|
||||
assertTrue(findCauseUsingPlainJava(ex) instanceof IllegalArgumentException);
|
||||
assertTrue(RootCauseFinder.findCauseUsingPlainJava(ex) instanceof IllegalArgumentException);
|
||||
}
|
||||
}
|
||||
|
@ -12,9 +12,5 @@ This module contains articles about core java exceptions
|
||||
- [“Sneaky Throws” in Java](https://www.baeldung.com/java-sneaky-throws)
|
||||
- [The StackOverflowError in Java](https://www.baeldung.com/java-stack-overflow-error)
|
||||
- [Checked and Unchecked Exceptions in Java](https://www.baeldung.com/java-checked-unchecked-exceptions)
|
||||
- [Java – Try with Resources](https://www.baeldung.com/java-try-with-resources)
|
||||
- [Java Global Exception Handler](https://www.baeldung.com/java-global-exception-handler)
|
||||
- [Common Java Exceptions](https://www.baeldung.com/java-common-exceptions)
|
||||
- [How to Find an Exception’s Root Cause in Java](https://www.baeldung.com/java-exception-root-cause)
|
||||
- [Is It a Bad Practice to Catch Throwable?](https://www.baeldung.com/java-catch-throwable-bad-practice)
|
||||
- [[Next -->]](/core-java-modules/core-java-exceptions-2)
|
@ -4,6 +4,5 @@ This module contains articles about core Java input/output(IO) conversions.
|
||||
|
||||
### Relevant Articles:
|
||||
- [Java InputStream to String](https://www.baeldung.com/convert-input-stream-to-string)
|
||||
- [Java InputStream to Byte Array and ByteBuffer](https://www.baeldung.com/convert-input-stream-to-array-of-bytes)
|
||||
- [Java – Write an InputStream to a File](https://www.baeldung.com/convert-input-stream-to-a-file)
|
||||
- More articles: [[<-- prev]](/core-java-modules/core-java-io-conversions)
|
||||
|
@ -2,7 +2,6 @@ package com.baeldung.inputstreamtostring;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.io.ByteSource;
|
||||
import com.google.common.io.ByteStreams;
|
||||
import com.google.common.io.CharStreams;
|
||||
import com.google.common.io.Files;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
@ -11,13 +10,26 @@ import org.junit.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.*;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
import java.io.StringWriter;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.Scanner;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
@ -46,6 +58,18 @@ public class JavaInputStreamToXUnitTest {
|
||||
assertEquals(textBuilder.toString(), originalString);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenUsingJava8_whenConvertingAnInputStreamToAString_thenCorrect() {
|
||||
final String originalString = randomAlphabetic(DEFAULT_SIZE);
|
||||
final InputStream inputStream = new ByteArrayInputStream(originalString.getBytes());
|
||||
|
||||
final String text = new BufferedReader(new InputStreamReader(inputStream, Charset.forName(StandardCharsets.UTF_8.name())))
|
||||
.lines()
|
||||
.collect(Collectors.joining("\n"));
|
||||
|
||||
assertThat(text, equalTo(originalString));
|
||||
}
|
||||
|
||||
@Test
|
||||
public final void givenUsingJava7_whenConvertingAnInputStreamToAString_thenCorrect() throws IOException {
|
||||
final String originalString = randomAlphabetic(DEFAULT_SIZE);
|
||||
@ -127,42 +151,6 @@ public class JavaInputStreamToXUnitTest {
|
||||
assertThat(result, equalTo(originalString));
|
||||
}
|
||||
|
||||
// tests - InputStream to byte[]
|
||||
|
||||
@Test
|
||||
public final void givenUsingPlainJavaOnFixedSizeStream_whenConvertingAnInputStreamToAByteArray_thenCorrect() throws IOException {
|
||||
final InputStream initialStream = new ByteArrayInputStream(new byte[] { 0, 1, 2 });
|
||||
final byte[] targetArray = new byte[initialStream.available()];
|
||||
initialStream.read(targetArray);
|
||||
}
|
||||
|
||||
@Test
|
||||
public final void givenUsingPlainJavaOnUnknownSizeStream_whenConvertingAnInputStreamToAByteArray_thenCorrect() throws IOException {
|
||||
final InputStream is = new ByteArrayInputStream(new byte[] { 0, 1, 2 });
|
||||
|
||||
final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||
int nRead;
|
||||
final byte[] data = new byte[1024];
|
||||
while ((nRead = is.read(data, 0, data.length)) != -1) {
|
||||
buffer.write(data, 0, nRead);
|
||||
}
|
||||
|
||||
buffer.flush();
|
||||
final byte[] byteArray = buffer.toByteArray();
|
||||
}
|
||||
|
||||
@Test
|
||||
public final void givenUsingGuava_whenConvertingAnInputStreamToAByteArray_thenCorrect() throws IOException {
|
||||
final InputStream initialStream = ByteSource.wrap(new byte[] { 0, 1, 2 }).openStream();
|
||||
final byte[] targetArray = ByteStreams.toByteArray(initialStream);
|
||||
}
|
||||
|
||||
@Test
|
||||
public final void givenUsingCommonsIO_whenConvertingAnInputStreamToAByteArray_thenCorrect() throws IOException {
|
||||
final InputStream initialStream = new ByteArrayInputStream(new byte[] { 0, 1, 2 });
|
||||
final byte[] targetArray = IOUtils.toByteArray(initialStream);
|
||||
}
|
||||
|
||||
// tests - InputStream to File
|
||||
|
||||
@Test
|
||||
|
@ -10,3 +10,4 @@
|
||||
- [Difference Between Java Matcher find() and matches()](https://www.baeldung.com/java-matcher-find-vs-matches)
|
||||
- [How to Use Regular Expressions to Replace Tokens in Strings](https://www.baeldung.com/java-regex-token-replacement)
|
||||
- [Regular Expressions \s and \s+ in Java](https://www.baeldung.com/java-regex-s-splus)
|
||||
- [Validate Phone Numbers With Java Regex](https://www.baeldung.com/java-regex-validate-phone-numbers)
|
||||
|
@ -4,8 +4,10 @@ import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
@ -39,6 +41,27 @@ public class EncodeDecodeUnitTest {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenJavaBase64_whenEncodedStream_thenDecodedStreamOK() throws IOException {
|
||||
|
||||
try (OutputStream os = java.util.Base64.getEncoder().wrap(new FileOutputStream(OUT_FILE));
|
||||
FileInputStream fis = new FileInputStream(IN_FILE)) {
|
||||
byte[] bytes = new byte[1024];
|
||||
int read;
|
||||
while ((read = fis.read(bytes)) > -1) {
|
||||
os.write(bytes, 0, read);
|
||||
}
|
||||
}
|
||||
|
||||
byte[] encoded = java.util.Base64.getEncoder().encode(inFileBytes);
|
||||
byte[] encodedOnDisk = Files.readAllBytes(Paths.get(OUT_FILE));
|
||||
assertArrayEquals(encoded, encodedOnDisk);
|
||||
|
||||
byte[] decoded = java.util.Base64.getDecoder().decode(encoded);
|
||||
byte[] decodedOnDisk = java.util.Base64.getDecoder().decode(encodedOnDisk);
|
||||
assertArrayEquals(decoded, decodedOnDisk);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenApacheCommons_givenJavaBase64_whenEncoded_thenDecodedOK() throws IOException {
|
||||
|
||||
|
@ -9,3 +9,4 @@ This module contains articles about core Kotlin collections.
|
||||
- [Converting a List to Map in Kotlin](https://www.baeldung.com/kotlin-list-to-map)
|
||||
- [Filtering Kotlin Collections](https://www.baeldung.com/kotlin-filter-collection)
|
||||
- [Collection Transformations in Kotlin](https://www.baeldung.com/kotlin-collection-transformations)
|
||||
- [Difference between fold and reduce in Kotlin](https://www.baeldung.com/kotlin/fold-vs-reduce)
|
||||
|
@ -0,0 +1,86 @@
|
||||
package com.baeldung.ifelseexpression
|
||||
|
||||
fun ifStatementUsage(): String {
|
||||
val number = 15
|
||||
|
||||
if (number > 0) {
|
||||
return "Positive number"
|
||||
}
|
||||
return "Positive number not found"
|
||||
}
|
||||
|
||||
fun ifElseStatementUsage(): String {
|
||||
val number = -50
|
||||
|
||||
if (number > 0) {
|
||||
return "Positive number"
|
||||
} else {
|
||||
return "Negative number"
|
||||
}
|
||||
}
|
||||
|
||||
fun ifElseExpressionUsage(): String {
|
||||
val number = -50
|
||||
|
||||
val result = if (number > 0) {
|
||||
"Positive number"
|
||||
} else {
|
||||
"Negative number"
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
fun ifElseExpressionSingleLineUsage(): String {
|
||||
val number = -50
|
||||
val result = if (number > 0) "Positive number" else "Negative number"
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
fun ifElseMultipleExpressionUsage(): Int {
|
||||
val x = 24
|
||||
val y = 73
|
||||
|
||||
val result = if (x > y) {
|
||||
println("$x is greater than $y")
|
||||
x
|
||||
} else {
|
||||
println("$x is less than or equal to $y")
|
||||
y
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
fun ifElseLadderExpressionUsage(): String {
|
||||
val number = 60
|
||||
|
||||
val result = if (number < 0) {
|
||||
"Negative number"
|
||||
} else if (number in 0..9) {
|
||||
"Single digit number"
|
||||
} else if (number in 10..99) {
|
||||
"Double digit number"
|
||||
} else {
|
||||
"Number has more digits"
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
fun ifElseNestedExpressionUsage(): Int {
|
||||
val x = 37
|
||||
val y = 89
|
||||
val z = 6
|
||||
|
||||
val result = if (x > y) {
|
||||
if (x > z)
|
||||
x
|
||||
else
|
||||
z
|
||||
} else {
|
||||
if (y > z)
|
||||
y
|
||||
else
|
||||
z
|
||||
}
|
||||
return result
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
package com.baeldung.ifelseexpression
|
||||
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Assertions.assertNotEquals
|
||||
|
||||
class IfElseExpressionExampleTest {
|
||||
|
||||
@Test
|
||||
fun givenNumber_whenIfStatementCalled_thenReturnsString() {
|
||||
assertEquals("Positive number", ifStatementUsage())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenNumber_whenIfElseStatementCalled_thenReturnsString() {
|
||||
assertEquals("Negative number", ifElseStatementUsage())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenNumber_whenIfElseExpressionCalled_thenReturnsString() {
|
||||
assertEquals("Negative number", ifElseExpressionUsage())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenNumber_whenIfElseExpressionSingleLineCalled_thenReturnsString() {
|
||||
assertEquals("Negative number", ifElseExpressionSingleLineUsage())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenNumber_whenIfElseMultipleExpressionCalled_thenReturnsNumber() {
|
||||
assertEquals(73, ifElseMultipleExpressionUsage())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenNumber_whenIfElseLadderExpressionCalled_thenReturnsString() {
|
||||
assertEquals("Double digit number", ifElseLadderExpressionUsage())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenNumber_whenIfElseNestedExpressionCalled_thenReturnsNumber() {
|
||||
assertEquals(89, ifElseNestedExpressionUsage())
|
||||
}
|
||||
}
|
3
gradle/gradle-employee-app/README.md
Normal file
3
gradle/gradle-employee-app/README.md
Normal file
@ -0,0 +1,3 @@
|
||||
### Relevant Articles:
|
||||
|
||||
- [Building a Java Application With Gradle](https://www.baeldung.com/gradle-building-a-java-app)
|
@ -4,4 +4,5 @@ This module contains articles about conversions among Collection types and array
|
||||
|
||||
### Relevant Articles:
|
||||
- [Array to String Conversions](https://www.baeldung.com/java-array-to-string)
|
||||
- More articles: [[<-- prev]](../java-collections-conversions)
|
||||
- [Mapping Lists with ModelMapper](https://www.baeldung.com/java-modelmapper-lists)
|
||||
- More articles: [[<-- prev]](../java-collections-conversions)
|
||||
|
@ -88,7 +88,7 @@ public class CollectionToArrayListUnitTest {
|
||||
Iterator<Foo> iterA = a.iterator();
|
||||
Iterator<Foo> iterB = b.iterator();
|
||||
while (iterA.hasNext()) {
|
||||
// use '==' to test instance identity
|
||||
// test instance identity
|
||||
assertSame("Foo instances differ!", iterA.next(), iterB.next());
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +0,0 @@
|
||||
## Java Python Interop
|
||||
|
||||
This module contains articles about Java and Python interoperability.
|
||||
|
||||
### Relevant Articles:
|
@ -11,3 +11,4 @@ This module contains articles about JEE 7.
|
||||
- [Introduction to Testing with Arquillian](https://www.baeldung.com/arquillian)
|
||||
- [Java EE 7 Batch Processing](https://www.baeldung.com/java-ee-7-batch-processing)
|
||||
- [The Difference Between CDI and EJB Singleton](https://www.baeldung.com/jee-cdi-vs-ejb-singleton)
|
||||
- [Invoking a SOAP Web Service in Java](https://www.baeldung.com/java-soap-web-service)
|
||||
|
@ -4,6 +4,7 @@ This module contains articles about jsoup.
|
||||
|
||||
### Relevant Articles:
|
||||
- [Parsing HTML in Java with Jsoup](https://www.baeldung.com/java-with-jsoup)
|
||||
- [How to add proxy support to Jsoup?](https://www.baeldung.com/java-jsoup-proxy)
|
||||
|
||||
### Build the Project
|
||||
|
||||
|
@ -1,27 +0,0 @@
|
||||
package com.baeldung.jsonproxy;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Proxy;
|
||||
|
||||
import org.jsoup.Jsoup;
|
||||
import org.junit.Test;
|
||||
|
||||
public class JsoupProxyIntegrationTest {
|
||||
|
||||
@Test
|
||||
public void whenUsingHostAndPort_thenConnect() throws IOException {
|
||||
Jsoup.connect("https://spring.io/blog")
|
||||
.proxy("200.216.227.141", 53281)
|
||||
.get();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenUsingProxyClass_thenConnect() throws IOException {
|
||||
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("200.216.227.141", 53281));
|
||||
|
||||
Jsoup.connect("https://spring.io/blog")
|
||||
.proxy(proxy)
|
||||
.get();
|
||||
}
|
||||
}
|
3
kaniko/README.md
Normal file
3
kaniko/README.md
Normal file
@ -0,0 +1,3 @@
|
||||
### Relevant Articles:
|
||||
|
||||
- [An Introduction to Kaniko](https://www.baeldung.com/ops/kaniko)
|
5
language-interop/README.md
Normal file
5
language-interop/README.md
Normal file
@ -0,0 +1,5 @@
|
||||
## Language Interop
|
||||
|
||||
This module contains articles about Java interop with other language integrations.
|
||||
|
||||
### Relevant Articles:
|
@ -3,9 +3,9 @@
|
||||
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>java-python-interop</artifactId>
|
||||
<artifactId>language-interop</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>java-python-interop</name>
|
||||
<name>language-interop</name>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
@ -33,7 +33,7 @@
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>java-python-interop</finalName>
|
||||
<finalName>language-interop</finalName>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
@ -52,4 +52,4 @@
|
||||
<assertj.version>3.6.1</assertj.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
</project>
|
@ -1,4 +1,4 @@
|
||||
package com.baeldung.python.interop;
|
||||
package com.baeldung.language.interop.python;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -1,4 +1,4 @@
|
||||
package com.baeldung.python.interop;
|
||||
package com.baeldung.language.interop.python;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.empty;
|
@ -11,7 +11,8 @@ This module contains articles about libraries for data processing in Java.
|
||||
- [Guide to JMapper](https://www.baeldung.com/jmapper)
|
||||
- [An Introduction to SuanShu](https://www.baeldung.com/suanshu)
|
||||
- [Intro to Derive4J](https://www.baeldung.com/derive4j)
|
||||
More articles: [[<-- prev]](/../libraries-data)
|
||||
- [Java-R Integration](https://www.baeldung.com/java-r-integration)
|
||||
- More articles: [[<-- prev]](/../libraries-data)
|
||||
|
||||
##### Building the project
|
||||
You can build the project from the command line using: *mvn clean install*, or in an IDE. If you have issues with the derive4j imports in your IDE, you have to add the folder: *target/generated-sources/annotations* to the project build path in your IDE.
|
||||
|
@ -116,6 +116,11 @@
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
<version>${slf4j.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.univocity</groupId>
|
||||
<artifactId>univocity-parsers</artifactId>
|
||||
<version>${univocity.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.awaitility</groupId>
|
||||
<artifactId>awaitility</artifactId>
|
||||
@ -175,6 +180,7 @@
|
||||
<assertj.version>3.6.2</assertj.version>
|
||||
<slf4j.version>1.7.25</slf4j.version>
|
||||
<awaitility.version>3.0.0</awaitility.version>
|
||||
<univocity.version>2.8.4</univocity.version>
|
||||
<renjin.version>RELEASE</renjin.version>
|
||||
<rcaller.version>3.0</rcaller.version>
|
||||
<rserve.version>1.8.1</rserve.version>
|
||||
|
@ -0,0 +1,80 @@
|
||||
package com.baeldung.univocity;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Writer;
|
||||
import java.util.List;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.baeldung.univocity.model.Product;
|
||||
import com.univocity.parsers.common.processor.BeanWriterProcessor;
|
||||
import com.univocity.parsers.csv.CsvWriter;
|
||||
import com.univocity.parsers.csv.CsvWriterSettings;
|
||||
import com.univocity.parsers.fixed.FixedWidthFields;
|
||||
import com.univocity.parsers.fixed.FixedWidthWriter;
|
||||
import com.univocity.parsers.fixed.FixedWidthWriterSettings;
|
||||
import com.univocity.parsers.tsv.TsvWriter;
|
||||
import com.univocity.parsers.tsv.TsvWriterSettings;
|
||||
|
||||
public class OutputService {
|
||||
private Logger logger = LoggerFactory.getLogger(ParsingService.class);
|
||||
|
||||
public enum OutputType {
|
||||
CSV, TSV, FIXED_WIDTH
|
||||
};
|
||||
|
||||
public boolean writeData(List<Object[]> products, OutputType outputType, String outputPath) {
|
||||
try (Writer outputWriter = new OutputStreamWriter(new FileOutputStream(new File(outputPath)), "UTF-8")) {
|
||||
switch (outputType) {
|
||||
case CSV: {
|
||||
CsvWriter writer = new CsvWriter(outputWriter, new CsvWriterSettings());
|
||||
writer.writeRowsAndClose(products);
|
||||
}
|
||||
break;
|
||||
case TSV: {
|
||||
TsvWriter writer = new TsvWriter(outputWriter, new TsvWriterSettings());
|
||||
writer.writeRowsAndClose(products);
|
||||
}
|
||||
break;
|
||||
case FIXED_WIDTH: {
|
||||
FixedWidthFields fieldLengths = new FixedWidthFields(8, 30, 10);
|
||||
FixedWidthWriterSettings settings = new FixedWidthWriterSettings(fieldLengths);
|
||||
FixedWidthWriter writer = new FixedWidthWriter(outputWriter, settings);
|
||||
writer.writeRowsAndClose(products);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
logger.warn("Invalid OutputType: " + outputType);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
logger.error(e.getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean writeBeanToFixedWidthFile(List<Product> products, String outputPath) {
|
||||
try (Writer outputWriter = new OutputStreamWriter(new FileOutputStream(new File(outputPath)), "UTF-8")) {
|
||||
BeanWriterProcessor<Product> rowProcessor = new BeanWriterProcessor<Product>(Product.class);
|
||||
FixedWidthFields fieldLengths = new FixedWidthFields(8, 30, 10);
|
||||
FixedWidthWriterSettings settings = new FixedWidthWriterSettings(fieldLengths);
|
||||
settings.setHeaders("product_no", "description", "unit_price");
|
||||
settings.setRowWriterProcessor(rowProcessor);
|
||||
FixedWidthWriter writer = new FixedWidthWriter(outputWriter, settings);
|
||||
writer.writeHeaders();
|
||||
for (Product product : products) {
|
||||
writer.processRecord(product);
|
||||
}
|
||||
writer.close();
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
logger.error(e.getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,85 @@
|
||||
package com.baeldung.univocity;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.baeldung.univocity.model.Product;
|
||||
import com.univocity.parsers.common.processor.BatchedColumnProcessor;
|
||||
import com.univocity.parsers.common.processor.BeanListProcessor;
|
||||
import com.univocity.parsers.csv.CsvParser;
|
||||
import com.univocity.parsers.csv.CsvParserSettings;
|
||||
import com.univocity.parsers.fixed.FixedWidthFields;
|
||||
import com.univocity.parsers.fixed.FixedWidthParser;
|
||||
import com.univocity.parsers.fixed.FixedWidthParserSettings;
|
||||
|
||||
public class ParsingService {
|
||||
private Logger logger = LoggerFactory.getLogger(ParsingService.class);
|
||||
|
||||
public List<String[]> parseCsvFile(String relativePath) {
|
||||
try (Reader inputReader = new InputStreamReader(new FileInputStream(new File(relativePath)), "UTF-8")) {
|
||||
CsvParserSettings settings = new CsvParserSettings();
|
||||
settings.setMaxCharsPerColumn(100);
|
||||
settings.setMaxColumns(50);
|
||||
CsvParser parser = new CsvParser(settings);
|
||||
List<String[]> parsedRows = parser.parseAll(inputReader);
|
||||
return parsedRows;
|
||||
} catch (IOException e) {
|
||||
logger.error("IOException opening file: " + relativePath + " " + e.getMessage());
|
||||
return new ArrayList<String[]>();
|
||||
}
|
||||
}
|
||||
|
||||
public List<String[]> parseFixedWidthFile(String relativePath) {
|
||||
try (Reader inputReader = new InputStreamReader(new FileInputStream(new File(relativePath)), "UTF-8")) {
|
||||
FixedWidthFields fieldLengths = new FixedWidthFields(8, 30, 10);
|
||||
FixedWidthParserSettings settings = new FixedWidthParserSettings(fieldLengths);
|
||||
|
||||
FixedWidthParser parser = new FixedWidthParser(settings);
|
||||
List<String[]> parsedRows = parser.parseAll(inputReader);
|
||||
return parsedRows;
|
||||
} catch (IOException e) {
|
||||
logger.error("IOException opening file: " + relativePath + " " + e.getMessage());
|
||||
return new ArrayList<String[]>();
|
||||
}
|
||||
}
|
||||
|
||||
public List<Product> parseCsvFileIntoBeans(String relativePath) {
|
||||
try (Reader inputReader = new InputStreamReader(new FileInputStream(new File(relativePath)), "UTF-8")) {
|
||||
BeanListProcessor<Product> rowProcessor = new BeanListProcessor<Product>(Product.class);
|
||||
CsvParserSettings settings = new CsvParserSettings();
|
||||
settings.setHeaderExtractionEnabled(true);
|
||||
settings.setProcessor(rowProcessor);
|
||||
CsvParser parser = new CsvParser(settings);
|
||||
parser.parse(inputReader);
|
||||
return rowProcessor.getBeans();
|
||||
} catch (IOException e) {
|
||||
logger.error("IOException opening file: " + relativePath + " " + e.getMessage());
|
||||
return new ArrayList<Product>();
|
||||
}
|
||||
}
|
||||
|
||||
public List<String[]> parseCsvFileInBatches(String relativePath) {
|
||||
try (Reader inputReader = new InputStreamReader(new FileInputStream(new File(relativePath)), "UTF-8")) {
|
||||
CsvParserSettings settings = new CsvParserSettings();
|
||||
settings.setProcessor(new BatchedColumnProcessor(5) {
|
||||
@Override
|
||||
public void batchProcessed(int rowsInThisBatch) {
|
||||
}
|
||||
});
|
||||
CsvParser parser = new CsvParser(settings);
|
||||
List<String[]> parsedRows = parser.parseAll(inputReader);
|
||||
return parsedRows;
|
||||
} catch (IOException e) {
|
||||
logger.error("IOException opening file: " + relativePath + " " + e.getMessage());
|
||||
return new ArrayList<String[]>();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
package com.baeldung.univocity.model;
|
||||
|
||||
import com.univocity.parsers.annotations.Parsed;
|
||||
|
||||
public class Product {
|
||||
|
||||
@Parsed(field = "product_no")
|
||||
private String productNumber;
|
||||
|
||||
@Parsed
|
||||
private String description;
|
||||
|
||||
@Parsed(field = "unit_price")
|
||||
private float unitPrice;
|
||||
|
||||
public String getProductNumber() {
|
||||
return productNumber;
|
||||
}
|
||||
|
||||
public void setProductNumber(String productNumber) {
|
||||
this.productNumber = productNumber;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public float getUnitPrice() {
|
||||
return unitPrice;
|
||||
}
|
||||
|
||||
public void setUnitPrice(float unitPrice) {
|
||||
this.unitPrice = unitPrice;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Product [Product Number: " + productNumber + ", Description: " + description + ", Unit Price: " + unitPrice + "]";
|
||||
}
|
||||
}
|
@ -0,0 +1,112 @@
|
||||
package com.baeldung.univocity;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.baeldung.univocity.model.Product;
|
||||
|
||||
public class ParsingServiceUnitTest {
|
||||
|
||||
@Test
|
||||
public void givenCsvFile_thenParsedResultsShouldBeReturned() {
|
||||
ParsingService parsingService = new ParsingService();
|
||||
List<String[]> productData = parsingService.parseCsvFile("src/test/resources/productList.csv");
|
||||
assertEquals(3, productData.size());
|
||||
assertEquals(3, productData.get(0).length);
|
||||
assertEquals("A8993-10", productData.get(0)[0]);
|
||||
assertEquals("Extra large widget", productData.get(0)[1]);
|
||||
assertEquals("35.42", productData.get(0)[2]);
|
||||
assertEquals("D-2938-1", productData.get(1)[0]);
|
||||
assertEquals("Winding widget \"Deluxe Model\"", productData.get(1)[1]);
|
||||
assertEquals("245.99", productData.get(1)[2]);
|
||||
assertEquals("R3212-32", productData.get(2)[0]);
|
||||
assertEquals("Standard widget", productData.get(2)[1]);
|
||||
assertEquals("2.34", productData.get(2)[2]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenFixedWidthFile_thenParsedResultsShouldBeReturned() {
|
||||
ParsingService parsingService = new ParsingService();
|
||||
List<String[]> productData = parsingService.parseFixedWidthFile("src/test/resources/productList.txt");
|
||||
// Note: any extra spaces on the end will cause a null line to be added
|
||||
assertEquals(3, productData.size());
|
||||
assertEquals(3, productData.get(0).length);
|
||||
assertEquals("A8993-10", productData.get(0)[0]);
|
||||
assertEquals("Extra large widget", productData.get(0)[1]);
|
||||
assertEquals("35.42", productData.get(0)[2]);
|
||||
assertEquals("D-2938-1", productData.get(1)[0]);
|
||||
assertEquals("Winding widget \"Deluxe Model\"", productData.get(1)[1]);
|
||||
assertEquals("245.99", productData.get(1)[2]);
|
||||
assertEquals("R3212-32", productData.get(2)[0]);
|
||||
assertEquals("Standard widget", productData.get(2)[1]);
|
||||
assertEquals("2.34", productData.get(2)[2]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenDataAndCsvOutputType_thenCsvFileProduced() {
|
||||
OutputService outputService = new OutputService();
|
||||
List<Object[]> productData = new ArrayList<>();
|
||||
productData.add(new Object[] { "1000-3-0", "Widget No. 96", "5.67" });
|
||||
productData.add(new Object[] { "G930-M-P", "1/4\" Wocket", ".67" });
|
||||
productData.add(new Object[] { "8080-0-M", "No. 54 Jumbo Widget", "35.74" });
|
||||
outputService.writeData(productData, OutputService.OutputType.CSV, "src/test/resources/outputProductList.csv");
|
||||
|
||||
ParsingService parsingService = new ParsingService();
|
||||
List<String[]> writtenData = parsingService.parseCsvFile("src/test/resources/outputProductList.csv");
|
||||
assertEquals(3, writtenData.size());
|
||||
assertEquals(3, writtenData.get(0).length);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenDataAndFixedWidthOutputType_thenFixedWidthFileProduced() {
|
||||
OutputService outputService = new OutputService();
|
||||
List<Object[]> productData = new ArrayList<>();
|
||||
productData.add(new Object[] { "1000-3-0", "Widget No. 96", "5.67" });
|
||||
productData.add(new Object[] { "G930-M-P", "1/4\" Wocket", ".67" });
|
||||
productData.add(new Object[] { "8080-0-M", "No. 54 Jumbo Widget", "35.74" });
|
||||
outputService.writeData(productData, OutputService.OutputType.FIXED_WIDTH, "src/test/resources/outputProductList.txt");
|
||||
|
||||
ParsingService parsingService = new ParsingService();
|
||||
List<String[]> writtenData = parsingService.parseFixedWidthFile("src/test/resources/outputProductList.txt");
|
||||
assertEquals(3, writtenData.size());
|
||||
assertEquals(3, writtenData.get(0).length);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenCsvFile_thenCsvFileParsedIntoBeans() {
|
||||
ParsingService parsingService = new ParsingService();
|
||||
List<Product> products = parsingService.parseCsvFileIntoBeans("src/test/resources/productListWithHeaders.csv");
|
||||
assertEquals(2, products.size());
|
||||
assertEquals("Product [Product Number: 99-378AG, Description: Wocket Widget #42, Unit Price: 3.56]", products.get(0)
|
||||
.toString());
|
||||
assertEquals("Product [Product Number: TB-333-0, Description: Turbine Widget replacement kit, Unit Price: 800.99]", products.get(1)
|
||||
.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenLisOfProduct_thenWriteFixedWidthFile() {
|
||||
OutputService outputService = new OutputService();
|
||||
Product product = new Product();
|
||||
product.setProductNumber("007-PPG0");
|
||||
product.setDescription("3/8\" x 1\" Wocket");
|
||||
product.setUnitPrice(45.99f);
|
||||
List<Product> products = new ArrayList<>();
|
||||
products.add(product);
|
||||
outputService.writeBeanToFixedWidthFile(products, "src/test/resources/productListWithHeaders.txt");
|
||||
ParsingService parsingService = new ParsingService();
|
||||
List<String[]> writtenData = parsingService.parseFixedWidthFile("src/test/resources/productListWithHeaders.txt");
|
||||
assertEquals(2, writtenData.size());
|
||||
assertEquals(3, writtenData.get(0).length);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenLargeCsvFile_thenParsedDataShouldBeReturned() {
|
||||
ParsingService parsingService = new ParsingService();
|
||||
List<String[]> productData = parsingService.parseCsvFileInBatches("src/test/resources/largeProductList.csv");
|
||||
assertEquals(36, productData.size());
|
||||
}
|
||||
}
|
36
libraries-data-2/src/test/resources/largeProductList.csv
Normal file
36
libraries-data-2/src/test/resources/largeProductList.csv
Normal file
@ -0,0 +1,36 @@
|
||||
A8993-10,"Extra large widget",35.42
|
||||
D-2938-1,"Winding widget ""Deluxe Model""",245.99
|
||||
R3212-32,"Standard widget",2.34
|
||||
A8993-10,"Extra large widget",35.42
|
||||
D-2938-1,"Winding widget ""Deluxe Model""",245.99
|
||||
R3212-32,"Standard widget",2.34
|
||||
A8993-10,"Extra large widget",35.42
|
||||
D-2938-1,"Winding widget ""Deluxe Model""",245.99
|
||||
R3212-32,"Standard widget",2.34
|
||||
A8993-10,"Extra large widget",35.42
|
||||
D-2938-1,"Winding widget ""Deluxe Model""",245.99
|
||||
R3212-32,"Standard widget",2.34
|
||||
A8993-10,"Extra large widget",35.42
|
||||
D-2938-1,"Winding widget ""Deluxe Model""",245.99
|
||||
R3212-32,"Standard widget",2.34
|
||||
A8993-10,"Extra large widget",35.42
|
||||
D-2938-1,"Winding widget ""Deluxe Model""",245.99
|
||||
R3212-32,"Standard widget",2.34
|
||||
A8993-10,"Extra large widget",35.42
|
||||
D-2938-1,"Winding widget ""Deluxe Model""",245.99
|
||||
R3212-32,"Standard widget",2.34
|
||||
A8993-10,"Extra large widget",35.42
|
||||
D-2938-1,"Winding widget ""Deluxe Model""",245.99
|
||||
R3212-32,"Standard widget",2.34
|
||||
A8993-10,"Extra large widget",35.42
|
||||
D-2938-1,"Winding widget ""Deluxe Model""",245.99
|
||||
R3212-32,"Standard widget",2.34
|
||||
A8993-10,"Extra large widget",35.42
|
||||
D-2938-1,"Winding widget ""Deluxe Model""",245.99
|
||||
R3212-32,"Standard widget",2.34
|
||||
A8993-10,"Extra large widget",35.42
|
||||
D-2938-1,"Winding widget ""Deluxe Model""",245.99
|
||||
R3212-32,"Standard widget",2.34
|
||||
A8993-10,"Extra large widget",35.42
|
||||
D-2938-1,"Winding widget ""Deluxe Model""",245.99
|
||||
R3212-32,"Standard widget",2.34
|
|
3
libraries-data-2/src/test/resources/productList.csv
Normal file
3
libraries-data-2/src/test/resources/productList.csv
Normal file
@ -0,0 +1,3 @@
|
||||
A8993-10,"Extra large widget",35.42
|
||||
D-2938-1,"Winding widget ""Deluxe Model""",245.99
|
||||
R3212-32,"Standard widget",2.34
|
|
3
libraries-data-2/src/test/resources/productList.txt
Normal file
3
libraries-data-2/src/test/resources/productList.txt
Normal file
@ -0,0 +1,3 @@
|
||||
A8993-10Extra large widget 35.42
|
||||
D-2938-1Winding widget "Deluxe Model" 245.99
|
||||
R3212-32Standard widget 2.34
|
@ -0,0 +1,3 @@
|
||||
product_no, description, unit_price
|
||||
99-378AG,Wocket Widget #42,3.56
|
||||
TB-333-0,Turbine Widget replacement kit,800.99
|
|
@ -0,0 +1,2 @@
|
||||
product_description unit_price
|
||||
007-PPG03/8" x 1" Wocket 45.99
|
@ -35,6 +35,37 @@
|
||||
<version>${mockwebserver.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<!-- Dependencies for Jetty ReactiveStreams HTTP Client -->
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-reactive-httpclient</artifactId>
|
||||
<version>${jetty.httpclient.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-server</artifactId>
|
||||
<version>${jetty.server.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.reactivex.rxjava2</groupId>
|
||||
<artifactId>rxjava</artifactId>
|
||||
<version>${rxjava2.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-webflux</artifactId>
|
||||
<version>${spring.webflux.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.projectreactor</groupId>
|
||||
<artifactId>reactor-core</artifactId>
|
||||
<version>${reactor.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.reactivestreams</groupId>
|
||||
<artifactId>reactive-streams</artifactId>
|
||||
<version>${reactive.stream.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
@ -42,6 +73,12 @@
|
||||
<gson.version>2.8.5</gson.version>
|
||||
<mockwebserver.version>3.14.2</mockwebserver.version>
|
||||
<jackson.version>2.9.8</jackson.version>
|
||||
<jetty.httpclient.version>1.0.3</jetty.httpclient.version>
|
||||
<jetty.server.version>9.4.19.v20190610</jetty.server.version>
|
||||
<rxjava2.version>2.2.11</rxjava2.version>
|
||||
<spring.webflux.version>5.1.9.RELEASE</spring.webflux.version>
|
||||
<reactive.stream.version>1.0.3</reactive.stream.version>
|
||||
<reactor.version>3.2.12.RELEASE</reactor.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
|
@ -0,0 +1,35 @@
|
||||
package com.baeldung.jetty.httpclient;
|
||||
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.jetty.reactive.client.ReactiveResponse;
|
||||
import org.reactivestreams.Subscriber;
|
||||
import org.reactivestreams.Subscription;
|
||||
|
||||
public class BlockingSubscriber implements Subscriber<ReactiveResponse> {
|
||||
BlockingQueue<ReactiveResponse> sink = new LinkedBlockingQueue<>(1);
|
||||
|
||||
@Override
|
||||
public void onSubscribe(Subscription subscription) {
|
||||
subscription.request(1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNext(ReactiveResponse response) {
|
||||
sink.offer(response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Throwable failure) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete() {
|
||||
}
|
||||
|
||||
public ReactiveResponse block() throws InterruptedException {
|
||||
return sink.poll(5, TimeUnit.SECONDS);
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package com.baeldung.jetty.httpclient;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.eclipse.jetty.server.Request;
|
||||
import org.eclipse.jetty.server.handler.AbstractHandler;
|
||||
import org.eclipse.jetty.util.IO;
|
||||
|
||||
public class RequestHandler extends AbstractHandler {
|
||||
|
||||
@Override
|
||||
public void handle(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
|
||||
jettyRequest.setHandled(true);
|
||||
response.setContentType(request.getContentType());
|
||||
IO.copy(request.getInputStream(), response.getOutputStream());
|
||||
}
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
package com.baeldung.jetty.httpclient;
|
||||
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.server.Handler;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
|
||||
public abstract class AbstractUnitTest {
|
||||
|
||||
protected HttpClient httpClient;
|
||||
protected Server server;
|
||||
protected static final String CONTENT = "Hello World!";
|
||||
protected final int port = 9080;
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
startServer(new RequestHandler());
|
||||
startClient();
|
||||
}
|
||||
|
||||
private void startClient() {
|
||||
httpClient = new HttpClient();
|
||||
try {
|
||||
httpClient.start();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void startServer(Handler handler) {
|
||||
server = new Server(port);
|
||||
server.setHandler(handler);
|
||||
try {
|
||||
server.start();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@After
|
||||
public void dispose() throws Exception {
|
||||
if (httpClient != null) {
|
||||
httpClient.stop();
|
||||
}
|
||||
if (server != null) {
|
||||
server.stop();
|
||||
}
|
||||
}
|
||||
|
||||
protected String uri() {
|
||||
return "http://localhost:" + port;
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package com.baeldung.jetty.httpclient;
|
||||
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
import org.eclipse.jetty.reactive.client.ReactiveRequest;
|
||||
import org.eclipse.jetty.reactive.client.ReactiveResponse;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.reactivestreams.Publisher;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
public class ProjectReactorUnitTest extends AbstractUnitTest {
|
||||
|
||||
@Test
|
||||
public void givenReactiveClient_whenRequested_shouldReturn200() throws Exception {
|
||||
|
||||
Request request = httpClient.newRequest(uri());
|
||||
ReactiveRequest reactiveRequest = ReactiveRequest.newBuilder(request)
|
||||
.build();
|
||||
Publisher<ReactiveResponse> publisher = reactiveRequest.response();
|
||||
|
||||
ReactiveResponse response = Mono.from(publisher)
|
||||
.block();
|
||||
|
||||
Assert.assertNotNull(response);
|
||||
Assert.assertEquals(response.getStatus(), HttpStatus.OK_200);
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
package com.baeldung.jetty.httpclient;
|
||||
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
import org.eclipse.jetty.reactive.client.ReactiveRequest;
|
||||
import org.eclipse.jetty.reactive.client.ReactiveResponse;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.reactivestreams.Publisher;
|
||||
|
||||
public class ReactiveStreamsUnitTest extends AbstractUnitTest {
|
||||
|
||||
@Test
|
||||
public void givenReactiveClient_whenRequested_shouldReturn200() throws Exception {
|
||||
|
||||
Request request = httpClient.newRequest(uri());
|
||||
ReactiveRequest reactiveRequest = ReactiveRequest.newBuilder(request)
|
||||
.build();
|
||||
Publisher<ReactiveResponse> publisher = reactiveRequest.response();
|
||||
|
||||
BlockingSubscriber subscriber = new BlockingSubscriber();
|
||||
publisher.subscribe(subscriber);
|
||||
ReactiveResponse response = subscriber.block();
|
||||
Assert.assertNotNull(response);
|
||||
Assert.assertEquals(response.getStatus(), HttpStatus.OK_200);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
package com.baeldung.jetty.httpclient;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
import org.eclipse.jetty.reactive.client.ReactiveRequest;
|
||||
import org.eclipse.jetty.reactive.client.ReactiveRequest.Event.Type;
|
||||
import org.eclipse.jetty.reactive.client.ReactiveResponse;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.reactivestreams.Publisher;
|
||||
import org.springframework.http.MediaType;
|
||||
|
||||
import io.reactivex.Flowable;
|
||||
import io.reactivex.Single;
|
||||
|
||||
public class RxJava2UnitTest extends AbstractUnitTest {
|
||||
|
||||
@Test
|
||||
public void givenReactiveClient_whenRequestedWithBody_ShouldReturnBody() throws Exception {
|
||||
|
||||
Request request = httpClient.newRequest(uri());
|
||||
ReactiveRequest reactiveRequest = ReactiveRequest.newBuilder(request)
|
||||
.content(ReactiveRequest.Content.fromString(CONTENT, MediaType.TEXT_PLAIN_VALUE, UTF_8))
|
||||
.build();
|
||||
Publisher<String> publisher = reactiveRequest.response(ReactiveResponse.Content.asString());
|
||||
|
||||
String responseContent = Single.fromPublisher(publisher)
|
||||
.blockingGet();
|
||||
|
||||
Assert.assertEquals(CONTENT, responseContent);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenReactiveClient_whenRequested_ShouldPrintEvents() throws Exception {
|
||||
ReactiveRequest request = ReactiveRequest.newBuilder(httpClient, uri())
|
||||
.content(ReactiveRequest.Content.fromString(CONTENT, MediaType.TEXT_PLAIN_VALUE, UTF_8))
|
||||
.build();
|
||||
Publisher<ReactiveRequest.Event> requestEvents = request.requestEvents();
|
||||
Publisher<ReactiveResponse.Event> responseEvents = request.responseEvents();
|
||||
|
||||
List<Type> requestEventTypes = new ArrayList<>();
|
||||
List<ReactiveResponse.Event.Type> responseEventTypes = new ArrayList<>();
|
||||
|
||||
Flowable.fromPublisher(requestEvents)
|
||||
.map(ReactiveRequest.Event::getType)
|
||||
.subscribe(requestEventTypes::add);
|
||||
|
||||
Flowable.fromPublisher(responseEvents)
|
||||
.map(ReactiveResponse.Event::getType)
|
||||
.subscribe(responseEventTypes::add);
|
||||
|
||||
Single<ReactiveResponse> response = Single.fromPublisher(request.response());
|
||||
int actualStatus = response.blockingGet()
|
||||
.getStatus();
|
||||
|
||||
Assert.assertEquals(6, requestEventTypes.size());
|
||||
Assert.assertEquals(5, responseEventTypes.size());
|
||||
|
||||
Assert.assertEquals(actualStatus, HttpStatus.OK_200);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
package com.baeldung.jetty.httpclient;
|
||||
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.client.reactive.ClientHttpConnector;
|
||||
import org.springframework.http.client.reactive.JettyClientHttpConnector;
|
||||
import org.springframework.web.reactive.function.BodyInserters;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
public class SpringWebFluxUnitTest extends AbstractUnitTest {
|
||||
|
||||
@Test
|
||||
public void givenReactiveClient_whenRequested_shouldReturnResponse() throws Exception {
|
||||
|
||||
HttpClient httpClient = new HttpClient();
|
||||
httpClient.start();
|
||||
|
||||
ClientHttpConnector clientConnector = new JettyClientHttpConnector(httpClient);
|
||||
WebClient client = WebClient.builder()
|
||||
.clientConnector(clientConnector)
|
||||
.build();
|
||||
String responseContent = client.post()
|
||||
.uri(uri())
|
||||
.contentType(MediaType.TEXT_PLAIN)
|
||||
.body(BodyInserters.fromPublisher(Mono.just(CONTENT), String.class))
|
||||
.retrieve()
|
||||
.bodyToMono(String.class)
|
||||
.block();
|
||||
Assert.assertNotNull(responseContent);
|
||||
Assert.assertEquals(CONTENT, responseContent);
|
||||
}
|
||||
}
|
@ -24,6 +24,8 @@ import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import static com.baeldung.dbunit.ConnectionSettings.JDBC_URL;
|
||||
import static com.baeldung.dbunit.ConnectionSettings.PASSWORD;
|
||||
import static com.baeldung.dbunit.ConnectionSettings.USER;
|
||||
import static java.util.stream.Collectors.joining;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.dbunit.Assertion.assertEqualsIgnoreCols;
|
||||
@ -33,12 +35,14 @@ public class DataSourceDBUnitTest extends DataSourceBasedDBTestCase {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(DataSourceDBUnitTest.class);
|
||||
|
||||
private Connection connection;
|
||||
|
||||
@Override
|
||||
protected DataSource getDataSource() {
|
||||
JdbcDataSource dataSource = new JdbcDataSource();
|
||||
dataSource.setURL(JDBC_URL);
|
||||
dataSource.setUser("sa");
|
||||
dataSource.setPassword("");
|
||||
dataSource.setUser(USER);
|
||||
dataSource.setPassword(PASSWORD);
|
||||
return dataSource;
|
||||
}
|
||||
|
||||
@ -62,6 +66,7 @@ public class DataSourceDBUnitTest extends DataSourceBasedDBTestCase {
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
connection = getConnection().getConnection();
|
||||
}
|
||||
|
||||
@After
|
||||
@ -71,9 +76,7 @@ public class DataSourceDBUnitTest extends DataSourceBasedDBTestCase {
|
||||
|
||||
@Test
|
||||
public void givenDataSet_whenSelect_thenFirstTitleIsGreyTShirt() throws SQLException {
|
||||
final Connection connection = getDataSource().getConnection();
|
||||
|
||||
final ResultSet rs = connection.createStatement().executeQuery("select * from ITEMS where id = 1");
|
||||
ResultSet rs = connection.createStatement().executeQuery("select * from ITEMS where id = 1");
|
||||
|
||||
assertThat(rs.next()).isTrue();
|
||||
assertThat(rs.getString("title")).isEqualTo("Grey T-Shirt");
|
||||
@ -81,58 +84,59 @@ public class DataSourceDBUnitTest extends DataSourceBasedDBTestCase {
|
||||
|
||||
@Test
|
||||
public void givenDataSetEmptySchema_whenDataSetCreated_thenTablesAreEqual() throws Exception {
|
||||
final IDataSet expectedDataSet = getDataSet();
|
||||
final ITable expectedTable = expectedDataSet.getTable("CLIENTS");
|
||||
final IDataSet databaseDataSet = getConnection().createDataSet();
|
||||
final ITable actualTable = databaseDataSet.getTable("CLIENTS");
|
||||
IDataSet expectedDataSet = getDataSet();
|
||||
ITable expectedTable = expectedDataSet.getTable("CLIENTS");
|
||||
IDataSet databaseDataSet = getConnection().createDataSet();
|
||||
ITable actualTable = databaseDataSet.getTable("CLIENTS");
|
||||
Assertion.assertEquals(expectedTable, actualTable);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenDataSet_whenInsert_thenTableHasNewClient() throws Exception {
|
||||
try (final InputStream is = getClass().getClassLoader().getResourceAsStream("dbunit/expected-user.xml")) {
|
||||
final IDataSet expectedDataSet = new FlatXmlDataSetBuilder().build(is);
|
||||
final ITable expectedTable = expectedDataSet.getTable("CLIENTS");
|
||||
final Connection conn = getDataSource().getConnection();
|
||||
try (InputStream is = getClass().getClassLoader().getResourceAsStream("dbunit/expected-user.xml")) {
|
||||
// given
|
||||
IDataSet expectedDataSet = new FlatXmlDataSetBuilder().build(is);
|
||||
ITable expectedTable = expectedDataSet.getTable("CLIENTS");
|
||||
Connection conn = getDataSource().getConnection();
|
||||
|
||||
// when
|
||||
conn.createStatement()
|
||||
.executeUpdate(
|
||||
"INSERT INTO CLIENTS (first_name, last_name) VALUES ('John', 'Jansen')");
|
||||
final ITable actualData = getConnection()
|
||||
.createQueryTable(
|
||||
"result_name",
|
||||
"SELECT * FROM CLIENTS WHERE last_name='Jansen'");
|
||||
.executeUpdate("INSERT INTO CLIENTS (first_name, last_name) VALUES ('John', 'Jansen')");
|
||||
ITable actualData = getConnection()
|
||||
.createQueryTable("result_name", "SELECT * FROM CLIENTS WHERE last_name='Jansen'");
|
||||
|
||||
// then
|
||||
assertEqualsIgnoreCols(expectedTable, actualData, new String[] { "id" });
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenDataSet_whenDelete_thenItemIsDeleted() throws Exception {
|
||||
final Connection connection = getConnection().getConnection();
|
||||
|
||||
try (final InputStream is = DataSourceDBUnitTest.class.getClassLoader().getResourceAsStream("dbunit/items_exp_delete.xml")) {
|
||||
try (InputStream is = DataSourceDBUnitTest.class.getClassLoader()
|
||||
.getResourceAsStream("dbunit/items_exp_delete.xml")) {
|
||||
// given
|
||||
ITable expectedTable = (new FlatXmlDataSetBuilder().build(is)).getTable("ITEMS");
|
||||
|
||||
// when
|
||||
connection.createStatement().executeUpdate("delete from ITEMS where id = 2");
|
||||
|
||||
final IDataSet databaseDataSet = getConnection().createDataSet();
|
||||
// then
|
||||
IDataSet databaseDataSet = getConnection().createDataSet();
|
||||
ITable actualTable = databaseDataSet.getTable("ITEMS");
|
||||
|
||||
Assertion.assertEquals(expectedTable, actualTable);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenDataSet_whenUpdate_thenItemHasNewName() throws Exception {
|
||||
final Connection connection = getConnection().getConnection();
|
||||
|
||||
try (final InputStream is = DataSourceDBUnitTest.class.getClassLoader().getResourceAsStream("dbunit/items_exp_rename.xml")) {
|
||||
try (InputStream is = DataSourceDBUnitTest.class.getClassLoader()
|
||||
.getResourceAsStream("dbunit/items_exp_rename.xml")) {
|
||||
// given
|
||||
ITable expectedTable = (new FlatXmlDataSetBuilder().build(is)).getTable("ITEMS");
|
||||
|
||||
connection.createStatement().executeUpdate("update ITEMS set title='new name' where id = 1");
|
||||
|
||||
final IDataSet databaseDataSet = getConnection().createDataSet();
|
||||
IDataSet databaseDataSet = getConnection().createDataSet();
|
||||
ITable actualTable = databaseDataSet.getTable("ITEMS");
|
||||
|
||||
Assertion.assertEquals(expectedTable, actualTable);
|
||||
@ -140,22 +144,24 @@ public class DataSourceDBUnitTest extends DataSourceBasedDBTestCase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenDataSet_whenInsertUnexpectedData_thenFailOnAllUnexpectedValues() throws Exception {
|
||||
try (final InputStream is = getClass().getClassLoader().getResourceAsStream("dbunit/expected-multiple-failures.xml")) {
|
||||
final IDataSet expectedDataSet = new FlatXmlDataSetBuilder().build(is);
|
||||
final ITable expectedTable = expectedDataSet.getTable("ITEMS");
|
||||
final Connection conn = getDataSource().getConnection();
|
||||
final DiffCollectingFailureHandler collectingHandler = new DiffCollectingFailureHandler();
|
||||
public void givenDataSet_whenInsertUnexpectedData_thenFail() throws Exception {
|
||||
try (InputStream is = getClass().getClassLoader()
|
||||
.getResourceAsStream("dbunit/expected-multiple-failures.xml")) {
|
||||
|
||||
conn.createStatement().executeUpdate(
|
||||
"INSERT INTO ITEMS (title, price) VALUES ('Battery', '1000000')");
|
||||
final ITable actualData = getConnection().createDataSet().getTable("ITEMS");
|
||||
// given
|
||||
IDataSet expectedDataSet = new FlatXmlDataSetBuilder().build(is);
|
||||
ITable expectedTable = expectedDataSet.getTable("ITEMS");
|
||||
Connection conn = getDataSource().getConnection();
|
||||
DiffCollectingFailureHandler collectingHandler = new DiffCollectingFailureHandler();
|
||||
|
||||
// when
|
||||
conn.createStatement().executeUpdate("INSERT INTO ITEMS (title, price) VALUES ('Battery', '1000000')");
|
||||
ITable actualData = getConnection().createDataSet().getTable("ITEMS");
|
||||
|
||||
// then
|
||||
Assertion.assertEquals(expectedTable, actualData, collectingHandler);
|
||||
if (!collectingHandler.getDiffList().isEmpty()) {
|
||||
String message = (String) collectingHandler
|
||||
.getDiffList()
|
||||
.stream()
|
||||
String message = (String) collectingHandler.getDiffList().stream()
|
||||
.map(d -> formatDifference((Difference) d)).collect(joining("\n"));
|
||||
logger.error(() -> message);
|
||||
}
|
||||
@ -163,6 +169,8 @@ public class DataSourceDBUnitTest extends DataSourceBasedDBTestCase {
|
||||
}
|
||||
|
||||
private static String formatDifference(Difference diff) {
|
||||
return "expected value in " + diff.getExpectedTable().getTableMetaData().getTableName() + "." + diff.getColumnName() + " row " + diff.getRowIndex() + ":" + diff.getExpectedValue() + ", but was: " + diff.getActualValue();
|
||||
return "expected value in " + diff.getExpectedTable().getTableMetaData().getTableName() + "." + diff
|
||||
.getColumnName() + " row " + diff.getRowIndex() + ":" + diff.getExpectedValue() + ", but was: " + diff
|
||||
.getActualValue();
|
||||
}
|
||||
}
|
||||
|
@ -31,13 +31,15 @@ public class OldSchoolDbUnitTest {
|
||||
|
||||
private static IDatabaseTester tester = null;
|
||||
|
||||
private Connection connection;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUp() throws Exception {
|
||||
tester = initDatabaseTester();
|
||||
}
|
||||
|
||||
private static IDatabaseTester initDatabaseTester() throws Exception {
|
||||
final JdbcDatabaseTester tester = new JdbcDatabaseTester(JDBC_DRIVER, JDBC_URL, USER, PASSWORD);
|
||||
JdbcDatabaseTester tester = new JdbcDatabaseTester(JDBC_DRIVER, JDBC_URL, USER, PASSWORD);
|
||||
tester.setDataSet(initDataSet());
|
||||
tester.setSetUpOperation(DatabaseOperation.REFRESH);
|
||||
tester.setTearDownOperation(DatabaseOperation.DELETE_ALL);
|
||||
@ -45,7 +47,7 @@ public class OldSchoolDbUnitTest {
|
||||
}
|
||||
|
||||
private static IDataSet initDataSet() throws Exception {
|
||||
try (final InputStream is = OldSchoolDbUnitTest.class.getClassLoader().getResourceAsStream("dbunit/data.xml")) {
|
||||
try (InputStream is = OldSchoolDbUnitTest.class.getClassLoader().getResourceAsStream("dbunit/data.xml")) {
|
||||
return new FlatXmlDataSetBuilder().build(is);
|
||||
}
|
||||
}
|
||||
@ -53,6 +55,7 @@ public class OldSchoolDbUnitTest {
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
tester.onSetup();
|
||||
connection = tester.getConnection().getConnection();
|
||||
}
|
||||
|
||||
@After
|
||||
@ -62,94 +65,100 @@ public class OldSchoolDbUnitTest {
|
||||
|
||||
@Test
|
||||
public void givenDataSet_whenSelect_thenFirstTitleIsGreyTShirt() throws Exception {
|
||||
final Connection connection = tester.getConnection().getConnection();
|
||||
|
||||
final ResultSet rs = connection.createStatement().executeQuery("select * from ITEMS where id = 1");
|
||||
ResultSet rs = connection.createStatement().executeQuery("select * from ITEMS where id = 1");
|
||||
|
||||
assertThat(rs.next()).isTrue();
|
||||
assertThat(rs.getString("title")).isEqualTo("Grey T-Shirt");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenDataSet_whenInsert_thenGetResultsAreStillEqualIfIgnoringColumnsWithDifferentProduced() throws Exception {
|
||||
final Connection connection = tester.getConnection().getConnection();
|
||||
final String[] excludedColumns = { "id", "produced" };
|
||||
try (final InputStream is = getClass().getClassLoader().getResourceAsStream("dbunit/expected-ignoring-registered_at.xml")) {
|
||||
final IDataSet expectedDataSet = new FlatXmlDataSetBuilder().build(is);
|
||||
final ITable expectedTable = DefaultColumnFilter.excludedColumnsTable(
|
||||
expectedDataSet.getTable("ITEMS"), excludedColumns);
|
||||
public void givenDataSet_whenInsert_thenGetResultsAreStillEqualIfIgnoringColumnsWithDifferentProduced()
|
||||
throws Exception {
|
||||
String[] excludedColumns = { "id", "produced" };
|
||||
try (InputStream is = getClass().getClassLoader()
|
||||
.getResourceAsStream("dbunit/expected-ignoring-registered_at.xml")) {
|
||||
// given
|
||||
IDataSet expectedDataSet = new FlatXmlDataSetBuilder().build(is);
|
||||
ITable expectedTable = DefaultColumnFilter
|
||||
.excludedColumnsTable(expectedDataSet.getTable("ITEMS"), excludedColumns);
|
||||
|
||||
connection.createStatement().executeUpdate(
|
||||
"INSERT INTO ITEMS (title, price, produced) VALUES('Necklace', 199.99, now())");
|
||||
|
||||
final IDataSet databaseDataSet = tester.getConnection().createDataSet();
|
||||
final ITable actualTable = DefaultColumnFilter.excludedColumnsTable(
|
||||
databaseDataSet.getTable("ITEMS"), excludedColumns);
|
||||
// when
|
||||
connection.createStatement()
|
||||
.executeUpdate("INSERT INTO ITEMS (title, price, produced) VALUES('Necklace', 199.99, now())");
|
||||
|
||||
// then
|
||||
IDataSet databaseDataSet = tester.getConnection().createDataSet();
|
||||
ITable actualTable = DefaultColumnFilter
|
||||
.excludedColumnsTable(databaseDataSet.getTable("ITEMS"), excludedColumns);
|
||||
Assertion.assertEquals(expectedTable, actualTable);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenDataSet_whenDelete_thenItemIsRemoved() throws Exception {
|
||||
final Connection connection = tester.getConnection().getConnection();
|
||||
|
||||
try (final InputStream is = OldSchoolDbUnitTest.class.getClassLoader().getResourceAsStream("dbunit/items_exp_delete.xml")) {
|
||||
try (InputStream is = OldSchoolDbUnitTest.class.getClassLoader()
|
||||
.getResourceAsStream("dbunit/items_exp_delete.xml")) {
|
||||
// given
|
||||
ITable expectedTable = new FlatXmlDataSetBuilder().build(is).getTable("ITEMS");
|
||||
|
||||
// when
|
||||
connection.createStatement().executeUpdate("delete from ITEMS where id = 2");
|
||||
|
||||
final IDataSet databaseDataSet = tester.getConnection().createDataSet();
|
||||
// then
|
||||
IDataSet databaseDataSet = tester.getConnection().createDataSet();
|
||||
ITable actualTable = databaseDataSet.getTable("ITEMS");
|
||||
|
||||
assertEquals(expectedTable, actualTable);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenDataSet_whenDelete_thenItemIsRemovedAndResultsEqualIfProducedIsIgnored() throws Exception {
|
||||
final Connection connection = tester.getConnection().getConnection();
|
||||
|
||||
try (final InputStream is = OldSchoolDbUnitTest.class.getClassLoader().getResourceAsStream("dbunit/items_exp_delete_no_produced.xml")) {
|
||||
final ITable expectedTable = new FlatXmlDataSetBuilder().build(is).getTable("ITEMS");
|
||||
public void givenDataSet_whenProductIgnoredAndDelete_thenItemIsRemoved() throws Exception {
|
||||
try (InputStream is = OldSchoolDbUnitTest.class.getClassLoader()
|
||||
.getResourceAsStream("dbunit/items_exp_delete_no_produced.xml")) {
|
||||
// given
|
||||
ITable expectedTable = new FlatXmlDataSetBuilder().build(is).getTable("ITEMS");
|
||||
|
||||
// when
|
||||
connection.createStatement().executeUpdate("delete from ITEMS where id = 2");
|
||||
|
||||
final IDataSet databaseDataSet = tester.getConnection().createDataSet();
|
||||
// then
|
||||
IDataSet databaseDataSet = tester.getConnection().createDataSet();
|
||||
ITable actualTable = databaseDataSet.getTable("ITEMS");
|
||||
actualTable = DefaultColumnFilter.excludedColumnsTable(actualTable, new String[] { "produced" });
|
||||
|
||||
assertEquals(expectedTable, actualTable);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenDataSet_whenUpdate_thenItemHasNewName() throws Exception {
|
||||
final Connection connection = tester.getConnection().getConnection();
|
||||
|
||||
try (final InputStream is = OldSchoolDbUnitTest.class.getClassLoader().getResourceAsStream("dbunit/items_exp_rename.xml")) {
|
||||
final ITable expectedTable = new FlatXmlDataSetBuilder().build(is).getTable("ITEMS");
|
||||
try (InputStream is = OldSchoolDbUnitTest.class.getClassLoader()
|
||||
.getResourceAsStream("dbunit/items_exp_rename.xml")) {
|
||||
// given
|
||||
ITable expectedTable = new FlatXmlDataSetBuilder().build(is).getTable("ITEMS");
|
||||
|
||||
// when
|
||||
connection.createStatement().executeUpdate("update ITEMS set title='new name' where id = 1");
|
||||
|
||||
final IDataSet databaseDataSet = tester.getConnection().createDataSet();
|
||||
// then
|
||||
IDataSet databaseDataSet = tester.getConnection().createDataSet();
|
||||
ITable actualTable = databaseDataSet.getTable("ITEMS");
|
||||
|
||||
assertEquals(expectedTable, actualTable);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenDataSet_whenUpdateWithNoProduced_thenItemHasNewName() throws Exception {
|
||||
final Connection connection = tester.getConnection().getConnection();
|
||||
|
||||
try (final InputStream is = OldSchoolDbUnitTest.class.getClassLoader().getResourceAsStream("dbunit/items_exp_rename_no_produced.xml")) {
|
||||
try (InputStream is = OldSchoolDbUnitTest.class.getClassLoader()
|
||||
.getResourceAsStream("dbunit/items_exp_rename_no_produced.xml")) {
|
||||
// given
|
||||
ITable expectedTable = new FlatXmlDataSetBuilder().build(is).getTable("ITEMS");
|
||||
expectedTable = DefaultColumnFilter.excludedColumnsTable(expectedTable, new String[] { "produced" });
|
||||
|
||||
// when
|
||||
connection.createStatement().executeUpdate("update ITEMS set title='new name' where id = 1");
|
||||
|
||||
final IDataSet databaseDataSet = tester.getConnection().createDataSet();
|
||||
// then
|
||||
IDataSet databaseDataSet = tester.getConnection().createDataSet();
|
||||
ITable actualTable = databaseDataSet.getTable("ITEMS");
|
||||
actualTable = DefaultColumnFilter.excludedColumnsTable(actualTable, new String[] { "produced" });
|
||||
assertEquals(expectedTable, actualTable);
|
||||
|
@ -5,3 +5,4 @@ This module contains articles about Apache Maven. Please refer to its submodules
|
||||
### Relevant Articles
|
||||
|
||||
- [Apache Maven Tutorial](https://www.baeldung.com/maven)
|
||||
- [Find Unused Maven Dependencies](https://www.baeldung.com/maven-unused-dependencies)
|
||||
|
@ -53,7 +53,7 @@
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<spring.version>4.3.26.RELEASE</spring.version>
|
||||
<spring.version>4.3.27.RELEASE</spring.version>
|
||||
<cargo-maven2-plugin.version>1.6.1</cargo-maven2-plugin.version>
|
||||
</properties>
|
||||
|
||||
|
30
patterns/cqrs-es/pom.xml
Normal file
30
patterns/cqrs-es/pom.xml
Normal file
@ -0,0 +1,30 @@
|
||||
<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>cqrs-es</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<name>cqrs-es</name>
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>patterns</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<properties>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.12</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.13</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
@ -0,0 +1,30 @@
|
||||
package com.baeldung.patterns.cqrs.aggregates;
|
||||
|
||||
import com.baeldung.patterns.cqrs.commands.CreateUserCommand;
|
||||
import com.baeldung.patterns.cqrs.commands.UpdateUserCommand;
|
||||
import com.baeldung.patterns.cqrs.repository.UserWriteRepository;
|
||||
import com.baeldung.patterns.domain.User;
|
||||
|
||||
public class UserAggregate {
|
||||
|
||||
private UserWriteRepository writeRepository;
|
||||
|
||||
public UserAggregate(UserWriteRepository repository) {
|
||||
this.writeRepository = repository;
|
||||
}
|
||||
|
||||
public User handleCreateUserCommand(CreateUserCommand command) {
|
||||
User user = new User(command.getUserId(), command.getFirstName(), command.getLastName());
|
||||
writeRepository.addUser(user.getUserid(), user);
|
||||
return user;
|
||||
}
|
||||
|
||||
public User handleUpdateUserCommand(UpdateUserCommand command) {
|
||||
User user = writeRepository.getUser(command.getUserId());
|
||||
user.setAddresses(command.getAddresses());
|
||||
user.setContacts(command.getContacts());
|
||||
writeRepository.addUser(user.getUserid(), user);
|
||||
return user;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package com.baeldung.patterns.cqrs.commands;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class CreateUserCommand {
|
||||
|
||||
private String userId;
|
||||
private String firstName;
|
||||
private String lastName;
|
||||
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package com.baeldung.patterns.cqrs.commands;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import com.baeldung.patterns.domain.Address;
|
||||
import com.baeldung.patterns.domain.Contact;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class UpdateUserCommand {
|
||||
|
||||
private String userId;
|
||||
private Set<Address> addresses = new HashSet<>();
|
||||
private Set<Contact> contacts = new HashSet<>();
|
||||
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package com.baeldung.patterns.cqrs.projections;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import com.baeldung.patterns.cqrs.queries.AddressByRegionQuery;
|
||||
import com.baeldung.patterns.cqrs.queries.ContactByTypeQuery;
|
||||
import com.baeldung.patterns.cqrs.repository.UserReadRepository;
|
||||
import com.baeldung.patterns.domain.Address;
|
||||
import com.baeldung.patterns.domain.Contact;
|
||||
import com.baeldung.patterns.domain.UserAddress;
|
||||
import com.baeldung.patterns.domain.UserContact;
|
||||
|
||||
public class UserProjection {
|
||||
|
||||
private UserReadRepository repository;
|
||||
|
||||
public UserProjection(UserReadRepository repository) {
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
public Set<Contact> handle(ContactByTypeQuery query) throws Exception {
|
||||
UserContact userContact = repository.getUserContact(query.getUserId());
|
||||
if (userContact == null)
|
||||
throw new Exception("User does not exist.");
|
||||
return userContact.getContactByType()
|
||||
.get(query.getContactType());
|
||||
}
|
||||
|
||||
public Set<Address> handle(AddressByRegionQuery query) throws Exception {
|
||||
UserAddress userAddress = repository.getUserAddress(query.getUserId());
|
||||
if (userAddress == null)
|
||||
throw new Exception("User does not exist.");
|
||||
return userAddress.getAddressByRegion()
|
||||
.get(query.getState());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
package com.baeldung.patterns.cqrs.projectors;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
import com.baeldung.patterns.cqrs.repository.UserReadRepository;
|
||||
import com.baeldung.patterns.domain.Address;
|
||||
import com.baeldung.patterns.domain.Contact;
|
||||
import com.baeldung.patterns.domain.User;
|
||||
import com.baeldung.patterns.domain.UserAddress;
|
||||
import com.baeldung.patterns.domain.UserContact;
|
||||
|
||||
public class UserProjector {
|
||||
|
||||
UserReadRepository readRepository = new UserReadRepository();
|
||||
|
||||
public UserProjector(UserReadRepository readRepository) {
|
||||
this.readRepository = readRepository;
|
||||
}
|
||||
|
||||
public void project(User user) {
|
||||
UserContact userContact = Optional.ofNullable(readRepository.getUserContact(user.getUserid()))
|
||||
.orElse(new UserContact());
|
||||
Map<String, Set<Contact>> contactByType = new HashMap<>();
|
||||
for (Contact contact : user.getContacts()) {
|
||||
Set<Contact> contacts = Optional.ofNullable(contactByType.get(contact.getType()))
|
||||
.orElse(new HashSet<>());
|
||||
contacts.add(contact);
|
||||
contactByType.put(contact.getType(), contacts);
|
||||
}
|
||||
userContact.setContactByType(contactByType);
|
||||
readRepository.addUserContact(user.getUserid(), userContact);
|
||||
|
||||
UserAddress userAddress = Optional.ofNullable(readRepository.getUserAddress(user.getUserid()))
|
||||
.orElse(new UserAddress());
|
||||
Map<String, Set<Address>> addressByRegion = new HashMap<>();
|
||||
for (Address address : user.getAddresses()) {
|
||||
Set<Address> addresses = Optional.ofNullable(addressByRegion.get(address.getState()))
|
||||
.orElse(new HashSet<>());
|
||||
addresses.add(address);
|
||||
addressByRegion.put(address.getState(), addresses);
|
||||
}
|
||||
userAddress.setAddressByRegion(addressByRegion);
|
||||
readRepository.addUserAddress(user.getUserid(), userAddress);
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package com.baeldung.patterns.cqrs.queries;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class AddressByRegionQuery {
|
||||
|
||||
private String userId;
|
||||
private String state;
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package com.baeldung.patterns.cqrs.queries;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class ContactByTypeQuery {
|
||||
|
||||
private String userId;
|
||||
private String contactType;
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package com.baeldung.patterns.cqrs.repository;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.baeldung.patterns.domain.UserAddress;
|
||||
import com.baeldung.patterns.domain.UserContact;
|
||||
|
||||
public class UserReadRepository {
|
||||
|
||||
private Map<String, UserAddress> userAddress = new HashMap<>();
|
||||
|
||||
private Map<String, UserContact> userContact = new HashMap<>();
|
||||
|
||||
public void addUserAddress(String id, UserAddress user) {
|
||||
userAddress.put(id, user);
|
||||
}
|
||||
|
||||
public UserAddress getUserAddress(String id) {
|
||||
return userAddress.get(id);
|
||||
}
|
||||
|
||||
public void addUserContact(String id, UserContact user) {
|
||||
userContact.put(id, user);
|
||||
}
|
||||
|
||||
public UserContact getUserContact(String id) {
|
||||
return userContact.get(id);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package com.baeldung.patterns.cqrs.repository;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.baeldung.patterns.domain.User;
|
||||
|
||||
public class UserWriteRepository {
|
||||
|
||||
private Map<String, User> store = new HashMap<>();
|
||||
|
||||
public void addUser(String id, User user) {
|
||||
store.put(id, user);
|
||||
}
|
||||
|
||||
public User getUser(String id) {
|
||||
return store.get(id);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package com.baeldung.patterns.crud.repository;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.baeldung.patterns.domain.User;
|
||||
|
||||
public class UserRepository {
|
||||
|
||||
private Map<String, User> store = new HashMap<>();
|
||||
|
||||
public void addUser(String id, User user) {
|
||||
store.put(id, user);
|
||||
}
|
||||
|
||||
public User getUser(String id) {
|
||||
return store.get(id);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
package com.baeldung.patterns.crud.service;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.baeldung.patterns.crud.repository.UserRepository;
|
||||
import com.baeldung.patterns.domain.Address;
|
||||
import com.baeldung.patterns.domain.Contact;
|
||||
import com.baeldung.patterns.domain.User;
|
||||
|
||||
public class UserService {
|
||||
|
||||
private UserRepository repository;
|
||||
|
||||
public UserService(UserRepository repository) {
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
public void createUser(String userId, String firstName, String lastName) {
|
||||
User user = new User(userId, firstName, lastName);
|
||||
repository.addUser(userId, user);
|
||||
}
|
||||
|
||||
public void updateUser(String userId, Set<Contact> contacts, Set<Address> addresses) throws Exception {
|
||||
User user = repository.getUser(userId);
|
||||
if (user == null)
|
||||
throw new Exception("User does not exist.");
|
||||
user.setContacts(contacts);
|
||||
user.setAddresses(addresses);
|
||||
repository.addUser(userId, user);
|
||||
}
|
||||
|
||||
public Set<Contact> getContactByType(String userId, String contactType) throws Exception {
|
||||
User user = repository.getUser(userId);
|
||||
if (user == null)
|
||||
throw new Exception("User does not exit.");
|
||||
Set<Contact> contacts = user.getContacts();
|
||||
return contacts.stream()
|
||||
.filter(c -> c.getType()
|
||||
.equals(contactType))
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
public Set<Address> getAddressByRegion(String userId, String state) throws Exception {
|
||||
User user = repository.getUser(userId);
|
||||
if (user == null)
|
||||
throw new Exception("User does not exist.");
|
||||
Set<Address> addresses = user.getAddresses();
|
||||
return addresses.stream()
|
||||
.filter(a -> a.getState()
|
||||
.equals(state))
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package com.baeldung.patterns.domain;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class Address {
|
||||
|
||||
private String city;
|
||||
private String state;
|
||||
private String postcode;
|
||||
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package com.baeldung.patterns.domain;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class Contact {
|
||||
|
||||
private String type;
|
||||
private String detail;
|
||||
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package com.baeldung.patterns.domain;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@Data
|
||||
@RequiredArgsConstructor
|
||||
public class User {
|
||||
@NonNull
|
||||
private String userid;
|
||||
@NonNull
|
||||
private String firstname;
|
||||
@NonNull
|
||||
private String lastname;
|
||||
private Set<Contact> contacts = new HashSet<>();
|
||||
private Set<Address> addresses = new HashSet<>();
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user