Java 11 migration: ambassador async-method-invocation balking bridge builder (#1076)

* Moves ambassador pattern to java 11

* Moves async-method-invocation pattern  to java 11

* Moves balking pattern  to java 11

* Moves bridge pattern  to java 11

* Moves builder pattern  to java 11
This commit is contained in:
Anurag Agarwal
2019-11-12 01:17:09 +05:30
committed by Ilkka Seppälä
parent f0f0143d48
commit c4418311c6
27 changed files with 173 additions and 176 deletions

View File

@ -64,15 +64,14 @@ public class App {
*/
public static void main(String[] args) throws Exception {
// construct a new executor that will run async tasks
AsyncExecutor executor = new ThreadAsyncExecutor();
var executor = new ThreadAsyncExecutor();
// start few async tasks with varying processing times, two last with callback handlers
final AsyncResult<Integer> asyncResult1 = executor.startProcess(lazyval(10, 500));
final AsyncResult<String> asyncResult2 = executor.startProcess(lazyval("test", 300));
final AsyncResult<Long> asyncResult3 = executor.startProcess(lazyval(50L, 700));
final AsyncResult<Integer> asyncResult4 =
executor.startProcess(lazyval(20, 400), callback("Callback result 4"));
final AsyncResult<String> asyncResult5 =
final var asyncResult1 = executor.startProcess(lazyval(10, 500));
final var asyncResult2 = executor.startProcess(lazyval("test", 300));
final var asyncResult3 = executor.startProcess(lazyval(50L, 700));
final var asyncResult4 = executor.startProcess(lazyval(20, 400), callback("Callback result 4"));
final var asyncResult5 =
executor.startProcess(lazyval("callback", 600), callback("Callback result 5"));
// emulate processing in the current thread while async tasks are running in their own threads
@ -80,9 +79,9 @@ public class App {
log("Some hard work done");
// wait for completion of the tasks
final Integer result1 = executor.endProcess(asyncResult1);
final String result2 = executor.endProcess(asyncResult2);
final Long result3 = executor.endProcess(asyncResult3);
final var result1 = executor.endProcess(asyncResult1);
final var result2 = executor.endProcess(asyncResult2);
final var result3 = executor.endProcess(asyncResult3);
asyncResult4.await();
asyncResult5.await();

View File

@ -45,7 +45,7 @@ public class ThreadAsyncExecutor implements AsyncExecutor {
@Override
public <T> AsyncResult<T> startProcess(Callable<T> task, AsyncCallback<T> callback) {
CompletableResult<T> result = new CompletableResult<>(callback);
var result = new CompletableResult<>(callback);
new Thread(() -> {
try {
result.setValue(task.call());

View File

@ -28,11 +28,9 @@ import org.junit.jupiter.api.Test;
/**
* Application test
*/
public class AppTest {
class AppTest {
@Test
public void test() throws Exception {
String[] args = {};
App.main(args);
void test() throws Exception {
App.main(new String[]{});
}
}

View File

@ -24,39 +24,66 @@
package com.iluwatar.async.method.invocation;
import static java.time.Duration.ofMillis;
import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertTimeout;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.*;
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
import static org.mockito.internal.verification.VerificationModeFactory.times;
import java.util.Optional;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Matchers;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
/**
* Date: 12/6/15 - 10:49 AM
*
* @author Jeroen Meulemeester
*/
public class ThreadAsyncExecutorTest {
class ThreadAsyncExecutorTest {
@Captor
private ArgumentCaptor<Optional<Exception>> optionalCaptor;
@Mock
private Callable<Object> task;
@Mock
private AsyncCallback<Object> callback;
@BeforeEach
void setUp() {
MockitoAnnotations.initMocks(this);
}
/**
* Test used to verify the happy path of {@link ThreadAsyncExecutor#startProcess(Callable)}
*/
@Test
public void testSuccessfulTaskWithoutCallback() throws Exception {
void testSuccessfulTaskWithoutCallback() throws Exception {
assertTimeout(ofMillis(3000), () -> {
// Instantiate a new executor and start a new 'null' task ...
final ThreadAsyncExecutor executor = new ThreadAsyncExecutor();
final var executor = new ThreadAsyncExecutor();
final Object result = new Object();
final Callable<Object> task = mock(Callable.class);
final var result = new Object();
when(task.call()).thenReturn(result);
final AsyncResult<Object> asyncResult = executor.startProcess(task);
final var asyncResult = executor.startProcess(task);
assertNotNull(asyncResult);
asyncResult.await(); // Prevent timing issues, and wait until the result is available
assertTrue(asyncResult.isCompleted());
@ -74,17 +101,15 @@ public class ThreadAsyncExecutorTest {
* AsyncCallback)}
*/
@Test
public void testSuccessfulTaskWithCallback() throws Exception {
void testSuccessfulTaskWithCallback() throws Exception {
assertTimeout(ofMillis(3000), () -> {
// Instantiate a new executor and start a new 'null' task ...
final ThreadAsyncExecutor executor = new ThreadAsyncExecutor();
final var executor = new ThreadAsyncExecutor();
final Object result = new Object();
final Callable<Object> task = mock(Callable.class);
final var result = new Object();
when(task.call()).thenReturn(result);
final AsyncCallback callback = mock(AsyncCallback.class);
final AsyncResult<Object> asyncResult = executor.startProcess(task, callback);
final var asyncResult = executor.startProcess(task, callback);
assertNotNull(asyncResult);
asyncResult.await(); // Prevent timing issues, and wait until the result is available
assertTrue(asyncResult.isCompleted());
@ -93,11 +118,9 @@ public class ThreadAsyncExecutorTest {
verify(task, times(1)).call();
// ... same for the callback, we expect our object
final ArgumentCaptor<Optional<Exception>> optionalCaptor =
ArgumentCaptor.forClass((Class) Optional.class);
verify(callback, times(1)).onComplete(eq(result), optionalCaptor.capture());
final Optional<Exception> optionalException = optionalCaptor.getValue();
final var optionalException = optionalCaptor.getValue();
assertNotNull(optionalException);
assertFalse(optionalException.isPresent());
@ -111,19 +134,18 @@ public class ThreadAsyncExecutorTest {
* task takes a while to execute
*/
@Test
public void testLongRunningTaskWithoutCallback() throws Exception {
void testLongRunningTaskWithoutCallback() throws Exception {
assertTimeout(ofMillis(5000), () -> {
// Instantiate a new executor and start a new 'null' task ...
final ThreadAsyncExecutor executor = new ThreadAsyncExecutor();
final var executor = new ThreadAsyncExecutor();
final Object result = new Object();
final Callable<Object> task = mock(Callable.class);
final var result = new Object();
when(task.call()).thenAnswer(i -> {
Thread.sleep(1500);
return result;
});
final AsyncResult<Object> asyncResult = executor.startProcess(task);
final var asyncResult = executor.startProcess(task);
assertNotNull(asyncResult);
assertFalse(asyncResult.isCompleted());
@ -152,20 +174,18 @@ public class ThreadAsyncExecutorTest {
* AsyncCallback)} when a task takes a while to execute
*/
@Test
public void testLongRunningTaskWithCallback() throws Exception {
void testLongRunningTaskWithCallback() throws Exception {
assertTimeout(ofMillis(5000), () -> {
// Instantiate a new executor and start a new 'null' task ...
final ThreadAsyncExecutor executor = new ThreadAsyncExecutor();
final var executor = new ThreadAsyncExecutor();
final Object result = new Object();
final Callable<Object> task = mock(Callable.class);
final var result = new Object();
when(task.call()).thenAnswer(i -> {
Thread.sleep(1500);
return result;
});
final AsyncCallback<Object> callback = mock(AsyncCallback.class);
final AsyncResult<Object> asyncResult = executor.startProcess(task, callback);
final var asyncResult = executor.startProcess(task, callback);
assertNotNull(asyncResult);
assertFalse(asyncResult.isCompleted());
@ -180,12 +200,9 @@ public class ThreadAsyncExecutorTest {
// Our task should only execute once, but it can take a while ...
verify(task, timeout(3000).times(1)).call();
final ArgumentCaptor<Optional<Exception>> optionalCaptor =
ArgumentCaptor.forClass((Class) Optional.class);
verify(callback, timeout(3000).times(1)).onComplete(eq(result), optionalCaptor.capture());
final Optional<Exception> optionalException = optionalCaptor.getValue();
final var optionalException = optionalCaptor.getValue();
assertNotNull(optionalException);
assertFalse(optionalException.isPresent());
@ -205,19 +222,18 @@ public class ThreadAsyncExecutorTest {
* ThreadAsyncExecutor#endProcess(AsyncResult)}
*/
@Test
public void testEndProcess() throws Exception {
void testEndProcess() throws Exception {
assertTimeout(ofMillis(5000), () -> {
// Instantiate a new executor and start a new 'null' task ...
final ThreadAsyncExecutor executor = new ThreadAsyncExecutor();
final var executor = new ThreadAsyncExecutor();
final Object result = new Object();
final Callable<Object> task = mock(Callable.class);
final var result = new Object();
when(task.call()).thenAnswer(i -> {
Thread.sleep(1500);
return result;
});
final AsyncResult<Object> asyncResult = executor.startProcess(task);
final var asyncResult = executor.startProcess(task);
assertNotNull(asyncResult);
assertFalse(asyncResult.isCompleted());
@ -243,11 +259,11 @@ public class ThreadAsyncExecutorTest {
* the callable is 'null'
*/
@Test
public void testNullTask() throws Exception {
void testNullTask() throws Exception {
assertTimeout(ofMillis(3000), () -> {
// Instantiate a new executor and start a new 'null' task ...
final ThreadAsyncExecutor executor = new ThreadAsyncExecutor();
final AsyncResult<Object> asyncResult = executor.startProcess(null);
final var executor = new ThreadAsyncExecutor();
final var asyncResult = executor.startProcess(null);
assertNotNull(asyncResult, "The AsyncResult should not be 'null', even though the task was 'null'.");
asyncResult.await(); // Prevent timing issues, and wait until the result is available
@ -270,26 +286,22 @@ public class ThreadAsyncExecutorTest {
* AsyncCallback)} when the callable is 'null', but the asynchronous callback is provided
*/
@Test
public void testNullTaskWithCallback() throws Exception {
void testNullTaskWithCallback() throws Exception {
assertTimeout(ofMillis(3000), () -> {
// Instantiate a new executor and start a new 'null' task ...
final ThreadAsyncExecutor executor = new ThreadAsyncExecutor();
final AsyncCallback<Object> callback = mock(AsyncCallback.class);
final AsyncResult<Object> asyncResult = executor.startProcess(null, callback);
final var executor = new ThreadAsyncExecutor();
final var asyncResult = executor.startProcess(null, callback);
assertNotNull(asyncResult, "The AsyncResult should not be 'null', even though the task was 'null'.");
asyncResult.await(); // Prevent timing issues, and wait until the result is available
assertTrue(asyncResult.isCompleted());
final ArgumentCaptor<Optional<Exception>> optionalCaptor =
ArgumentCaptor.forClass((Class) Optional.class);
verify(callback, times(1)).onComplete(Matchers.isNull(), optionalCaptor.capture());
final Optional<Exception> optionalException = optionalCaptor.getValue();
final var optionalException = optionalCaptor.getValue();
assertNotNull(optionalException);
assertTrue(optionalException.isPresent());
final Exception exception = optionalException.get();
final var exception = optionalException.get();
assertNotNull(exception);
assertEquals(NullPointerException.class, exception.getClass());
@ -310,11 +322,11 @@ public class ThreadAsyncExecutorTest {
* AsyncCallback)} when both the callable and the asynchronous callback are 'null'
*/
@Test
public void testNullTaskWithNullCallback() throws Exception {
void testNullTaskWithNullCallback() throws Exception {
assertTimeout(ofMillis(3000), () -> {
// Instantiate a new executor and start a new 'null' task ...
final ThreadAsyncExecutor executor = new ThreadAsyncExecutor();
final AsyncResult<Object> asyncResult = executor.startProcess(null, null);
final var executor = new ThreadAsyncExecutor();
final var asyncResult = executor.startProcess(null, null);
assertNotNull(
asyncResult,