use of org.opensearch.ad.model.ADTaskType.HISTORICAL_DETECTOR_TASK_TYPES in project anomaly-detection by opensearch-project.
the class DeleteAnomalyDetectorTransportAction method doExecute.
@Override
protected void doExecute(Task task, DeleteAnomalyDetectorRequest request, ActionListener<DeleteResponse> actionListener) {
String detectorId = request.getDetectorID();
LOG.info("Delete anomaly detector job {}", detectorId);
User user = getUserContext(client);
ActionListener<DeleteResponse> listener = wrapRestActionListener(actionListener, FAIL_TO_DELETE_DETECTOR);
// By the time request reaches here, the user permissions are validated by Security plugin.
try (ThreadContext.StoredContext context = client.threadPool().getThreadContext().stashContext()) {
resolveUserAndExecute(user, detectorId, filterByEnabled, listener, (anomalyDetector) -> adTaskManager.getDetector(detectorId, detector -> {
if (!detector.isPresent()) {
// In a mixed cluster, if delete detector request routes to node running AD1.0, then it will
// not delete detector tasks. User can re-delete these deleted detector after cluster upgraded,
// in that case, the detector is not present.
LOG.info("Can't find anomaly detector {}", detectorId);
adTaskManager.deleteADTasks(detectorId, () -> deleteAnomalyDetectorJobDoc(detectorId, listener), listener);
return;
}
// Check if there is realtime job or historical analysis task running. If none of these running, we
// can delete the detector.
getDetectorJob(detectorId, listener, () -> {
adTaskManager.getAndExecuteOnLatestDetectorLevelTask(detectorId, HISTORICAL_DETECTOR_TASK_TYPES, adTask -> {
if (adTask.isPresent() && !adTask.get().isDone()) {
listener.onFailure(new OpenSearchStatusException("Detector is running", RestStatus.INTERNAL_SERVER_ERROR));
} else {
adTaskManager.deleteADTasks(detectorId, () -> deleteAnomalyDetectorJobDoc(detectorId, listener), listener);
}
}, transportService, true, listener);
});
}, listener), client, clusterService, xContentRegistry);
} catch (Exception e) {
LOG.error(e);
listener.onFailure(e);
}
}
use of org.opensearch.ad.model.ADTaskType.HISTORICAL_DETECTOR_TASK_TYPES in project anomaly-detection by opensearch-project.
the class ADTaskManager method maintainRunningHistoricalTasks.
// =========================================================
// Methods below are maintenance code triggered by hourly cron
// =========================================================
/**
* Maintain running historical tasks.
* Search current running latest tasks, then maintain tasks one by one.
* Get task profile to check if task is really running on worker node.
* 1. If not running, reset task state as STOPPED.
* 2. If task is running and task for HC detector, check if there is any stale running entities and
* clean up.
*
* @param transportService transport service
* @param size return how many tasks
*/
public void maintainRunningHistoricalTasks(TransportService transportService, int size) {
// Clean expired HC batch task run state cache.
adTaskCacheManager.cleanExpiredHCBatchTaskRunStates();
// Find owning node with highest AD version to make sure we only have 1 node maintain running historical tasks
// and we use the latest logic.
Optional<DiscoveryNode> owningNode = hashRing.getOwningNodeWithHighestAdVersion(AD_TASK_MAINTAINENCE_NODE_MODEL_ID);
if (!owningNode.isPresent() || !clusterService.localNode().getId().equals(owningNode.get().getId())) {
return;
}
logger.info("Start to maintain running historical tasks");
BoolQueryBuilder query = new BoolQueryBuilder();
query.filter(new TermQueryBuilder(IS_LATEST_FIELD, true));
query.filter(new TermsQueryBuilder(TASK_TYPE_FIELD, taskTypeToString(HISTORICAL_DETECTOR_TASK_TYPES)));
query.filter(new TermsQueryBuilder(STATE_FIELD, NOT_ENDED_STATES));
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
// default maintain interval is 5 seconds, so maintain 10 tasks will take at least 50 seconds.
sourceBuilder.query(query).sort(LAST_UPDATE_TIME_FIELD, SortOrder.DESC).size(size);
SearchRequest searchRequest = new SearchRequest();
searchRequest.source(sourceBuilder);
searchRequest.indices(DETECTION_STATE_INDEX);
client.search(searchRequest, ActionListener.wrap(r -> {
if (r == null || r.getHits().getTotalHits() == null || r.getHits().getTotalHits().value == 0) {
return;
}
ConcurrentLinkedQueue<ADTask> taskQueue = new ConcurrentLinkedQueue<>();
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);
taskQueue.add(ADTask.parse(parser, searchHit.getId()));
} catch (Exception e) {
logger.error("Maintaining running historical task: failed to parse AD task " + searchHit.getId(), e);
}
}
maintainRunningHistoricalTask(taskQueue, transportService);
}, e -> {
if (e instanceof IndexNotFoundException) {
// the method will be called hourly
// don't log stack trace as most of OpenSearch domains have no AD installed
logger.debug(STATE_INDEX_NOT_EXIST_MSG);
} else {
logger.error("Failed to search historical tasks in maintaining job", e);
}
}));
}
Aggregations