Search in sources :

Example 11 with Entity

use of org.opensearch.ad.model.Entity in project anomaly-detection by opensearch-project.

the class ADTaskManagerTests method testParseEntityForMultiCategoryHC.

public void testParseEntityForMultiCategoryHC() throws IOException {
    ADTask adTask = randomAdTask(randomAlphaOfLength(5), ADTaskState.INIT, Instant.now(), randomAlphaOfLength(5), TestHelpers.randomAnomalyDetectorUsingCategoryFields(randomAlphaOfLength(5), ImmutableList.of(randomAlphaOfLength(5), randomAlphaOfLength(5))));
    String entityValue = adTaskManager.convertEntityToString(adTask);
    Entity entity = adTaskManager.parseEntityFromString(entityValue, adTask);
    assertEquals(entity, adTask.getEntity());
}
Also used : Entity.createSingleAttributeEntity(org.opensearch.ad.model.Entity.createSingleAttributeEntity) Entity(org.opensearch.ad.model.Entity) ADTask(org.opensearch.ad.model.ADTask) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString)

Example 12 with Entity

use of org.opensearch.ad.model.Entity in project anomaly-detection by opensearch-project.

the class ADTaskManagerTests method testParseEntityForSingleCategoryHC.

public void testParseEntityForSingleCategoryHC() throws IOException {
    ADTask adTask = randomAdTask(randomAlphaOfLength(5), ADTaskState.INIT, Instant.now(), randomAlphaOfLength(5), TestHelpers.randomAnomalyDetectorUsingCategoryFields(randomAlphaOfLength(5), ImmutableList.of(randomAlphaOfLength(5))));
    String entityValue = adTaskManager.convertEntityToString(adTask);
    Entity entity = adTaskManager.parseEntityFromString(entityValue, adTask);
    assertEquals(entity, adTask.getEntity());
}
Also used : Entity.createSingleAttributeEntity(org.opensearch.ad.model.Entity.createSingleAttributeEntity) Entity(org.opensearch.ad.model.Entity) ADTask(org.opensearch.ad.model.ADTask) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString)

Example 13 with Entity

use of org.opensearch.ad.model.Entity in project anomaly-detection by opensearch-project.

the class ADStatsTests method testADStatsNodeResponseWithEntity.

/**
 * Test we can serialize stats with entity
 * @throws IOException when writeTo and toXContent have errors.
 * @throws JsonPathNotFoundException when json deserialization cannot find a path
 */
@Test
public void testADStatsNodeResponseWithEntity() throws IOException, JsonPathNotFoundException {
    TreeMap<String, String> attributes = new TreeMap<>();
    String name1 = "a";
    String name2 = "b";
    String val1 = "a1";
    String val2 = "a2";
    attributes.put(name1, val1);
    attributes.put(name2, val2);
    String detectorId = "detectorId";
    Entity entity = Entity.createEntityFromOrderedMap(attributes);
    EntityModel entityModel = new EntityModel(entity, null, null);
    Clock clock = mock(Clock.class);
    when(clock.instant()).thenReturn(Instant.now());
    ModelState<EntityModel> state = new ModelState<EntityModel>(entityModel, entity.getModelId(detectorId).get(), detectorId, "entity", clock, 0.1f);
    Map<String, Object> stats = state.getModelStateAsMap();
    // Test serialization
    ADStatsNodeResponse adStatsNodeResponse = new ADStatsNodeResponse(discoveryNode1, stats);
    BytesStreamOutput output = new BytesStreamOutput();
    adStatsNodeResponse.writeTo(output);
    StreamInput streamInput = output.bytes().streamInput();
    ADStatsNodeResponse readResponse = ADStatsNodeResponse.readStats(streamInput);
    assertEquals("readStats failed", readResponse.getStatsMap(), adStatsNodeResponse.getStatsMap());
    // Test toXContent
    XContentBuilder builder = jsonBuilder();
    adStatsNodeResponse.toXContent(builder.startObject(), ToXContent.EMPTY_PARAMS).endObject();
    String json = Strings.toString(builder);
    for (Map.Entry<String, Object> stat : stats.entrySet()) {
        if (stat.getKey().equals(ModelState.LAST_CHECKPOINT_TIME_KEY) || stat.getKey().equals(ModelState.LAST_USED_TIME_KEY)) {
            assertEquals("toXContent does not work", JsonDeserializer.getLongValue(json, stat.getKey()), stat.getValue());
        } else if (stat.getKey().equals(CommonName.ENTITY_KEY)) {
            JsonArray array = JsonDeserializer.getArrayValue(json, stat.getKey());
            assertEquals(2, array.size());
            for (int i = 0; i < 2; i++) {
                JsonElement element = array.get(i);
                String entityName = JsonDeserializer.getChildNode(element, Entity.ATTRIBUTE_NAME_FIELD).getAsString();
                String entityValue = JsonDeserializer.getChildNode(element, Entity.ATTRIBUTE_VALUE_FIELD).getAsString();
                assertTrue(entityName.equals(name1) || entityName.equals(name2));
                if (entityName.equals(name1)) {
                    assertEquals(val1, entityValue);
                } else {
                    assertEquals(val2, entityValue);
                }
            }
        } else {
            assertEquals("toXContent does not work", JsonDeserializer.getTextValue(json, stat.getKey()), stat.getValue());
        }
    }
}
Also used : Entity(org.opensearch.ad.model.Entity) EntityModel(org.opensearch.ad.ml.EntityModel) ModelState(org.opensearch.ad.ml.ModelState) TreeMap(java.util.TreeMap) Clock(java.time.Clock) BytesStreamOutput(org.opensearch.common.io.stream.BytesStreamOutput) JsonArray(com.google.gson.JsonArray) JsonElement(com.google.gson.JsonElement) StreamInput(org.opensearch.common.io.stream.StreamInput) HashMap(java.util.HashMap) Map(java.util.Map) Collections.emptyMap(java.util.Collections.emptyMap) TreeMap(java.util.TreeMap) XContentBuilder(org.opensearch.common.xcontent.XContentBuilder) Test(org.junit.Test)

