Search in sources :

Example 1 with EntityFeatureRequest

use of org.opensearch.ad.ratelimit.EntityFeatureRequest in project anomaly-detection by opensearch-project.

the class EntityResultTransportAction method onGetDetector.

private ActionListener<Optional<AnomalyDetector>> onGetDetector(ActionListener<AcknowledgedResponse> listener, String detectorId, EntityResultRequest request, Optional<Exception> prevException) {
    return ActionListener.wrap(detectorOptional -> {
        if (!detectorOptional.isPresent()) {
            listener.onFailure(new EndRunException(detectorId, "AnomalyDetector is not available.", true));
            return;
        }
        AnomalyDetector detector = detectorOptional.get();
        if (request.getEntities() == null) {
            listener.onResponse(null);
            return;
        }
        Instant executionStartTime = Instant.now();
        Map<Entity, double[]> cacheMissEntities = new HashMap<>();
        for (Entry<Entity, double[]> entityEntry : request.getEntities().entrySet()) {
            Entity categoricalValues = entityEntry.getKey();
            if (isEntityeFromOldNodeMsg(categoricalValues) && detector.getCategoryField() != null && detector.getCategoryField().size() == 1) {
                Map<String, String> attrValues = categoricalValues.getAttributes();
                // handle a request from a version before OpenSearch 1.1.
                categoricalValues = Entity.createSingleAttributeEntity(detector.getCategoryField().get(0), attrValues.get(CommonName.EMPTY_FIELD));
            }
            Optional<String> modelIdOptional = categoricalValues.getModelId(detectorId);
            if (false == modelIdOptional.isPresent()) {
                continue;
            }
            String modelId = modelIdOptional.get();
            double[] datapoint = entityEntry.getValue();
            ModelState<EntityModel> entityModel = cache.get().get(modelId, detector);
            if (entityModel == null) {
                // cache miss
                cacheMissEntities.put(categoricalValues, datapoint);
                continue;
            }
            ThresholdingResult result = modelManager.getAnomalyResultForEntity(datapoint, entityModel, modelId, categoricalValues, detector.getShingleSize());
            // So many OpenSearchRejectedExecutionException if we write no matter what
            if (result.getRcfScore() > 0) {
                AnomalyResult resultToSave = result.toAnomalyResult(detector, Instant.ofEpochMilli(request.getStart()), Instant.ofEpochMilli(request.getEnd()), executionStartTime, Instant.now(), ParseUtils.getFeatureData(datapoint, detector), categoricalValues, indexUtil.getSchemaVersion(ADIndex.RESULT), modelId, null, null);
                resultWriteQueue.put(new ResultWriteRequest(System.currentTimeMillis() + detector.getDetectorIntervalInMilliseconds(), detectorId, result.getGrade() > 0 ? RequestPriority.HIGH : RequestPriority.MEDIUM, resultToSave, detector.getResultIndex()));
            }
        }
        // split hot and cold entities
        Pair<List<Entity>, List<Entity>> hotColdEntities = cache.get().selectUpdateCandidate(cacheMissEntities.keySet(), detectorId, detector);
        List<EntityFeatureRequest> hotEntityRequests = new ArrayList<>();
        List<EntityFeatureRequest> coldEntityRequests = new ArrayList<>();
        for (Entity hotEntity : hotColdEntities.getLeft()) {
            double[] hotEntityValue = cacheMissEntities.get(hotEntity);
            if (hotEntityValue == null) {
                LOG.error(new ParameterizedMessage("feature value should not be null: [{}]", hotEntity));
                continue;
            }
            hotEntityRequests.add(new EntityFeatureRequest(System.currentTimeMillis() + detector.getDetectorIntervalInMilliseconds(), detectorId, // hot entities has MEDIUM priority
            RequestPriority.MEDIUM, hotEntity, hotEntityValue, request.getStart()));
        }
        for (Entity coldEntity : hotColdEntities.getRight()) {
            double[] coldEntityValue = cacheMissEntities.get(coldEntity);
            if (coldEntityValue == null) {
                LOG.error(new ParameterizedMessage("feature value should not be null: [{}]", coldEntity));
                continue;
            }
            coldEntityRequests.add(new EntityFeatureRequest(System.currentTimeMillis() + detector.getDetectorIntervalInMilliseconds(), detectorId, // cold entities has LOW priority
            RequestPriority.LOW, coldEntity, coldEntityValue, request.getStart()));
        }
        checkpointReadQueue.putAll(hotEntityRequests);
        coldEntityQueue.putAll(coldEntityRequests);
        // respond back
        if (prevException.isPresent()) {
            listener.onFailure(prevException.get());
        } else {
            listener.onResponse(new AcknowledgedResponse(true));
        }
    }, exception -> {
        LOG.error(new ParameterizedMessage("fail to get entity's anomaly grade for detector [{}]: start: [{}], end: [{}]", detectorId, request.getStart(), request.getEnd()), exception);
        listener.onFailure(exception);
    });
}
Also used : Entity(org.opensearch.ad.model.Entity) EndRunException(org.opensearch.ad.common.exception.EndRunException) EntityFeatureRequest(org.opensearch.ad.ratelimit.EntityFeatureRequest) HashMap(java.util.HashMap) Instant(java.time.Instant) EntityModel(org.opensearch.ad.ml.EntityModel) ArrayList(java.util.ArrayList) AcknowledgedResponse(org.opensearch.action.support.master.AcknowledgedResponse) AnomalyDetector(org.opensearch.ad.model.AnomalyDetector) ThresholdingResult(org.opensearch.ad.ml.ThresholdingResult) AnomalyResult(org.opensearch.ad.model.AnomalyResult) ArrayList(java.util.ArrayList) List(java.util.List) ParameterizedMessage(org.apache.logging.log4j.message.ParameterizedMessage) ResultWriteRequest(org.opensearch.ad.ratelimit.ResultWriteRequest)

