Skip to content

Commit

Permalink
Merge pull request #42 from abes-esr/develop
Browse files Browse the repository at this point in the history
Correction écrasement fichier .bad
  • Loading branch information
SamuelQuetin authored Apr 15, 2024
2 parents 018f25e + bd55319 commit 05c99d7
Show file tree
Hide file tree
Showing 7 changed files with 192 additions and 14 deletions.
5 changes: 5 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,11 @@
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<version>4.5.14</version>
</dependency>

<!-- === SpringDoc (swagger) === -->
<dependency>
Expand Down
15 changes: 15 additions & 0 deletions src/main/java/fr/abes/logskbart/dto/MailDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package fr.abes.logskbart.dto;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class MailDto {
private String app;
private String[] to;
private String[] cc;
private String[] cci;
private String subject;
private String text;
}
68 changes: 56 additions & 12 deletions src/main/java/fr/abes/logskbart/kafka/LogsListener.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import fr.abes.logskbart.dto.LogKbartDto;
import fr.abes.logskbart.entity.LogKbart;
import fr.abes.logskbart.repository.LogKbartRepository;
import fr.abes.logskbart.service.EmailService;
import fr.abes.logskbart.utils.UtilsMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.kafka.clients.consumer.ConsumerRecord;
Expand All @@ -12,12 +13,13 @@

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.sql.Date;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Arrays;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.TimeUnit;

