/** * Copyright 2015 Otto (GmbH & Co KG) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.ottogroup.bi.spqr.pipeline; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Properties; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import org.junit.AfterClass; import org.junit.Assert; import org.junit.Test; import org.mockito.Mockito; import com.ottogroup.bi.spqr.exception.ComponentInitializationFailedException; import com.ottogroup.bi.spqr.exception.QueueInitializationFailedException; import com.ottogroup.bi.spqr.exception.RequiredInputMissingException; import com.ottogroup.bi.spqr.pipeline.component.MicroPipelineComponent; import com.ottogroup.bi.spqr.pipeline.component.MicroPipelineComponentConfiguration; import com.ottogroup.bi.spqr.pipeline.component.MicroPipelineComponentType; import com.ottogroup.bi.spqr.pipeline.component.operator.DelayedResponseOperator; import com.ottogroup.bi.spqr.pipeline.component.operator.DelayedResponseOperatorWaitStrategy; import com.ottogroup.bi.spqr.pipeline.component.operator.DirectResponseOperator; import com.ottogroup.bi.spqr.pipeline.component.operator.MessageCountResponseWaitStrategy; import com.ottogroup.bi.spqr.pipeline.exception.UnknownWaitStrategyException; import com.ottogroup.bi.spqr.pipeline.queue.StreamingMessageQueue; import com.ottogroup.bi.spqr.pipeline.queue.StreamingMessageQueueConfiguration; import com.ottogroup.bi.spqr.pipeline.queue.chronicle.DefaultStreamingMessageQueue; import com.ottogroup.bi.spqr.repository.ComponentRepository; import com.ottogroup.bi.spqr.repository.exception.ComponentInstantiationFailedException; import com.ottogroup.bi.spqr.repository.exception.UnknownComponentException; /** * Test case for {@link MicroPipelineFactory} * @author mnxfst * @since Mar 6, 2015 * TODO implement test for fully working micro pipeline configuration */ public class MicroPipelineFactoryTest { private final static ExecutorService executorService = Executors.newCachedThreadPool(); @AfterClass public static void shutdown() { if(executorService != null) executorService.shutdownNow(); } /** * Test case for {@link MicroPipelineFactory#instantiatePipeline(MicroPipelineConfiguration)} being provided * null as input to processing node id which must lead to a {@link RequiredInputMissingException} */ @Test public void testInstantiatePipeline_withNullProcessingNodeId() throws QueueInitializationFailedException, ComponentInitializationFailedException { try { new MicroPipelineFactory(null, Mockito.mock(ComponentRepository.class)).instantiatePipeline(new MicroPipelineConfiguration(), executorService); Assert.fail("Missing required input"); } catch(RequiredInputMissingException e) { // expected } } /** * Test case for {@link MicroPipelineFactory#instantiatePipeline(MicroPipelineConfiguration)} being provided * null as input which must lead to a {@link RequiredInputMissingException} */ @Test public void testInstantiatePipeline_withNullInput() throws QueueInitializationFailedException, ComponentInitializationFailedException { try { new MicroPipelineFactory("id", Mockito.mock(ComponentRepository.class)).instantiatePipeline(null, executorService); Assert.fail("Missing required input"); } catch(RequiredInputMissingException e) { // expected } } /** * Test case for {@link MicroPipelineFactory#instantiatePipeline(MicroPipelineConfiguration)} being provided * an empty configuration as input which must lead to a {@link RequiredInputMissingException} */ @Test public void testInstantiatePipeline_withEmptyInput() throws QueueInitializationFailedException, ComponentInitializationFailedException { try { new MicroPipelineFactory("id", Mockito.mock(ComponentRepository.class)).instantiatePipeline(new MicroPipelineConfiguration(), executorService); Assert.fail("Missing required input"); } catch(RequiredInputMissingException e) { // expected } } /** * Test case for {@link MicroPipelineFactory#instantiatePipeline(MicroPipelineConfiguration)} being provided * an empty identifier as input which must lead to a {@link RequiredInputMissingException} */ @Test public void testInstantiatePipeline_withEmptyId() throws QueueInitializationFailedException, ComponentInitializationFailedException { MicroPipelineComponentConfiguration componentCfg = Mockito.mock(MicroPipelineComponentConfiguration.class); StreamingMessageQueueConfiguration queueCfg = Mockito.mock(StreamingMessageQueueConfiguration.class); try { MicroPipelineConfiguration cfg = new MicroPipelineConfiguration(); cfg.setId(""); cfg.getComponents().add(componentCfg); cfg.getQueues().add(queueCfg); new MicroPipelineFactory("id", Mockito.mock(ComponentRepository.class)).instantiatePipeline(cfg, executorService); Assert.fail("Missing required input"); } catch(RequiredInputMissingException e) { // expected } } /** * Test case for {@link MicroPipelineFactory#instantiatePipeline(MicroPipelineConfiguration)} being provided * an empty component cfg list as input which must lead to a {@link RequiredInputMissingException} */ @Test public void testInstantiatePipeline_withEmptyComponentCfg() throws QueueInitializationFailedException, ComponentInitializationFailedException { StreamingMessageQueueConfiguration queueCfg = Mockito.mock(StreamingMessageQueueConfiguration.class); try { MicroPipelineConfiguration cfg = new MicroPipelineConfiguration(); cfg.setId("test"); cfg.getQueues().add(queueCfg); new MicroPipelineFactory("id", Mockito.mock(ComponentRepository.class)).instantiatePipeline(cfg, executorService); Assert.fail("Missing required input"); } catch(RequiredInputMissingException e) { // expected } } /** * Test case for {@link MicroPipelineFactory#instantiatePipeline(MicroPipelineConfiguration)} being provided * an empty queue cfg list as input which must lead to a {@link RequiredInputMissingException} */ @Test public void testInstantiatePipeline_withEmptyQueueCfg() throws QueueInitializationFailedException, ComponentInitializationFailedException { MicroPipelineComponentConfiguration componentCfg = Mockito.mock(MicroPipelineComponentConfiguration.class); try { MicroPipelineConfiguration cfg = new MicroPipelineConfiguration(); cfg.setId("test"); cfg.getComponents().add(componentCfg); new MicroPipelineFactory("id", Mockito.mock(ComponentRepository.class)).instantiatePipeline(cfg, executorService); Assert.fail("Missing required input"); } catch(RequiredInputMissingException e) { // expected } } /** * Test case for {@link MicroPipelineFactory#instantiatePipeline(MicroPipelineConfiguration)} being provided * a queue cfg list which holds two configurations referenced by the same id which must lead to a {@link QueueInitializationFailedException} */ @Test public void testInstantiatePipeline_withNonUniqueQueueId() throws RequiredInputMissingException, ComponentInitializationFailedException { MicroPipelineComponentConfiguration componentCfg = Mockito.mock(MicroPipelineComponentConfiguration.class); Properties queueProps = new Properties(); StreamingMessageQueueConfiguration validQueueCfg = new StreamingMessageQueueConfiguration(); validQueueCfg.setId("testInstantiatePipeline_withNonUniqueQueueId"); validQueueCfg.setProperties(queueProps); StreamingMessageQueueConfiguration invalidQueueCfg = new StreamingMessageQueueConfiguration(); invalidQueueCfg.setId("testInstantiatePipeline_withNonUniqueQueueId"); invalidQueueCfg.setProperties(queueProps); try { MicroPipelineConfiguration cfg = new MicroPipelineConfiguration(); cfg.setId("test"); cfg.getComponents().add(componentCfg); cfg.getQueues().add(validQueueCfg); cfg.getQueues().add(invalidQueueCfg); new MicroPipelineFactory("id", Mockito.mock(ComponentRepository.class)).instantiatePipeline(cfg, executorService); Assert.fail("Missing required input"); } catch(QueueInitializationFailedException e) { // expected } } /** * Test case for {@link MicroPipelineFactory#instantiatePipeline(MicroPipelineConfiguration)} being provided * a component cfg which references an unknown component which must lead to a {@link ComponentInitializationFailedException} */ @Test public void testInstantiatePipeline_withInvalidComponentConfiguration() throws RequiredInputMissingException, QueueInitializationFailedException, ComponentInstantiationFailedException, UnknownComponentException { StreamingMessageQueueConfiguration validQueueCfg = new StreamingMessageQueueConfiguration(); validQueueCfg.setId("queue-1"); MicroPipelineComponentConfiguration component1Cfg = new MicroPipelineComponentConfiguration(); component1Cfg.setId("test-id"); component1Cfg.setSettings(new Properties()); component1Cfg.setType(MicroPipelineComponentType.SOURCE); component1Cfg.setName("testInitializeComponent_source_withReferenceToUnknownQueue"); component1Cfg.setVersion("0.0.1"); component1Cfg.setToQueue("queue-1"); MicroPipelineComponentConfiguration component2Cfg = new MicroPipelineComponentConfiguration(); component2Cfg.setId("test-id-2"); component2Cfg.setSettings(new Properties()); component2Cfg.setType(MicroPipelineComponentType.SOURCE); component2Cfg.setName("testInitializeComponent_source_withReferenceToUnknownQueue-2"); component2Cfg.setVersion("0.0.1"); component2Cfg.setToQueue("queue-1"); MicroPipelineConfiguration pipelineCfg = new MicroPipelineConfiguration(); pipelineCfg.setId("test-id"); pipelineCfg.getQueues().add(validQueueCfg); pipelineCfg.getComponents().add(component2Cfg); pipelineCfg.getComponents().add(component1Cfg); MicroPipelineComponent mockComponent2 = Mockito.mock(MicroPipelineComponent.class); Mockito.when(mockComponent2.getId()).thenReturn("mock-component-2"); ComponentRepository repo = Mockito.mock(ComponentRepository.class); Mockito.when(repo.newInstance(component1Cfg.getId(), component1Cfg.getName(), component1Cfg.getVersion(), component1Cfg.getSettings())).thenThrow(new UnknownComponentException("Unknown component class")); Mockito.when(repo.newInstance(component2Cfg.getId(), component2Cfg.getName(), component2Cfg.getVersion(), component2Cfg.getSettings())).thenReturn(mockComponent2); try { new MicroPipelineFactory("id", repo).instantiatePipeline(pipelineCfg, executorService); Assert.fail("Missing required input"); } catch(ComponentInitializationFailedException e) { // expected } } /** * Test case for {@link MicroPipelineFactory#instantiatePipeline(MicroPipelineConfiguration)} being provided * a cfg which references the same component twice which must lead to a {@link ComponentInitializationFailedException} */ @Test public void testInstantiatePipeline_withComponentConfigurationTwice() throws RequiredInputMissingException, QueueInitializationFailedException, ComponentInstantiationFailedException, UnknownComponentException { StreamingMessageQueueConfiguration validQueueCfg = new StreamingMessageQueueConfiguration(); validQueueCfg.setId("queue-1"); MicroPipelineComponentConfiguration component1Cfg = new MicroPipelineComponentConfiguration(); component1Cfg.setId("test-id"); component1Cfg.setSettings(new Properties()); component1Cfg.setType(MicroPipelineComponentType.SOURCE); component1Cfg.setName("testInitializeComponent_source_withReferenceToUnknownQueue"); component1Cfg.setVersion("0.0.1"); component1Cfg.setToQueue("queue-1"); MicroPipelineConfiguration pipelineCfg = new MicroPipelineConfiguration(); pipelineCfg.setId("test-id"); pipelineCfg.getQueues().add(validQueueCfg); pipelineCfg.getComponents().add(component1Cfg); pipelineCfg.getComponents().add(component1Cfg); MicroPipelineComponent mockComponent1 = Mockito.mock(MicroPipelineComponent.class); Mockito.when(mockComponent1.getId()).thenReturn("mock-component-1"); Mockito.when(mockComponent1.getType()).thenReturn(MicroPipelineComponentType.SOURCE); ComponentRepository repo = Mockito.mock(ComponentRepository.class); Mockito.when(repo.newInstance(component1Cfg.getId(), component1Cfg.getName(), component1Cfg.getVersion(), component1Cfg.getSettings())).thenReturn(mockComponent1); try { new MicroPipelineFactory("id", repo).instantiatePipeline(pipelineCfg, executorService); Assert.fail("Missing required input"); } catch(ComponentInitializationFailedException e) { // expected } } /** * Test case for {@link MicroPipelineFactory#instantiatePipeline(MicroPipelineConfiguration)} being provided * a cfg which references a component with type null which must lead to a {@link ComponentInitializationFailedException} */ @Test public void testInstantiatePipeline_withComponentTypeNull() throws RequiredInputMissingException, QueueInitializationFailedException, ComponentInstantiationFailedException, UnknownComponentException { StreamingMessageQueueConfiguration validQueueCfg = new StreamingMessageQueueConfiguration(); validQueueCfg.setId("queue-1"); MicroPipelineComponentConfiguration component1Cfg = new MicroPipelineComponentConfiguration(); component1Cfg.setId("test-id"); component1Cfg.setSettings(new Properties()); component1Cfg.setType(MicroPipelineComponentType.SOURCE); component1Cfg.setName("testInitializeComponent_source_withReferenceToUnknownQueue"); component1Cfg.setVersion("0.0.1"); component1Cfg.setToQueue("queue-1"); MicroPipelineConfiguration pipelineCfg = new MicroPipelineConfiguration(); pipelineCfg.setId("test-id"); pipelineCfg.getQueues().add(validQueueCfg); pipelineCfg.getComponents().add(component1Cfg); MicroPipelineComponent mockComponent1 = Mockito.mock(MicroPipelineComponent.class); Mockito.when(mockComponent1.getId()).thenReturn("mock-component-1"); Mockito.when(mockComponent1.getType()).thenReturn(null); ComponentRepository repo = Mockito.mock(ComponentRepository.class); Mockito.when(repo.newInstance(component1Cfg.getId(), component1Cfg.getName(), component1Cfg.getVersion(), component1Cfg.getSettings())).thenReturn(mockComponent1); try { new MicroPipelineFactory("id", repo).instantiatePipeline(pipelineCfg, executorService); Assert.fail("Missing required input"); } catch(ComponentInitializationFailedException e) { // expected } } ////////////////////////////////////////////////////////////////////////////////////////////////////////// // @see MicroPipelineFactory#initializeQueue /** * Test case for {@link MicroPipelineFactory#initializeQueue(StreamingMessageQueueConfiguration)} being * provided null as input which must lead to a {@link RequiredInputMissingException} */ @Test public void testInitializeQueue_withNullInput() throws QueueInitializationFailedException { try { new MicroPipelineFactory("id", Mockito.mock(ComponentRepository.class)).initializeQueue(null); Assert.fail("Missing required input"); } catch(RequiredInputMissingException e) { // expected } } /** * Test case for {@link MicroPipelineFactory#initializeQueue(StreamingMessageQueueConfiguration)} being * provided an empty configuration as input which must lead to a {@link RequiredInputMissingException} */ @Test public void testInitializeQueue_withEmptyInput() throws QueueInitializationFailedException { try { new MicroPipelineFactory("id", Mockito.mock(ComponentRepository.class)).initializeQueue(new StreamingMessageQueueConfiguration()); Assert.fail("Missing required input"); } catch(RequiredInputMissingException e) { // expected } } /** * Test case for {@link MicroPipelineFactory#initializeQueue(StreamingMessageQueueConfiguration)} being * provided an empty queue identifier as input which must lead to a {@link RequiredInputMissingException} */ @Test public void testInitializeQueue_withEmptyQueueId() throws QueueInitializationFailedException { try { StreamingMessageQueueConfiguration cfg = new StreamingMessageQueueConfiguration(); cfg.setProperties(new Properties()); cfg.setId(""); new MicroPipelineFactory("id", Mockito.mock(ComponentRepository.class)).initializeQueue(cfg); Assert.fail("Missing required input"); } catch(RequiredInputMissingException e) { // expected } } /** * Test case for {@link MicroPipelineFactory#initializeQueue(StreamingMessageQueueConfiguration)} being * provided null as queue settings as input which must be processed without problems */ @Test public void testInitializeQueue_withNullQueueSettings() throws QueueInitializationFailedException, RequiredInputMissingException { StreamingMessageQueueConfiguration cfg = new StreamingMessageQueueConfiguration(); cfg.setProperties(null); cfg.setId("test-id"); new MicroPipelineFactory("id", Mockito.mock(ComponentRepository.class)).initializeQueue(cfg); } /** * Test case for {@link MicroPipelineFactory#initializeQueue(StreamingMessageQueueConfiguration)} being * provided valid input to receive {@link DefaultStreamingMessageQueue}. */ @Test public void testInitializeQueue_withValidSettingsForDefaultQueue() throws RequiredInputMissingException, QueueInitializationFailedException { Properties props = new Properties(); props.put(DefaultStreamingMessageQueue.CFG_CHRONICLE_QUEUE_DELETE_ON_EXIT, "true"); props.put(DefaultStreamingMessageQueue.CFG_CHRONICLE_QUEUE_PATH, System.getProperty("java.io.tmpdir")); StreamingMessageQueueConfiguration cfg = new StreamingMessageQueueConfiguration(); cfg.setProperties(props); cfg.setId("testInitializeQueue_withValidSettingsForDefaultQueue"); StreamingMessageQueue queue = new MicroPipelineFactory("id", Mockito.mock(ComponentRepository.class)).initializeQueue(cfg); Assert.assertNotNull("The queue instance must not be null");; Assert.assertEquals("The classes must be equal", DefaultStreamingMessageQueue.class, queue.getClass()); } ////////////////////////////////////////////////////////////////////////////////////////////////////////// // @see MicroPipelineFactory#initializeComponent /** * Test case for {@link MicroPipelineFactory#initializeComponent(MicroPipelineComponentConfiguration)} being provided * null as input which must lead to a {@link RequiredInputMissingException} * @throws ComponentInitializationFailedException */ @Test public void testInitializeComponent_withNullInput() throws ComponentInitializationFailedException { try { new MicroPipelineFactory("id", Mockito.mock(ComponentRepository.class)).initializeComponent(null, Collections.<String, StreamingMessageQueue>emptyMap()); Assert.fail("Missing required input"); } catch(RequiredInputMissingException e) { // expected } } /** * Test case for {@link MicroPipelineFactory#initializeComponent(MicroPipelineComponentConfiguration)} being provided * an empty input which must lead to a {@link RequiredInputMissingException} * @throws ComponentInitializationFailedException */ @Test public void testInitializeComponent_withEmptyInput() throws ComponentInitializationFailedException { try { new MicroPipelineFactory("id", Mockito.mock(ComponentRepository.class)).initializeComponent(new MicroPipelineComponentConfiguration(), Collections.<String, StreamingMessageQueue>emptyMap()); Assert.fail("Missing required input"); } catch(RequiredInputMissingException e) { // expected } } /** * Test case for {@link MicroPipelineFactory#initializeComponent(MicroPipelineComponentConfiguration)} being provided * an empty input to component type which must lead to a {@link RequiredInputMissingException} * @throws ComponentInitializationFailedException */ @Test public void testInitializeComponent_withEmptyComponentType() throws ComponentInitializationFailedException { try { MicroPipelineComponentConfiguration cfg = new MicroPipelineComponentConfiguration(); cfg.setId("test-id");; cfg.setSettings(new Properties()); cfg.setName(""); cfg.setVersion("0.0.1"); new MicroPipelineFactory("id", Mockito.mock(ComponentRepository.class)).initializeComponent(cfg, Collections.<String, StreamingMessageQueue>emptyMap()); Assert.fail("Missing required input"); } catch(RequiredInputMissingException e) { // expected } } /** * Test case for {@link MicroPipelineFactory#initializeComponent(MicroPipelineComponentConfiguration)} being provided * an empty input to component class which must lead to a {@link RequiredInputMissingException} * @throws ComponentInitializationFailedException */ @Test public void testInitializeComponent_withEmptyComponentClass() throws ComponentInitializationFailedException { try { MicroPipelineComponentConfiguration cfg = new MicroPipelineComponentConfiguration(); cfg.setId("test-id");; cfg.setSettings(new Properties()); cfg.setType(MicroPipelineComponentType.SOURCE); cfg.setName(""); cfg.setVersion("0.0.1"); new MicroPipelineFactory("id", Mockito.mock(ComponentRepository.class)).initializeComponent(cfg, Collections.<String, StreamingMessageQueue>emptyMap()); Assert.fail("Missing required input"); } catch(RequiredInputMissingException e) { // expected } } /** * Test case for {@link MicroPipelineFactory#initializeComponent(MicroPipelineComponentConfiguration)} being provided * an empty input to component version which must lead to a {@link RequiredInputMissingException} * @throws ComponentInitializationFailedException */ @Test public void testInitializeComponent_withEmptyComponentVersion() throws ComponentInitializationFailedException { try { MicroPipelineComponentConfiguration cfg = new MicroPipelineComponentConfiguration(); cfg.setId("test-id");; cfg.setSettings(new Properties()); cfg.setType(MicroPipelineComponentType.SOURCE); cfg.setName("test-class"); cfg.setVersion(""); new MicroPipelineFactory("id", Mockito.mock(ComponentRepository.class)).initializeComponent(cfg, Collections.<String, StreamingMessageQueue>emptyMap()); Assert.fail("Missing required input"); } catch(RequiredInputMissingException e) { // expected } } /** * Test case for {@link MicroPipelineFactory#initializeComponent(MicroPipelineComponentConfiguration)} being provided * an empty input to component settings which must lead to a {@link RequiredInputMissingException} * @throws ComponentInitializationFailedException */ @Test public void testInitializeComponent_withEmptyComponentSettings() throws ComponentInitializationFailedException { try { MicroPipelineComponentConfiguration cfg = new MicroPipelineComponentConfiguration(); cfg.setId("test-id");; cfg.setSettings(null); cfg.setType(MicroPipelineComponentType.SOURCE); cfg.setName("test-name"); cfg.setVersion("0.0.1"); new MicroPipelineFactory("id", Mockito.mock(ComponentRepository.class)).initializeComponent(cfg, Collections.<String, StreamingMessageQueue>emptyMap()); Assert.fail("Missing required input"); } catch(RequiredInputMissingException e) { // expected } } /** * Test case for {@link MicroPipelineFactory#initializeComponent(MicroPipelineComponentConfiguration)} being provided * an empty input to queues to write to which must lead to a {@link RequiredInputMissingException} * @throws ComponentInitializationFailedException */ @Test public void testInitializeComponent_source_withEmptyToQueuesSettings() throws ComponentInitializationFailedException { try { MicroPipelineComponentConfiguration cfg = new MicroPipelineComponentConfiguration(); cfg.setId("test-id"); cfg.setSettings(new Properties()); cfg.setType(MicroPipelineComponentType.SOURCE); cfg.setName("test name"); cfg.setVersion("0.0.1"); new MicroPipelineFactory("id", Mockito.mock(ComponentRepository.class)).initializeComponent(cfg, Collections.<String, StreamingMessageQueue>emptyMap()); Assert.fail("Missing required input"); } catch(RequiredInputMissingException e) { // expected } } /** * Test case for {@link MicroPipelineFactory#initializeComponent(MicroPipelineComponentConfiguration)} being provided * a reference towards a queue that does not exist which must lead to a {@link RequiredInputMissingException} * @throws ComponentInitializationFailedException */ @Test public void testInitializeComponent_source_withReferenceToUnknownQueue() throws ComponentInitializationFailedException { @SuppressWarnings("unchecked") Map<String, StreamingMessageQueue> queues = Mockito.mock(HashMap.class); Mockito.when(queues.containsKey("queue-1")).thenReturn(false); try { MicroPipelineComponentConfiguration cfg = new MicroPipelineComponentConfiguration(); cfg.setId("test-id"); cfg.setSettings(new Properties()); cfg.setType(MicroPipelineComponentType.SOURCE); cfg.setName("testInitializeComponent_source_withReferenceToUnknownQueue"); cfg.setVersion("0.0.1"); cfg.setToQueue("queue-1"); new MicroPipelineFactory("id", Mockito.mock(ComponentRepository.class)).initializeComponent(cfg, queues); Assert.fail("Missing required input"); } catch(RequiredInputMissingException e) { // expected } Mockito.verify(queues).containsKey("queue-1"); } /** * Test case for {@link MicroPipelineFactory#initializeComponent(MicroPipelineComponentConfiguration)} being provided * a valid configuration for a {@link MicroPipelineComponentType#SOURCE} component. When accessing the repository * it throws an exception which must lead to a {@link ComponentInitializationFailedException} * @throws ComponentInitializationFailedException */ @Test public void testInitializeComponent_source_withValidConfigurationButExceptionThrownByRepository() throws Exception { @SuppressWarnings("unchecked") Map<String, StreamingMessageQueue> queues = Mockito.mock(HashMap.class); Mockito.when(queues.containsKey("queue-1")).thenReturn(true); MicroPipelineComponentConfiguration cfg = new MicroPipelineComponentConfiguration(); cfg.setId("test-id"); cfg.setSettings(new Properties()); cfg.setType(MicroPipelineComponentType.SOURCE); cfg.setName("testInitializeComponent_source_withReferenceToUnknownQueue"); cfg.setVersion("0.0.1"); cfg.setToQueue("queue-1"); ComponentRepository repo = Mockito.mock(ComponentRepository.class); Mockito.when(repo.newInstance(cfg.getId(), cfg.getName(), cfg.getVersion(), cfg.getSettings())).thenThrow(new NullPointerException()); try { new MicroPipelineFactory("id", repo).initializeComponent(cfg, queues); Assert.fail("Repo access fails"); } catch(ComponentInitializationFailedException e) { // expected } Mockito.verify(queues).containsKey("queue-1"); } // DIRECT_RESPONSE_OPERATOR /** * Test case for {@link MicroPipelineFactory#initializeComponent(MicroPipelineComponentConfiguration)} being provided * an empty input to queues to write to which must lead to a {@link RequiredInputMissingException} * @throws ComponentInitializationFailedException */ @Test public void testInitializeComponent_direct_response_operator_withEmptyToQueuesSettings() throws ComponentInitializationFailedException { try { MicroPipelineComponentConfiguration cfg = new MicroPipelineComponentConfiguration(); cfg.setId("test-id"); cfg.setSettings(new Properties()); cfg.setType(MicroPipelineComponentType.DIRECT_RESPONSE_OPERATOR); cfg.setName("test name"); cfg.setVersion("0.0.1"); cfg.setToQueue(""); new MicroPipelineFactory("id", Mockito.mock(ComponentRepository.class)).initializeComponent(cfg, Collections.<String, StreamingMessageQueue>emptyMap()); Assert.fail("Missing required input"); } catch(RequiredInputMissingException e) { // expected } } /** * Test case for {@link MicroPipelineFactory#initializeComponent(MicroPipelineComponentConfiguration)} being provided * a reference towards a queue that does not exist which must lead to a {@link RequiredInputMissingException} * @throws ComponentInitializationFailedException */ @Test public void testInitializeComponent_direct_response_operator_withReferenceToUnknownToQueue() throws ComponentInitializationFailedException { @SuppressWarnings("unchecked") Map<String, StreamingMessageQueue> queues = Mockito.mock(HashMap.class); Mockito.when(queues.containsKey("unknown-queue")).thenReturn(false); Mockito.when(queues.containsKey("queue-1")).thenReturn(true); try { MicroPipelineComponentConfiguration cfg = new MicroPipelineComponentConfiguration(); cfg.setId("test-id"); cfg.setSettings(new Properties()); cfg.setType(MicroPipelineComponentType.DIRECT_RESPONSE_OPERATOR); cfg.setName("testInitializeComponent_source_withReferenceToUnknownQueue"); cfg.setVersion("0.0.1"); cfg.setToQueue("unknown-queue"); cfg.setFromQueue("queue-1"); new MicroPipelineFactory("id", Mockito.mock(ComponentRepository.class)).initializeComponent(cfg, queues); Assert.fail("Missing required input"); } catch(RequiredInputMissingException e) { // expected } Mockito.verify(queues).containsKey("unknown-queue"); Mockito.verify(queues, Mockito.never()).containsKey("queue-1"); } /** * Test case for {@link MicroPipelineFactory#initializeComponent(MicroPipelineComponentConfiguration)} being provided * an empty input from queues to write to which must lead to a {@link RequiredInputMissingException} * @throws ComponentInitializationFailedException */ @Test public void testInitializeComponent_direct_response_operator_withEmptyFromQueuesSettings() throws ComponentInitializationFailedException { @SuppressWarnings("unchecked") Map<String, StreamingMessageQueue> queues = Mockito.mock(HashMap.class); Mockito.when(queues.containsKey("unknown-queue")).thenReturn(false); Mockito.when(queues.containsKey("queue-1")).thenReturn(true); try { MicroPipelineComponentConfiguration cfg = new MicroPipelineComponentConfiguration(); cfg.setId("test-id"); cfg.setSettings(new Properties()); cfg.setType(MicroPipelineComponentType.DIRECT_RESPONSE_OPERATOR); cfg.setName("test name"); cfg.setVersion("0.0.1"); cfg.setToQueue("queue-1"); cfg.setFromQueue(""); new MicroPipelineFactory("id", Mockito.mock(ComponentRepository.class)).initializeComponent(cfg, queues); Assert.fail("Missing required input"); } catch(RequiredInputMissingException e) { // expected } Mockito.verify(queues).containsKey("queue-1"); Mockito.verify(queues, Mockito.never()).containsKey("unknown-queue"); } /** * Test case for {@link MicroPipelineFactory#initializeComponent(MicroPipelineComponentConfiguration)} being provided * an unknown input from queues to write to which must lead to a {@link RequiredInputMissingException} * @throws ComponentInitializationFailedException */ @Test public void testInitializeComponent_direct_response_operator_withUnknownFromQueuesSettings() throws ComponentInitializationFailedException { @SuppressWarnings("unchecked") Map<String, StreamingMessageQueue> queues = Mockito.mock(HashMap.class); Mockito.when(queues.containsKey("unknown-queue")).thenReturn(false); Mockito.when(queues.containsKey("queue-1")).thenReturn(true); try { MicroPipelineComponentConfiguration cfg = new MicroPipelineComponentConfiguration(); cfg.setId("test-id"); cfg.setSettings(new Properties()); cfg.setType(MicroPipelineComponentType.DIRECT_RESPONSE_OPERATOR); cfg.setName("test name"); cfg.setVersion("0.0.1"); cfg.setToQueue("queue-1"); cfg.setFromQueue("unknown-queue"); new MicroPipelineFactory("id", Mockito.mock(ComponentRepository.class)).initializeComponent(cfg, queues); Assert.fail("Missing required input"); } catch(RequiredInputMissingException e) { // expected } Mockito.verify(queues).containsKey("queue-1"); Mockito.verify(queues).containsKey("unknown-queue"); } /** * Test case for {@link MicroPipelineFactory#initializeComponent(MicroPipelineComponentConfiguration)} being provided * valid input */ @Test public void testInitializeComponent_direct_response_operator_withValidSettings() throws ComponentInitializationFailedException, RequiredInputMissingException, UnknownComponentException, ComponentInstantiationFailedException { DirectResponseOperator directResponseOperator = Mockito.mock(DirectResponseOperator.class); Mockito.when(directResponseOperator.getId()).thenReturn("test-id"); ComponentRepository repo = Mockito.mock(ComponentRepository.class); Mockito.when(repo.newInstance("test-id", "test name", "0.0.1", new Properties())).thenReturn(directResponseOperator); @SuppressWarnings("unchecked") Map<String, StreamingMessageQueue> queues = Mockito.mock(HashMap.class); Mockito.when(queues.containsKey("queue-1")).thenReturn(true); Mockito.when(queues.containsKey("queue-2")).thenReturn(true); MicroPipelineComponentConfiguration cfg = new MicroPipelineComponentConfiguration(); cfg.setId("test-id"); cfg.setSettings(new Properties()); cfg.setType(MicroPipelineComponentType.DIRECT_RESPONSE_OPERATOR); cfg.setName("test name"); cfg.setVersion("0.0.1"); cfg.setToQueue("queue-1"); cfg.setFromQueue("queue-2"); MicroPipelineComponent operator = new MicroPipelineFactory("id", repo).initializeComponent(cfg, queues); Assert.assertNotNull("The operator must not be null", operator);; Assert.assertEquals("Values must be equal", "test-id", operator.getId()); Mockito.verify(queues).containsKey("queue-1"); Mockito.verify(queues, Mockito.never()).containsKey("unknown-queue"); } // DELAYED_RESPONSE_OPERATOR /** * Test case for {@link MicroPipelineFactory#initializeComponent(MicroPipelineComponentConfiguration)} being provided * an empty input to queues to write to which must lead to a {@link RequiredInputMissingException} * @throws ComponentInitializationFailedException */ @Test public void testInitializeComponent_delayed_response_operator_withEmptyToQueuesSettings() throws ComponentInitializationFailedException { @SuppressWarnings("unchecked") Map<String, StreamingMessageQueue> queues = Mockito.mock(HashMap.class); Mockito.when(queues.containsKey("queue-1")).thenReturn(true); Mockito.when(queues.containsKey("queue-2")).thenReturn(true); try { MicroPipelineComponentConfiguration cfg = new MicroPipelineComponentConfiguration(); cfg.setId("test-id"); cfg.setSettings(new Properties()); cfg.setType(MicroPipelineComponentType.DELAYED_RESPONSE_OPERATOR); cfg.setName("test name"); cfg.setVersion("0.0.1"); cfg.setToQueue(""); cfg.setFromQueue("queue-2"); cfg.getSettings().put(DelayedResponseOperator.CFG_WAIT_STRATEGY_NAME, "test-strategy"); new MicroPipelineFactory("id", Mockito.mock(ComponentRepository.class)).initializeComponent(cfg, Collections.<String, StreamingMessageQueue>emptyMap()); Assert.fail("Missing required input"); } catch(RequiredInputMissingException e) { // expected } Mockito.verify(queues, Mockito.never()).containsKey("queue-1"); Mockito.verify(queues, Mockito.never()).containsKey("queue-2"); } /** * Test case for {@link MicroPipelineFactory#initializeComponent(MicroPipelineComponentConfiguration)} being provided * a reference towards a queue that does not exist which must lead to a {@link RequiredInputMissingException} * @throws ComponentInitializationFailedException */ @Test public void testInitializeComponent_delayed_response_operator_withReferenceToUnknownToQueue() throws ComponentInitializationFailedException { @SuppressWarnings("unchecked") Map<String, StreamingMessageQueue> queues = Mockito.mock(HashMap.class); Mockito.when(queues.containsKey("unknown-queue")).thenReturn(false); Mockito.when(queues.containsKey("queue-1")).thenReturn(true); try { MicroPipelineComponentConfiguration cfg = new MicroPipelineComponentConfiguration(); cfg.setId("test-id"); cfg.setSettings(new Properties()); cfg.setType(MicroPipelineComponentType.DELAYED_RESPONSE_OPERATOR); cfg.setName("testInitializeComponent_source_withReferenceToUnknownQueue"); cfg.setVersion("0.0.1"); cfg.setToQueue("unknown-queue"); cfg.setFromQueue("queue-1"); cfg.getSettings().put(DelayedResponseOperator.CFG_WAIT_STRATEGY_NAME, "test-strategy"); new MicroPipelineFactory("id", Mockito.mock(ComponentRepository.class)).initializeComponent(cfg, queues); Assert.fail("Missing required input"); } catch(RequiredInputMissingException e) { // expected } Mockito.verify(queues).containsKey("unknown-queue"); Mockito.verify(queues, Mockito.never()).containsKey("queue-1"); } /** * Test case for {@link MicroPipelineFactory#initializeComponent(MicroPipelineComponentConfiguration)} being provided * an empty input from queues to write to which must lead to a {@link RequiredInputMissingException} * @throws ComponentInitializationFailedException */ @Test public void testInitializeComponent_delayed_response_operator_withEmptyFromQueuesSettings() throws ComponentInitializationFailedException { @SuppressWarnings("unchecked") Map<String, StreamingMessageQueue> queues = Mockito.mock(HashMap.class); Mockito.when(queues.containsKey("unknown-queue")).thenReturn(false); Mockito.when(queues.containsKey("queue-1")).thenReturn(true); try { MicroPipelineComponentConfiguration cfg = new MicroPipelineComponentConfiguration(); cfg.setId("test-id"); cfg.setSettings(new Properties()); cfg.setType(MicroPipelineComponentType.DIRECT_RESPONSE_OPERATOR); cfg.setName("test name"); cfg.setVersion("0.0.1"); cfg.setToQueue("queue-1"); cfg.setFromQueue(""); cfg.getSettings().put(DelayedResponseOperator.CFG_WAIT_STRATEGY_NAME, "test-strategy"); new MicroPipelineFactory("id", Mockito.mock(ComponentRepository.class)).initializeComponent(cfg, queues); Assert.fail("Missing required input"); } catch(RequiredInputMissingException e) { // expected } Mockito.verify(queues).containsKey("queue-1"); Mockito.verify(queues, Mockito.never()).containsKey("unknown-queue"); } /** * Test case for {@link MicroPipelineFactory#initializeComponent(MicroPipelineComponentConfiguration)} being provided * an unknown input from queues to write to which must lead to a {@link RequiredInputMissingException} * @throws ComponentInitializationFailedException */ @Test public void testInitializeComponent_delayed_response_operator_withUnknownFromQueuesSettings() throws ComponentInitializationFailedException { @SuppressWarnings("unchecked") Map<String, StreamingMessageQueue> queues = Mockito.mock(HashMap.class); Mockito.when(queues.containsKey("unknown-queue")).thenReturn(false); Mockito.when(queues.containsKey("queue-1")).thenReturn(true); try { MicroPipelineComponentConfiguration cfg = new MicroPipelineComponentConfiguration(); cfg.setId("test-id"); cfg.setSettings(new Properties()); cfg.setType(MicroPipelineComponentType.DIRECT_RESPONSE_OPERATOR); cfg.setName("test name"); cfg.setVersion("0.0.1"); cfg.setToQueue("queue-1"); cfg.setFromQueue("unknown-queue"); cfg.getSettings().put(DelayedResponseOperator.CFG_WAIT_STRATEGY_NAME, "test-strategy"); new MicroPipelineFactory("id", Mockito.mock(ComponentRepository.class)).initializeComponent(cfg, queues); Assert.fail("Missing required input"); } catch(RequiredInputMissingException e) { // expected } Mockito.verify(queues).containsKey("queue-1"); Mockito.verify(queues).containsKey("unknown-queue"); } /** * Test case for {@link MicroPipelineFactory#initializeComponent(MicroPipelineComponentConfiguration)} being provided * an empty input to wait strategy settings which must lead to a {@link RequiredInputMissingException} * @throws ComponentInitializationFailedException */ @Test public void testInitializeComponent_direct_response_operator_withEmptyResponseWaitStrategy() throws ComponentInitializationFailedException { @SuppressWarnings("unchecked") Map<String, StreamingMessageQueue> queues = Mockito.mock(HashMap.class); Mockito.when(queues.containsKey("queue-2")).thenReturn(true); Mockito.when(queues.containsKey("queue-1")).thenReturn(true); try { MicroPipelineComponentConfiguration cfg = new MicroPipelineComponentConfiguration(); cfg.setId("test-id"); cfg.setSettings(new Properties()); cfg.setType(MicroPipelineComponentType.DELAYED_RESPONSE_OPERATOR); cfg.setName("test name"); cfg.setVersion("0.0.1"); cfg.setToQueue("queue-1"); cfg.setFromQueue("queue-2"); new MicroPipelineFactory("id", Mockito.mock(ComponentRepository.class)).initializeComponent(cfg, queues); Assert.fail("Missing required input"); } catch(RequiredInputMissingException e) { // expected } Mockito.verify(queues).containsKey("queue-1"); Mockito.verify(queues).containsKey("queue-2"); } // EMITTER /** * Test case for {@link MicroPipelineFactory#initializeComponent(MicroPipelineComponentConfiguration)} being provided * an empty input to queues to write to which must lead to a {@link RequiredInputMissingException} * @throws ComponentInitializationFailedException */ @Test public void testInitializeComponent_emitter_withEmptyFromQueuesSettings() throws ComponentInitializationFailedException { try { MicroPipelineComponentConfiguration cfg = new MicroPipelineComponentConfiguration(); cfg.setId("test-id"); cfg.setSettings(new Properties()); cfg.setType(MicroPipelineComponentType.EMITTER); cfg.setName("test name"); cfg.setVersion("0.0.1"); cfg.setFromQueue(""); new MicroPipelineFactory("id", Mockito.mock(ComponentRepository.class)).initializeComponent(cfg, Collections.<String, StreamingMessageQueue>emptyMap()); Assert.fail("Missing required input"); } catch(RequiredInputMissingException e) { // expected } } /** * Test case for {@link MicroPipelineFactory#initializeComponent(MicroPipelineComponentConfiguration)} being provided * a reference towards a queue that does not exist which must lead to a {@link RequiredInputMissingException} * @throws ComponentInitializationFailedException */ @Test public void testInitializeComponent_emitter_withReferenceToUnknownFromQueue() throws ComponentInitializationFailedException { @SuppressWarnings("unchecked") Map<String, StreamingMessageQueue> queues = Mockito.mock(HashMap.class); Mockito.when(queues.containsKey("queue-1")).thenReturn(false); try { MicroPipelineComponentConfiguration cfg = new MicroPipelineComponentConfiguration(); cfg.setId("test-id"); cfg.setSettings(new Properties()); cfg.setType(MicroPipelineComponentType.EMITTER); cfg.setName("testInitializeComponent_source_withReferenceToUnknownQueue"); cfg.setVersion("0.0.1"); cfg.setFromQueue("queue-1"); new MicroPipelineFactory("id", Mockito.mock(ComponentRepository.class)).initializeComponent(cfg, queues); Assert.fail("Missing required input"); } catch(RequiredInputMissingException e) { // expected } Mockito.verify(queues).containsKey("queue-1"); } ////////////////////////////////////////////////////////////////////////////////////////////////////////// // @see MicroPipelineFactory#getResponseWaitStrategy /** * Test case for {@link MicroPipelineFactory#getResponseWaitStrategy(MicroPipelineComponentConfiguration)} being provided * null as input which must lead to {@link RequiredInputMissingException} */ @Test public void testGetResponseWaitStrategy_withNullInput() throws UnknownWaitStrategyException { try { new MicroPipelineFactory("id", Mockito.mock(ComponentRepository.class)).getResponseWaitStrategy(null); Assert.fail("Invalid input"); } catch(RequiredInputMissingException e) { // expected } } /** * Test case for {@link MicroPipelineFactory#getResponseWaitStrategy(MicroPipelineComponentConfiguration)} being provided * a configuration that misses the settings which must lead to {@link RequiredInputMissingException} */ @Test public void testGetResponseWaitStrategy_withEmptySettings() throws UnknownWaitStrategyException { MicroPipelineComponentConfiguration cfg = new MicroPipelineComponentConfiguration(); cfg.setSettings(null); try { new MicroPipelineFactory("id", Mockito.mock(ComponentRepository.class)).getResponseWaitStrategy(cfg); Assert.fail("Invalid input"); } catch(RequiredInputMissingException e) { // expected } } /** * Test case for {@link MicroPipelineFactory#getResponseWaitStrategy(MicroPipelineComponentConfiguration)} being provided * a configuration that misses the strategy name inside the settings must lead to {@link RequiredInputMissingException} */ @Test public void testGetResponseWaitStrategy_withEmptyStrategyName() throws UnknownWaitStrategyException{ try { new MicroPipelineFactory("id", Mockito.mock(ComponentRepository.class)).getResponseWaitStrategy(new MicroPipelineComponentConfiguration()); Assert.fail("Invalid input"); } catch(RequiredInputMissingException e) { // expected } } /** * Test case for {@link MicroPipelineFactory#getResponseWaitStrategy(MicroPipelineComponentConfiguration)} being provided * a configuration that names an unknown strategy */ @Test public void testGetResponseWaitStrategy_withInvalidStrategyName() throws RequiredInputMissingException { MicroPipelineComponentConfiguration cfg = new MicroPipelineComponentConfiguration(); cfg.getSettings().put(DelayedResponseOperator.CFG_WAIT_STRATEGY_NAME, "test-strategy"); try { new MicroPipelineFactory("id", Mockito.mock(ComponentRepository.class)).getResponseWaitStrategy(cfg); Assert.fail("Unknown wait strategy"); } catch(UnknownWaitStrategyException e) { // expected } } /** * Test case for {@link MicroPipelineFactory#getResponseWaitStrategy(MicroPipelineComponentConfiguration)} being provided * a configuration that names a strategy and provides settings to it */ @Test public void testGetResponseWaitStrategy_withValidStrategyAndSettings() throws RequiredInputMissingException, UnknownWaitStrategyException { MicroPipelineComponentConfiguration cfg = new MicroPipelineComponentConfiguration(); cfg.getSettings().put(DelayedResponseOperator.CFG_WAIT_STRATEGY_NAME, MessageCountResponseWaitStrategy.WAIT_STRATEGY_NAME); cfg.getSettings().put(DelayedResponseOperator.CFG_WAIT_STRATEGY_SETTINGS_PREFIX + "key-2", "value-2"); cfg.getSettings().put(DelayedResponseOperator.CFG_WAIT_STRATEGY_SETTINGS_PREFIX + "key-1", "value-1"); DelayedResponseOperatorWaitStrategy strategy = new MicroPipelineFactory("id", Mockito.mock(ComponentRepository.class)).getResponseWaitStrategy(cfg); Assert.assertNotNull("The strategy must not be null", strategy); Assert.assertEquals("Types must be equal", MessageCountResponseWaitStrategy.class, strategy.getClass()); } // @Test // public void test() throws Exception { // ComponentRepository repo = new ComponentRepository(); // repo.addComponentFolder("/opt/transport/streaming/spqr-0.1.0/spqr-node/repo/spqr-twitter"); // repo.addComponentFolder("/opt/transport/streaming/spqr-0.1.0/spqr-node/repo/spqr-kafka"); // MicroPipelineFactory factory = new MicroPipelineFactory(repo); // // MicroPipelineConfiguration cfg = new ObjectMapper().readValue(new File("/home/mnxfst/projects/spqr/twitter-to-kafka.json"), MicroPipelineConfiguration.class); // // factory.instantiatePipeline(cfg, executorService); // // System.in.read(); // } // }