Example 14 with Entity

use of org.opensearch.ad.model.Entity in project anomaly-detection by opensearch-project.

the class EntityProfileTransportAction method doExecute.

@Override
protected void doExecute(Task task, EntityProfileRequest request, ActionListener<EntityProfileResponse> listener) {
    String adID = request.getAdID();
    Entity entityValue = request.getEntityValue();
    Optional<String> modelIdOptional = entityValue.getModelId(adID);
    if (false == modelIdOptional.isPresent()) {
        listener.onFailure(new AnomalyDetectionException(adID, NO_MODEL_ID_FOUND_MSG));
        return;
    }
    // we use entity's toString (e.g., app_0) to find its node
    // This should be consistent with how we land a model node in AnomalyResultTransportAction
    Optional<DiscoveryNode> node = hashRing.getOwningNodeWithSameLocalAdVersionForRealtimeAD(entityValue.toString());
    if (false == node.isPresent()) {
        listener.onFailure(new AnomalyDetectionException(adID, NO_NODE_FOUND_MSG));
        return;
    }
    String nodeId = node.get().getId();
    String modelId = modelIdOptional.get();
    DiscoveryNode localNode = clusterService.localNode();
    if (localNode.getId().equals(nodeId)) {
        EntityCache cache = cacheProvider.get();
        Set<EntityProfileName> profilesToCollect = request.getProfilesToCollect();
        EntityProfileResponse.Builder builder = new EntityProfileResponse.Builder();
        if (profilesToCollect.contains(EntityProfileName.ENTITY_INFO)) {
            builder.setActive(cache.isActive(adID, modelId));
            builder.setLastActiveMs(cache.getLastActiveMs(adID, modelId));
        }
        if (profilesToCollect.contains(EntityProfileName.INIT_PROGRESS) || profilesToCollect.contains(EntityProfileName.STATE)) {
            builder.setTotalUpdates(cache.getTotalUpdates(adID, modelId));
        }
        if (profilesToCollect.contains(EntityProfileName.MODELS)) {
            Optional<ModelProfile> modleProfile = cache.getModelProfile(adID, modelId);
            if (modleProfile.isPresent()) {
                builder.setModelProfile(new ModelProfileOnNode(nodeId, modleProfile.get()));
            }
        }
        listener.onResponse(builder.build());
    } else if (request.remoteAddress() == null) {
        // redirect if request comes from local host.
        // If a request comes from remote machine, it is already redirected.
        // One redirection should be enough.
        // We don't want a potential infinite loop due to any bug and thus give up.
        LOG.info("Sending entity profile request to {} for detector {}, entity {}", nodeId, adID, entityValue);
        try {
            transportService.sendRequest(node.get(), EntityProfileAction.NAME, request, option, new TransportResponseHandler<EntityProfileResponse>() {

                @Override
                public EntityProfileResponse read(StreamInput in) throws IOException {
                    return new EntityProfileResponse(in);
                }

                @Override
                public void handleResponse(EntityProfileResponse response) {
                    listener.onResponse(response);
                }

                @Override
                public void handleException(TransportException exp) {
                    listener.onFailure(exp);
                }

                @Override
                public String executor() {
                    return ThreadPool.Names.SAME;
                }
            });
        } catch (Exception e) {
            LOG.error(String.format(Locale.ROOT, "Fail to get entity profile for detector {}, entity {}", adID, entityValue), e);
            listener.onFailure(new AnomalyDetectionException(adID, FAIL_TO_GET_ENTITY_PROFILE_MSG, e));
        }
    } else {
        // Prior to Opensearch 1.1, we map a node using model id in the profile API.
        // This is not consistent how we map node in AnomalyResultTransportAction, where
        // we use entity values. We fixed that bug in Opensearch 1.1. But this can cause
        // issue when a request involving an old node according to model id.
        // The new node finds the entity value does not map to itself, so it redirects to another node.
        // The redirection can cause an infinite loop. This branch breaks the loop and gives up.
        LOG.error("Fail to get entity profile for detector {}, entity {}. Maybe because old and new node" + " are using different keys for the hash ring.", adID, entityValue);
        listener.onFailure(new AnomalyDetectionException(adID, FAIL_TO_GET_ENTITY_PROFILE_MSG));
    }
}
Also used : AnomalyDetectionException(org.opensearch.ad.common.exception.AnomalyDetectionException) Entity(org.opensearch.ad.model.Entity) DiscoveryNode(org.opensearch.cluster.node.DiscoveryNode) EntityCache(org.opensearch.ad.caching.EntityCache) ModelProfileOnNode(org.opensearch.ad.model.ModelProfileOnNode) TransportResponseHandler(org.opensearch.transport.TransportResponseHandler) TransportException(org.opensearch.transport.TransportException) ModelProfile(org.opensearch.ad.model.ModelProfile) AnomalyDetectionException(org.opensearch.ad.common.exception.AnomalyDetectionException) IOException(java.io.IOException) TransportException(org.opensearch.transport.TransportException) StreamInput(org.opensearch.common.io.stream.StreamInput) EntityProfileName(org.opensearch.ad.model.EntityProfileName)

