Pages

Run a task in a different interval during weekend using Spring Scheduler and Custom Trigger

Run a task in a different interval during weekend.

Instead of defining fixed interval to run a task every 1 minute (as shown in example below) using @Scheduled, we can customize Spring Task Scheduler to schedule job with a custom trigger to run the tasks in different schedule depending on business logic. 

@Scheduled(fixedRate = 1, timeUnit = TimeUnit.MINUTES)
void job1() {
System.out.println("Running job1 - this won't run on weekend");
}

 

For example, we can do the following to run the task every 15 minute instead of 1 minute during weekends. Here we are registering a task job1 with TaskScheduler with a CustomTrigger.

The CustomTrigger implements Spring's Trigger interface and overrides nextExecution() method to do business logic to find the interval on which the task should run. For the example purpose we are running tasks less often (every 15 minute) during weekend.


DayOfWeek day = LocalDate.now(ZoneId.of(ZoneId.SHORT_IDS.get("CST"))).getDayOfWeek();
Duration nextSchedulePeriod = WORKDAY_INTERVAL;

/*
* Run the task every 15 minute often during weekend
*/

if (day == DayOfWeek.SATURDAY || day == DayOfWeek.SUNDAY) {
nextSchedulePeriod = WEEKEND_INTERVAL;
}
return new PeriodicTrigger(nextSchedulePeriod).nextExecution(ctx);



import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.Trigger;
import org.springframework.scheduling.TriggerContext;
import org.springframework.scheduling.support.PeriodicTrigger;

import java.time.DayOfWeek;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;

@Configuration
class CustomTaskScheduler implements InitializingBean {

static final Duration WORKDAY_INTERVAL = Duration.ofMinutes(1);
static final Duration WEEKEND_INTERVAL = Duration.ofMinutes(15);

@Autowired
TaskScheduler taskScheduler;


@Override
public void afterPropertiesSet() {
taskScheduler.schedule(this::job1, new CustomTrigger());
// schedule more tasks
}

void job1() {
System.out.println("Running job1 - this won't run on weekend");
}


static class CustomTrigger implements Trigger {
/**
* Determine the next execution time according to the given trigger context.
*/
@Override
public Instant nextExecution(TriggerContext ctx) {
DayOfWeek day = LocalDate.now(ZoneId.of(ZoneId.SHORT_IDS.get("CST"))).getDayOfWeek();
Duration nextSchedulePeriod = WORKDAY_INTERVAL;

/*
* Run the task every 15 minute often during weekend
*/

if (day == DayOfWeek.SATURDAY || day == DayOfWeek.SUNDAY) {
nextSchedulePeriod = WEEKEND_INTERVAL;
}
return new PeriodicTrigger(nextSchedulePeriod).nextExecution(ctx);
}


}

}

Append a file into existing ZIP using Java

 

The following code reads a input file 'in.zip' appends 'abc.txt' with some String content into it and creates output zip file 'out.zip' using Java.


import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.zip.ZipOutputStream;

public class ZipTests {

public static void main(String[] args) throws Exception {
var zipFile = new java.util.zip.ZipFile("in.zip");
final var zos = new ZipOutputStream(new FileOutputStream("out.zip"));
for (var e = zipFile.entries(); e.hasMoreElements(); ) {
var entryIn = e.nextElement();
System.out.println("Processing entry " + entryIn.getName());

//need to set next entry before modifying /adding content
zos.putNextEntry(entryIn);

if (entryIn.getName().equalsIgnoreCase("abc.txt")) {
//modify content and save to output zip stream

String content = isToString(zipFile.getInputStream(entryIn));
content = content.replaceAll("key1=value1", "key1=val2");
content += LocalDateTime.now() + "\r\n";

byte[] buf = content.getBytes();
zos.write(buf, 0, buf.length);
} else {
//copy the content
var inputStream = zipFile.getInputStream(entryIn);
byte[] buf = new byte[9096];
int len;
while ((len = inputStream.read(buf)) > 0) {
zos.write(buf, 0, len);
}

}
zos.closeEntry();
}
zos.close();
}

static String isToString(InputStream stringStream) throws Exception {
var result = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
for (int length; (length = stringStream.read(buffer)) != -1; ) {
result.write(buffer, 0, length);
}
return result.toString(StandardCharsets.UTF_8);
}

}

Spring Boot - get Trace and Span ID programmatically

 Autowire Tracer tracer

and get traceId and spanId from current Span


Span
span = tracer.currentSpan();
span.context().traceId() //trace ID span.context().spanId() //span ID