use of org.opensearch.ad.model.EntityProfile in project anomaly-detection by opensearch-project.
the class EntityProfileRunner method validateEntity.
/**
* Verify if the input entity exists or not in case of typos.
*
* If a user deletes the entity after job start, then we will not be able to
* get this entity in the index. For this case, we will not return a profile
* for this entity even if it's running on some data node. the entity's model
* will be deleted by another entity or by maintenance due to long inactivity.
*
* @param entity Entity accessor
* @param categoryFields category fields defined for a detector
* @param detectorId Detector Id
* @param profilesToCollect Profile to collect from the input
* @param detector Detector config accessor
* @param listener Callback to send responses.
*/
private void validateEntity(Entity entity, List<String> categoryFields, String detectorId, Set<EntityProfileName> profilesToCollect, AnomalyDetector detector, ActionListener<EntityProfile> listener) {
Map<String, String> attributes = entity.getAttributes();
if (attributes == null || attributes.size() != categoryFields.size()) {
listener.onFailure(new IllegalArgumentException(EMPTY_ENTITY_ATTRIBUTES));
return;
}
for (String field : categoryFields) {
if (false == attributes.containsKey(field)) {
listener.onFailure(new IllegalArgumentException("Cannot find " + field));
return;
}
}
BoolQueryBuilder internalFilterQuery = QueryBuilders.boolQuery().filter(detector.getFilterQuery());
for (TermQueryBuilder term : entity.getTermQueryBuilders()) {
internalFilterQuery.filter(term);
}
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder().query(internalFilterQuery).size(1);
SearchRequest searchRequest = new SearchRequest(detector.getIndices().toArray(new String[0]), searchSourceBuilder).preference(Preference.LOCAL.toString());
client.search(searchRequest, ActionListener.wrap(searchResponse -> {
try {
if (searchResponse.getHits().getHits().length == 0) {
listener.onFailure(new IllegalArgumentException(NO_ENTITY));
return;
}
prepareEntityProfile(listener, detectorId, entity, profilesToCollect, detector, categoryFields.get(0));
} catch (Exception e) {
listener.onFailure(new IllegalArgumentException(NO_ENTITY));
return;
}
}, e -> listener.onFailure(new IllegalArgumentException(NO_ENTITY))));
}
use of org.opensearch.ad.model.EntityProfile in project anomaly-detection by opensearch-project.
the class EntityProfileRunner method prepareEntityProfile.
private void prepareEntityProfile(ActionListener<EntityProfile> listener, String detectorId, Entity entityValue, Set<EntityProfileName> profilesToCollect, AnomalyDetector detector, String categoryField) {
EntityProfileRequest request = new EntityProfileRequest(detectorId, entityValue, profilesToCollect);
client.execute(EntityProfileAction.INSTANCE, request, ActionListener.wrap(r -> getJob(detectorId, entityValue, profilesToCollect, detector, r, listener), listener::onFailure));
}
use of org.opensearch.ad.model.EntityProfile in project anomaly-detection by opensearch-project.
the class EntityProfileRunner method sendRunningState.
private void sendRunningState(Set<EntityProfileName> profilesToCollect, Entity entityValue, MultiResponsesDelegateActionListener<EntityProfile> delegateListener) {
EntityProfile.Builder builder = new EntityProfile.Builder();
if (profilesToCollect.contains(EntityProfileName.STATE)) {
builder.state(EntityState.RUNNING);
}
if (profilesToCollect.contains(EntityProfileName.INIT_PROGRESS)) {
InitProgressProfile initProgress = new InitProgressProfile("100%", 0, 0);
builder.initProgress(initProgress);
}
delegateListener.onResponse(builder.build());
}
use of org.opensearch.ad.model.EntityProfile in project anomaly-detection by opensearch-project.
the class EntityProfileRunnerTests method testJobIndexNotFound.
@SuppressWarnings("unchecked")
public void testJobIndexNotFound() throws InterruptedException {
setUpExecuteEntityProfileAction(InittedEverResultStatus.INITTED);
final CountDownLatch inProgressLatch = new CountDownLatch(1);
doAnswer(invocation -> {
Object[] args = invocation.getArguments();
GetRequest request = (GetRequest) args[0];
ActionListener<GetResponse> listener = (ActionListener<GetResponse>) args[1];
String indexName = request.index();
if (indexName.equals(ANOMALY_DETECTORS_INDEX)) {
listener.onResponse(TestHelpers.createGetResponse(detector, detector.getDetectorId(), AnomalyDetector.ANOMALY_DETECTORS_INDEX));
} else if (indexName.equals(ANOMALY_DETECTOR_JOB_INDEX)) {
listener.onFailure(new IndexNotFoundException(ANOMALY_DETECTOR_JOB_INDEX));
}
return null;
}).when(client).get(any(), any());
EntityProfile expectedProfile = new EntityProfile.Builder().build();
runner.profile(detectorId, entity, initNInfo, ActionListener.wrap(response -> {
assertEquals(expectedProfile, response);
inProgressLatch.countDown();
}, exception -> {
LOG.error("Unexpected error", exception);
assertTrue("Should not reach here", false);
inProgressLatch.countDown();
}));
assertTrue(inProgressLatch.await(100, TimeUnit.SECONDS));
}
use of org.opensearch.ad.model.EntityProfile in project anomaly-detection by opensearch-project.
the class GetAnomalyDetectorTransportActionTests method testGetAnomalyDetectorProfileResponse.
@SuppressWarnings("unchecked")
@Test
public void testGetAnomalyDetectorProfileResponse() throws IOException {
BytesStreamOutput out = new BytesStreamOutput();
AnomalyDetector detector = TestHelpers.randomAnomalyDetector(ImmutableMap.of("testKey", "testValue"), Instant.now());
AnomalyDetectorJob adJob = TestHelpers.randomAnomalyDetectorJob();
InitProgressProfile initProgress = new InitProgressProfile("99%", 2L, 2);
EntityProfile entityProfile = new EntityProfile.Builder().initProgress(initProgress).build();
GetAnomalyDetectorResponse response = new GetAnomalyDetectorResponse(4321, "1234", 5678, 9867, detector, adJob, false, mock(ADTask.class), mock(ADTask.class), false, RestStatus.OK, null, entityProfile, true);
response.writeTo(out);
NamedWriteableAwareStreamInput input = new NamedWriteableAwareStreamInput(out.bytes().streamInput(), writableRegistry());
GetAnomalyDetectorResponse newResponse = new GetAnomalyDetectorResponse(input);
XContentBuilder builder = TestHelpers.builder();
Assert.assertNotNull(newResponse.toXContent(builder, ToXContent.EMPTY_PARAMS));
// {init_progress={percentage=99%, estimated_minutes_left=2, needed_shingles=2}}
Map<String, Object> map = TestHelpers.XContentBuilderToMap(builder);
Map<String, Object> parsedInitProgress = (Map<String, Object>) (map.get(CommonName.INIT_PROGRESS));
Assert.assertEquals(initProgress.getPercentage(), parsedInitProgress.get(InitProgressProfile.PERCENTAGE).toString());
assertTrue(initProgress.toString().contains("[percentage=99%,estimated_minutes_left=2,needed_shingles=2]"));
Assert.assertEquals(String.valueOf(initProgress.getEstimatedMinutesLeft()), parsedInitProgress.get(InitProgressProfile.ESTIMATED_MINUTES_LEFT).toString());
Assert.assertEquals(String.valueOf(initProgress.getNeededDataPoints()), parsedInitProgress.get(InitProgressProfile.NEEDED_SHINGLES).toString());
}
Aggregations