TaskTriggerHandler implements TriggerHandler { @Override @Transactional public void handle(MotechEvent event) { LOGGER.info("Handling the motech event with subject: {}", event.getSubject()); Map<String, Object> eventParams = event.getParameters(); eventParams.putAll(event.getMetadata()); TasksEventParser parser = null; if (eventParams != null) { parser = taskService.findCustomParser((String) eventParams.get(TasksEventParser.CUSTOM_PARSER_EVENT_KEY)); } String triggerSubject = parser == null ? event.getSubject() : parser.parseEventSubject(event.getSubject(), eventParams); Map<String, Object> parameters = parser == null ? eventParams : parser.parseEventParameters(event.getSubject(), eventParams); List<Task> tasks = taskService.findActiveTasksForTriggerSubject(triggerSubject); for (Task task : tasks) { checkAndHandleTask(task, parameters); } }  @PostConstruct void init(); @PreDestroy void preDestroy(); @Override void registerHandlerFor(String subject); @Override void registerHandlerFor(String subject, boolean isRetryHandler); @Override @Transactional void handle(MotechEvent event); @Override @Transactional void handleRetry(MotechEvent event); @Override @Transactional void retryTask(Long activityId); @Override void addDataProvider(DataProvider provider); @Override void removeDataProvider(String taskDataProviderId); @Autowired void setBundleContext(BundleContext bundleContext);  }
@Test public void shouldHandleErrorWhenActionIsNotFound() throws Exception { setTriggerEvent(); when(taskService.findActiveTasksForTriggerSubject(TRIGGER_SUBJECT)).thenReturn(tasks); when(taskService.getActionEventFor(task.getActions().get(0))).thenThrow(new ActionNotFoundException("")); handler.handle(createEvent()); verifyErrorHandling("task.error.actionNotFound"); }
@Test public void shouldHandleErrorWhenActionEventParameterDoesNotContainValue() throws Exception { setTriggerEvent(); setActionEvent(); when(taskService.findActiveTasksForTriggerSubject(TRIGGER_SUBJECT)).thenReturn(tasks); when(taskService.getActionEventFor(task.getActions().get(0))).thenReturn(actionEvent); task.getActions().get(0).getValues().remove("phone"); handler.handle(createEvent()); verifyErrorHandling("task.error.taskActionNotContainsField"); }
@Test public void shouldHandleErrorWhenActionEventParameterTemplateIsNull() throws Exception { setTriggerEvent(); setActionEvent(); when(taskService.findActiveTasksForTriggerSubject(TRIGGER_SUBJECT)).thenReturn(tasks); when(taskService.getActionEventFor(task.getActions().get(0))).thenReturn(actionEvent); task.getActions().get(0).getValues().put("phone", null); handler.handle(createEvent()); verifyErrorHandling("task.error.templateNull"); }
@Test public void shouldHandleErrorWhenEventParameterCanNotBeConvertedToInteger() throws Exception { setTriggerEvent(); setActionEvent(); when(taskService.findActiveTasksForTriggerSubject(TRIGGER_SUBJECT)).thenReturn(tasks); when(taskService.getActionEventFor(task.getActions().get(0))).thenReturn(actionEvent); task.getActions().get(0).getValues().put("phone", "1234 d"); handler.handle(createEvent()); verifyErrorHandling("task.error.convertToInteger"); }
@Test public void shouldHandleErrorWhenActionEventParameterCanNotBeConvertedToLong() throws Exception { setTriggerEvent(); setActionEvent(); setLongField(); when(taskService.findActiveTasksForTriggerSubject(TRIGGER_SUBJECT)).thenReturn(tasks); when(taskService.getActionEventFor(task.getActions().get(0))).thenReturn(actionEvent); task.getActions().get(0).getValues().put("long", "1234 d"); handler.handle(createEvent()); verifyErrorHandling("task.error.convertToLong"); }
@Test public void shouldHandleErrorWhenActionEventParameterCanNotBeConvertedToDouble() throws Exception { setTriggerEvent(); setActionEvent(); setDoubleField(); when(taskService.findActiveTasksForTriggerSubject(TRIGGER_SUBJECT)).thenReturn(tasks); when(taskService.getActionEventFor(task.getActions().get(0))).thenReturn(actionEvent); task.getActions().get(0).getValues().put("double", "1234 d"); handler.handle(createEvent()); verifyErrorHandling("task.error.convertToDouble"); }
@Test public void shouldHandleErrorWhenActionEventParameterCanNotBeConvertedToBoolean() throws Exception { setTriggerEvent(); setActionEvent(); setBooleanField(); when(taskService.findActiveTasksForTriggerSubject(TRIGGER_SUBJECT)).thenReturn(tasks); when(taskService.getActionEventFor(task.getActions().get(0))).thenReturn(actionEvent); task.getActions().get(0).getValues().put("boolean", "abc"); handler.handle(createEvent()); verifyErrorHandling("task.error.convertToBoolean"); }
@Test public void shouldHandleErrorWhenActionEventParameterCanNotBeConvertedToTime() throws Exception { setTriggerEvent(); setActionEvent(); setTimeField(); when(taskService.findActiveTasksForTriggerSubject(TRIGGER_SUBJECT)).thenReturn(tasks); when(taskService.getActionEventFor(task.getActions().get(0))).thenReturn(actionEvent); task.getActions().get(0).getValues().put("time", "234543fgf"); handler.handle(createEvent()); verifyErrorHandling("task.error.convertToTime"); }
@Test public void shouldHandleErrorWhenActionEventParameterCanNotBeConvertedToDate() throws Exception { setTriggerEvent(); setActionEvent(); setDateField(); when(taskService.findActiveTasksForTriggerSubject(TRIGGER_SUBJECT)).thenReturn(tasks); when(taskService.getActionEventFor(task.getActions().get(0))).thenReturn(actionEvent); task.getActions().get(0).getValues().put("date", "234543fgf"); handler.handle(createEvent()); verifyErrorHandling("task.error.convertToDate"); }
@Test public void shouldSendEventAndConvertDateWithAndWithoutManipulation() throws Exception { setTriggerEvent(); setActionEvent(); when(taskService.findActiveTasksForTriggerSubject(TRIGGER_SUBJECT)).thenReturn(tasks); when(taskService.getActionEventFor(task.getActions().get(0))).thenReturn(actionEvent); task.getActions().get(0).getValues().put("date1", "2012-12-21 21:21 +0100"); actionEvent.addParameter(new ActionParameterBuilder().setDisplayName("Date1").setKey("date1") .setType(DATE).build(), true); task.getActions().get(0).getValues().put("date2", "{{trigger.startDate?datetime(yyyyy.MMMMM.dd GGG hh:mm aaa)}}"); actionEvent.addParameter(new ActionParameterBuilder().setDisplayName("Date2").setKey("date2") .setType(UNICODE).build(), true); handler.handle(createEvent()); verify(taskService).findActiveTasksForTriggerSubject(TRIGGER_SUBJECT); verify(taskService).getActionEventFor(task.getActions().get(0)); ArgumentCaptor<MotechEvent> captorEvent = ArgumentCaptor.forClass(MotechEvent.class); verify(eventRelay).sendEventMessage(captorEvent.capture()); MotechEvent motechEvent = captorEvent.getValue(); assertEquals(ACTION_SUBJECT, motechEvent.getSubject()); Map<String, Object> motechEventParameters = motechEvent.getParameters(); assertNotNull(motechEventParameters); assertEquals(task.getActions().get(0).getValues().get("phone"), motechEventParameters.get("phone").toString()); assertEquals(4, motechEventParameters.size()); assertNotNull(motechEventParameters.get("date1")); assertNotNull(motechEventParameters.get("date2")); }
@Test public void shouldNotSendEventIfDataProviderNotFoundObject() throws Exception { setTriggerEvent(); setActionEvent(); setTaskActivities(); task.setFailuresInRow(taskActivities.size()); setAdditionalData(true); Map<String, String> lookupFields = new HashMap<>(); lookupFields.put("id", "123456789"); when(taskService.findActiveTasksForTriggerSubject(TRIGGER_SUBJECT)).thenReturn(tasks); when(taskService.getActionEventFor(task.getActions().get(0))).thenReturn(actionEvent); when(dataProvider.getName()).thenReturn("TEST"); when(dataProvider.supports("TestObjectField")).thenReturn(true); when(dataProvider.lookup("TestObjectField", "id", lookupFields)).thenReturn(null); assertTrue(task.isEnabled()); handler.handle(createEvent()); verify(taskService).findActiveTasksForTriggerSubject(TRIGGER_SUBJECT); verify(dataProvider).lookup("TestObjectField", "id", lookupFields); verify(postExecutionHandler).handleError(eq(createEventParameters()), anyMap(), eq(task), exceptionCaptor.capture(), eq(TASK_ACTIVITY_ID)); verify(postExecutionHandler, never()).handleActionExecuted(eq(createEventParameters()), anyMap(), eq(TASK_ACTIVITY_ID)); assertEquals("task.error.objectOfTypeNotFound", exceptionCaptor.getValue().getMessage()); }
@Test public void shouldNotSendEventIfDataProviderObjectNotContainsField() throws Exception { setTriggerEvent(); setActionEvent(); setTaskActivities(); task.setFailuresInRow(taskActivities.size()); setAdditionalData(true); Map<String, String> lookupFields = new HashMap<>(); lookupFields.put("id", "123456789"); when(taskService.findActiveTasksForTriggerSubject(TRIGGER_SUBJECT)).thenReturn(tasks); when(taskService.getActionEventFor(task.getActions().get(0))).thenReturn(actionEvent); when(dataProvider.getName()).thenReturn("TEST"); when(dataProvider.supports("TestObjectField")).thenReturn(true); when(dataProvider.lookup("TestObjectField", "id", lookupFields)).thenReturn(new Object()); assertTrue(task.isEnabled()); handler.handle(createEvent()); verify(taskService).findActiveTasksForTriggerSubject(TRIGGER_SUBJECT); verify(dataProvider).lookup("TestObjectField", "id", lookupFields); verify(postExecutionHandler).handleError(eq(createEventParameters()), anyMap(), eq(task), exceptionCaptor.capture(), eq(TASK_ACTIVITY_ID)); verify(postExecutionHandler, never()).handleActionExecuted(anyMap(), anyMap(), eq(TASK_ACTIVITY_ID)); assertEquals("task.error.objectDoesNotContainField", exceptionCaptor.getValue().getMessage()); }
@Test public void shouldNotSendEventIfDateFormatInManipulationIsNotValid() throws Exception { setTriggerEvent(); setActionEvent(); setManipulation(); when(taskService.findActiveTasksForTriggerSubject(TRIGGER_SUBJECT)).thenReturn(tasks); when(taskService.getActionEventFor(task.getActions().get(0))).thenReturn(actionEvent); task.getActions().get(0).getValues().put("manipulations", "{{trigger.startDate?dateTime(BadFormat)}}"); handler.handle(createEvent()); verifyErrorHandling("error.date.format"); }
@Test public void shouldGetWarningWhenManipulationHaveMistake() throws Exception { setTriggerEvent(); setActionEvent(); setManipulation(); when(taskService.findActiveTasksForTriggerSubject(TRIGGER_SUBJECT)).thenReturn(tasks); when(taskService.getActionEventFor(task.getActions().get(0))).thenReturn(actionEvent); task.getActions().get(0).getValues().put("manipulations", "{{trigger.eventName?toUper}}"); handler.handle(createEvent()); verify(taskService).findActiveTasksForTriggerSubject(TRIGGER_SUBJECT); verify(taskService).getActionEventFor(task.getActions().get(0)); verify(eventRelay).sendEventMessage(any(MotechEvent.class)); verify(taskActivityService).addWarning(task, "task.warning.manipulation", "toUper"); }
@Test public void shouldPassFiltersCriteria() throws Exception { setTriggerEvent(); setActionEvent(); setFilters(); when(taskService.findActiveTasksForTriggerSubject(TRIGGER_SUBJECT)).thenReturn(tasks); when(taskService.getActionEventFor(task.getActions().get(0))).thenReturn(actionEvent); handler.handle(createEvent()); verify(taskService).findActiveTasksForTriggerSubject(TRIGGER_SUBJECT); verify(taskService).getActionEventFor(task.getActions().get(0)); verify(eventRelay).sendEventMessage(any(MotechEvent.class)); }
@Test public void shouldNotPassFiltersCriteria() throws Exception { List<String> filtersManipulations = new ArrayList<>(); setTriggerEvent(); setActionEvent(); setFilters(); task.getTaskConfig().add(new FilterSet(asList(new Filter("ExternalID (Trigger)", "trigger.externalId", INTEGER, false, EXIST.getValue(), "", filtersManipulations)))); when(taskService.findActiveTasksForTriggerSubject(TRIGGER_SUBJECT)).thenReturn(tasks); when(taskService.getActionEventFor(task.getActions().get(0))).thenReturn(actionEvent); handler.handle(createEvent()); verify(taskService).findActiveTasksForTriggerSubject(TRIGGER_SUBJECT); verify(taskService, never()).getActionEventFor(task.getActions().get(0)); verify(eventRelay, never()).sendEventMessage(any(MotechEvent.class)); verify(taskActivityService).addTaskFiltered(TASK_ACTIVITY_ID); }
@Test public void shouldNotPassFiltersCriteriaAndNotExecuteSecondAction() throws Exception { setTriggerEvent(); setActionEvent(); addActionFilterNotPassingCriteria(); setSecondAction(); when(taskService.findActiveTasksForTriggerSubject(TRIGGER_SUBJECT)).thenReturn(tasks); when(taskService.getActionEventFor(any(TaskActionInformation.class))).thenReturn(actionEvent); ArgumentCaptor<MotechEvent> captor = ArgumentCaptor.forClass(MotechEvent.class); handler.handle(createEvent()); verify(taskService).findActiveTasksForTriggerSubject(TRIGGER_SUBJECT); verify(taskService).getActionEventFor(task.getActions().get(0)); verify(taskService, never()).getActionEventFor(task.getActions().get(1)); verify(eventRelay, times(1)).sendEventMessage(captor.capture()); verify(taskActivityService, never()).addTaskFiltered(TASK_ACTIVITY_ID); List<MotechEvent> events = captor.getAllValues(); assertEquals(asList(ACTION_SUBJECT), extract(events, on(MotechEvent.class).getSubject())); MotechEvent motechEventAction1 = events.get(0); assertEquals(ACTION_SUBJECT, motechEventAction1.getSubject()); assertNotNull(motechEventAction1.getParameters()); assertEquals(2, motechEventAction1.getParameters().size()); assertEquals(task.getActions().get(0).getValues().get("phone"), motechEventAction1.getParameters().get("phone").toString()); assertEquals("Hello 123456789, You have an appointment on 2012-11-20", motechEventAction1.getParameters().get("message")); }
@Test public void shouldSendEventForGivenTrigger() throws Exception { setTriggerEvent(); setActionEvent(); setManipulation(); setDateField(); setTimeField(); setFilters(); setAdditionalData(true); setLongField(); setDoubleField(); setBooleanField(); setListField(); setMapField(); setNonRequiredField(); Map<String, String> testObjectLookup = new HashMap<>(); testObjectLookup.put("id", "123456789-6789"); TestObject testObject = new TestObject(); TestObjectField testObjectField = new TestObjectField(); Map<String, String> testObjectFieldLookup = new HashMap<>(); testObjectFieldLookup.put("id", "123456789"); when(taskService.findActiveTasksForTriggerSubject(TRIGGER_SUBJECT)).thenReturn(tasks); when(taskService.getActionEventFor(task.getActions().get(0))).thenReturn(actionEvent); when(dataProvider.getName()).thenReturn("TEST"); when(dataProvider.supports("TestObject")).thenReturn(true); when(dataProvider.lookup("TestObject", "id", testObjectLookup)).thenReturn(testObject); when(dataProvider.supports("TestObjectField")).thenReturn(true); when(dataProvider.lookup("TestObjectField", "id", testObjectFieldLookup)).thenReturn(testObjectField); ArgumentCaptor<MotechEvent> captor = ArgumentCaptor.forClass(MotechEvent.class); handler.handle(createEvent()); verify(taskActivityService).addTaskStarted(task, createEventParameters()); verify(taskService).findActiveTasksForTriggerSubject(TRIGGER_SUBJECT); verify(taskService).getActionEventFor(task.getActions().get(0)); verify(eventRelay).sendEventMessage(captor.capture()); MotechEvent motechEvent = captor.getValue(); assertEquals(ACTION_SUBJECT, motechEvent.getSubject()); Map<String, Object> motechEventParameters = motechEvent.getParameters(); assertNotNull(motechEventParameters); assertEquals(13, motechEventParameters.size()); assertEquals(task.getActions().get(0).getValues().get("phone"), motechEventParameters.get("phone").toString()); assertEquals("Hello 123456789, You have an appointment on 2012-11-20", motechEventParameters.get("message")); assertEquals("String manipulation: Event-Name, Date manipulation: 20121120", motechEventParameters.get("manipulations")); assertEquals(DateTime.parse(task.getActions().get(0).getValues().get("date"), DateTimeFormat.forPattern("yyyy-MM-dd HH:mm Z")), motechEventParameters.get("date")); assertEquals("test: 6789", motechEventParameters.get("dataSourceTrigger")); assertEquals("test: 6789", motechEventParameters.get("dataSourceObject")); assertEquals(DateTime.parse(task.getActions().get(0).getValues().get("time"), DateTimeFormat.forPattern("HH:mm Z")), motechEventParameters.get("time")); assertEquals(10000000000L, motechEventParameters.get("long")); assertEquals(true, motechEventParameters.get("boolean")); assertEquals(getExpectedList(), motechEventParameters.get("list")); assertEquals(getExpectedMap(), motechEventParameters.get("map")); assertNull(motechEventParameters.get("delivery_time")); }
@Test public void shouldNotExecuteServiceMethodIfBundleContextIsNull() throws Exception { setTriggerEvent(); setActionEvent(); actionEvent.setServiceInterface("TestService"); actionEvent.setServiceMethod("throwException"); actionEvent.setSubject(null); when(taskService.findActiveTasksForTriggerSubject(TRIGGER_SUBJECT)).thenReturn(tasks); when(taskService.getActionEventFor(task.getActions().get(0))).thenReturn(actionEvent); handler.handle(createEvent()); verifyErrorHandling("task.error.cantExecuteAction"); }
@Test public void shouldExecuteTwoActions() throws Exception { setTriggerEvent(); setActionEvent(); setSecondAction(); when(taskService.findActiveTasksForTriggerSubject(TRIGGER_SUBJECT)).thenReturn(tasks); when(taskService.getActionEventFor(any(TaskActionInformation.class))).thenReturn(actionEvent); ArgumentCaptor<MotechEvent> captor = ArgumentCaptor.forClass(MotechEvent.class); handler.handle(createEvent()); verify(taskService).findActiveTasksForTriggerSubject(TRIGGER_SUBJECT); verify(taskService).getActionEventFor(task.getActions().get(0)); verify(taskService).getActionEventFor(task.getActions().get(1)); verify(eventRelay, times(2)).sendEventMessage(captor.capture()); List<MotechEvent> events = captor.getAllValues(); assertEquals( asList(ACTION_SUBJECT, ACTION_SUBJECT), extract(events, on(MotechEvent.class).getSubject()) ); MotechEvent motechEventAction1 = events.get(0); assertEquals(ACTION_SUBJECT, motechEventAction1.getSubject()); assertNotNull(motechEventAction1.getParameters()); assertEquals(2, motechEventAction1.getParameters().size()); assertEquals(task.getActions().get(0).getValues().get("phone"), motechEventAction1.getParameters().get("phone").toString()); assertEquals("Hello 123456789, You have an appointment on 2012-11-20", motechEventAction1.getParameters().get("message")); MotechEvent motechEventAction2 = events.get(1); assertEquals(ACTION_SUBJECT, motechEventAction2.getSubject()); assertNotNull(motechEventAction2.getParameters()); assertEquals(2, motechEventAction2.getParameters().size()); assertEquals(task.getActions().get(0).getValues().get("phone"), motechEventAction2.getParameters().get("phone").toString()); assertEquals("Hello, world! I'm second action", motechEventAction2.getParameters().get("message")); }
@Test public void shouldHandleFormatManipulation() throws Exception { setTriggerEvent(); setActionEvent(); setFormatManipulation(); setAdditionalData(true); Map<String, String> testObjectLookup = new HashMap<>(); testObjectLookup.put("id", "123456789-6789"); TestObject testObject = new TestObject(); TestObjectField testObjectField = new TestObjectField(); Map<String, String> testObjectFieldLookup = new HashMap<>(); testObjectFieldLookup.put("id", "123456789"); when(taskService.findActiveTasksForTriggerSubject(TRIGGER_SUBJECT)).thenReturn(tasks); when(taskService.getActionEventFor(any(TaskActionInformation.class))).thenReturn(actionEvent); when(dataProvider.getName()).thenReturn("TEST"); when(dataProvider.supports("TestObject")).thenReturn(true); when(dataProvider.lookup("TestObject", "id", testObjectLookup)).thenReturn(testObject); when(dataProvider.supports("TestObjectField")).thenReturn(true); when(dataProvider.lookup("TestObjectField", "id", testObjectFieldLookup)).thenReturn(testObjectField); ArgumentCaptor<MotechEvent> captor = ArgumentCaptor.forClass(MotechEvent.class); handler.handle(createEvent()); verify(eventRelay).sendEventMessage(captor.capture()); MotechEvent event = captor.getAllValues().get(0); assertEquals("123456789 || 6789 || YourName", event.getParameters().get("format")); }
@Test public void shouldHandleTriggerWithCustomParser() throws Exception { setTriggerEvent(); setActionEvent(); when(taskService.findActiveTasksForTriggerSubject(TRIGGER_SUBJECT)).thenReturn(tasks); when(taskService.getActionEventFor(any(TaskActionInformation.class))).thenReturn(actionEvent); when(taskService.findCustomParser(SampleTasksEventParser.PARSER_NAME)).thenReturn(new SampleTasksEventParser()); ArgumentCaptor<Map> captor = ArgumentCaptor.forClass(Map.class); handler.handle(createEvent(true)); verify(taskActivityService).addTaskStarted(eq(task), captor.capture()); Map<String, Object> paramsMap = captor.getValue(); assertTrue(paramsMap.containsKey("eve")); assertTrue(paramsMap.containsKey("ext")); assertTrue(paramsMap.containsKey("fac")); assertTrue(paramsMap.containsKey("lis")); assertEquals("eve", paramsMap.get("eve")); assertEquals("123", paramsMap.get("ext")); assertEquals("987", paramsMap.get("fac")); assertEquals("[1,", paramsMap.get("lis")); }