From c620d6a0ad4ed201478f08a71d369d44af14392e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A0=D0=B0=D1=83=D1=84=20=D0=9B=D0=B0=D1=82=D1=8B=D0=BF?= =?UTF-8?q?=D0=BE=D0=B2?= Date: Wed, 4 Sep 2024 16:02:03 +0300 Subject: [PATCH] SUPPORT-8507: adding response treatment --- .../av/exception/FileUploadException.java | 4 ++ .../micord/ervu/av/response/AvResponse.java | 15 ++-- .../ervu/av/response/AvScanResponse.java | 11 +++ .../ervu/av/service/FileUploadService.java | 70 ++++++++++++++++--- 4 files changed, 86 insertions(+), 14 deletions(-) create mode 100644 src/main/java/ru/micord/ervu/av/response/AvScanResponse.java diff --git a/src/main/java/ru/micord/ervu/av/exception/FileUploadException.java b/src/main/java/ru/micord/ervu/av/exception/FileUploadException.java index 79e7555..5c2b06a 100644 --- a/src/main/java/ru/micord/ervu/av/exception/FileUploadException.java +++ b/src/main/java/ru/micord/ervu/av/exception/FileUploadException.java @@ -11,4 +11,8 @@ public class FileUploadException extends Exception { public FileUploadException(Throwable cause) { super(cause); } + + public FileUploadException(String message, Throwable cause) { + super(message, cause); + } } diff --git a/src/main/java/ru/micord/ervu/av/response/AvResponse.java b/src/main/java/ru/micord/ervu/av/response/AvResponse.java index 8b74329..48e71ae 100644 --- a/src/main/java/ru/micord/ervu/av/response/AvResponse.java +++ b/src/main/java/ru/micord/ervu/av/response/AvResponse.java @@ -1,14 +1,17 @@ package ru.micord.ervu.av.response; +import java.util.Map; + /** * @author r.latypov */ -public record AvResponse(String completed, String created, String progress, ScanResult scan_result, - String status, String[] verdicts) { - public record ScanResult(Scan noname) { - public record Scan(String started, String stopped, Threat[] threats, String verdict) { - public record Threat(String name, String object) { - } +public record AvResponse(String completed, String created, Integer progress, + Map 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) { } } } diff --git a/src/main/java/ru/micord/ervu/av/response/AvScanResponse.java b/src/main/java/ru/micord/ervu/av/response/AvScanResponse.java new file mode 100644 index 0000000..35616f0 --- /dev/null +++ b/src/main/java/ru/micord/ervu/av/response/AvScanResponse.java @@ -0,0 +1,11 @@ +package ru.micord.ervu.av.response; + +/** + * @author r.latypov + */ +public record AvScanResponse(String id, String location, Error error, String status) { + public static final String STATUS_ERROR = "error"; + + public record Error(String code, String message) { + } +} diff --git a/src/main/java/ru/micord/ervu/av/service/FileUploadService.java b/src/main/java/ru/micord/ervu/av/service/FileUploadService.java index 416f0a4..5013438 100644 --- a/src/main/java/ru/micord/ervu/av/service/FileUploadService.java +++ b/src/main/java/ru/micord/ervu/av/service/FileUploadService.java @@ -4,11 +4,12 @@ import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.util.Arrays; -import java.util.UUID; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.TimeUnit; import com.google.gson.Gson; import com.google.gson.GsonBuilder; +import com.google.gson.JsonSyntaxException; import org.apache.http.HttpEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpDelete; @@ -20,6 +21,7 @@ import org.apache.http.entity.mime.MultipartEntityBuilder; import org.apache.http.entity.mime.content.FileBody; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; +import org.apache.http.util.EntityUtils; import org.apache.kafka.clients.admin.NewTopic; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -37,6 +39,7 @@ import ru.micord.ervu.av.exception.InvalidHttpFileUrlException; import ru.micord.ervu.av.kafka.dto.InMessage; import ru.micord.ervu.av.kafka.dto.OutErrorMessage; import ru.micord.ervu.av.response.AvResponse; +import ru.micord.ervu.av.response.AvScanResponse; /** * @author r.latypov @@ -171,19 +174,70 @@ public class FileUploadService { try (CloseableHttpClient client = HttpClients.createDefault()) { HttpPost post = new HttpPost(avRestAddress); - post.addHeader("Content-type", "application/json"); HttpEntity entity = MultipartEntityBuilder.create() .addPart("file", new FileBody(file)) .build(); post.setEntity(entity); - try (CloseableHttpResponse response = client.execute(post)) { - int statusCode = response.getStatusLine().getStatusCode(); - if (statusCode != HttpStatus.OK.value()) { - String message = "http status code " + statusCode + " for " + avRestAddress + " request"; - throw new FileUploadException(message); + try (CloseableHttpResponse postResponse = client.execute(post)) { + int postStatusCode = postResponse.getStatusLine().getStatusCode(); + String postResponseJson = EntityUtils.toString(postResponse.getEntity()); + + AvScanResponse avScanResponse = null; + try { + avScanResponse = new Gson().fromJson(postResponseJson, AvScanResponse.class); } - return new Gson().fromJson(response.getEntity().toString(), AvResponse.class); + catch (JsonSyntaxException e) { + throw new FileUploadException("error json: " + postResponseJson, e); + } + + if (postStatusCode != HttpStatus.CREATED.value()) { + StringBuilder stringBuilder = new StringBuilder( + "http status code " + postStatusCode + " for " + avRestAddress + " post request."); + + String status = avScanResponse.status(); + if (status != null) { + stringBuilder.append(" Status: ").append(status).append("."); + } + if (avScanResponse.error() != null) { + stringBuilder.append(" Error code: ").append(avScanResponse.error().code()) + .append(". Error message: ").append(avScanResponse.error().message()).append(". "); + } + throw new FileUploadException(stringBuilder.toString()); + } + + String id = avScanResponse.id(); + String reportRequestUri = avRestAddress + "/" + id; + HttpGet get = new HttpGet(reportRequestUri); + + int countdown = 10; + long timeout = 1L; + AvResponse avResponse = null; + + do { + try { + TimeUnit.SECONDS.sleep(timeout); + } + catch (InterruptedException e) { + throw new FileUploadException(e); + } + + try (CloseableHttpResponse getResponse = client.execute(get)) { + int getStatusCode = getResponse.getStatusLine().getStatusCode(); + if (getStatusCode == HttpStatus.OK.value()) { + String getResponseJson = EntityUtils.toString(getResponse.getEntity()); + avResponse = new Gson().fromJson(getResponseJson, AvResponse.class); + } + else { + throw new FileUploadException("http status code " + getStatusCode + " for " + + reportRequestUri + " get request."); + } + } + countdown--; + } + while (countdown > 0 && (avResponse != null && avResponse.completed() == null)); + + return avResponse; } } catch (IOException e) {