Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -622,6 +622,12 @@
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-jpamodelgen</artifactId>
<version>${hibernate.version}</version>
<scope>provided</scope>
</dependency>
<!-- <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId>
<version>${spring.boot.version}</version> </dependency> -->
<dependency>
Expand Down Expand Up @@ -1094,15 +1100,9 @@
</exclusions>
</dependency>
<dependency>
<groupId>com.odysseusinc.arachne</groupId>
<artifactId>arachne-scheduler</artifactId>
<version>${arachne.version}</version>
<exclusions>
<exclusion>
<artifactId>org.hibernate</artifactId>
<groupId>hibernate-validator</groupId>
</exclusion>
</exclusions>
<groupId>com.cronutils</groupId>
<artifactId>cron-utils</artifactId>
<version>9.1.6</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
package com.odysseusinc.scheduler.api.v1.converter;

import com.cronutils.builder.CronBuilder;
import com.cronutils.model.Cron;
import com.cronutils.model.definition.CronDefinition;
import com.cronutils.model.field.expression.FieldExpression;
import com.cronutils.model.field.expression.FieldExpressionFactory;
import com.cronutils.model.field.expression.On;
import com.cronutils.model.field.value.IntegerFieldValue;
import com.odysseusinc.arachne.commons.converter.BaseConvertionServiceAwareConverter;
import com.odysseusinc.scheduler.api.v1.dto.ArachneJobDTO;
import com.odysseusinc.scheduler.model.ArachneJob;
import com.odysseusinc.scheduler.model.JobExecutingType;

import java.time.DayOfWeek;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import static com.cronutils.model.field.expression.FieldExpressionFactory.always;
import static com.cronutils.model.field.expression.FieldExpressionFactory.every;
import static com.cronutils.model.field.expression.FieldExpressionFactory.on;
import static com.cronutils.model.field.expression.FieldExpressionFactory.questionMark;