Expand All @@ -33,16 +35,19 @@ public class LogsListener {

private final Map<String, Timestamp> lastTimeStampByFilename;

public LogsListener(ObjectMapper mapper, UtilsMapper logsMapper, LogKbartRepository repository, Map<String, Timestamp> lastTimeStampByFilename) {
private final EmailService emailService;

public LogsListener(ObjectMapper mapper, UtilsMapper logsMapper, LogKbartRepository repository, Map<String, Timestamp> lastTimeStampByFilename, EmailService emailService) {
this.mapper = mapper;
this.logsMapper = logsMapper;
this.repository = repository;
this.lastTimeStampByFilename = lastTimeStampByFilename;
this.emailService = emailService;
}


/**
* Ecoute les topic de log d'erreurs et de fin de traitement bestPpn et génère un fichier err pour chaque fichier kbart
* Ecoute le topic de log d'erreurs et génère un fichier bad pour chaque fichier kbart
*
* @param message le message kafka
* @throws IOException exception levée
Expand All @@ -65,18 +70,23 @@ public void listenInfoKbart2KafkaAndErrorKbart2Kafka(ConsumerRecord<String, Stri

// Vérifie qu'un fichier portant le nom du kbart en cours existe
if (!logKbart.getPackageName().contains("ctx:package") && !logKbart.getPackageName().contains("_FORCE")) {
Path tempPath = Path.of("tempLog");

Path tempPath = Path.of("tempLogLocal");
if(!Files.exists(tempPath)) {
Files.createDirectory(tempPath);
}
Path of = Path.of("tempLog" + File.separator + logKbart.getPackageName().replace(".tsv", ".bad"));
Path of = Path.of("tempLogLocal" + File.separator + logKbart.getPackageName().replace(".tsv", ".bad"));

// Si la ligne de log sur le topic errorkbart2kafka est de type ERROR
// Si la ligne de log sur le topic est de type ERROR
if (logKbart.getLevel().toString().equals("ERROR")) {

// vérifie la présence de fichiers obsolètes dans le répertoire tempLogLocal et les supprime le cas échéant
deleteOldLocalTempLog();

if (lastTimeStampByFilename.get(logKbart.getPackageName()) != null) {
Timestamp LastTimestampPlusTwoMinutes = new Timestamp(lastTimeStampByFilename.get(logKbart.getPackageName()).getTime() + TimeUnit.MINUTES.toMillis(2 ));

// Si ca fait 2min qu'on a pas recu de message pour ce fichier
// Si ça fait 2min qu'on n'a pas reçu de message pour ce fichier
if (currentTimestamp.after(LastTimestampPlusTwoMinutes)) {
log.debug("Suppression fichier " + logKbart.getPackageName() + " si existe");
Files.deleteIfExists(of);
Expand All @@ -98,15 +108,49 @@ public void listenInfoKbart2KafkaAndErrorKbart2Kafka(ConsumerRecord<String, Stri
// Inscrit les informations sur la ligne
Files.write(of, (line + System.lineSeparator()).getBytes(), StandardOpenOption.APPEND);
log.info("Fichier temporaire créé.");
} catch (SecurityException | IOException e) {
} catch (SecurityException | IOException e) {
log.error("Erreur lors de la création du fichier temporaire. " + e);
throw new RuntimeException(e);
}
}
} else if (logKbart.getLevel().toString().equals("INFO") && logKbart.getMessage().contains("Traitement terminé pour fichier " + logKbart.getPackageName())) {
// Envoi du mail uniquement si le fichier temporaire a été créé
if (Files.exists(of)) {
Path tempPathTarget = Path.of("tempLog");
if(!Files.exists(tempPathTarget)) {
Files.createDirectory(tempPathTarget);
}
// Copie le fichier existant vers le répertoire temporaire
Path target = Path.of("tempLog" + File.separator + logKbart.getPackageName().replace(".tsv", ".bad"));
// Déplacement du fichier
Files.copy(of, target, StandardCopyOption.REPLACE_EXISTING);
log.info("Fichier de log transféré dans le dossier temporaire.");

emailService.sendMailWithAttachment(logKbart.getPackageName(), of);
}
}
}

// Inscrit l'entity en BDD
repository.save(logKbart);
}

public void deleteOldLocalTempLog() throws IOException {
File dirToCheck = new File("tempLogLocal");
File[] listeFilesTempLogLocal = dirToCheck.listFiles();
if (listeFilesTempLogLocal != null) {
for (File fileToCheck: listeFilesTempLogLocal) {
BasicFileAttributes basicFileAttributes = Files.readAttributes(fileToCheck.toPath(), BasicFileAttributes.class);
if (basicFileAttributes.isRegularFile()) {
String nameFile = String.valueOf(fileToCheck);
Date dateOfLastModification = new Date(basicFileAttributes.lastModifiedTime().toMillis());
Date dateNow = Date.from(LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant());
long interval = dateNow.getTime() - dateOfLastModification.getTime();
if (interval > 600000) {
fileToCheck.delete();
log.debug("Fichier obsolète supprimé : " + nameFile);
}
}
}
}
}
}
101 changes: 101 additions & 0 deletions src/main/java/fr/abes/logskbart/service/EmailService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package fr.abes.logskbart.service;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.HttpPost;
import fr.abes.logskbart.dto.MailDto;
import lombok.extern.log4j.Log4j2;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;

@Log4j2
@Service
public class EmailService {

@Value("${mail.ws.recipient}")
private String recipient;

@Value("${mail.ws.url}")
private String url;

@Value("${spring.profiles.active}")
private String env;

public void sendMailWithAttachment(String packageName, Path mailAttachmentPath) {
try {
// Création du mail
String requestJson = mailToJSON(this.recipient, "[CONVERGENCE]["+env.toUpperCase()+"] Log(s) d'erreur de " + packageName, "");

// Récupération du fichier
File file = mailAttachmentPath.toFile();

// Envoi du message par mail
sendMailWithFile(requestJson, file);

// Suppression du fichier temporaire
Files.deleteIfExists(mailAttachmentPath);

log.info("L'email a été correctement envoyé à " + recipient);

} catch (IOException e) {
throw new RuntimeException(e);
}
}

protected void sendMailWithFile(String requestJson, File f) {
// Création du l'adresse du ws d'envoi de mails
HttpPost uploadFile = new HttpPost(this.url + "htmlMailAttachment/");

// Création du builder
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.addTextBody("mail", requestJson, ContentType.APPLICATION_JSON);

try {
builder.addBinaryBody(
"attachment",
new FileInputStream(f),
ContentType.APPLICATION_OCTET_STREAM,
f.getName()
);
} catch (FileNotFoundException e) {
log.warn("Le fichier n'a pas été trouvé. " + e.getMessage());
}

// Envoi du mail
HttpEntity multipart = builder.build();
uploadFile.setEntity(multipart);

try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
httpClient.execute(uploadFile);
} catch (IOException e) {
log.warn("Erreur lors de l'envoi du mail. " + e.getMessage());
}
}

protected String mailToJSON(String to, String subject, String text) {
String json = "";
ObjectMapper mapper = new ObjectMapper();
MailDto mail = new MailDto();
mail.setApp("convergence");
mail.setTo(to.split(";"));
mail.setCc(new String[]{});
mail.setCci(new String[]{});
mail.setSubject(subject);
mail.setText(text);
try {
json = mapper.writeValueAsString(mail);
} catch (JsonProcessingException e) {
log.warn("Erreur lors de la création du mail. " + e);
}
return json;
}
}
6 changes: 5 additions & 1 deletion src/main/resources/application-dev.properties
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Consumer properties
spring.kafka.consumer.bootstrap-servers=

# Base Postgres
# Properties defined from .env on server #ignore resolution error
spring.datasource.logsdb.driver-class-name=org.postgresql.Driver
spring.datasource.logsdb.jdbcurl=
spring.datasource.logsdb.username=
Expand All @@ -19,3 +19,7 @@ logging.level.root=INFO
logging.level.fr.abes=DEBUG

topic.groupid.source=logskbartConsumer

# Mailing
mail.ws.url=
mail.ws.recipient=
5 changes: 5 additions & 0 deletions src/main/resources/application-prod.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
spring.kafka.consumer.bootstrap-servers=

# Base Postgres
# Properties defined from .env on server #ignore resolution error
spring.datasource.logsdb.driver-class-name=org.postgresql.Driver
spring.datasource.logsdb.jdbcurl=
spring.datasource.logsdb.username=
Expand All @@ -20,3 +21,7 @@ logging.level.root=ERROR
logging.level.fr.abes=ERROR

topic.groupid.source=logskbartConsumer

# Mailing
mail.ws.url=
mail.ws.recipient=
6 changes: 5 additions & 1 deletion src/main/resources/application-test.properties
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Consumer properties
spring.kafka.consumer.bootstrap-servers=

# Base Postgres
# Properties defined from .env on server #ignore resolution error
spring.datasource.logsdb.driver-class-name=org.postgresql.Driver
spring.datasource.logsdb.jdbcurl=
spring.datasource.logsdb.username=
Expand All @@ -19,3 +19,7 @@ logging.level.root=INFO
logging.level.fr.abes=INFO

topic.groupid.source=logskbartConsumer

# Mailing
mail.ws.url=
mail.ws.recipient=

0 comments on commit 05c99d7

Please sign in to comment.