Example 2 with EntityFeatureRequest

use of org.opensearch.ad.ratelimit.EntityFeatureRequest in project anomaly-detection by opensearch-project.

the class MultiEntityResultTests method testCacheSelectionError.

public void testCacheSelectionError() throws IOException, InterruptedException {
    CountDownLatch inProgress = setUpSearchResponse();
    setUpTransportInterceptor(this::entityResultHandler);
    setUpEntityResult(1);
    when(hashRing.getOwningNodeWithSameLocalAdVersionForRealtimeAD(any(String.class))).thenReturn(Optional.of(testNodes[1].discoveryNode()));
    List<Entity> hotEntities = new ArrayList<>();
    Map<String, Object> attrs4 = new HashMap<>();
    attrs4.put(serviceField, app0);
    attrs4.put(hostField, "server_4");
    Entity entity4 = Entity.createEntityByReordering(attrs4);
    hotEntities.add(entity4);
    List<Entity> coldEntities = new ArrayList<>();
    Map<String, Object> attrs5 = new HashMap<>();
    attrs5.put(serviceField, app0);
    attrs5.put(hostField, "server_5");
    Entity entity5 = Entity.createEntityByReordering(attrs5);
    coldEntities.add(entity5);
    when(entityCache.selectUpdateCandidate(any(), any(), any())).thenReturn(Pair.of(hotEntities, coldEntities));
    PlainActionFuture<AnomalyResultResponse> listener = new PlainActionFuture<>();
    action.doExecute(null, request, listener);
    assertTrue(inProgress.await(10000L, TimeUnit.MILLISECONDS));
    // size 0 because cacheMissEntities has no record of these entities
    verify(checkpointReadQueue).putAll(argThat(new ArgumentMatcher<List<EntityFeatureRequest>>() {

        @Override
        public boolean matches(List<EntityFeatureRequest> argument) {
            List<EntityFeatureRequest> arg = (argument);
            LOG.info("size: " + arg.size());
            return arg.size() == 0;
        }
    }));
    verify(coldEntityQueue).putAll(argThat(new ArgumentMatcher<List<EntityFeatureRequest>>() {

        @Override
        public boolean matches(List<EntityFeatureRequest> argument) {
            List<EntityFeatureRequest> arg = (argument);
            LOG.info("size: " + arg.size());
            return arg.size() == 0;
        }
    }));
}
Also used : Entity(org.opensearch.ad.model.Entity) EntityFeatureRequest(org.opensearch.ad.ratelimit.EntityFeatureRequest) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) Matchers.containsString(org.hamcrest.Matchers.containsString) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) CountDownLatch(java.util.concurrent.CountDownLatch) PlainActionFuture(org.opensearch.action.support.PlainActionFuture) ArgumentMatcher(org.mockito.ArgumentMatcher) ArrayList(java.util.ArrayList) List(java.util.List) ImmutableList(com.google.common.collect.ImmutableList)

Example 3 with EntityFeatureRequest

use of org.opensearch.ad.ratelimit.EntityFeatureRequest in project anomaly-detection by opensearch-project.

the class MultiEntityResultTests method testCacheSelection.

