Merge remote-tracking branch 'origin/develop'
This commit is contained in:
commit
fcb323961d
6 changed files with 19 additions and 51 deletions
|
|
@ -1,4 +1,4 @@
|
||||||
FROM bellsoft/liberica-openjdk-alpine:17-cds
|
FROM bellsoft/liberica-openjdk-alpine:17-cds
|
||||||
COPY target/*.jar app.jar
|
COPY target/*.jar app.jar
|
||||||
|
|
||||||
CMD ["java", "-jar", "app.jar"]
|
CMD ["java", "-Dcom.sun.management.jmxremote", "-Dfile.encoding=UTF-8", "-Dcom.amazonaws.sdk.disableCertChecking", "-jar", "app.jar"]
|
||||||
|
|
|
||||||
4
pom.xml
4
pom.xml
|
|
@ -7,13 +7,13 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-parent</artifactId>
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
<version>3.3.5</version>
|
<version>3.4.4</version>
|
||||||
<relativePath/>
|
<relativePath/>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<groupId>ru.micord.ervu.lkrp</groupId>
|
<groupId>ru.micord.ervu.lkrp</groupId>
|
||||||
<artifactId>file-upload</artifactId>
|
<artifactId>file-upload</artifactId>
|
||||||
<version>1.9.8</version>
|
<version>1.10.0-SNAPSHOT</version>
|
||||||
|
|
||||||
<dependencyManagement>
|
<dependencyManagement>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ public record DownloadRequest(OrgInfo orgInfo, @NonNull FileInfo fileInfo) {
|
||||||
private final String fileName;
|
private final String fileName;
|
||||||
private final String fileSize;
|
private final String fileSize;
|
||||||
private final String filePatternCode;
|
private final String filePatternCode;
|
||||||
private final String FilePatternName;
|
private final String filePatternName;
|
||||||
private final String departureDateTime;
|
private final String departureDateTime;
|
||||||
private final String timeZone;
|
private final String timeZone;
|
||||||
@Setter
|
@Setter
|
||||||
|
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
package ru.micord.ervu.av.response;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author r.latypov
|
|
||||||
*/
|
|
||||||
public record AvResponse(String completed, String created, Integer progress,
|
|
||||||
Map<String, Scan> scan_result, String status, String[] verdicts) {
|
|
||||||
public record Scan(String started, String stopped, Threat[] threats, String verdict) {
|
|
||||||
public static final String VERDICT_CLEAN = "clean";
|
|
||||||
public static final String VERDICT_INFECTED = "infected";
|
|
||||||
|
|
||||||
public record Threat(String name, String object) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -5,7 +5,6 @@ import java.nio.charset.StandardCharsets;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
|
|
@ -30,7 +29,6 @@ import ru.micord.ervu.av.exception.RetryableException;
|
||||||
import ru.micord.ervu.av.kafka.dto.DownloadRequest;
|
import ru.micord.ervu.av.kafka.dto.DownloadRequest;
|
||||||
import ru.micord.ervu.av.kafka.dto.DownloadResponse;
|
import ru.micord.ervu.av.kafka.dto.DownloadResponse;
|
||||||
import ru.micord.ervu.av.kafka.dto.FileStatus;
|
import ru.micord.ervu.av.kafka.dto.FileStatus;
|
||||||
import ru.micord.ervu.av.response.AvResponse;
|
|
||||||
import ru.micord.ervu.av.s3.S3Service;
|
import ru.micord.ervu.av.s3.S3Service;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -38,7 +36,8 @@ import ru.micord.ervu.av.s3.S3Service;
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
public class FileUploadService {
|
public class FileUploadService {
|
||||||
private static final Logger logger = LoggerFactory.getLogger(FileUploadService.class);
|
private static final int INFECTED_CODE = 72;
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(FileUploadService.class);
|
||||||
@Value("${av.check.enabled}")
|
@Value("${av.check.enabled}")
|
||||||
private boolean avCheckEnabled;
|
private boolean avCheckEnabled;
|
||||||
@Value("${file.saving.path}")
|
@Value("${file.saving.path}")
|
||||||
|
|
@ -78,36 +77,25 @@ public class FileUploadService {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
FileUrl fileUrl = parseFileUrl(downloadRequest.fileInfo().getFileUrl());
|
FileUrl fileUrl = parseFileUrl(downloadRequest.fileInfo().getFileUrl());
|
||||||
|
Files.createDirectories(Paths.get(fileSavingPath));
|
||||||
try {
|
LOGGER.info("working in {}", System.getProperty("user.home"));
|
||||||
Files.createDirectories(Paths.get(fileSavingPath));
|
|
||||||
}
|
|
||||||
catch (IOException e) {
|
|
||||||
throw new RuntimeException("Failed to create directory " + fileSavingPath, e);
|
|
||||||
}
|
|
||||||
logger.info("working in {}", System.getProperty("user.home"));
|
|
||||||
Path filePath = Paths.get(fileSavingPath, fileUrl.fileName());
|
Path filePath = Paths.get(fileSavingPath, fileUrl.fileName());
|
||||||
String downloadUrl = fileUrl.fileUrl();
|
String downloadUrl = fileUrl.fileUrl();
|
||||||
fIleManager.downloadFile(downloadUrl, filePath);
|
fIleManager.downloadFile(downloadUrl, filePath);
|
||||||
boolean isAvError = false;
|
boolean isAvError = false;
|
||||||
boolean clean = true;
|
int exitCode = 0;
|
||||||
boolean infected = false;
|
|
||||||
|
|
||||||
if (avCheckEnabled) {
|
if (avCheckEnabled) {
|
||||||
try {
|
try {
|
||||||
AvResponse avResponse = receiveScanReportRetryable.checkFile(filePath);
|
exitCode = receiveScanReportRetryable.checkFile(filePath);
|
||||||
clean = Arrays.stream(avResponse.verdicts())
|
|
||||||
.anyMatch(verdict -> verdict.equalsIgnoreCase(AvResponse.Scan.VERDICT_CLEAN));
|
|
||||||
infected = Arrays.stream(avResponse.verdicts())
|
|
||||||
.anyMatch(verdict -> verdict.equalsIgnoreCase(AvResponse.Scan.VERDICT_INFECTED));
|
|
||||||
}
|
}
|
||||||
catch (FileUploadException | RetryableException e) {
|
catch (FileUploadException | RetryableException e) {
|
||||||
logger.error(e.getMessage(), e);
|
LOGGER.error(e.getMessage(), e);
|
||||||
isAvError = true;
|
isAvError = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isAvError || infected || !clean) {
|
if (isAvError || exitCode == INFECTED_CODE) {
|
||||||
downloadRequest.fileInfo().setFileUrl(null);
|
downloadRequest.fileInfo().setFileUrl(null);
|
||||||
FileStatus fileStatus = isAvError ? FileStatus.FILE_STATUS_11 : FileStatus.FILE_STATUS_02;
|
FileStatus fileStatus = isAvError ? FileStatus.FILE_STATUS_11 : FileStatus.FILE_STATUS_02;
|
||||||
downloadRequest.fileInfo().setFileStatus(fileStatus);
|
downloadRequest.fileInfo().setFileStatus(fileStatus);
|
||||||
|
|
@ -131,7 +119,7 @@ public class FileUploadService {
|
||||||
Files.delete(filePath);
|
Files.delete(filePath);
|
||||||
}
|
}
|
||||||
catch (IOException e) {
|
catch (IOException e) {
|
||||||
throw new RuntimeException("Failed to delete file " + filePath.getFileName());
|
LOGGER.error("Failed to delete file " + filePath, e);
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
acknowledgment.acknowledge();
|
acknowledgment.acknowledge();
|
||||||
|
|
@ -140,16 +128,16 @@ public class FileUploadService {
|
||||||
catch (InvalidHttpFileUrlException e) {
|
catch (InvalidHttpFileUrlException e) {
|
||||||
// считаем, что повторная обработка сообщения не нужна
|
// считаем, что повторная обработка сообщения не нужна
|
||||||
// ошибку логируем, отправляем сообщение с новым статусом, помечаем прочтение сообщения
|
// ошибку логируем, отправляем сообщение с новым статусом, помечаем прочтение сообщения
|
||||||
logger.error(e.getMessage() + ": " + kafkaInMessage);
|
LOGGER.error(e.getMessage() + ": " + kafkaInMessage);
|
||||||
downloadRequest.fileInfo().setFileUrl(null);
|
downloadRequest.fileInfo().setFileUrl(null);
|
||||||
downloadRequest.fileInfo().setFileStatus(FileStatus.FILE_STATUS_11);
|
downloadRequest.fileInfo().setFileStatus(FileStatus.FILE_STATUS_11);
|
||||||
sendMessage(inStatusTopic.name(), downloadRequest, messageId, inKafkaTemplate);
|
sendMessage(inStatusTopic.name(), downloadRequest, messageId, inKafkaTemplate);
|
||||||
acknowledgment.acknowledge();
|
acknowledgment.acknowledge();
|
||||||
}
|
}
|
||||||
catch (FileUploadException e) {
|
catch (FileUploadException | IOException e) {
|
||||||
// считаем, что нужно повторное считывание сообщения
|
// считаем, что нужно повторное считывание сообщения
|
||||||
// ошибку логируем, сообщение оставляем непрочитанным
|
// ошибку логируем, сообщение оставляем непрочитанным
|
||||||
logger.error(e.getMessage(), e);
|
LOGGER.error(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import org.apache.http.HttpEntity;
|
import org.apache.http.HttpEntity;
|
||||||
import org.apache.http.client.ClientProtocolException;
|
import org.apache.http.client.ClientProtocolException;
|
||||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||||
|
|
@ -24,7 +23,6 @@ import org.springframework.retry.annotation.Retryable;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import ru.micord.ervu.av.exception.FileUploadException;
|
import ru.micord.ervu.av.exception.FileUploadException;
|
||||||
import ru.micord.ervu.av.exception.RetryableException;
|
import ru.micord.ervu.av.exception.RetryableException;
|
||||||
import ru.micord.ervu.av.response.AvResponse;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author r.latypov
|
* @author r.latypov
|
||||||
|
|
@ -38,12 +36,11 @@ public class ReceiveScanReportRetryable {
|
||||||
@Retryable(retryFor = {RetryableException.class},
|
@Retryable(retryFor = {RetryableException.class},
|
||||||
maxAttemptsExpression = "${av.retry.max.attempts.count}",
|
maxAttemptsExpression = "${av.retry.max.attempts.count}",
|
||||||
backoff = @Backoff(delayExpression = "${av.retry.delay.milliseconds}"))
|
backoff = @Backoff(delayExpression = "${av.retry.delay.milliseconds}"))
|
||||||
public AvResponse checkFile(Path filePath) throws RetryableException, FileUploadException {
|
public int checkFile(Path filePath) throws RetryableException, FileUploadException {
|
||||||
File file = filePath.toFile();
|
File file = filePath.toFile();
|
||||||
|
|
||||||
try (CloseableHttpClient client = HttpClients.createDefault()) {
|
try (CloseableHttpClient client = HttpClients.createDefault()) {
|
||||||
URI uri = new URIBuilder(avRestAddress)
|
URI uri = new URIBuilder(avRestAddress)
|
||||||
.addParameter("wait", "1")
|
|
||||||
.build();
|
.build();
|
||||||
HttpPost post = new HttpPost(uri);
|
HttpPost post = new HttpPost(uri);
|
||||||
HttpEntity entity = MultipartEntityBuilder.create()
|
HttpEntity entity = MultipartEntityBuilder.create()
|
||||||
|
|
@ -53,10 +50,10 @@ public class ReceiveScanReportRetryable {
|
||||||
|
|
||||||
try (CloseableHttpResponse postResponse = client.execute(post)) {
|
try (CloseableHttpResponse postResponse = client.execute(post)) {
|
||||||
int postStatusCode = postResponse.getStatusLine().getStatusCode();
|
int postStatusCode = postResponse.getStatusLine().getStatusCode();
|
||||||
String postResponseJson = EntityUtils.toString(postResponse.getEntity());
|
String exitCode = EntityUtils.toString(postResponse.getEntity());
|
||||||
|
|
||||||
if (postStatusCode == HttpStatus.OK.value()) {
|
if (postStatusCode == HttpStatus.OK.value()) {
|
||||||
return new Gson().fromJson(postResponseJson, AvResponse.class);
|
return Integer.parseInt(exitCode);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw new FileUploadException(
|
throw new FileUploadException(
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue