use of org.opensearch.ad.NodeStateManager in project anomaly-detection by opensearch-project.
the class AnomalyResultTests method testMute.
@SuppressWarnings("unchecked")
public void testMute() {
NodeStateManager muteStateManager = mock(NodeStateManager.class);
when(muteStateManager.isMuted(any(String.class), any(String.class))).thenReturn(true);
doAnswer(invocation -> {
ActionListener<Optional<AnomalyDetector>> listener = invocation.getArgument(1);
listener.onResponse(Optional.of(detector));
return null;
}).when(muteStateManager).getAnomalyDetector(any(String.class), any(ActionListener.class));
AnomalyResultTransportAction action = new AnomalyResultTransportAction(new ActionFilters(Collections.emptySet()), transportService, settings, client, muteStateManager, featureQuery, normalModelManager, hashRing, clusterService, indexNameResolver, adCircuitBreakerService, adStats, threadPool, NamedXContentRegistry.EMPTY, adTaskManager);
AnomalyResultRequest request = new AnomalyResultRequest(adID, 100, 200);
PlainActionFuture<AnomalyResultResponse> listener = new PlainActionFuture<>();
action.doExecute(null, request, listener);
Throwable exception = assertException(listener, AnomalyDetectionException.class);
assertThat(exception.getMessage(), containsString(AnomalyResultTransportAction.NODE_UNRESPONSIVE_ERR_MSG));
}
use of org.opensearch.ad.NodeStateManager in project anomaly-detection by opensearch-project.
the class EntityColdStarterTests method setUp.
@SuppressWarnings("unchecked")
@Override
public void setUp() throws Exception {
super.setUp();
numMinSamples = AnomalyDetectorSettings.NUM_MIN_SAMPLES;
clock = mock(Clock.class);
when(clock.instant()).thenReturn(Instant.now());
threadPool = mock(ThreadPool.class);
setUpADThreadPool(threadPool);
settings = Settings.EMPTY;
Client client = mock(Client.class);
clientUtil = mock(ClientUtil.class);
detector = TestHelpers.AnomalyDetectorBuilder.newInstance().setDetectionInterval(new IntervalTimeConfiguration(1, ChronoUnit.MINUTES)).setCategoryFields(ImmutableList.of(randomAlphaOfLength(5))).build();
job = TestHelpers.randomAnomalyDetectorJob(true, Instant.ofEpochMilli(1602401500000L), null);
doAnswer(invocation -> {
GetRequest request = invocation.getArgument(0);
ActionListener<GetResponse> listener = invocation.getArgument(2);
if (request.index().equals(AnomalyDetectorJob.ANOMALY_DETECTOR_JOB_INDEX)) {
listener.onResponse(TestHelpers.createGetResponse(job, detectorId, AnomalyDetectorJob.ANOMALY_DETECTOR_JOB_INDEX));
} else {
listener.onResponse(TestHelpers.createGetResponse(detector, detectorId, AnomalyDetector.ANOMALY_DETECTORS_INDEX));
}
return null;
}).when(clientUtil).asyncRequest(any(GetRequest.class), any(), any(ActionListener.class));
Set<Setting<?>> nodestateSetting = new HashSet<>(ClusterSettings.BUILT_IN_CLUSTER_SETTINGS);
nodestateSetting.add(MAX_RETRY_FOR_UNRESPONSIVE_NODE);
nodestateSetting.add(BACKOFF_MINUTES);
ClusterSettings clusterSettings = new ClusterSettings(Settings.EMPTY, nodestateSetting);
DiscoveryNode discoveryNode = new DiscoveryNode("node1", OpenSearchTestCase.buildNewFakeTransportAddress(), Collections.emptyMap(), DiscoveryNodeRole.BUILT_IN_ROLES, Version.CURRENT);
ClusterService clusterService = ClusterServiceUtils.createClusterService(threadPool, discoveryNode, clusterSettings);
stateManager = new NodeStateManager(client, xContentRegistry(), settings, clientUtil, clock, AnomalyDetectorSettings.HOURLY_MAINTENANCE, clusterService);
SingleFeatureLinearUniformInterpolator singleFeatureLinearUniformInterpolator = new IntegerSensitiveSingleFeatureLinearUniformInterpolator();
interpolator = new LinearUniformInterpolator(singleFeatureLinearUniformInterpolator);
searchFeatureDao = mock(SearchFeatureDao.class);
checkpoint = mock(CheckpointDao.class);
featureManager = new FeatureManager(searchFeatureDao, interpolator, clock, AnomalyDetectorSettings.MAX_TRAIN_SAMPLE, AnomalyDetectorSettings.MAX_SAMPLE_STRIDE, AnomalyDetectorSettings.TRAIN_SAMPLE_TIME_RANGE_IN_HOURS, AnomalyDetectorSettings.MIN_TRAIN_SAMPLES, AnomalyDetectorSettings.MAX_SHINGLE_PROPORTION_MISSING, AnomalyDetectorSettings.MAX_IMPUTATION_NEIGHBOR_DISTANCE, AnomalyDetectorSettings.PREVIEW_SAMPLE_RATE, AnomalyDetectorSettings.MAX_PREVIEW_SAMPLES, AnomalyDetectorSettings.HOURLY_MAINTENANCE, threadPool, AnomalyDetectorPlugin.AD_THREAD_POOL_NAME);
checkpointWriteQueue = mock(CheckpointWriteWorker.class);
rcfSeed = 2051L;
entityColdStarter = new EntityColdStarter(clock, threadPool, stateManager, AnomalyDetectorSettings.NUM_SAMPLES_PER_TREE, AnomalyDetectorSettings.NUM_TREES, AnomalyDetectorSettings.TIME_DECAY, numMinSamples, AnomalyDetectorSettings.MAX_SAMPLE_STRIDE, AnomalyDetectorSettings.MAX_TRAIN_SAMPLE, interpolator, searchFeatureDao, AnomalyDetectorSettings.THRESHOLD_MIN_PVALUE, featureManager, settings, AnomalyDetectorSettings.HOURLY_MAINTENANCE, checkpointWriteQueue, rcfSeed, AnomalyDetectorSettings.MAX_COLD_START_ROUNDS);
detectorId = "123";
modelId = "123_entity_abc";
entityName = "abc";
priority = 0.3f;
entity = Entity.createSingleAttributeEntity("field", entityName);
released = new AtomicBoolean();
inProgressLatch = new CountDownLatch(1);
releaseSemaphore = () -> {
released.set(true);
inProgressLatch.countDown();
};
listener = ActionListener.wrap(releaseSemaphore);
modelManager = new ModelManager(mock(CheckpointDao.class), mock(Clock.class), AnomalyDetectorSettings.NUM_TREES, AnomalyDetectorSettings.NUM_SAMPLES_PER_TREE, AnomalyDetectorSettings.TIME_DECAY, AnomalyDetectorSettings.NUM_MIN_SAMPLES, AnomalyDetectorSettings.THRESHOLD_MIN_PVALUE, AnomalyDetectorSettings.MIN_PREVIEW_SIZE, AnomalyDetectorSettings.HOURLY_MAINTENANCE, AnomalyDetectorSettings.HOURLY_MAINTENANCE, entityColdStarter, mock(FeatureManager.class), mock(MemoryTracker.class));
}
use of org.opensearch.ad.NodeStateManager in project anomaly-detection by opensearch-project.
the class MultiEntityResultTests method testTimeOutExceptionInModelNode.
/**
* Test that in model node, previously recorded exception is OpenSearchTimeoutException,
* @throws IOException when failing to set up transport layer
* @throws InterruptedException when failing to wait for inProgress to finish
*/
public void testTimeOutExceptionInModelNode() throws IOException, InterruptedException {
Pair<NodeStateManager, CountDownLatch> preparedFixture = setUpTestExceptionTestingInModelNode();
NodeStateManager modelNodeStateManager = preparedFixture.getLeft();
CountDownLatch inProgress = preparedFixture.getRight();
when(modelNodeStateManager.fetchExceptionAndClear(anyString())).thenReturn(Optional.of(new OpenSearchTimeoutException("blah")));
setUpEntityResult(1, modelNodeStateManager);
PlainActionFuture<AnomalyResultResponse> listener = new PlainActionFuture<>();
action.doExecute(null, request, listener);
AnomalyResultResponse response = listener.actionGet(10000L);
assertEquals(Double.NaN, response.getAnomalyGrade(), 0.01);
assertTrue(inProgress.await(10000L, TimeUnit.MILLISECONDS));
// since OpenSearchTimeoutException is not end run exception (now = true), the normal workflow continues
verify(resultWriteQueue, times(3)).put(any());
ArgumentCaptor<Exception> exceptionCaptor = ArgumentCaptor.forClass(Exception.class);
verify(stateManager).setException(anyString(), exceptionCaptor.capture());
Exception actual = exceptionCaptor.getValue();
assertTrue("actual exception is " + actual, actual instanceof InternalFailure);
}
use of org.opensearch.ad.NodeStateManager in project anomaly-detection by opensearch-project.
the class MultiEntityResultTests method setUpTestExceptionTestingInModelNode.
@SuppressWarnings("unchecked")
private Pair<NodeStateManager, CountDownLatch> setUpTestExceptionTestingInModelNode() throws IOException {
CountDownLatch inProgress = setUpSearchResponse();
setUpTransportInterceptor(this::entityResultHandler);
// mock hashing ring response. This has to happen after setting up test nodes with the failure interceptor
when(hashRing.getOwningNodeWithSameLocalAdVersionForRealtimeAD(any(String.class))).thenReturn(Optional.of(testNodes[1].discoveryNode()));
NodeStateManager modelNodeStateManager = mock(NodeStateManager.class);
// make sure parameters are not null, otherwise this mock won't get invoked
doAnswer(invocation -> {
ActionListener<Optional<AnomalyDetector>> listener = invocation.getArgument(1);
listener.onResponse(Optional.of(detector));
return null;
}).when(modelNodeStateManager).getAnomalyDetector(anyString(), any(ActionListener.class));
return Pair.of(modelNodeStateManager, inProgress);
}
use of org.opensearch.ad.NodeStateManager in project anomaly-detection by opensearch-project.
the class MultiEntityResultTests method testSelectHigherExceptionInModelNode.
/**
* Test that when both previous and current run returns exception, we return more
* important exception (EndRunException is more important)
* @throws InterruptedException when failing to wait for inProgress to finish
* @throws IOException when failing to set up transport layer
*/
public void testSelectHigherExceptionInModelNode() throws InterruptedException, IOException {
when(entityCache.get(any(), any())).thenThrow(EndRunException.class);
Pair<NodeStateManager, CountDownLatch> preparedFixture = setUpTestExceptionTestingInModelNode();
NodeStateManager modelNodeStateManager = preparedFixture.getLeft();
CountDownLatch inProgress = preparedFixture.getRight();
when(modelNodeStateManager.fetchExceptionAndClear(anyString())).thenReturn(Optional.of(new OpenSearchTimeoutException("blah")));
setUpEntityResult(1, modelNodeStateManager);
PlainActionFuture<AnomalyResultResponse> listener = new PlainActionFuture<>();
action.doExecute(null, request, listener);
AnomalyResultResponse response = listener.actionGet(10000L);
assertEquals(Double.NaN, response.getAnomalyGrade(), 0.01);
assertTrue(inProgress.await(10000L, TimeUnit.MILLISECONDS));
// since EndRunException is thrown before getting any result, we cannot save anything
verify(resultWriteQueue, never()).put(any());
ArgumentCaptor<Exception> exceptionCaptor = ArgumentCaptor.forClass(Exception.class);
verify(stateManager).setException(anyString(), exceptionCaptor.capture());
EndRunException endRunException = (EndRunException) (exceptionCaptor.getValue());
assertTrue(!endRunException.isEndNow());
}
Aggregations