Skip to content

Commit

Permalink
Update scheduled-client
Browse files Browse the repository at this point in the history
  • Loading branch information
lmammucari committed Jul 9, 2024
1 parent c6bc550 commit 9526cdc
Show file tree
Hide file tree
Showing 7 changed files with 203 additions and 18 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ jobs:
with:
push: true
# tags: ${{ env.DOCKER_IMAGES }}
tags: "ghcr.io/glaciation-heu/mef-sog-uc1/scheduled-client:1.0.0"
tags: "ghcr.io/glaciation-heu/mef-sog-uc1/scheduled-client:1.1.0"
# labels: ${{ steps.meta.outputs.labels }}
context: "${{ github.workspace }}/workload-core/scheduled-client"

Expand Down
2 changes: 1 addition & 1 deletion workload-core/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ spec:
spec:
containers:
- name: scheduled-client
image: ghcr.io/glaciation-heu/mef-sog-uc1/scheduled-client:1.0.0
image: ghcr.io/glaciation-heu/mef-sog-uc1/scheduled-client:1.1.0
resources:
requests:
memory: "2Gi"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import static it.mef.tm.scheduled.client.costants.Costants.TYPE_API_OPERATION;
import static it.mef.tm.scheduled.client.costants.Costants.URL_BASE;
import static it.mef.tm.scheduled.client.costants.Costants.URL_SERVIZI_GFT_JOB;
import static it.mef.tm.scheduled.client.costants.Costants.URL_SERVIZI_GFT_MASS_SCHED_START;
import static it.mef.tm.scheduled.client.costants.Costants.URL_SERVIZI_GFT_MASS_START;

import java.io.File;
Expand Down Expand Up @@ -116,4 +117,62 @@ private static void cleanFolder(String path) throws IOException {
}
}
}


