@Override public void onFailure(Throwable t) { returnSession(); for (ISessionCallback<R> handler : configuration.getSessionCallbacks()) { handler.onFailure(t); } }
@Override public void onSuccess(R result) { returnSession(); for (ISessionCallback<R> handler : configuration.getSessionCallbacks()) { handler.onSuccess(result); } }
/** * {@inheritDoc} */ @Override public void analyze(I input) throws DiagnosisEngineException { analyze(input, Session.EMPTY_SESSION_VARIABLES); }
@Test public void testwithError() throws DiagnosisEngineException { final List<DefaultSessionResult<String>> results = new ArrayList<>(); final List<Throwable> exceptions = new ArrayList<>(); DiagnosisEngineConfiguration<String, DefaultSessionResult<String>> configuration = new DiagnosisEngineConfiguration<String, DefaultSessionResult<String>>().setNumSessionWorkers(1) .addRuleClasses(RuleA.class, RuleB.class, RuleC.class, RuleE.class, RuleD.class).setStorageClass(DefaultRuleOutputStorage.class) .setResultCollector(new DefaultSessionResultCollector<String>()).addSessionCallback(new ISessionCallback<DefaultSessionResult<String>>() { @Override public void onSuccess(DefaultSessionResult<String> result) { results.add(result); } @Override public void onFailure(Throwable t) { exceptions.add(t); } }); configuration.setShutdownTimeout(6000); DiagnosisEngine<String, DefaultSessionResult<String>> diagnosisEngine = new DiagnosisEngine<>(configuration); String input = "Trace"; diagnosisEngine.analyze(input); diagnosisEngine.shutdown(true); assertThat(exceptions, hasSize(1)); } }
DiagnosisEngineConfiguration<InvocationSequenceData, List<ProblemOccurrence>> configuration = new DiagnosisEngineConfiguration<InvocationSequenceData, List<ProblemOccurrence>>(); configuration.setNumSessionWorkers(numberOfSessionWorker); configuration.addRuleClasses(ruleClasses); configuration.setResultCollector(new ProblemOccurrenceResultCollector()); configuration.addSessionCallback(new DelegatingResultHandler()); engine = new DiagnosisEngine<>(configuration); } catch (DiagnosisEngineException e) { LOG.info("DiagnosisEngine could not be initialized.");
@Test(expectedExceptions = { IllegalArgumentException.class }) public void nullRules() throws Exception { when(config.getRuleClasses()).thenReturn(null); when(config.getResultCollector()).thenReturn(resultCollector); Answer<Class<? extends IRuleOutputStorage>> callableAnswer = new Answer<Class<? extends IRuleOutputStorage>>() { @Override public Class<? extends IRuleOutputStorage> answer(InvocationOnMock invocation) throws Throwable { return DefaultRuleOutputStorage.class; } }; doAnswer(callableAnswer).when(config).getStorageClass(); sessionFactory = new SessionFactory<>(config); sessionFactory.makeObject(); }
@Override public Session<I, R> makeObject() throws Exception { return new Session<>(ruleDefinitions, configuration.getResultCollector(), ReflectionUtils.tryInstantiate(configuration.getStorageClass())); }
private void returnSession() { try { sessionPool.returnObject(session); } catch (Exception e) { for (ISessionCallback<R> handler : configuration.getSessionCallbacks()) { handler.onFailure(new DiagnosisEngineException("Failed to return Session to ObjectPool.", e)); } } } });
/** * Default constructor to create new {@link SessionFactory}s. * * @param configuration * The {@link DiagnosisEngineConfiguration} * @throws DiagnosisEngineException * If {@link DiagnosisEngineConfiguration} is invalid. */ public SessionFactory(DiagnosisEngineConfiguration<I, R> configuration) throws DiagnosisEngineException { this.configuration = checkNotNull(configuration, "Diagnosis engine configuration must not be null."); this.ruleDefinitions = prepareRuleDefinitions(configuration.getRuleClasses()); }
/** * Default constructor to create a new DiagnosisEngine instance. * * @param configuration * The {@link DiagnosisEngineConfiguration} to be used. Must not be null. * @throws DiagnosisEngineException * If the provided configuration is not valid. */ public DiagnosisEngine(DiagnosisEngineConfiguration<I, R> configuration) throws DiagnosisEngineException { this.configuration = checkNotNull(configuration, "The configuration must not be null."); this.configuration.validate(); this.sessionPool = new SessionPool<>(configuration); // Wrap in listing executor this.sessionExecutor = MoreExecutors.listeningDecorator(configuration.getExecutorService()); }
if (isShutdown()) { throw new DiagnosisEngineException("Analysis failed! Diagnosis Engine has been shut down."); session = sessionPool.borrowObject(input, variables); } catch (Exception e) { throw new DiagnosisEngineException("Failed to borrow Object from SessionPool.", e);
@Test public void stopDiagnosis() throws DiagnosisEngineException { double baseline = 1000; InvocationSequenceData invocationSequenceData = new InvocationSequenceData(); when(diagnosisServiceExecutor.isShutdown()).thenReturn(true); diagnosisService.diagnose(invocationSequenceData, baseline); diagnosisService.run(); verify(engine, times(1)).analyze(invocationSequenceData, Collections.singletonMap(RuleConstants.DIAGNOSIS_VAR_BASELINE, baseline)); verify(diagnosisServiceExecutor, times(0)).execute(diagnosisService); } }
/** * Adds a list of new {@link ISessionCallback}s {@link #callbacks}. * * @param sessionCallbacks * New entries for {@link #callbacks} * @return DiagnosisEngineConfiguration itself */ public DiagnosisEngineConfiguration<I, R> addSessionCallbacks(List<ISessionCallback<R>> sessionCallbacks) { for (ISessionCallback<R> callback : sessionCallbacks) { addSessionCallback(callback); } return this; }
/** * Adds new Classes to {@link #ruleClasses}. * * @param ruleClasses * New values for {@link #ruleClasses} * @return DiagnosisEngineConfiguration itself */ public DiagnosisEngineConfiguration<I, R> addRuleClasses(Class<?>... ruleClasses) { addRuleClasses(Arrays.asList(checkNotNull(ruleClasses, "Array of rule classes must not be null."))); return this; }
/** * Validates the {@link DiagnosisEngineConfiguration}. * * @throws DiagnosisEngineException * If any of the configuration elements is invalid or is missing. */ public void validate() throws DiagnosisEngineException { try { checkArgument(numSessionWorkers > 0, "numSessionWorkers must be at least 1."); checkArgument(shutdownTimeout > 0, "shutdownTimeout must be at least 1."); checkArgument(CollectionUtils.isNotEmpty(ruleClasses), "At least one rule class must be specified."); checkNotNull(resultCollector, "Result collector must not be null."); if (executorService == null) { executorService = Executors.newFixedThreadPool(getNumSessionWorkers()); } } catch (IllegalArgumentException e) { throw new DiagnosisEngineException("Invalid Diagnosis Engine configuration!", e); } }
/** * {@inheritDoc} */ @Override public void shutdown(boolean awaitShutdown) { // 1. Shutdown the ExecutorService if (!sessionExecutor.isShutdown()) { sessionExecutor.shutdown(); if (awaitShutdown) { try { if (!sessionExecutor.awaitTermination(configuration.getShutdownTimeout(), TimeUnit.SECONDS)) { log.error("DiagnosisEngine executor did not shutdown within: {} seconds.", configuration.getShutdownTimeout()); } } catch (InterruptedException e) { log.error("InterruptedException occured during termination of the DiagnosisEngine executor.", e); } } } // 2. Shutdown the session pool try { sessionPool.close(); } catch (Exception e) { log.error("Failed closing DiagnosisEngine session pool.", e); } }
/** * Adds new Classes to {@link #ruleClasses}. * * @param ruleClasses * New values for {@link #ruleClasses} * @return DiagnosisEngineConfiguration itself */ public DiagnosisEngineConfiguration<I, R> addRuleClasses(Collection<Class<?>> ruleClasses) { checkNotNull(ruleClasses, "Set of rule classes must not be null."); for (Class<?> ruleClass : ruleClasses) { addRuleClass(ruleClass); } return this; }
/** * Utility method to create a default GenericObjectPool.Config with configuration values from * DiagnosisEngineConfiguration. * * @param configuration * The top-level DiagnosisEngineConfiguration * @return A new {@link GenericObjectPool.Config} instance. */ private static GenericObjectPool.Config defaultConfig(DiagnosisEngineConfiguration<?, ?> configuration) { GenericObjectPool.Config config = new GenericObjectPool.Config(); config.whenExhaustedAction = GenericObjectPool.DEFAULT_WHEN_EXHAUSTED_ACTION; config.maxActive = configuration.getNumSessionWorkers(); return config; } }
@Test(expectedExceptions = { IllegalArgumentException.class }) public void missingRules() throws Exception { when(config.getRuleClasses()).thenReturn(Collections.<Class<?>> emptySet()); when(config.getResultCollector()).thenReturn(resultCollector); Answer<Class<? extends IRuleOutputStorage>> callableAnswer = new Answer<Class<? extends IRuleOutputStorage>>() { @Override public Class<? extends IRuleOutputStorage> answer(InvocationOnMock invocation) throws Throwable { return DefaultRuleOutputStorage.class; } }; doAnswer(callableAnswer).when(config).getStorageClass(); sessionFactory = new SessionFactory<>(config); sessionFactory.makeObject(); }
@Test public void runDiagnosis() throws DiagnosisEngineException { double baseline = 1000; InvocationSequenceData invocationSequenceData = new InvocationSequenceData(); invocationSequenceData.setDuration(5000d); verify(engine, times(0)).analyze(invocationSequenceData, Collections.singletonMap(RuleConstants.DIAGNOSIS_VAR_BASELINE, baseline)); verify(diagnosisServiceExecutor, times(0)).execute(diagnosisService); diagnosisService.diagnose(invocationSequenceData, baseline); diagnosisService.diagnose(invocationSequenceData, baseline); diagnosisService.diagnose(invocationSequenceData, baseline); diagnosisService.run(); diagnosisService.run(); diagnosisService.run(); verify(engine, times(3)).analyze(invocationSequenceData, Collections.singletonMap(RuleConstants.DIAGNOSIS_VAR_BASELINE, baseline)); verify(diagnosisServiceExecutor, times(3)).execute(diagnosisService); }