use of org.opensearch.jobscheduler.spi.LockModel in project anomaly-detection by opensearch-project.
the class AnomalyDetectorJobRunner method runAnomalyDetectionJob.
private void runAnomalyDetectionJob(AnomalyDetectorJob jobParameter, LockService lockService, LockModel lock, Instant detectionStartTime, Instant executionStartTime, String detectorId, String user, List<String> roles) {
try (InjectSecurity injectSecurity = new InjectSecurity(detectorId, settings, client.threadPool().getThreadContext())) {
// Injecting user role to verify if the user has permissions for our API.
injectSecurity.inject(user, roles);
AnomalyResultRequest request = new AnomalyResultRequest(detectorId, detectionStartTime.toEpochMilli(), executionStartTime.toEpochMilli());
client.execute(AnomalyResultAction.INSTANCE, request, ActionListener.wrap(response -> {
indexAnomalyResult(jobParameter, lockService, lock, detectionStartTime, executionStartTime, response);
}, exception -> {
handleAdException(jobParameter, lockService, lock, detectionStartTime, executionStartTime, exception);
}));
} catch (Exception e) {
indexAnomalyResultException(jobParameter, lockService, lock, detectionStartTime, executionStartTime, e, true);
log.error("Failed to execute AD job " + detectorId, e);
}
}
use of org.opensearch.jobscheduler.spi.LockModel in project anomaly-detection by opensearch-project.
the class AnomalyDetectorJobRunnerTests method testRunAdJobWithLock.
@Test
public void testRunAdJobWithLock() {
LockModel lock = new LockModel("indexName", "jobId", Instant.now(), 10, false);
runner.runAdJob(jobParameter, lockService, lock, Instant.now().minusMillis(1000 * 60), Instant.now());
verify(client, times(1)).execute(any(), any(), any());
}
use of org.opensearch.jobscheduler.spi.LockModel in project anomaly-detection by opensearch-project.
the class AnomalyDetectorJobRunnerTests method testRunAdJobWithEndRunExceptionNotNowAndRetryUntilStop.
@Test
public void testRunAdJobWithEndRunExceptionNotNowAndRetryUntilStop() throws InterruptedException {
LockModel lock = new LockModel(AnomalyDetectorJob.ANOMALY_DETECTOR_JOB_INDEX, jobParameter.getName(), Instant.now(), 10, false);
Instant executionStartTime = Instant.now();
Schedule schedule = mock(IntervalSchedule.class);
when(jobParameter.getSchedule()).thenReturn(schedule);
when(schedule.getNextExecutionTime(executionStartTime)).thenReturn(executionStartTime.plusSeconds(5));
doAnswer(invocation -> {
Exception exception = new EndRunException(jobParameter.getName(), randomAlphaOfLength(5), false);
ActionListener<?> listener = invocation.getArgument(2);
listener.onFailure(exception);
return null;
}).when(client).execute(any(), any(), any());
for (int i = 0; i < 3; i++) {
runner.runAdJob(jobParameter, lockService, lock, Instant.now().minusSeconds(60), executionStartTime);
assertEquals(i + 1, testAppender.countMessage("EndRunException happened for"));
}
runner.runAdJob(jobParameter, lockService, lock, Instant.now().minusSeconds(60), executionStartTime);
assertEquals(1, testAppender.countMessage("JobRunner will stop AD job due to EndRunException retry exceeds upper limit"));
}
use of org.opensearch.jobscheduler.spi.LockModel in project anomaly-detection by opensearch-project.
the class AnomalyDetectorJobRunnerTests method testRunAdJobWithNullLock.
@Test
public void testRunAdJobWithNullLock() {
LockModel lock = null;
runner.runAdJob(jobParameter, lockService, lock, Instant.now().minusMillis(1000 * 60), Instant.now());
verify(client, never()).execute(any(), any(), any());
}
use of org.opensearch.jobscheduler.spi.LockModel in project job-scheduler by opensearch-project.
the class LockService method acquireLock.
/**
* Attempts to acquire lock the job. If the lock does not exists it attempts to create the lock document.
* If the Lock document exists, it will try to update and acquire lock.
*
* @param jobParameter a {@code ScheduledJobParameter} containing the lock duration.
* @param context a {@code JobExecutionContext} containing job index name and job id.
* @param listener an {@code ActionListener} that has onResponse and onFailure that is used to return the lock if it was acquired
* or else null. Passes {@code IllegalArgumentException} to onFailure if the {@code ScheduledJobParameter} does not
* have {@code LockDurationSeconds}.
*/
public void acquireLock(final ScheduledJobParameter jobParameter, final JobExecutionContext context, ActionListener<LockModel> listener) {
final String jobIndexName = context.getJobIndexName();
final String jobId = context.getJobId();
if (jobParameter.getLockDurationSeconds() == null) {
listener.onFailure(new IllegalArgumentException("Job LockDuration should not be null"));
} else {
final long lockDurationSecond = jobParameter.getLockDurationSeconds();
createLockIndex(ActionListener.wrap(created -> {
if (created) {
try {
findLock(LockModel.generateLockId(jobIndexName, jobId), ActionListener.wrap(existingLock -> {
if (existingLock != null) {
if (isLockReleasedOrExpired(existingLock)) {
// Lock is expired. Attempt to acquire lock.
logger.debug("lock is released or expired: " + existingLock);
LockModel updateLock = new LockModel(existingLock, getNow(), lockDurationSecond, false);
updateLock(updateLock, listener);
} else {
logger.debug("Lock is NOT released or expired. " + existingLock);
// Lock is still not expired. Return null as we cannot acquire lock.
listener.onResponse(null);
}
} else {
// There is no lock object and it is first time. Create new lock.
LockModel tempLock = new LockModel(jobIndexName, jobId, getNow(), lockDurationSecond, false);
logger.debug("Lock does not exist. Creating new lock" + tempLock);
createLock(tempLock, listener);
}
}, listener::onFailure));
} catch (VersionConflictEngineException e) {
logger.debug("could not acquire lock {}", e.getMessage());
listener.onResponse(null);
}
} else {
listener.onResponse(null);
}
}, listener::onFailure));
}
}
Aggregations