use of org.opensearch.transport.TransportService in project anomaly-detection by opensearch-project.
the class ADTaskManager method cleanDetectorCache.
/**
* Clean detector cache on coordinating node.
* If task's coordinating node is still in cluster, will forward stop
* task request to coordinating node, then coordinating node will
* remove detector from cache.
* If task's coordinating node is not in cluster, we don't need to
* forward stop task request to coordinating node.
* [Important!] Make sure listener returns in function
*
* @param adTask AD task
* @param transportService transport service
* @param function will execute it when detector cache cleaned successfully or coordinating node left cluster
* @param listener action listener
* @param <T> response type of listener
*/
public <T> void cleanDetectorCache(ADTask adTask, TransportService transportService, AnomalyDetectorFunction function, ActionListener<T> listener) {
String coordinatingNode = adTask.getCoordinatingNode();
String detectorId = adTask.getDetectorId();
String taskId = adTask.getTaskId();
try {
forwardADTaskToCoordinatingNode(adTask, ADTaskAction.CLEAN_CACHE, transportService, ActionListener.wrap(r -> {
function.execute();
}, e -> {
logger.error("Failed to clear detector cache on coordinating node " + coordinatingNode, e);
listener.onFailure(e);
}));
} catch (ResourceNotFoundException e) {
logger.warn("Task coordinating node left cluster, taskId: {}, detectorId: {}, coordinatingNode: {}", taskId, detectorId, coordinatingNode);
function.execute();
} catch (Exception e) {
logger.error("Failed to forward clean cache event for detector " + detectorId + ", task " + taskId, e);
listener.onFailure(e);
}
}
use of org.opensearch.transport.TransportService in project anomaly-detection by opensearch-project.
the class ADTaskManager method stopLatestRealtimeTask.
/**
* Update latest realtime task.
*
* @param detectorId detector id
* @param state task state
* @param error error
* @param transportService transport service
* @param listener action listener
*/
public void stopLatestRealtimeTask(String detectorId, ADTaskState state, Exception error, TransportService transportService, ActionListener<AnomalyDetectorJobResponse> listener) {
getAndExecuteOnLatestDetectorLevelTask(detectorId, REALTIME_TASK_TYPES, (adTask) -> {
if (adTask.isPresent() && !adTask.get().isDone()) {
Map<String, Object> updatedFields = new HashMap<>();
updatedFields.put(ADTask.STATE_FIELD, state.name());
if (error != null) {
updatedFields.put(ADTask.ERROR_FIELD, error.getMessage());
}
AnomalyDetectorFunction function = () -> updateADTask(adTask.get().getTaskId(), updatedFields, ActionListener.wrap(r -> {
if (error == null) {
listener.onResponse(new AnomalyDetectorJobResponse(detectorId, 0, 0, 0, RestStatus.OK));
} else {
listener.onFailure(error);
}
}, e -> {
listener.onFailure(e);
}));
String coordinatingNode = adTask.get().getCoordinatingNode();
if (coordinatingNode != null && transportService != null) {
cleanDetectorCache(adTask.get(), transportService, function, listener);
} else {
function.execute();
}
} else {
listener.onFailure(new OpenSearchStatusException("Anomaly detector job is already stopped: " + detectorId, RestStatus.OK));
}
}, null, false, listener);
}
use of org.opensearch.transport.TransportService in project anomaly-detection by opensearch-project.
the class IndexAnomalyDetectorJobActionHandler method stopAnomalyDetectorJob.
/**
* Stop anomaly detector job.
* 1.If job not exists, return error message
* 2.If job exists: a).if job state is disabled, return error message; b).if job state is enabled, disable job.
*
* @param detectorId detector identifier
*/
public void stopAnomalyDetectorJob(String detectorId) {
GetRequest getRequest = new GetRequest(AnomalyDetectorJob.ANOMALY_DETECTOR_JOB_INDEX).id(detectorId);
client.get(getRequest, ActionListener.wrap(response -> {
if (response.isExists()) {
try (XContentParser parser = createXContentParserFromRegistry(xContentRegistry, response.getSourceAsBytesRef())) {
ensureExpectedToken(XContentParser.Token.START_OBJECT, parser.nextToken(), parser);
AnomalyDetectorJob job = AnomalyDetectorJob.parse(parser);
if (!job.isEnabled()) {
adTaskManager.stopLatestRealtimeTask(detectorId, ADTaskState.STOPPED, null, transportService, listener);
} else {
AnomalyDetectorJob newJob = new AnomalyDetectorJob(job.getName(), job.getSchedule(), job.getWindowDelay(), false, job.getEnabledTime(), Instant.now(), Instant.now(), job.getLockDurationSeconds(), job.getUser(), job.getResultIndex());
indexAnomalyDetectorJob(newJob, () -> client.execute(StopDetectorAction.INSTANCE, new StopDetectorRequest(detectorId), stopAdDetectorListener(detectorId)));
}
} catch (IOException e) {
String message = "Failed to parse anomaly detector job " + detectorId;
logger.error(message, e);
listener.onFailure(new OpenSearchStatusException(message, RestStatus.INTERNAL_SERVER_ERROR));
}
} else {
listener.onFailure(new OpenSearchStatusException("Anomaly detector job not exist: " + detectorId, RestStatus.BAD_REQUEST));
}
}, exception -> listener.onFailure(exception)));
}
use of org.opensearch.transport.TransportService in project anomaly-detection by opensearch-project.
the class MultiEntityResultTests method setUpTransportInterceptor.
private <T extends TransportResponse> void setUpTransportInterceptor(Function<TransportResponseHandler<T>, TransportResponseHandler<T>> interceptor) {
entityResultInterceptor = new TransportInterceptor() {
@Override
public AsyncSender interceptSender(AsyncSender sender) {
return new AsyncSender() {
@SuppressWarnings("unchecked")
@Override
public <T2 extends TransportResponse> void sendRequest(Transport.Connection connection, String action, TransportRequest request, TransportRequestOptions options, TransportResponseHandler<T2> handler) {
if (action.equals(EntityResultAction.NAME)) {
sender.sendRequest(connection, action, request, options, interceptor.apply((TransportResponseHandler<T>) handler));
} else {
sender.sendRequest(connection, action, request, options, handler);
}
}
};
}
};
// we start support multi-category fields since 1.1
// Set version to 1.1 will force the outbound/inbound message to use 1.1 version
setupTestNodes(entityResultInterceptor, 5, settings, BwcTests.V_1_1_0, MAX_ENTITIES_PER_QUERY, PAGE_SIZE);
TransportService realTransportService = testNodes[0].transportService;
ClusterService realClusterService = testNodes[0].clusterService;
action = new AnomalyResultTransportAction(new ActionFilters(Collections.emptySet()), realTransportService, settings, client, stateManager, featureQuery, normalModelManager, hashRing, realClusterService, indexNameResolver, adCircuitBreakerService, adStats, threadPool, xContentRegistry(), adTaskManager);
}
use of org.opensearch.transport.TransportService in project anomaly-detection by opensearch-project.
the class AnomalyResultTests method nodeNotConnectedExceptionTemplate.
/**
* Test whether we can handle NodeNotConnectedException when sending requests to
* remote nodes.
*
* @param isRCF whether RCF model node throws node connection
* exception or not
* @param temporary whether node has only temporary connection issue. If
* yes, we should not trigger hash ring rebuilding.
* @param numberOfBuildCall the number of expected hash ring build call
*/
private void nodeNotConnectedExceptionTemplate(boolean isRCF, boolean temporary, int numberOfBuildCall) {
ClusterService hackedClusterService = spy(clusterService);
TransportService exceptionTransportService = spy(transportService);
DiscoveryNode rcfNode = clusterService.state().nodes().getLocalNode();
DiscoveryNode thresholdNode = testNodes[1].discoveryNode();
if (isRCF) {
doThrow(new NodeNotConnectedException(rcfNode, "rcf node not connected")).when(exceptionTransportService).getConnection(same(rcfNode));
} else {
when(hashRing.getOwningNodeWithSameLocalAdVersionForRealtimeAD(eq(thresholdModelID))).thenReturn(Optional.of(thresholdNode));
when(hashRing.getNodeByAddress(any())).thenReturn(Optional.of(thresholdNode));
doThrow(new NodeNotConnectedException(rcfNode, "rcf node not connected")).when(exceptionTransportService).getConnection(same(thresholdNode));
}
if (!temporary) {
when(hackedClusterService.state()).thenReturn(ClusterState.builder(new ClusterName("test")).build());
}
// These constructors register handler in transport service
new RCFResultTransportAction(new ActionFilters(Collections.emptySet()), exceptionTransportService, normalModelManager, adCircuitBreakerService, hashRing);
AnomalyResultTransportAction action = new AnomalyResultTransportAction(new ActionFilters(Collections.emptySet()), exceptionTransportService, settings, client, stateManager, featureQuery, normalModelManager, hashRing, hackedClusterService, indexNameResolver, adCircuitBreakerService, adStats, threadPool, NamedXContentRegistry.EMPTY, adTaskManager);
AnomalyResultRequest request = new AnomalyResultRequest(adID, 100, 200);
PlainActionFuture<AnomalyResultResponse> listener = new PlainActionFuture<>();
action.doExecute(null, request, listener);
assertException(listener, AnomalyDetectionException.class);
if (!temporary) {
verify(hashRing, times(numberOfBuildCall)).buildCirclesForRealtimeAD();
verify(stateManager, never()).addPressure(any(String.class), any(String.class));
} else {
verify(hashRing, never()).buildCirclesForRealtimeAD();
verify(stateManager, times(numberOfBuildCall)).addPressure(any(String.class), any(String.class));
}
}
Aggregations