Merge branch 'feature/SUPPORT-8863_retry_esnsi' into hotfix/1.9.8
This commit is contained in:
commit
2451e49530
4 changed files with 68 additions and 28 deletions
|
|
@ -1,20 +1,24 @@
|
|||
package ervu.client.okopf;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.Duration;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.zip.ZipInputStream;
|
||||
|
||||
import ervu.exception.EsnsiException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.retry.annotation.Backoff;
|
||||
import org.springframework.retry.annotation.Recover;
|
||||
import org.springframework.retry.annotation.Retryable;
|
||||
import org.springframework.retry.support.RetrySynchronizationManager;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
|
|
@ -22,27 +26,43 @@ import org.springframework.stereotype.Component;
|
|||
*/
|
||||
@Component
|
||||
public class EsnsiOkopfClient {
|
||||
private static final Logger logger = LoggerFactory.getLogger(EsnsiOkopfClient.class);
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(EsnsiOkopfClient.class);
|
||||
|
||||
@Value("${esnsi.okopf.url}")
|
||||
private String url;
|
||||
@Value("${esnsi.okopf.connect.timeout:2}")
|
||||
private long connectTimeout;
|
||||
@Value("${esnsi.okopf.read.timeout:4}")
|
||||
private long readTimeout;
|
||||
|
||||
@Retryable(value = IOException.class, maxAttemptsExpression = "${esnsi.okopf.retry.max.attempts.load:3}", backoff =
|
||||
@Backoff(delayExpression = "${esnsi.okop.retry.delay.load:30000}"))
|
||||
public String getJsonOkopFormData() {
|
||||
try (BufferedInputStream in = new BufferedInputStream(new URL(url).openStream());
|
||||
ZipInputStream archiveStream = new ZipInputStream(in);
|
||||
BufferedReader br = new BufferedReader(
|
||||
new InputStreamReader(archiveStream, StandardCharsets.UTF_8))) {
|
||||
if (Objects.nonNull(archiveStream.getNextEntry())) {
|
||||
logger.info("Received an archive in response.");
|
||||
return br.lines().collect(Collectors.joining(System.lineSeparator()));
|
||||
@Retryable(value = {IOException.class, EsnsiException.class}, maxAttemptsExpression = "${esnsi.okopf.retry.max.attempts.load:3}", backoff =
|
||||
@Backoff(delayExpression = "${esnsi.okop.retry.delay.load:3000}"))
|
||||
public String getJsonOkopFormData() throws IOException {
|
||||
int retryCount = RetrySynchronizationManager.getContext().getRetryCount() + 1;
|
||||
LOGGER.info("Attempt #{} to load json okopf form data from URL: {}", retryCount, url);
|
||||
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
|
||||
connection.setConnectTimeout((int) Duration.ofSeconds(connectTimeout).toMillis());
|
||||
connection.setReadTimeout((int) Duration.ofSeconds(connectTimeout).toMillis());
|
||||
int statusCode = connection.getResponseCode();
|
||||
LOGGER.info("Connecting timeout set to {} ms, read timeout set to {}", connectTimeout, readTimeout);
|
||||
if (statusCode >= 200 && statusCode <= 202) {
|
||||
try (ZipInputStream archiveStream = new ZipInputStream(connection.getInputStream());
|
||||
BufferedReader br = new BufferedReader(
|
||||
new InputStreamReader(archiveStream, StandardCharsets.UTF_8))) {
|
||||
if (Objects.nonNull(archiveStream.getNextEntry())) {
|
||||
LOGGER.info("Received an archive in response.");
|
||||
return br.lines().collect(Collectors.joining(System.lineSeparator()));
|
||||
}
|
||||
LOGGER.info("Received an empty archive in response.");
|
||||
}
|
||||
logger.info("Received an empty archive in response. Skipping load okpof file process");
|
||||
}
|
||||
catch (SecurityException | IOException e) {
|
||||
logger.error("Failed to send HTTP request {} or process the response for okopf file.", url, e);
|
||||
}
|
||||
throw new EsnsiException("Http status: " + statusCode + " Skipping load okopf file process. URL: " + url);
|
||||
}
|
||||
|
||||
@Recover
|
||||
public String recover(Exception e) {
|
||||
LOGGER.error("All retry attempts for IO operation failed for URL: {}. Triggering fallback logic.", url, e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
18
backend/src/main/java/ervu/exception/EsnsiException.java
Normal file
18
backend/src/main/java/ervu/exception/EsnsiException.java
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
package ervu.exception;
|
||||
|
||||
/**
|
||||
* @author Artyom Khakimullin
|
||||
*/
|
||||
public class EsnsiException extends RuntimeException {
|
||||
public EsnsiException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public EsnsiException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public EsnsiException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
|
|
@ -32,7 +32,7 @@ import static org.springframework.util.StringUtils.hasText;
|
|||
@Service
|
||||
@DependsOn({"liquibase"})
|
||||
public class EsnsiOkopfSchedulerServiceImpl implements EsnsiOkopfSchedulerService {
|
||||
private static final Logger logger = LoggerFactory.getLogger(
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(
|
||||
EsnsiOkopfSchedulerServiceImpl.class);
|
||||
|
||||
@Autowired
|
||||
|
|
@ -48,11 +48,11 @@ public class EsnsiOkopfSchedulerServiceImpl implements EsnsiOkopfSchedulerServic
|
|||
@Transactional
|
||||
public void init() {
|
||||
if (!cronLoad.equals(CRON_DISABLED)) {
|
||||
logger.info("Synchronization with esnsi okopf enabled");
|
||||
LOGGER.info("Synchronization with esnsi okopf enabled");
|
||||
load();
|
||||
}
|
||||
else {
|
||||
logger.info("Synchronization with esnsi okopf disabled");
|
||||
LOGGER.info("Synchronization with esnsi okopf disabled");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -60,22 +60,24 @@ public class EsnsiOkopfSchedulerServiceImpl implements EsnsiOkopfSchedulerServic
|
|||
@SchedulerLock(name = "loadOkopf")
|
||||
@Transactional
|
||||
public void load() {
|
||||
logger.info("Loading okopf file");
|
||||
LOGGER.info("Loading okopf file");
|
||||
try {
|
||||
String data = esnsiOkopfClient.getJsonOkopFormData();
|
||||
if (hasText(data)) {
|
||||
logger.info("Parsing from json file to okopf model");
|
||||
LOGGER.info("Parsing from json file to okopf model");
|
||||
OkopfOrgModel orgModel = mapper.readValue(data, OkopfOrgModel.class);
|
||||
int currentVersion = mapper.readTree(data).findValue("version").asInt();
|
||||
List<OkopfModel> okopfRecords = mapToOkopfRecords(orgModel.getData(), currentVersion);
|
||||
logger.info("Finished parsing from json file to okopf model");
|
||||
logger.info("Loaded {} okopf records with version {}. Beginning to save okopf data", okopfRecords.size(), currentVersion);
|
||||
LOGGER.info("Finished parsing from json file to okopf model");
|
||||
LOGGER.info("Loaded {} okopf records with version {}. Beginning to save okopf data", okopfRecords.size(), currentVersion);
|
||||
okopfDao.saveOrUpdate(okopfRecords);
|
||||
logger.info("Successfully saved okopf data");
|
||||
LOGGER.info("Successfully saved okopf data");
|
||||
} else {
|
||||
LOGGER.info("Data is empty");
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
logger.error("Failed to load okopf data", e);
|
||||
LOGGER.error("Failed to load okopf data", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,8 +33,6 @@ ERVU_KAFKA_REPLY_TIMEOUT=30
|
|||
ERVU_KAFKA_JOURNAL_REQUEST_TOPIC=ervu.organization.journal.request
|
||||
ERVU_KAFKA_JOURNAL_REPLY_TOPIC=ervu.organization.journal.response
|
||||
DB.JOURNAL.EXCLUDED.STATUSES=Направлено в ЕРВУ,Получен ЕРВУ
|
||||
ESNSI_OKOPF_URL=https://esnsi.gosuslugi.ru/rest/ext/v1/classifiers/11465/file?extension=JSON&encoding=UTF_8
|
||||
ESNSI_OKOPF_CRON_LOAD=0 0 */1 * * *
|
||||
ERVU_KAFKA_SECURITY_PROTOCOL=SASL_PLAINTEXT
|
||||
ERVU_KAFKA_SASL_MECHANISM=SCRAM-SHA-256
|
||||
ERVU_KAFKA_USERNAME=user1
|
||||
|
|
@ -44,7 +42,9 @@ ERVU_KAFKA_EXCERPT_REQUEST_TOPIC=ervu.lkrp.excerpt.request
|
|||
ESNSI_OKOPF_URL=https://esnsi.gosuslugi.ru/rest/ext/v1/classifiers/16271/file?extension=JSON&encoding=UTF_8
|
||||
ESNSI_OKOPF_CRON_LOAD=0 0 */1 * * *
|
||||
ESNSI_OKOPF_RETRY_MAX_ATTEMPTS_LOAD=3
|
||||
ESNSI_OKOPF_RETRY_DELAY_LOAD=30000
|
||||
ESNSI_OKOPF_RETRY_DELAY_LOAD=3000
|
||||
ESNSI_OKOPF_CONNECT_TIMEOUT=2
|
||||
ESNSI_OKOPF_READ_TIMEOUT=4
|
||||
|
||||
ERVU_FILE_UPLOAD_MAX_FILE_SIZE=5242880
|
||||
ERVU_FILE_UPLOAD_MAX_REQUEST_SIZE=6291456
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue