Skip to content

Commit

Permalink
upstream: b=main,r=476aa27ee767876a7908f2bf2e871f698038d623,t=2023-12…
Browse files Browse the repository at this point in the history
…-15-1346-4210
  • Loading branch information
sonatype-zion committed Dec 15, 2023
1 parent 9751d0b commit 3da2411
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -506,7 +506,7 @@ public Blob get(final BlobId blobId, final boolean includeDeleted) {
}

if (blobAttributes.isDeleted() && !includeDeleted) {
log.warn("Attempt to access soft-deleted blob {} attributes: {}", blobId, blobAttributes);
log.debug("Attempt to access soft-deleted blob {} attributes: {}", blobId, blobAttributes);
return null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
import org.sonatype.nexus.scheduling.TaskInfo;
import org.sonatype.nexus.scheduling.TaskRemovedException;
import org.sonatype.nexus.scheduling.TaskState;
import org.sonatype.nexus.scheduling.schedule.Cron;
import org.sonatype.nexus.scheduling.schedule.Manual;
import org.sonatype.nexus.scheduling.schedule.Now;
import org.sonatype.nexus.scheduling.schedule.Schedule;
Expand Down Expand Up @@ -92,6 +93,8 @@
import static org.sonatype.nexus.scheduling.TaskDescriptorSupport.LIMIT_NODE_KEY;
import static org.sonatype.nexus.scheduling.TaskState.INTERRUPTED;
import static org.sonatype.nexus.scheduling.TaskState.RUNNING;
import static org.sonatype.nexus.scheduling.schedule.Schedule.SCHEDULE_START_AT;
import static org.sonatype.nexus.scheduling.schedule.Schedule.stringToDate;

/**
* Quartz {@link SchedulerSPI}.
Expand Down Expand Up @@ -676,7 +679,14 @@ protected QuartzTaskInfo updateJob(
scheduler.addJob(jobDetail, true, true);
scheduler.rescheduleJob(trigger.getKey(), trigger);

// update TaskInfo, but only if it's WAITING, as running one will pick up the change by job listener when done
JobDataMap jobData = trigger.getJobDataMap();
String type = jobData.getString(Schedule.SCHEDULE_TYPE);

if (Cron.TYPE.equals(type)) {
verifyCron(jobData);
}

// update TaskInfo, but only if it's WAITING, as running one will pick up the change by job listener when done
old.setNexusTaskStateIfWaiting(
new QuartzTaskState(
config,
Expand All @@ -696,6 +706,17 @@ protected QuartzTaskInfo updateJob(
return old;
}

private void verifyCron(final JobDataMap jobData) throws SchedulerException {
Date startAt = stringToDate(jobData.getString(SCHEDULE_START_AT));
String cronExpression = jobData.getString(Cron.SCHEDULE_CRON_EXPRESSION);
try {
scheduleFactory.cron(startAt, cronExpression);
}
catch (Exception e) {
throw new SchedulerException(e);
}
}

private JobDetail buildJob(final TaskConfiguration config, final JobKey jobKey) {
return JobBuilder.newJob(QuartzTaskJob.class)
.withIdentity(jobKey)
Expand Down Expand Up @@ -798,6 +819,7 @@ private Map<Trigger, JobDetail> getNexusJobs() throws SchedulerException {
* Returns task-info for given identifier, or null.
*/
@Nullable
@VisibleForTesting
protected QuartzTaskInfo findTaskById(final String id) throws SchedulerException {
try (TcclBlock tccl = TcclBlock.begin(this)) {
return allTasks().values().stream()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import org.sonatype.nexus.scheduling.CurrentState
import org.sonatype.nexus.scheduling.TaskConfiguration
import org.sonatype.nexus.scheduling.TaskInfo
import org.sonatype.nexus.scheduling.TaskState
import org.sonatype.nexus.scheduling.schedule.Cron
import org.sonatype.nexus.scheduling.schedule.Daily
import org.sonatype.nexus.scheduling.schedule.Hourly
import org.sonatype.nexus.scheduling.schedule.Manual
Expand Down Expand Up @@ -59,13 +60,13 @@ import org.quartz.spi.JobStore
import org.quartz.spi.OperableTrigger

import static junit.framework.TestCase.assertEquals
import static junit.framework.TestCase.fail
import static org.hamcrest.MatcherAssert.assertThat
import static org.hamcrest.Matchers.equalTo
import static org.hamcrest.Matchers.hasSize
import static org.mockito.ArgumentMatchers.any
import static org.mockito.ArgumentMatchers.isNotNull
import static org.mockito.ArgumentMatchers.eq
import static org.mockito.ArgumentMatchers.notNull
import static org.mockito.Mockito.*
import static org.sonatype.nexus.common.stateguard.StateGuardLifecycleSupport.State.STARTED
import static org.sonatype.nexus.scheduling.TaskConfiguration.LAST_RUN_STATE_END_STATE
Expand Down Expand Up @@ -189,6 +190,41 @@ class QuartzSchedulerSPITest
assert recordDelete.value.name == 'testJobKeyName'
}

@Test
void 'Updating a task should validate cron expression'() {
def now = DateTime.now()
def startAt = DateTime.parse('2010-06-30T01:20')
def taskConfig = new TaskConfiguration(id: 'test', typeId: 'test')
underTest.scheduleTask(taskConfig, new Hourly(startAt.toDate()))

def spyUnderTest = spy(underTest)
def taskInfo = mock(QuartzTaskInfo.class);
def jobKey = mock(JobKey.class)

when(jobKey.name).thenReturn('test')
when(taskInfo.jobKey).thenReturn(jobKey)
when(taskInfo.configuration).thenReturn(taskConfig)
when(spyUnderTest.findTaskById(anyString())).thenReturn(taskInfo)

// An invalid cron expression should cause an error.
try {
spyUnderTest.scheduleTask(taskConfig, new Cron(startAt.toDate(), "*0 0 /3 * * ?*"))
fail 'Failed to throw IllegalArgumentException'
}
catch(Exception e) {
assert e.getMessage().contains("java.lang.IllegalArgumentException: Invalid Cron expression:")
}

// A valid cron expression should work
try {
spyUnderTest.scheduleTask(taskConfig, new Cron(startAt.toDate(), "29 * * * * ?"))
}
catch(Exception e) {
fail 'Failed to schedule task with a valid cron expression ' + e.message
}

}

@Test
void 'Exercise scheduled trigger events'() {
def jobDetailEntity = mockJobDetailEntity()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -443,7 +443,7 @@ private S3Blob refreshBlob(final S3Blob blob, final BlobId blobId, final boolean
}

if (blobAttributes.isDeleted() && !includeDeleted) {
log.warn("Attempt to access soft-deleted blob {} attributes: {}", blobId, blobAttributes);
log.debug("Attempt to access soft-deleted blob {} attributes: {}", blobId, blobAttributes);
return null;
}

Expand Down
2 changes: 1 addition & 1 deletion revision.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
b=main,r=969c2dd868d5671df17eeb1dcefb4b176e0cb9a8,t=2023-12-08-1342-45813
b=main,r=476aa27ee767876a7908f2bf2e871f698038d623,t=2023-12-15-1346-4210

0 comments on commit 3da2411

Please sign in to comment.