public void testCacheSelection() throws IOException, InterruptedException {
    CountDownLatch inProgress = setUpSearchResponse();
    setUpTransportInterceptor(this::entityResultHandler);
    when(hashRing.getOwningNodeWithSameLocalAdVersionForRealtimeAD(any(String.class))).thenReturn(Optional.of(testNodes[1].discoveryNode()));
    List<Entity> hotEntities = new ArrayList<>();
    Entity entity1 = Entity.createEntityByReordering(attrs1);
    hotEntities.add(entity1);
    List<Entity> coldEntities = new ArrayList<>();
    Entity entity2 = Entity.createEntityByReordering(attrs2);
    coldEntities.add(entity2);
    provider = mock(CacheProvider.class);
    entityCache = mock(EntityCache.class);
    when(provider.get()).thenReturn(entityCache);
    when(entityCache.selectUpdateCandidate(any(), any(), any())).thenReturn(Pair.of(hotEntities, coldEntities));
    when(entityCache.get(any(), any())).thenReturn(null);
    new EntityResultTransportAction(new ActionFilters(Collections.emptySet()), // since we send requests to testNodes[1]
    testNodes[1].transportService, normalModelManager, adCircuitBreakerService, provider, stateManager, indexUtil, resultWriteQueue, checkpointReadQueue, coldEntityQueue, threadPool);
    PlainActionFuture<AnomalyResultResponse> listener = new PlainActionFuture<>();
    action.doExecute(null, request, listener);
    assertTrue(inProgress.await(10000L, TimeUnit.MILLISECONDS));
    verify(checkpointReadQueue).putAll(argThat(new ArgumentMatcher<List<EntityFeatureRequest>>() {

        @Override
        public boolean matches(List<EntityFeatureRequest> argument) {
            List<EntityFeatureRequest> arg = (argument);
            LOG.info("size: " + arg.size() + " ; element: " + arg.get(0));
            return arg.size() == 1 && arg.get(0).getEntity().equals(entity1);
        }
    }));
    verify(coldEntityQueue).putAll(argThat(new ArgumentMatcher<List<EntityFeatureRequest>>() {

        @Override
        public boolean matches(List<EntityFeatureRequest> argument) {
            List<EntityFeatureRequest> arg = (argument);
            LOG.info("size: " + arg.size() + " ; element: " + arg.get(0));
            return arg.size() == 1 && arg.get(0).getEntity().equals(entity2);
        }
    }));
}
Also used : Entity(org.opensearch.ad.model.Entity) EntityCache(org.opensearch.ad.caching.EntityCache) EntityFeatureRequest(org.opensearch.ad.ratelimit.EntityFeatureRequest) ArrayList(java.util.ArrayList) Matchers.containsString(org.hamcrest.Matchers.containsString) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) ActionFilters(org.opensearch.action.support.ActionFilters) CountDownLatch(java.util.concurrent.CountDownLatch) CacheProvider(org.opensearch.ad.caching.CacheProvider) PlainActionFuture(org.opensearch.action.support.PlainActionFuture) ArgumentMatcher(org.mockito.ArgumentMatcher) ArrayList(java.util.ArrayList) List(java.util.List) ImmutableList(com.google.common.collect.ImmutableList)

Aggregations

ArrayList (java.util.ArrayList)3 List (java.util.List)3 Entity (org.opensearch.ad.model.Entity)3 EntityFeatureRequest (org.opensearch.ad.ratelimit.EntityFeatureRequest)3 ImmutableList (com.google.common.collect.ImmutableList)2 HashMap (java.util.HashMap)2 CountDownLatch (java.util.concurrent.CountDownLatch)2 Matchers.containsString (org.hamcrest.Matchers.containsString)2 ArgumentMatcher (org.mockito.ArgumentMatcher)2 ArgumentMatchers.anyString (org.mockito.ArgumentMatchers.anyString)2 PlainActionFuture (org.opensearch.action.support.PlainActionFuture)2 Instant (java.time.Instant)1 ParameterizedMessage (org.apache.logging.log4j.message.ParameterizedMessage)1 ActionFilters (org.opensearch.action.support.ActionFilters)1 AcknowledgedResponse (org.opensearch.action.support.master.AcknowledgedResponse)1 CacheProvider (org.opensearch.ad.caching.CacheProvider)1 EntityCache (org.opensearch.ad.caching.EntityCache)1 EndRunException (org.opensearch.ad.common.exception.EndRunException)1 EntityModel (org.opensearch.ad.ml.EntityModel)1 ThresholdingResult (org.opensearch.ad.ml.ThresholdingResult)1