/*
* Copyright (C) 2006-2016 DLR, Germany
*
* All rights reserved
*
* http://www.rcenvironment.de/
*/
package de.rcenvironment.core.component.execution.internal;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import org.easymock.Capture;
import org.easymock.EasyMock;
import org.easymock.IAnswer;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.osgi.framework.BundleContext;
import de.rcenvironment.core.communication.api.CommunicationService;
import de.rcenvironment.core.communication.api.PlatformService;
import de.rcenvironment.core.communication.common.InstanceNodeSessionId;
import de.rcenvironment.core.communication.common.LogicalNodeId;
import de.rcenvironment.core.communication.common.NodeIdentifierTestUtils;
import de.rcenvironment.core.component.execution.api.ComponentExecutionController;
import de.rcenvironment.core.component.execution.api.EndpointDatumSerializer;
import de.rcenvironment.core.component.execution.api.ExecutionControllerException;
import de.rcenvironment.core.component.execution.api.LocalExecutionControllerUtilsService;
import de.rcenvironment.core.component.execution.api.RemotableComponentExecutionControllerService;
import de.rcenvironment.core.component.execution.api.RemotableEndpointDatumDispatcher;
import de.rcenvironment.core.component.model.endpoint.api.EndpointDatum;
import de.rcenvironment.core.component.testutils.EndpointDatumDefaultStub;
import de.rcenvironment.core.datamodel.api.DataType;
import de.rcenvironment.core.datamodel.api.TypedDatum;
import de.rcenvironment.core.utils.common.rpc.RemoteOperationException;
/**
* Test cases for {@link EndpointDatumDispatcherImpl}.
*
* @author Doreen Seider
* @author Robert Mischke (8.0.0 id adaptations)
*/
public class EndpointDatumDispatcherImplTest {
private static final String LOCAL_INP_EXE_ID_1 = "local-inp-exe-id-1";
private static final String LOCAL_INP_EXE_ID_2 = "local-inp-exe-id-2";
private static final String LOCAL_INP_EXE_ID_3 = "local-inp-exe-id-3";
private static final String REMOTE_INP_EXE_ID_1 = "remote-inp-exe-id-1";
private static final String REMOTE_INP_EXE_ID_2 = "remote-inp-exe-id-2";
private static final int TEST_TIMEOUT = 2000;
private final BundleContext bundleContextMock = EasyMock.createStrictMock(BundleContext.class);
private final RemoteOperationException remoteOperationException = new RemoteOperationException("ROE");
private final LogicalNodeId localNodeId = NodeIdentifierTestUtils.createTestInstanceNodeSessionIdWithDisplayName("local-target-node")
.convertToDefaultLogicalNodeId();
private final LogicalNodeId remoteCompNodeId = NodeIdentifierTestUtils
.createTestInstanceNodeSessionIdWithDisplayName("remote-target-node").convertToDefaultLogicalNodeId();
private final LogicalNodeId remoteWfCtrlNodeId = NodeIdentifierTestUtils.createTestInstanceNodeSessionIdWithDisplayName("wf-ctrl-node")
.convertToDefaultLogicalNodeId();
private final LogicalNodeId reachableCompNodeId = NodeIdentifierTestUtils
.createTestInstanceNodeSessionIdWithDisplayName("reachable-comp-node").convertToDefaultLogicalNodeId();
private final LogicalNodeId unreachableCompNodeId = NodeIdentifierTestUtils
.createTestInstanceNodeSessionIdWithDisplayName("unreachable-comp-node").convertToDefaultLogicalNodeId();
/**
* Set up before any of the test cases run.
*/
@BeforeClass
public static void setUp() {
ComponentExecutionUtils.waitUntilRetryMsec = 1;
}
/**
* Set up after all of the test cases run.
*/
@AfterClass
public static void tearDown() {
ComponentExecutionUtils.waitUntilRetryMsec = ComponentExecutionUtils.WAIT_UNIL_RETRY_MSEC;
}
/**
* Tests if decision is made correctly, whether {@link EndpointDatum}s are processed locally or forwarded to an
* {@link RemotableEndpointDatumDispatcher} of another node.
*
* @throws InterruptedException on unexpected error
* @throws RemoteOperationException on unexpected error
* @throws ExecutionControllerException on unexpected error
*/
@Test(timeout = TEST_TIMEOUT)
public void testDispatchEndpointDatum() throws InterruptedException, RemoteOperationException, ExecutionControllerException {
final String serializedEndpointDatumToProcess1 = "serial-ED-to-process-1";
final String serializedEndpointDatumToProcess2 = "serial-ED-to-process-2";
final String serializedEndpointDatumToProcess3 = "serial-ED-to-process-3";
final String serializedEndpointDatumToForward1 = "serial-ED-to-forward-1";
final String serializedEndpointDatumToForward2 = "serial-ED-to-forward-2";
final String serializedEndpointDatumToForwardFailing1 = "serial-ED-to-forward-failing-1";
final String serializedEndpointDatumToForwardFailing2 = "serial-ED-to-forward-failing-2";
final String serializedEndpointDatumToForwardFailing3 = "serial-ED-to-forward-failing-3";
final String serializedEndpointDatumToForwardFailing4 = "serial-ED-to-forward-failing-4";
EndpointDatum endpointDatumToProcessMock1 = EndpointDatumMockFactory.createEndpointDatumMock(
LOCAL_INP_EXE_ID_1, localNodeId, LOCAL_INP_EXE_ID_1, localNodeId);
EndpointDatum endpointDatumToProcessMock2 = EndpointDatumMockFactory.createEndpointDatumMock(
LOCAL_INP_EXE_ID_2, localNodeId, LOCAL_INP_EXE_ID_3, localNodeId);
EndpointDatum endpointDatumToProcessMock3 = EndpointDatumMockFactory.createEndpointDatumMock(
LOCAL_INP_EXE_ID_2, localNodeId, LOCAL_INP_EXE_ID_1, localNodeId);
EndpointDatum endpointDatumToForwardMock1 = EndpointDatumMockFactory.createEndpointDatumMock(
REMOTE_INP_EXE_ID_1, remoteCompNodeId, LOCAL_INP_EXE_ID_2, localNodeId);
EndpointDatum endpointDatumToForwardMock2 = EndpointDatumMockFactory.createEndpointDatumMock(
REMOTE_INP_EXE_ID_2, remoteCompNodeId, LOCAL_INP_EXE_ID_3, localNodeId);
EndpointDatum endpointDatumToForwardFailingMock1 = EndpointDatumMockFactory.createEndpointDatumMock(
REMOTE_INP_EXE_ID_1, remoteCompNodeId, LOCAL_INP_EXE_ID_2, localNodeId);
EndpointDatum endpointDatumToForwardFailingMock2 = EndpointDatumMockFactory.createEndpointDatumMock(
REMOTE_INP_EXE_ID_1, remoteCompNodeId, REMOTE_INP_EXE_ID_2, remoteCompNodeId);
EndpointDatum endpointDatumToForwardFailingMock3 = EndpointDatumMockFactory.createEndpointDatumMock(
REMOTE_INP_EXE_ID_1, remoteCompNodeId, LOCAL_INP_EXE_ID_2, localNodeId);
EndpointDatum endpointDatumToForwardFailingMock4 = EndpointDatumMockFactory.createEndpointDatumMock(
REMOTE_INP_EXE_ID_1, remoteCompNodeId, REMOTE_INP_EXE_ID_2, remoteCompNodeId);
EndpointDatumSerializer endpointDatumSerializerMock = EasyMock.createNiceMock(EndpointDatumSerializer.class);
EasyMock.expect(endpointDatumSerializerMock.serializeEndpointDatum(endpointDatumToProcessMock1))
.andReturn(serializedEndpointDatumToProcess1).anyTimes();
EasyMock.expect(endpointDatumSerializerMock.deserializeEndpointDatum(serializedEndpointDatumToProcess1))
.andReturn(endpointDatumToProcessMock1).anyTimes();
EasyMock.expect(endpointDatumSerializerMock.serializeEndpointDatum(endpointDatumToProcessMock2))
.andReturn(serializedEndpointDatumToProcess2).anyTimes();
EasyMock.expect(endpointDatumSerializerMock.deserializeEndpointDatum(serializedEndpointDatumToProcess2))
.andReturn(endpointDatumToProcessMock2).anyTimes();
EasyMock.expect(endpointDatumSerializerMock.serializeEndpointDatum(endpointDatumToProcessMock3))
.andReturn(serializedEndpointDatumToProcess3).anyTimes();
EasyMock.expect(endpointDatumSerializerMock.deserializeEndpointDatum(serializedEndpointDatumToProcess3))
.andReturn(endpointDatumToProcessMock3).anyTimes();
EasyMock.expect(endpointDatumSerializerMock.serializeEndpointDatum(endpointDatumToForwardMock1))
.andReturn(serializedEndpointDatumToForward1).anyTimes();
EasyMock.expect(endpointDatumSerializerMock.deserializeEndpointDatum(serializedEndpointDatumToForward1))
.andReturn(endpointDatumToForwardMock1).anyTimes();
EasyMock.expect(endpointDatumSerializerMock.serializeEndpointDatum(endpointDatumToForwardMock2))
.andReturn(serializedEndpointDatumToForward2).anyTimes();
EasyMock.expect(endpointDatumSerializerMock.deserializeEndpointDatum(serializedEndpointDatumToForward2))
.andReturn(endpointDatumToForwardMock2).anyTimes();
EasyMock.expect(endpointDatumSerializerMock.serializeEndpointDatum(endpointDatumToForwardFailingMock1))
.andReturn(serializedEndpointDatumToForwardFailing1).anyTimes();
EasyMock.expect(endpointDatumSerializerMock.deserializeEndpointDatum(serializedEndpointDatumToForwardFailing1))
.andReturn(endpointDatumToForwardFailingMock1).anyTimes();
EasyMock.expect(endpointDatumSerializerMock.serializeEndpointDatum(endpointDatumToForwardFailingMock2))
.andReturn(serializedEndpointDatumToForwardFailing2).anyTimes();
EasyMock.expect(endpointDatumSerializerMock.deserializeEndpointDatum(serializedEndpointDatumToForwardFailing2))
.andReturn(endpointDatumToForwardFailingMock2).anyTimes();
EasyMock.expect(endpointDatumSerializerMock.serializeEndpointDatum(endpointDatumToForwardFailingMock3))
.andReturn(serializedEndpointDatumToForwardFailing3).anyTimes();
EasyMock.expect(endpointDatumSerializerMock.deserializeEndpointDatum(serializedEndpointDatumToForwardFailing3))
.andReturn(endpointDatumToForwardFailingMock3).anyTimes();
EasyMock.expect(endpointDatumSerializerMock.serializeEndpointDatum(endpointDatumToForwardFailingMock4))
.andReturn(serializedEndpointDatumToForwardFailing4).anyTimes();
EasyMock.expect(endpointDatumSerializerMock.deserializeEndpointDatum(serializedEndpointDatumToForwardFailing4))
.andReturn(endpointDatumToForwardFailingMock4).anyTimes();
EasyMock.replay(endpointDatumSerializerMock);
ComponentExecutionController componentExecutionControllerMock = EasyMock.createStrictMock(ComponentExecutionController.class);
componentExecutionControllerMock.onEndpointDatumReceived(endpointDatumToProcessMock1);
componentExecutionControllerMock.onSendingEndointDatumFailed(endpointDatumToForwardFailingMock3, remoteOperationException);
componentExecutionControllerMock.onEndpointDatumReceived(endpointDatumToProcessMock2);
componentExecutionControllerMock.onEndpointDatumReceived(endpointDatumToProcessMock1);
Capture<EndpointDatum> finalEndpointDatumSentCapture = new Capture<>();
componentExecutionControllerMock.onEndpointDatumReceived(EasyMock.capture(finalEndpointDatumSentCapture));
EasyMock.replay(componentExecutionControllerMock);
RemotableComponentExecutionControllerService remotableCompExeCtrlServiceMock =
createRemotableExecutionControllerService(serializedEndpointDatumToForwardFailing4);
// code disabled as long as retrying is disabled
RemotableEndpointDatumDispatcher endpointDatumDispatcherMock = EasyMock.createStrictMock(RemotableEndpointDatumDispatcher.class);
endpointDatumDispatcherMock.dispatchEndpointDatum(serializedEndpointDatumToForward1);
// for (int i = 0; i < 5; i++) {
endpointDatumDispatcherMock.dispatchEndpointDatum(serializedEndpointDatumToForwardFailing3);
EasyMock.expectLastCall().andThrow(remoteOperationException);
// }
endpointDatumDispatcherMock.dispatchEndpointDatum(serializedEndpointDatumToForward2);
// endpointDatumDispatcherMock.dispatchEndpointDatum(serializedEndpointDatumToForwardFailing1);
// EasyMock.expectLastCall().andThrow(remoteOperationException);
// endpointDatumDispatcherMock.dispatchEndpointDatum(serializedEndpointDatumToForwardFailing1);
// for (int i = 0; i < 5; i++) {
endpointDatumDispatcherMock.dispatchEndpointDatum(serializedEndpointDatumToForwardFailing4);
EasyMock.expectLastCall().andThrow(remoteOperationException);
// }
// endpointDatumDispatcherMock.dispatchEndpointDatum(serializedEndpointDatumToForward2);
// endpointDatumDispatcherMock.dispatchEndpointDatum(serializedEndpointDatumToForwardFailing2);
// EasyMock.expectLastCall().andThrow(remoteOperationException);
// endpointDatumDispatcherMock.dispatchEndpointDatum(serializedEndpointDatumToForwardFailing2);
EasyMock.replay(endpointDatumDispatcherMock);
EndpointDatumDispatcherImpl endpointDatumDispatcher = new EndpointDatumDispatcherImpl();
endpointDatumDispatcher.activate(bundleContextMock);
endpointDatumDispatcher.bindEndpointDatumSerializer(endpointDatumSerializerMock);
endpointDatumDispatcher.bindPlatformService(createPlatformServiceMock());
endpointDatumDispatcher.bindCommunicationService(
createCommunicationServiceMock(remotableCompExeCtrlServiceMock, endpointDatumDispatcherMock));
endpointDatumDispatcher.bindLocalExecutionControllerUtilsService(
createLocalExecutionControllerUtilsServiceMock(componentExecutionControllerMock));
endpointDatumDispatcher.dispatchEndpointDatum(serializedEndpointDatumToProcess1);
endpointDatumDispatcher.dispatchEndpointDatum(serializedEndpointDatumToForward1);
endpointDatumDispatcher.dispatchEndpointDatum(serializedEndpointDatumToForwardFailing3);
endpointDatumDispatcher.dispatchEndpointDatum(serializedEndpointDatumToForward2);
endpointDatumDispatcher.dispatchEndpointDatum(serializedEndpointDatumToProcess2);
// endpointDatumDispatcher.dispatchEndpointDatum(serializedEndpointDatumToForwardFailing1);
endpointDatumDispatcher.dispatchEndpointDatum(serializedEndpointDatumToForwardFailing4);
endpointDatumDispatcher.dispatchEndpointDatum(serializedEndpointDatumToProcess1);
endpointDatumDispatcher.dispatchEndpointDatum(serializedEndpointDatumToProcess3);
endpointDatumDispatcher.dispatchEndpointDatum(serializedEndpointDatumToForward2);
// endpointDatumDispatcher.dispatchEndpointDatum(serializedEndpointDatumToForwardFailing2);
final int sleepInterval = 50;
while (!finalEndpointDatumSentCapture.hasCaptured()) {
Thread.sleep(sleepInterval);
}
finalEndpointDatumSentCapture.getValue().equals(endpointDatumToProcessMock3);
EasyMock.verify(componentExecutionControllerMock);
EasyMock.verify(endpointDatumDispatcherMock);
EasyMock.verify(remotableCompExeCtrlServiceMock);
}
/**
* Tests if the retrying forwarding is able to succeed again.
*
* @throws InterruptedException on expected errors
*/
@Test(timeout = TEST_TIMEOUT)
public void testRetriesInCaseForwardingFailedAndSucceeded() throws InterruptedException {
final InstanceNodeSessionId inputNodeId = NodeIdentifierTestUtils.createTestInstanceNodeSessionIdWithDisplayName("input-node-id");
final LogicalNodeId inputNodeLogicalNodeId = inputNodeId.convertToDefaultLogicalNodeId();
final CountDownLatch forwardCalledLatch = new CountDownLatch(1);
final EndpointDatumDispatcherImpl dispatcher = new EndpointDatumDispatcherImpl() {
@Override
protected void forwardEndpointDatum(LogicalNodeId node, EndpointDatum endpointDatum) {
if (node.equals(inputNodeLogicalNodeId) && endpointDatum.equals(endpointDatum)) {
forwardCalledLatch.countDown();
} else {
fail("forwardEndpointDatum() called with unexpected endpoint datum");
}
}
@Override
protected void processEndpointDatum(String executionId, EndpointDatum endpointDatum) {
fail("unexpected call of processEndpointDatum()");
}
@Override
protected void callbackComponentExecutionController(EndpointDatum endpointDatum, RemoteOperationException e) {
fail("unexpected call of callbackComponentExecutionController()");
}
};
CommunicationService communicationServiceMock = EasyMock.createStrictMock(CommunicationService.class);
Set<LogicalNodeId> nodeIds = new HashSet<>();
nodeIds.add(inputNodeLogicalNodeId);
EasyMock.expect(communicationServiceMock.getReachableLogicalNodes()).andReturn(nodeIds).anyTimes();
EasyMock.replay(communicationServiceMock);
testRetriesInCaseForwardingFailed(communicationServiceMock, dispatcher, inputNodeLogicalNodeId, forwardCalledLatch);
}
/**
* Tests if the retrying forwarding doesn't end up in endless loop on continuous failures.
*
* @throws InterruptedException on expected errors
*/
@Test(timeout = TEST_TIMEOUT)
public void testRetriesInCaseForwardingFailed() throws InterruptedException {
final InstanceNodeSessionId inputNodeId = NodeIdentifierTestUtils.createTestInstanceNodeSessionIdWithDisplayName("input-node-id");
final LogicalNodeId inputNodeLogicalNodeId = inputNodeId.convertToDefaultLogicalNodeId();
final CountDownLatch callbackCalledLatch = new CountDownLatch(1);
final EndpointDatumDispatcherImpl dispatcher = new EndpointDatumDispatcherImpl() {
@Override
protected void forwardEndpointDatum(LogicalNodeId node, EndpointDatum endpointDatum) {
fail("unexpected call of forwardEndpointDatum()");
}
@Override
protected void processEndpointDatum(String executionId, EndpointDatum endpointDatum) {
fail("unexpected call of processEndpointDatum()");
}
@Override
protected void callbackComponentExecutionController(EndpointDatum endpointDatum, RemoteOperationException e) {
if (endpointDatum.equals(endpointDatum)) {
callbackCalledLatch.countDown();
} else {
fail("callbackComponentExecutionController() called with unexpected endpoint datum");
}
}
};
CommunicationService communicationServiceMock = EasyMock.createNiceMock(CommunicationService.class);
EasyMock.expect(communicationServiceMock.getReachableLogicalNodes()).andReturn(new HashSet<LogicalNodeId>()).anyTimes();
EasyMock.replay(communicationServiceMock);
testRetriesInCaseForwardingFailed(communicationServiceMock, dispatcher, inputNodeLogicalNodeId, callbackCalledLatch);
}
private void testRetriesInCaseForwardingFailed(CommunicationService communicationServiceMock,
EndpointDatumDispatcherImpl dispatcher, LogicalNodeId inputNodeLogicalNodeId, CountDownLatch methodCalledLatch)
throws InterruptedException {
final InstanceNodeSessionId wfCtrlNodeInstanceSessionId =
NodeIdentifierTestUtils.createTestInstanceNodeSessionIdWithDisplayName("wf-ctrl-node-id");
final LogicalNodeId wfCtrlNodeLogicalNodeId = wfCtrlNodeInstanceSessionId.convertToDefaultLogicalNodeId();
final EndpointDatum endpointDatumMock = EasyMock.createNiceMock(EndpointDatum.class);
EasyMock.expect(endpointDatumMock.getInputsComponentExecutionIdentifier()).andReturn("comp-exe-id").anyTimes();
EasyMock.expect(endpointDatumMock.getInputsNodeId()).andReturn(inputNodeLogicalNodeId).anyTimes();
EasyMock.expect(endpointDatumMock.getWorkflowNodeId()).andReturn(wfCtrlNodeLogicalNodeId).anyTimes();
EasyMock.replay(endpointDatumMock);
PlatformService platformServiceMock = EasyMock.createStrictMock(PlatformService.class);
EasyMock.expect(platformServiceMock.matchesLocalInstance(inputNodeLogicalNodeId)).andReturn(false);
EasyMock.expect(platformServiceMock.matchesLocalInstance(wfCtrlNodeLogicalNodeId)).andReturn(true);
EasyMock.replay(platformServiceMock);
dispatcher.bindCommunicationService(communicationServiceMock);
dispatcher.bindPlatformService(platformServiceMock);
dispatcher.dispatchEndpointDatum(endpointDatumMock);
methodCalledLatch.await();
}
private CommunicationService createCommunicationServiceMock(
RemotableComponentExecutionControllerService remotableCompExeCtrlServiceMock,
RemotableEndpointDatumDispatcher endpointDatumDispatcherMock) throws RemoteOperationException {
CommunicationService communicationServiceMock = EasyMock.createNiceMock(CommunicationService.class);
EasyMock.expect(communicationServiceMock.getRemotableService(RemotableEndpointDatumDispatcher.class, remoteCompNodeId))
.andReturn(endpointDatumDispatcherMock).anyTimes();
EasyMock.expect(communicationServiceMock.getRemotableService(RemotableComponentExecutionControllerService.class, remoteCompNodeId))
.andReturn(remotableCompExeCtrlServiceMock).anyTimes();
Set<LogicalNodeId> nodeIds = new HashSet<>();
nodeIds.add(remoteCompNodeId);
EasyMock.expect(communicationServiceMock.getReachableLogicalNodes()).andReturn(nodeIds).anyTimes();
EasyMock.replay(communicationServiceMock);
return communicationServiceMock;
}
private PlatformService createPlatformServiceMock() {
PlatformService platformServiceMock = EasyMock.createNiceMock(PlatformService.class);
EasyMock.expect(platformServiceMock.matchesLocalInstance(localNodeId)).andReturn(true).anyTimes();
EasyMock.replay(platformServiceMock);
return platformServiceMock;
}
private RemotableComponentExecutionControllerService createRemotableExecutionControllerService(
String serializedEndpointDatumToForwardFailingMock) throws ExecutionControllerException, RemoteOperationException {
RemotableComponentExecutionControllerService remotableCompExeCtrlServiceMock = EasyMock.createStrictMock(
RemotableComponentExecutionControllerService.class);
remotableCompExeCtrlServiceMock.onSendingEndointDatumFailed(REMOTE_INP_EXE_ID_2,
serializedEndpointDatumToForwardFailingMock, remoteOperationException);
EasyMock.replay(remotableCompExeCtrlServiceMock);
return remotableCompExeCtrlServiceMock;
}
private LocalExecutionControllerUtilsService createLocalExecutionControllerUtilsServiceMock(
ComponentExecutionController componentExecutionControllerMock) throws ExecutionControllerException {
LocalExecutionControllerUtilsService exeCtrlUtilsServiceMock = EasyMock.createNiceMock(LocalExecutionControllerUtilsService.class);
EasyMock.expect(exeCtrlUtilsServiceMock.getExecutionController(ComponentExecutionController.class, LOCAL_INP_EXE_ID_1,
bundleContextMock)).andReturn(componentExecutionControllerMock).anyTimes();
EasyMock.expect(exeCtrlUtilsServiceMock.getExecutionController(ComponentExecutionController.class, LOCAL_INP_EXE_ID_2,
bundleContextMock)).andReturn(componentExecutionControllerMock).anyTimes();
EasyMock.expect(exeCtrlUtilsServiceMock.getExecutionController(ComponentExecutionController.class, LOCAL_INP_EXE_ID_3,
bundleContextMock)).andThrow(new IllegalStateException()).anyTimes();
EasyMock.replay(exeCtrlUtilsServiceMock);
return exeCtrlUtilsServiceMock;
}
/**
* Tests if passed {@link EndpointDatum}s are sent in correct order to {@link EndpointDatumProcessor} of the right node.
*
* @throws InterruptedException if waiting for endpoint datum sent failed
* @throws RemoteOperationException on unexpected test failures
*/
@Test(timeout = TEST_TIMEOUT)
public void testDispatchEndpointDatumViaWorkflowController() throws InterruptedException, RemoteOperationException {
Capture<String> captSerialEpDtsOnCompNode1 = new Capture<>();
Capture<String> captSerialEpDtsOnCompNode2 = new Capture<>();
Capture<String> captSerialEpDtsOnCompNode3 = new Capture<>();
Capture<String> captSerialEpDtsOnCompNode4 = new Capture<>();
RemotableEndpointDatumDispatcher compDispatcherMock = EasyMock.createStrictMock(RemotableEndpointDatumDispatcher.class);
compDispatcherMock.dispatchEndpointDatum(EasyMock.capture(captSerialEpDtsOnCompNode1));
compDispatcherMock.dispatchEndpointDatum(EasyMock.capture(captSerialEpDtsOnCompNode2));
compDispatcherMock.dispatchEndpointDatum(EasyMock.capture(captSerialEpDtsOnCompNode3));
compDispatcherMock.dispatchEndpointDatum(EasyMock.capture(captSerialEpDtsOnCompNode4));
EasyMock.replay(compDispatcherMock);
Capture<String> captSerialEpDtsOnWfCtrl1 = new Capture<>();
Capture<String> captSerialEpDtsOnWfCtrl2 = new Capture<>();
Capture<String> captSerialEpDtsOnWfCtrl3 = new Capture<>();
RemotableEndpointDatumDispatcher wfCtrlDispatcherMock = EasyMock.createStrictMock(RemotableEndpointDatumDispatcher.class);
wfCtrlDispatcherMock.dispatchEndpointDatum(EasyMock.capture(captSerialEpDtsOnWfCtrl1));
wfCtrlDispatcherMock.dispatchEndpointDatum(EasyMock.capture(captSerialEpDtsOnWfCtrl2));
wfCtrlDispatcherMock.dispatchEndpointDatum(EasyMock.capture(captSerialEpDtsOnWfCtrl3));
EasyMock.replay(wfCtrlDispatcherMock);
CommunicationService communicationServiceMock = EasyMock.createNiceMock(CommunicationService.class);
EasyMock.expect(communicationServiceMock.getRemotableService(RemotableEndpointDatumDispatcher.class, reachableCompNodeId))
.andReturn(compDispatcherMock).anyTimes();
EasyMock.expect(communicationServiceMock.getRemotableService(RemotableEndpointDatumDispatcher.class, remoteWfCtrlNodeId))
.andReturn(wfCtrlDispatcherMock).anyTimes();
Set<LogicalNodeId> nodeIds = new HashSet<>();
nodeIds.add(reachableCompNodeId);
nodeIds.add(remoteWfCtrlNodeId);
EasyMock.expect(communicationServiceMock.getReachableLogicalNodes()).andReturn(nodeIds).anyTimes();
EasyMock.replay(communicationServiceMock);
EndpointDatumSerializer endpointDatumSerializerMock = EasyMock.createNiceMock(EndpointDatumSerializer.class);
EasyMock.expect(endpointDatumSerializerMock.serializeEndpointDatum(EasyMock.anyObject(EndpointDatum.class))).andAnswer(
new IAnswer<String>() {
@Override
public String answer() {
return ((EndpointDatum) EasyMock.getCurrentArguments()[0]).getInputsComponentExecutionIdentifier();
}
}
).anyTimes();
EasyMock.replay(endpointDatumSerializerMock);
EndpointDatumDispatcherImpl dispatcher = new EndpointDatumDispatcherImpl();
dispatcher.activate(bundleContextMock);
dispatcher.bindCommunicationService(communicationServiceMock);
dispatcher.bindEndpointDatumSerializer(endpointDatumSerializerMock);
dispatcher.bindPlatformService(createPlatformServiceMock());
EndpointDatum[] endpointDatums = new EndpointDatum[] {
new DirectlyTransferableEndpointDatum("direct-1"),
new DirectlyTransferableEndpointDatum("direct-2"),
new NotDirectlyTransferableEndpointDatum("indirect-1"),
new DirectlyTransferableEndpointDatum("direct-3"),
new NotDirectlyTransferableEndpointDatum("indirect-2"),
new NotDirectlyTransferableEndpointDatum("indirect-3"),
new DirectlyTransferableEndpointDatum("direct-4"),
};
for (EndpointDatum endpointDatum : endpointDatums) {
dispatcher.dispatchEndpointDatum(endpointDatum);
}
final int sleepInterval = 200;
while (!captSerialEpDtsOnCompNode4.hasCaptured() || !captSerialEpDtsOnWfCtrl3.hasCaptured()) {
Thread.sleep(sleepInterval);
}
assertEquals("direct-1", captSerialEpDtsOnCompNode1.getValue());
assertEquals("direct-2", captSerialEpDtsOnCompNode2.getValue());
assertEquals("direct-3", captSerialEpDtsOnCompNode3.getValue());
assertEquals("direct-4", captSerialEpDtsOnCompNode4.getValue());
assertEquals("indirect-1", captSerialEpDtsOnWfCtrl1.getValue());
assertEquals("indirect-2", captSerialEpDtsOnWfCtrl2.getValue());
assertEquals("indirect-3", captSerialEpDtsOnWfCtrl3.getValue());
}
/**
* {@link EndpointDatum} that can be directly sent to target component node.
*
* @author Doreen Seider
*
*/
private class DirectlyTransferableEndpointDatum extends UniqueEndpointDatum {
protected DirectlyTransferableEndpointDatum(String id) {
super(id);
}
@Override
public LogicalNodeId getInputsNodeId() {
return reachableCompNodeId;
}
}
/**
* {@link EndpointDatum} that cannot be directly sent to target component node and must be sent to workflow controller node instead.
*
* @author Doreen Seider
*
*/
private class NotDirectlyTransferableEndpointDatum extends UniqueEndpointDatum {
protected NotDirectlyTransferableEndpointDatum(String id) {
super(id);
}
@Override
public LogicalNodeId getInputsNodeId() {
return unreachableCompNodeId;
}
@Override
public LogicalNodeId getWorkflowNodeId() {
return remoteWfCtrlNodeId;
}
}
/**
* Implementation {@link EndpointDatum} for test purposes.
*
* @author Doreen Seider
*
*/
private class UniqueEndpointDatum extends EndpointDatumDefaultStub {
private final String id;
protected UniqueEndpointDatum(String id) {
this.id = id;
}
@Override
public String getInputsComponentExecutionIdentifier() {
return id;
}
@Override
public TypedDatum getValue() {
TypedDatum typedDatumMock = EasyMock.createStrictMock(TypedDatum.class);
EasyMock.expect(typedDatumMock.getDataType()).andReturn(DataType.Boolean).anyTimes();
EasyMock.replay(typedDatumMock);
return typedDatumMock;
}
}
}