Skip to content

Commit

Permalink
Update naming and add additional randomization for cron schedule minute
Browse files Browse the repository at this point in the history
  • Loading branch information
chenselena committed Oct 28, 2024
1 parent 3a197f1 commit d5ab815
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,9 @@ public class ReplicationConfig {
@Schema(description = "Cron schedule generated from the interval.", example = "0 0 1/1 * ? *")
@Valid
String cronSchedule;

public enum Granularity {
H,
D
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import com.linkedin.openhouse.tables.common.DefaultColumnPattern;
import com.linkedin.openhouse.tables.common.ReplicationInterval;
import com.linkedin.openhouse.tables.model.TableDto;
import com.linkedin.openhouse.tables.utils.CronScheduleGenerator;
import com.linkedin.openhouse.tables.utils.IntervalToCronConverter;
import java.util.List;
import java.util.stream.Collectors;
import org.mapstruct.Mapper;
Expand Down Expand Up @@ -124,15 +124,16 @@ private Replication mapReplicationPolicies(Replication replicationPolicy) {
.toBuilder()
.interval(ReplicationInterval.DEFAULT.getInterval())
.cronSchedule(
CronScheduleGenerator.buildCronExpression(
IntervalToCronConverter.generateCronExpression(
ReplicationInterval.DEFAULT.getInterval()))
.build();
}
if (replication.getCronSchedule() == null) {
return replication
.toBuilder()
.cronSchedule(
CronScheduleGenerator.buildCronExpression(replication.getInterval()))
IntervalToCronConverter.generateCronExpression(
replication.getInterval()))
.build();
}
return replication;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import com.cronutils.builder.CronBuilder;
import com.cronutils.model.CronType;
import com.cronutils.model.definition.CronDefinitionBuilder;
import com.cronutils.model.field.expression.FieldExpression;
import com.cronutils.model.field.expression.FieldExpressionFactory;
import com.linkedin.openhouse.common.exception.RequestValidationFailureException;
import com.linkedin.openhouse.tables.api.spec.v0.request.components.ReplicationConfig;
Expand All @@ -14,7 +13,7 @@
/** Utility class for generating a cron schedule given an interval for which a job should run */
@Slf4j
@Component
public class CronScheduleGenerator {
public class IntervalToCronConverter {

/**
* Public api to generate a cron schedule for a {@link ReplicationConfig} based on a given
Expand All @@ -23,46 +22,48 @@ public class CronScheduleGenerator {
* @param interval
* @return schedule
*/
public static String buildCronExpression(String interval) {
public static String generateCronExpression(String interval) {
if (interval == null || interval.isEmpty()) {
log.error("Replication interval is null or empty");
throw new RequestValidationFailureException(
String.format("Replication interval is null or empty"));
String errorMessage = "Replication interval is null or empty";
log.error(errorMessage);
throw new RequestValidationFailureException(errorMessage);
}
int count = Integer.parseInt(interval.substring(0, interval.length() - 1));
int hour = new Random().nextInt(24);
int minute = new int[] {0, 15, 30, 45}[new Random().nextInt(4)];

String granularity = interval.substring(interval.length() - 1);
String schedule;

if (granularity.equals("H")) {
schedule = buildHourlyCronExpression(hour, count);
if (granularity.equals(ReplicationConfig.Granularity.H.toString())) {
schedule = generateHourlyCronExpression(hour, minute, count);
} else {
schedule = buildDailyCronExpression(hour, count);
schedule = generateDailyCronExpression(hour, minute, count);
}
return schedule;
}

private static String buildDailyCronExpression(int hour, int dailyInterval) {
private static String generateDailyCronExpression(int hour, int minute, int dailyInterval) {
return CronBuilder.cron(CronDefinitionBuilder.instanceDefinitionFor(CronType.QUARTZ))
.withYear(FieldExpressionFactory.always())
.withDoM(FieldExpression.questionMark())
.withDoM(FieldExpressionFactory.questionMark())
.withDoW(FieldExpressionFactory.every(dailyInterval))
.withMonth(FieldExpressionFactory.always())
.withHour(FieldExpressionFactory.on(hour))
.withMinute(FieldExpressionFactory.on(0))
.withMinute(FieldExpressionFactory.on(minute))
.withSecond(FieldExpressionFactory.on(0))
.instance()
.asString();
}

private static String buildHourlyCronExpression(int hour, int hourlyInterval) {
private static String generateHourlyCronExpression(int hour, int minute, int hourlyInterval) {
return CronBuilder.cron(CronDefinitionBuilder.instanceDefinitionFor(CronType.QUARTZ))
.withYear(FieldExpressionFactory.always())
.withDoM(FieldExpressionFactory.questionMark())
.withDoW(FieldExpressionFactory.always())
.withMonth(FieldExpressionFactory.always())
.withHour(FieldExpressionFactory.every(hourlyInterval))
.withMinute(FieldExpressionFactory.on(0))
.withMinute(FieldExpressionFactory.on(minute))
.withSecond(FieldExpressionFactory.on(0))
.instance()
.asString()
Expand Down

0 comments on commit d5ab815

Please sign in to comment.