WorkflowStateProcessorFactory { public int getPotentiallyStuckProcessors() { DateTime currentTime = now(); int potentiallyStuck = 0; for (WorkflowStateProcessor processor : processingInstances.values()) { Duration processingTime = new Duration(processor.getStartTime(), currentTime); if (processingTime.getStandardSeconds() > stuckThreadThresholdSeconds) { potentiallyStuck++; processor.logPotentiallyStuck(processingTime.getStandardSeconds()); processor.handlePotentiallyStuck(processingTime); } } return potentiallyStuck; } @Inject  WorkflowStateProcessorFactory(WorkflowDefinitionService workflowDefinitions, WorkflowInstanceService workflowInstances,
      ObjectStringMapper objectMapper, WorkflowInstanceDao workflowInstanceDao, MaintenanceDao maintenanceDao,
      WorkflowInstancePreProcessor workflowInstancePreProcessor, Environment env); WorkflowStateProcessor createProcessor(long instanceId, Supplier<Boolean> shutdownRequested); int getPotentiallyStuckProcessors();  }
@Test public void checkIfStateProcessorsAreStuckLogsLongRunningInstance() { WorkflowStateProcessor executor1 = mock(WorkflowStateProcessor.class); WorkflowStateProcessor executor2 = mock(WorkflowStateProcessor.class); when(executor1.getStartTime()).thenReturn(now().minusSeconds(STUCK_THREAD_THRESHOLD + 1)); when(executor2.getStartTime()).thenReturn(now().minusSeconds(STUCK_THREAD_THRESHOLD)); factory.processingInstances.put(111L, executor1); factory.processingInstances.put(222L, executor2); factory.listeners = listeners; int potentiallyStuckProcessors = factory.getPotentiallyStuckProcessors(); assertThat(potentiallyStuckProcessors, is(1)); verify(executor1).logPotentiallyStuck(anyLong()); verify(executor2, never()).logPotentiallyStuck(anyLong()); verify(executor1).handlePotentiallyStuck(any(Duration.class)); verify(executor2, never()).handlePotentiallyStuck(any(Duration.class)); }