/**
* Servizio per lo start del processo di watching
* della cartella contenente le timbrature da acquisire
* @return
* @throws PreconditionException
*/
@ApiOperation(value = TYPE_API_OPERATION, notes = "Service starts massive workload of collecting time stamps based on the day of week and the time of execution."
+ "Upload a zip file with the following structure: \n"
+ "<i>zip-file.zip</i>: \n"
+ "&emsp; - <i>DAY OF WEEK</i> (sub-folder pattern accepted: 1 to 7 or minumum of 3 letters of day 'MON','TUE', etc.) \n"
+ "&emsp;&emsp; - <i>HOUR OF DAY</i> (sub-folder pattern accepted: numbers from 0 to 23, or range of hours like 9-13) \n"
+ "&emsp;&emsp;&emsp; - <i>timestamps-file.xml</i> \n"
+ "This structure allows to set which time stamps files must be elaborated for certain hours of certain days of the week.")
@PostMapping(value = URL_SERVIZI_GFT_MASS_SCHED_START)
public Boolean startWorkloadScheduled(
@ApiParam(value = "Minute of the hour when the elaboration starts. If not set, the scheduling is done every hour at 00 (Ex. 9:00AM, 10:00AM, etc.)") @RequestParam(name = "minute", required = false) Integer minute,
@ApiParam(value = "File to upload (only .zip file)", required = true) @RequestPart(name="zip-file", required = true) MultipartFile fileZip) throws PreconditionException {
// Se c'è già una schedulazione
// e non è stata già annullata
// Lancio un'eccezione
if (ScheduledUtil.isScheduledFutureActive()) {
throw new PreconditionException(ErrorCode.ERRSCH02.getCode());
}

try (ZipInputStream zis = new ZipInputStream(fileZip.getInputStream())) {
if (zis.getNextEntry() == null) {
zis.closeEntry();
throw new PreconditionException(ErrorCode.ERRSCH03.getCode());
}
zis.closeEntry();
} catch (IOException e) {
log.error(ErrorCode.ERRSCH03.getCode(), e);
throw new PreconditionException(ErrorCode.ERRSCH03.getCode());
}

String pathFinale = StringUtility.concat(pathTimbrature, File.separator, "massive", File.separator, fileZip.getOriginalFilename());

try {
cleanFolder(StringUtility.concat(pathTimbrature, File.separator, "massive"));
Files.write(Paths.get(pathFinale), fileZip.getBytes(), StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.CREATE);
} catch(IOException ex) {
log.error(ErrorCode.TMGFT33.getCode(), ex);
throw new PreconditionException(ErrorCode.TMGFT33.getCode());
}

String cronExpression = minute != null ? "0 " + minute + " * * * *" : "0 0 * * * *";

ScheduledFuture<?> scheduledFuture = taskScheduler.schedule(taskRunnerService.runMassiveScheduledTask(), new CronTrigger(cronExpression));

log.info("Scheduled cron task: {}", cronExpression);

ScheduledUtil.storeScheduledFuture(scheduledFuture);
return true;
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public class Costants {
public static final String URL_SERVIZI_GFT_START = URL_VERSION + "/startWorkload";
public static final String URL_SERVIZI_GFT_STOP = URL_VERSION + "/stopWorkload";
public static final String URL_SERVIZI_GFT_MASS_START = URL_VERSION + "/startMassiveWorkload";
public static final String URL_SERVIZI_GFT_MASS_SCHED_START = URL_VERSION + "/startMassiveScheduledWorkload";
public static final String URL_SERVIZI_GFT_MASS_STOP = URL_VERSION + "/stopMassiveWorkload";


Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package it.mef.tm.scheduled.client.costants;

import java.util.stream.Stream;

public enum GiorniSettimana {
MONDAY(1,"LUN","MON"),
TUESDAY(2,"MAR","TUE"),
WEDNESDAY(3,"MER","WED"),
THURSDAY(4,"GIO","THU"),
FRIDAY(5,"VEN","FRI"),
SATURDAY(6,"SAB","SAT"),
SUNDAY(7,"SOM","SUN");

private int numDay;
private String[] acceptedPattern;
/**
*
*/
private GiorniSettimana(int i, String... acceptedPattern) {
this.numDay = i;
this.acceptedPattern = acceptedPattern;
}

public static final boolean verifyDay(String day, int dayOfWeek) {
GiorniSettimana giorno = Stream.of(GiorniSettimana.values()).filter(g -> g.numDay == dayOfWeek).findFirst().orElse(null);
return giorno != null && (Stream.of(giorno.acceptedPattern).anyMatch(day::contains) || day.contains(String.valueOf(giorno.numDay)));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,34 @@ public class TaskRunnerService {
@Autowired
private TaskService taskService;

/**
* Esegue il task classico di elabaorazione
* Metodo runTask
* @return
*/
public Runnable runTask() {

return () -> taskService.executeTask();
}

/**
* Esegue il task massivo di elabaorazione
* Metodo runTask
* @return
*/
public Runnable runMassiveTask() {

return () -> taskService.executeMassiveTask();
}

/**
* Esegue il task massivo schedulato
* di elabaorazione
* estraendo solo i file relativi al giorno/ora correnti
* @return
*/
public Runnable runMassiveScheduledTask() {

return () -> taskService.executeMassiveScheduledTask();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,21 @@
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.stream.IntStream;
import java.util.stream.Stream;

import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipFile;
import org.apache.commons.compress.archivers.zip.ZipFile.Builder;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import it.mef.tm.scheduled.client.costants.GiorniSettimana;
import it.mef.tm.scheduled.client.kafka.KafkaProducerService;
import it.mef.tm.scheduled.client.model.ElaborazioneModel;
import it.mef.tm.scheduled.client.util.StringUtility;
Expand All @@ -43,13 +49,44 @@ public class TaskService {
@Value("${path.timbrature.to-be-elaborated}")
private String pathTimbratureToBeElaborated;

/**
* Servizio che esegue l'elaborazione massiva del task
* in modo schedulato. <br>
* Si aspetta che il file zip sia strutturato nel seguente modo: <br><br>
* <b>zipFile.zip</b> <br>&emsp;
* - GIORNO DELLA SETTIMANA espresso come girno da 1 a 7,
* oppure in formato di almeno 3 lettere (LUN/MAR/.../DOM o MON/TUE/...SUN) <br>&emsp;&emsp;
* - ORA DEL GIORNO/FASCIA ORARIA espressa in numeri da 0 a 23 (es. 9 oppure 9-13) <br>&emsp;&emsp;&emsp;
* - tracciato.xml <br>
*/
public void executeMassiveScheduledTask() {
log.info("Process copying files started");
File[] listFiles = Paths.get(pathTimbrature + File.separator + "massive").toFile().listFiles();
SimpleDateFormat sdf = new SimpleDateFormat(FORMAT_DATE);
for (File file : listFiles) {
try {
createMassiveFiles(file, sdf, true);
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
log.info("Process copying files end");

executeTask();
}

/**
* Servizio che esegue l'elaborazione massiva del task.
* Vengono presi tutti i file contenuti nello zip
* e depositati sotto la cartella delle timbrature da acquisire.
*/
public void executeMassiveTask() {
log.info("Process copying files started");
File[] listFiles = Paths.get(pathTimbrature + File.separator + "massive").toFile().listFiles();
SimpleDateFormat sdf = new SimpleDateFormat(FORMAT_DATE);
for (File file : listFiles) {
try {
createMassiveFiles(file, sdf);
createMassiveFiles(file, sdf, false);
} catch (Exception e) {
log.error(e.getMessage(), e);
}
Expand All @@ -62,14 +99,16 @@ public void executeMassiveTask() {
/**
* Metodo createMassiveFiles
* @param fileZip
* @param sdf
* @param verifyTime
* @throws IOException
*/
private void createMassiveFiles(File fileZip, SimpleDateFormat sdf) throws IOException {
private void createMassiveFiles(File fileZip, SimpleDateFormat sdf, boolean verifyTime) throws IOException {

try (ZipFile zFile = new ZipFile(fileZip)) {
Enumeration<? extends ZipEntry> entries = zFile.entries();
try (ZipFile zFile = new Builder().setFile(fileZip).get()) {
Enumeration<ZipArchiveEntry> entries = zFile.getEntries();
while (entries.hasMoreElements()) {
createFile(zFile, entries.nextElement(), sdf);
createFile(zFile, entries.nextElement(), sdf, verifyTime);
}

} catch (IOException e) {
Expand All @@ -85,23 +124,60 @@ private void createMassiveFiles(File fileZip, SimpleDateFormat sdf) throws IOExc
* @param zFile
* @param zipEntry
* @param sdf
* @param verifyTime
* @return
* @throws IOException
*/
private void createFile(ZipFile zFile, ZipEntry zipEntry, SimpleDateFormat sdf) throws IOException {
private void createFile(ZipFile zFile, ZipArchiveEntry zipEntry, SimpleDateFormat sdf, boolean verifyTime) throws IOException {
if (!zipEntry.isDirectory()) {
try {
Path path = Paths.get(StringUtility.concat(pathTimbrature, File.separator, sdf.format(new Date()), "-", new File(zipEntry.getName()).getName()));
Files.copy(zFile.getInputStream(zipEntry), path);
} catch (IOException e) {
log.error("Error copying file " + zipEntry.getName());
// Rilancio l'eccezione unchecked dato
// che non è possibile modificare la firma del metodo run
throw e;
File fileEntry = new File(zipEntry.getName());
if (!verifyTime || verifyScheduling(fileEntry)) {
try {
Path path = Paths.get(StringUtility.concat(pathTimbrature, File.separator, sdf.format(new Date()), "-", new File(zipEntry.getName()).getName()));
Files.copy(zFile.getInputStream(zipEntry), path);
} catch (IOException e) {
log.error("Error copying file " + zipEntry.getName());
// Rilancio l'eccezione unchecked dato
// che non è possibile modificare la firma del metodo run
throw e;
}
}
}
}

/**
* Verifica che la data attuale
* corrisponda ad un giorno della settimana + orario presente nell'entry.
* L'entry deve essere così strutturata:
* parent(day)/parent(hour)/file.xml
* @param fileEntry
* @return
*/
private boolean verifyScheduling(File fileEntry) {
// Se l'entry risulta mancante della cartella "padre"
// e della cartella "nonno", non è possibile effettuare il controllo
if (fileEntry.getParentFile() == null || fileEntry.getParentFile().getParentFile() == null) {
return false;
}

DateTime dt = new DateTime(); // current time
int dayOfWeek = dt.getDayOfWeek(); // gets the day of week
String time = fileEntry.getParentFile().getName();
String[] split = time.split("-");
int start = Integer.parseInt(split[0]);
int end = start;
if (split.length > 1) {
end = Integer.parseInt(split[1]);
}
boolean verifyTime = IntStream.rangeClosed(start, end).anyMatch(i -> i == dt.getHourOfDay());

String day = fileEntry.getParentFile().getParentFile().getName();

boolean verifyDay = GiorniSettimana.verifyDay(day, dayOfWeek);

return verifyDay && verifyTime;
}

/**
* Metodo executeTask
*/
Expand Down

0 comments on commit 9526cdc

Please sign in to comment.