Example 15 with Entity

use of org.opensearch.ad.model.Entity in project anomaly-detection by opensearch-project.

the class FeatureManagerTests method getPreviewEntities.

@Test
public void getPreviewEntities() {
    long start = 0L;
    long end = 240_000L;
    Entity entity1 = Entity.createSingleAttributeEntity("fieldName", "value1");
    Entity entity2 = Entity.createSingleAttributeEntity("fieldName", "value2");
    List<Entity> entities = asList(entity1, entity2);
    doAnswer(invocation -> {
        ActionListener<List<Entity>> listener = invocation.getArgument(3);
        listener.onResponse(entities);
        return null;
    }).when(searchFeatureDao).getHighestCountEntities(any(), anyLong(), anyLong(), any());
    ActionListener<List<Entity>> listener = mock(ActionListener.class);
    featureManager.getPreviewEntities(detector, start, end, listener);
    verify(listener).onResponse(entities);
}
Also used : Entity(org.opensearch.ad.model.Entity) Arrays.asList(java.util.Arrays.asList) List(java.util.List) ArrayList(java.util.ArrayList) Test(org.junit.Test)

Aggregations

Entity (org.opensearch.ad.model.Entity)66 ActionListener (org.opensearch.action.ActionListener)37 ArrayList (java.util.ArrayList)36 List (java.util.List)35 AnomalyDetector (org.opensearch.ad.model.AnomalyDetector)34 Client (org.opensearch.client.Client)31 Optional (java.util.Optional)30 SearchRequest (org.opensearch.action.search.SearchRequest)30 HashMap (java.util.HashMap)29 Map (java.util.Map)28 IOException (java.io.IOException)26 LogManager (org.apache.logging.log4j.LogManager)26 Logger (org.apache.logging.log4j.Logger)26 SearchResponse (org.opensearch.action.search.SearchResponse)25 Settings (org.opensearch.common.settings.Settings)23 Set (java.util.Set)22 GetRequest (org.opensearch.action.get.GetRequest)22 ANOMALY_DETECTORS_INDEX (org.opensearch.ad.model.AnomalyDetector.ANOMALY_DETECTORS_INDEX)22 AnomalyDetectorJob (org.opensearch.ad.model.AnomalyDetectorJob)22 AnomalyDetectionException (org.opensearch.ad.common.exception.AnomalyDetectionException)21