use of org.opensearch.ad.model.ADTaskType in project anomaly-detection by opensearch-project.
the class ADTaskManager method getAndExecuteOnLatestADTasks.
/**
* Get latest AD tasks and execute consumer function.
* If resetTaskState is true, will collect latest task's profile data from all data nodes. If no data
* node running the latest task, will reset the task state as STOPPED; otherwise, check if there is
* any stale running entities(entity exists in coordinating node cache but no task running on worker
* node) and clean up.
* [Important!] Make sure listener returns in function
*
* @param detectorId detector id
* @param parentTaskId parent task id
* @param entity entity value
* @param adTaskTypes AD task types
* @param function consumer function
* @param transportService transport service
* @param resetTaskState reset task state or not
* @param size return how many AD tasks
* @param listener action listener
* @param <T> response type of action listener
*/
public <T> void getAndExecuteOnLatestADTasks(String detectorId, String parentTaskId, Entity entity, List<ADTaskType> adTaskTypes, Consumer<List<ADTask>> function, TransportService transportService, boolean resetTaskState, int size, ActionListener<T> listener) {
BoolQueryBuilder query = new BoolQueryBuilder();
query.filter(new TermQueryBuilder(DETECTOR_ID_FIELD, detectorId));
query.filter(new TermQueryBuilder(IS_LATEST_FIELD, true));
if (parentTaskId != null) {
query.filter(new TermQueryBuilder(PARENT_TASK_ID_FIELD, parentTaskId));
}
if (adTaskTypes != null && adTaskTypes.size() > 0) {
query.filter(new TermsQueryBuilder(TASK_TYPE_FIELD, taskTypeToString(adTaskTypes)));
}
if (entity != null && !isNullOrEmpty(entity.getAttributes())) {
String path = "entity";
String entityKeyFieldName = path + ".name";
String entityValueFieldName = path + ".value";
for (Map.Entry<String, String> attribute : entity.getAttributes().entrySet()) {
BoolQueryBuilder entityBoolQuery = new BoolQueryBuilder();
TermQueryBuilder entityKeyFilterQuery = QueryBuilders.termQuery(entityKeyFieldName, attribute.getKey());
TermQueryBuilder entityValueFilterQuery = QueryBuilders.termQuery(entityValueFieldName, attribute.getValue());
entityBoolQuery.filter(entityKeyFilterQuery).filter(entityValueFilterQuery);
NestedQueryBuilder nestedQueryBuilder = new NestedQueryBuilder(path, entityBoolQuery, ScoreMode.None);
query.filter(nestedQueryBuilder);
}
}
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(query).sort(EXECUTION_START_TIME_FIELD, SortOrder.DESC).size(size);
SearchRequest searchRequest = new SearchRequest();
searchRequest.source(sourceBuilder);
searchRequest.indices(DETECTION_STATE_INDEX);
client.search(searchRequest, ActionListener.wrap(r -> {
// https://github.com/opendistro-for-elasticsearch/anomaly-detection/pull/359#discussion_r558653132
// getTotalHits will be null when we track_total_hits is false in the query request.
// Add more checking here to cover some unknown cases.
List<ADTask> adTasks = new ArrayList<>();
if (r == null || r.getHits().getTotalHits() == null || r.getHits().getTotalHits().value == 0) {
// don't throw exception here as consumer functions need to handle missing task
// in different way.
function.accept(adTasks);
return;
}
Iterator<SearchHit> iterator = r.getHits().iterator();
while (iterator.hasNext()) {
SearchHit searchHit = iterator.next();
try (XContentParser parser = createXContentParserFromRegistry(xContentRegistry, searchHit.getSourceRef())) {
ensureExpectedToken(XContentParser.Token.START_OBJECT, parser.nextToken(), parser);
ADTask adTask = ADTask.parse(parser, searchHit.getId());
adTasks.add(adTask);
} catch (Exception e) {
String message = "Failed to parse AD task for detector " + detectorId + ", task id " + searchHit.getId();
logger.error(message, e);
listener.onFailure(new OpenSearchStatusException(message, RestStatus.INTERNAL_SERVER_ERROR));
}
}
if (resetTaskState) {
resetLatestDetectorTaskState(adTasks, function, transportService, listener);
} else {
function.accept(adTasks);
}
}, e -> {
if (e instanceof IndexNotFoundException) {
function.accept(new ArrayList<>());
} else {
logger.error("Failed to search AD task for detector " + detectorId, e);
listener.onFailure(e);
}
}));
}
use of org.opensearch.ad.model.ADTaskType in project anomaly-detection by opensearch-project.
the class ADDataMigrator method createRealtimeADTask.
private void createRealtimeADTask(AnomalyDetectorJob job, String error, ConcurrentLinkedQueue<AnomalyDetectorJob> detectorJobs, boolean migrateAll) {
client.get(new GetRequest(ANOMALY_DETECTORS_INDEX, job.getName()), ActionListener.wrap(r -> {
if (r != null && r.isExists()) {
try (XContentParser parser = createXContentParserFromRegistry(xContentRegistry, r.getSourceAsBytesRef())) {
ensureExpectedToken(XContentParser.Token.START_OBJECT, parser.nextToken(), parser);
AnomalyDetector detector = AnomalyDetector.parse(parser, r.getId());
ADTaskType taskType = detector.isMultientityDetector() ? ADTaskType.REALTIME_HC_DETECTOR : ADTaskType.REALTIME_SINGLE_ENTITY;
Instant now = Instant.now();
String userName = job.getUser() != null ? job.getUser().getName() : null;
ADTask adTask = new ADTask.Builder().detectorId(detector.getDetectorId()).detector(detector).error(error).isLatest(true).taskType(taskType.name()).executionStartTime(now).taskProgress(0.0f).initProgress(0.0f).state(ADTaskState.CREATED.name()).lastUpdateTime(now).startedBy(userName).coordinatingNode(null).detectionDateRange(null).user(job.getUser()).build();
IndexRequest indexRequest = new IndexRequest(DETECTION_STATE_INDEX).setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE).source(adTask.toXContent(XContentFactory.jsonBuilder(), XCONTENT_WITH_TYPE));
client.index(indexRequest, ActionListener.wrap(indexResponse -> {
logger.info("Backfill realtime task successfully for detector {}", job.getName());
backfillRealtimeTask(detectorJobs, migrateAll);
}, ex -> {
logger.error("Failed to backfill realtime task for detector " + job.getName(), ex);
backfillRealtimeTask(detectorJobs, migrateAll);
}));
} catch (IOException e) {
logger.error("Fail to parse detector " + job.getName(), e);
backfillRealtimeTask(detectorJobs, migrateAll);
}
} else {
logger.error("Detector doesn't exist " + job.getName());
backfillRealtimeTask(detectorJobs, migrateAll);
}
}, e -> {
logger.error("Fail to get detector " + job.getName(), e);
backfillRealtimeTask(detectorJobs, migrateAll);
}));
}
Aggregations