Merge branch 'hotfix/1.9.5'

# Conflicts:
#	backend/pom.xml
#	distribution/pom.xml
#	frontend/pom.xml
#	pom.xml
#	resources/pom.xml
This commit is contained in:
Zaripov Emil 2025-02-07 10:07:24 +03:00
commit 1911e67f8c
10 changed files with 61 additions and 37 deletions

View file

@ -5,7 +5,7 @@
<parent>
<groupId>ru.micord.ervu.lkrp</groupId>
<artifactId>ul</artifactId>
<version>1.9.4</version>
<version>1.9.5</version>
</parent>
<groupId>ru.micord.ervu.lkrp.ul</groupId>
<artifactId>backend</artifactId>

View file

@ -11,6 +11,7 @@ import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.time.ZonedDateTime;
import java.util.Arrays;
import java.util.Comparator;
@ -34,6 +35,7 @@ import ervu.model.webdav.Server;
import org.apache.http.client.ClientProtocolException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.InputStreamResource;
import org.springframework.core.io.Resource;
@ -44,6 +46,7 @@ import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import ru.micord.ervu.security.esia.config.EsiaConfig;
/**
* @author Alexandr Shalaginov
@ -60,6 +63,10 @@ public class WebDavClient {
private String password;
@Value("${webdav.bad_servers.cache.expire.seconds:120}")
private long cacheExpireSec;
@Value("${request.timeout:20}")
private long requestTimeout;
@Value("${connection.timeout:10}")
private long connectionTimeout;
private List<Server> servers;
private LoadingCache<String, String> badServersCache;
@ -167,10 +174,14 @@ public class WebDavClient {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password.toCharArray());
}
}).build();
})
.connectTimeout(Duration.ofSeconds(connectionTimeout))
.build();
HttpRequest httpRequest = HttpRequest.newBuilder().uri(URI.create(url))
.GET().build();
.GET()
.timeout(Duration.ofSeconds(requestTimeout))
.build();
HttpResponse<InputStream> response = httpClient.send(httpRequest,
HttpResponse.BodyHandlers.ofInputStream()

View file

@ -1,11 +1,14 @@
package ru.micord.ervu.kafka.service.impl;
import java.lang.invoke.MethodHandles;
import java.util.Optional;
import java.util.concurrent.ExecutionException;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.kafka.common.header.internals.RecordHeader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.kafka.requestreply.ReplyingKafkaTemplate;
import org.springframework.kafka.requestreply.RequestReplyFuture;
import org.springframework.kafka.support.KafkaHeaders;
@ -17,7 +20,7 @@ import ru.micord.ervu.kafka.service.ReplyingKafkaService;
*/
@Service
public class BaseReplyingKafkaServiceImpl implements ReplyingKafkaService {
private static final Logger LOGGER = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
private final ReplyingKafkaTemplate<String, String, String> replyingKafkaTemplate;
public BaseReplyingKafkaServiceImpl(
@ -28,16 +31,22 @@ public class BaseReplyingKafkaServiceImpl implements ReplyingKafkaService {
public String sendMessageAndGetReply(String requestTopic,
String replyTopic,
String requestMessage) {
long startTime = System.currentTimeMillis();
ProducerRecord<String, String> record = new ProducerRecord<>(requestTopic, requestMessage);
record.headers().add(new RecordHeader(KafkaHeaders.REPLY_TOPIC, replyTopic.getBytes()));
RequestReplyFuture<String, String, String> replyFuture = replyingKafkaTemplate.sendAndReceive(record);
try {
return Optional.ofNullable(replyFuture.get())
String result = Optional.ofNullable(replyFuture.get())
.map(ConsumerRecord::value)
.orElseThrow(() -> new RuntimeException("Kafka return result is null."));
LOGGER.info("Thread {} - KafkaSendMessageAndGetReply: {} ms",
Thread.currentThread().getId(), System.currentTimeMillis() - startTime);
return result;
}
catch (InterruptedException | ExecutionException e) {
LOGGER.error("Thread {} - KafkaSendMessageAndGetReply: {} ms",
Thread.currentThread().getId(), System.currentTimeMillis() - startTime);
throw new RuntimeException("Failed to get kafka response.", e);
}
}

View file

@ -38,10 +38,10 @@ public class EsiaConfig {
@Value("${esia.client.cert.hash}")
private String clientCertHash;
@Value("${esia.request.timeout:60}")
@Value("${request.timeout:20}")
private long requestTimeout;
@Value("${esia.connection.timeout:30}")
@Value("${connection.timeout:10}")
private long connectionTimeout;
@Value("${esia.logout.url:idp/ext/Logout}")

View file

@ -19,6 +19,7 @@ import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import ervu.service.okopf.OkopfService;
import org.springframework.stereotype.Service;
@ -241,12 +242,14 @@ public class EsiaAuthService {
throw new EsiaException(e);
}
finally {
LOGGER.info("Thread {}: SignSecret: {}ms RequestAccessToken: {}ms VerifySecret: {}ms",
LOGGER.info("Thread {} - SignSecret: {} ms RequestAccessToken: {} ms VerifySecret: {} ms",
Thread.currentThread().getId(), timeSignSecret, timeRequestAccessToken, timeVerifySecret);
}
OrgInfo orgInfo = null;
try {
orgInfo = getOrgInfo(esiaAccessTokenStr);
hasRole = ulDataService.checkRole(esiaAccessTokenStr);
String ervuId = getErvuId(esiaAccessTokenStr, prnOid);
String ervuId = getErvuId(prnOid, orgInfo);
createTokenAndAddCookie(response, prnOid, ervuId, hasRole, expiresIn);
if (!hasRole) {
LOGGER.error("The user with id = " + prnOid + " does not have the required role");
@ -333,7 +336,8 @@ public class EsiaAuthService {
Long expiresIn = tokenResponse.getExpires_in();
EsiaTokensStore.addAccessToken(prnOid, esiaAccessTokenStr, expiresIn);
EsiaTokensStore.addRefreshToken(prnOid, esiaNewRefreshToken, expiresIn);
String ervuId = getErvuId(esiaAccessTokenStr, prnOid);
OrgInfo orgInfo = getOrgInfo(esiaAccessTokenStr);
String ervuId = getErvuId(prnOid, orgInfo);
createTokenAndAddCookie(response, esiaAccessToken.getSbj_id(), ervuId, true, expiresIn);
}
catch (Exception e) {
@ -353,6 +357,7 @@ public class EsiaAuthService {
.uri(URI.create(esiaConfig.getSignUrl()))
.header("Content-Type", "text/plain")
.POST(HttpRequest.BodyPublishers.ofString(requestBody, StandardCharsets.UTF_8))
.timeout(Duration.ofSeconds(esiaConfig.getRequestTimeout()))
.build();
HttpResponse<String> response = HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(esiaConfig.getConnectionTimeout()))
@ -392,10 +397,23 @@ public class EsiaAuthService {
}
}
public String getErvuId(String accessToken, String prnOid) {
long timeRequestPersonDataOrg = 0, timeRequestPersonDataEmployee = 0, timeRequestPersonDataChief = 0, timeRequestIdERVU = 0;
public String getErvuId(String prnOid, OrgInfo orgInfo) throws JsonProcessingException {
orgInfo.setOrgTypeName(okopfService.findTitleByLeg(orgInfo.getOrgTypeLeg()));
String kafkaResponse = replyingKafkaService.sendMessageAndGetReply(requestTopic,
requestReplyTopic, objectMapper.writeValueAsString(orgInfo)
);
ErvuOrgResponse ervuOrgResponse = objectMapper.readValue(kafkaResponse, ErvuOrgResponse.class);
String ervuId = ervuOrgResponse.getData().getErvuId();
if (!StringUtils.hasText(ervuId)) {
throw new EsiaException("No ervuId for prnOid = " + prnOid);
}
return ervuId;
}
private OrgInfo getOrgInfo(String accessToken) {
long startTime = System.currentTimeMillis();
long timeRequestPersonDataOrg = 0, timeRequestPersonDataEmployee = 0, timeRequestPersonDataChief = 0;
try {
long startTime = System.currentTimeMillis();
OrganizationModel organizationModel = ulDataService.getOrganizationModel(accessToken);
timeRequestPersonDataOrg = System.currentTimeMillis() - startTime;
startTime = System.currentTimeMillis();
@ -404,27 +422,12 @@ public class EsiaAuthService {
startTime = System.currentTimeMillis();
EmployeeModel chiefModel = ulDataService.getChiefEmployeeModel(accessToken);
timeRequestPersonDataChief = System.currentTimeMillis() - startTime;
OrgInfo orgInfo = copyToOrgInfo(organizationModel, employeeModel, chiefModel);
orgInfo.setOrgTypeName(okopfService.findTitleByLeg(orgInfo.getOrgTypeLeg()));
startTime = System.currentTimeMillis();
String kafkaResponse = replyingKafkaService.sendMessageAndGetReply(requestTopic,
requestReplyTopic, objectMapper.writeValueAsString(orgInfo)
);
timeRequestIdERVU = System.currentTimeMillis() - startTime;
ErvuOrgResponse ervuOrgResponse = objectMapper.readValue(kafkaResponse, ErvuOrgResponse.class);
String ervuId = ervuOrgResponse.getData().getErvuId();
if (!StringUtils.hasText(ervuId)) {
throw new EsiaException("No ervuId for prnOid = " + prnOid);
}
return ervuId;
}
catch (Exception e) {
throw new EsiaException(e);
return copyToOrgInfo(organizationModel, employeeModel, chiefModel);
}
finally {
LOGGER.info("Thread {}: RequestPersonDataOrg: {}ms RequestPersonDataEmployee: {}ms RequestPersonDataChief: {}ms RequestIdERVU: {}ms",
Thread.currentThread().getId(), timeRequestPersonDataOrg, timeRequestPersonDataEmployee, timeRequestPersonDataChief, timeRequestIdERVU);
LOGGER.info("Thread {} - RequestPersonDataOrg: {} ms RequestPersonDataEmployee: {} ms RequestPersonDataChief: {} ms",
Thread.currentThread().getId(), timeRequestPersonDataOrg, timeRequestPersonDataEmployee, timeRequestPersonDataChief
);
}
}
@ -546,6 +549,7 @@ public class EsiaAuthService {
.uri(URI.create(esiaConfig.getSignVerifyUrl()))
.header("Content-Type", "text/plain")
.POST(HttpRequest.BodyPublishers.ofString(accessToken, StandardCharsets.UTF_8))
.timeout(Duration.ofSeconds(esiaConfig.getRequestTimeout()))
.build();
return HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(esiaConfig.getConnectionTimeout()))

View file

@ -4,7 +4,7 @@
<parent>
<groupId>ru.micord.ervu.lkrp</groupId>
<artifactId>ul</artifactId>
<version>1.9.4</version>
<version>1.9.5</version>
</parent>
<groupId>ru.micord.ervu.lkrp.ul</groupId>

View file

@ -4,7 +4,7 @@
<parent>
<groupId>ru.micord.ervu.lkrp</groupId>
<artifactId>ul</artifactId>
<version>1.9.4</version>
<version>1.9.5</version>
</parent>
<groupId>ru.micord.ervu.lkrp.ul</groupId>

View file

@ -1,7 +1,7 @@
<nav class="header" id="webbpm-header" [ngClass]="{'header-landing': isLanding}">
<div *ngIf="isLanding">
<div class="header-logo"></div>
<div class="header-title">Реестр повесток юридических лиц</div>
<div class="header-title">Личный кабинет для юридических лиц</div>
</div>
<div *ngIf="!isLanding" class="header-logo">
<div class="logo"><a routerLink="/"></a></div>

View file

@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>ru.micord.ervu.lkrp</groupId>
<artifactId>ul</artifactId>
<version>1.9.4</version>
<version>1.9.5</version>
<packaging>pom</packaging>
<modules>
<module>backend</module>

View file

@ -4,7 +4,7 @@
<parent>
<groupId>ru.micord.ervu.lkrp</groupId>
<artifactId>ul</artifactId>
<version>1.9.4</version>
<version>1.9.5</version>
</parent>
<groupId>ru.micord.ervu.lkrp.ul</groupId>