public abstract class BaseArachneJobDTOToArachneJobConverter<S extends ArachneJobDTO, T extends ArachneJob> extends BaseConvertionServiceAwareConverter<S, T> {

protected final CronDefinition cronDefinition;

protected BaseArachneJobDTOToArachneJobConverter(CronDefinition cronDefinition) {

this.cronDefinition = cronDefinition;
}

@Override
protected final void convert(final S source, T target) {
final Date startDate = source.getStartDate();
final JobExecutingType frequency = source.getFrequency();
final List<DayOfWeek> weekDays = source.getWeekDays();
final String cron = createCron(startDate, frequency, weekDays);
target.setCron(cron);
target.setId(source.getId());
target.setEnabled(source.isEnabled());
target.setFrequency(frequency);
target.setRecurringTimes(Optional.ofNullable(source.getRecurringTimes()).orElse(0));
target.setRecurringUntilDate(source.getRecurringUntilDate());
target.setStartDate(source.getStartDate());
target.setWeekDays(weekDays);
convertJob(source, target);
}

protected abstract void convertJob(final S source, T target);

protected String createCron(Date startDate, JobExecutingType frequency, List<DayOfWeek> weekDays) {

final Calendar calendar = Calendar.getInstance();
calendar.setTime(startDate);

final int second = calendar.get(Calendar.SECOND);
final int minute = calendar.get(Calendar.MINUTE);
final int hour = calendar.get(Calendar.HOUR_OF_DAY);
final int day = calendar.get(Calendar.DAY_OF_MONTH);
final int month = calendar.get(Calendar.MONTH) + 1;
final int year = calendar.get(Calendar.YEAR);

Cron cron;
switch (frequency) {
case ONCE:
cron = CronBuilder.cron(cronDefinition)
.withDoM(on(day))
.withMonth(on(month))
.withDoW(questionMark())
.withHour(on(hour))
.withMinute(on(minute))
.withSecond(on(second))
.instance();
break;
case HOURLY:
cron = CronBuilder.cron(cronDefinition)
.withDoM(always())
.withMonth(always())
.withDoW(questionMark())
.withHour(always())
.withMinute(on(minute))
.withSecond(on(second))
.instance();
break;
case DAILY: {
cron = CronBuilder.cron(cronDefinition)
.withDoM(every(1))
.withMonth(every(1))
.withDoW(questionMark())
.withHour(on(hour))
.withMinute(on(minute))
.withSecond(on(second))
.instance();
break;
}
case WEEKLY: {
if (weekDays == null || weekDays.isEmpty()) {
final String message = String.format("Execution period %s must have at least 1 day of execute", frequency);
throw new IllegalArgumentException(message);
}
final List<FieldExpression> collect = weekDays.stream().map(
dayOfWeek -> (FieldExpression) new On(new IntegerFieldValue(dayOfWeek.getValue()))).collect(Collectors.toList());
cron = CronBuilder.cron(cronDefinition)
.withDoM(questionMark())
.withMonth(always())
.withDoW(FieldExpressionFactory.and(collect))
.withHour(on(hour))
.withMinute(on(minute))
.withSecond(on(second))
.instance();
break;
}
case MONTHLY: {
cron = CronBuilder.cron(cronDefinition)
.withDoM(on(day))
.withMonth(always())
.withDoW(questionMark())
.withHour(on(hour))
.withMinute(on(minute))
.withSecond(on(second))
.instance();
break;
}
case YEARLY: {
cron = CronBuilder.cron(cronDefinition)
.withDoM(on(day))
.withMonth(on(month))
.withDoW(questionMark())
.withHour(on(hour))
.withMinute(on(minute))
.withSecond(on(second))
.instance();
break;
}
default: {
throw new IllegalArgumentException("Unsupported period: " + frequency);
}
}
return cron.asString();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.odysseusinc.scheduler.api.v1.converter;

import com.odysseusinc.arachne.commons.converter.BaseConvertionServiceAwareConverter;
import com.odysseusinc.scheduler.api.v1.dto.ArachneJobDTO;
import com.odysseusinc.scheduler.model.ArachneJob;

public abstract class BaseArachneJobToArachneJobDTOConverter<S extends ArachneJob, T extends ArachneJobDTO> extends BaseConvertionServiceAwareConverter<S, T> {

protected final void convert(S s, T dto) {

dto.setId(s.getId());
dto.setClosed(s.getClosed());
dto.setEnabled(s.getEnabled());
dto.setFrequency(s.getFrequency());
dto.setRecurringTimes(s.getRecurringTimes());
dto.setRecurringUntilDate(s.getRecurringUntilDate());
dto.setStartDate(s.getStartDate());
dto.setWeekDays(s.getWeekDays());
dto.setNextExecution(s.getNextExecution());
convertJob(s, dto);
}

protected abstract void convertJob(S source, T target);

}
116 changes: 116 additions & 0 deletions src/main/java/com/odysseusinc/scheduler/api/v1/dto/ArachneJobDTO.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
package com.odysseusinc.scheduler.api.v1.dto;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.odysseusinc.scheduler.model.JobExecutingType;

import javax.validation.constraints.NotNull;
import java.time.DayOfWeek;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class ArachneJobDTO {
private Long id;
private boolean enabled;
@NotNull
@JsonFormat(shape = JsonFormat.Shape.STRING)
private Date startDate;
@JsonFormat(shape = JsonFormat.Shape.STRING)
private Date nextExecution;
@NotNull
private JobExecutingType frequency;
private List<DayOfWeek> weekDays = new ArrayList<>();
private Date recurringUntilDate;
private Integer recurringTimes;
private Boolean isClosed;

public Long getId() {

return id;
}

public void setId(Long id) {

this.id = id;
}

public boolean isEnabled() {

return enabled;
}

public void setEnabled(boolean enabled) {

this.enabled = enabled;
}

public Date getStartDate() {

return startDate;
}

public void setStartDate(Date startDate) {

this.startDate = startDate;
}

public JobExecutingType getFrequency() {

return frequency;
}

public void setFrequency(JobExecutingType frequency) {

this.frequency = frequency;
}

public List<DayOfWeek> getWeekDays() {

return weekDays;
}

public void setWeekDays(List<DayOfWeek> weekDays) {

this.weekDays = weekDays;
}

public Date getRecurringUntilDate() {

return recurringUntilDate;
}

public void setRecurringUntilDate(Date recurringUntilDate) {

this.recurringUntilDate = recurringUntilDate;
}

public Integer getRecurringTimes() {

return recurringTimes;
}

public void setRecurringTimes(Integer recurringTimes) {

this.recurringTimes = recurringTimes;
}

public Boolean getClosed() {

return isClosed;
}

public void setClosed(Boolean closed) {

isClosed = closed;
}

public Date getNextExecution() {

return nextExecution;
}

public void setNextExecution(Date nextExecution) {

this.nextExecution = nextExecution;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.odysseusinc.scheduler.exception;

public class JobNotFoundException extends Exception {

public JobNotFoundException() {

}

public JobNotFoundException(String message) {

super(message);
}
}
Loading
Loading