Merge remote-tracking branch 'origin/hotfix/1.9.5' into test_audit

# Conflicts:
#	backend/src/main/java/ru/micord/ervu/controller/ExtractController.java
#	backend/src/main/java/ru/micord/ervu/security/esia/service/EsiaAuthService.java
This commit is contained in:
adel.ka 2025-02-03 14:24:35 +03:00
commit b5591f1198
23 changed files with 387 additions and 408 deletions

View file

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

View file

@ -19,8 +19,13 @@ import rtl.pgs.ervu.proto.ExtractRegistry;
import rtl.pgs.ervu.proto.ResponseData;
import ru.micord.ervu.audit.constants.AuditConstants;
import ru.micord.ervu.audit.service.AuditService;
import ru.micord.ervu.dto.ExtractEmptyRequestDto;
import ru.micord.ervu.dto.ExtractRequestDto;
import ru.micord.ervu.kafka.service.ReplyingKafkaService;
import ru.micord.ervu.security.esia.model.PersonModel;
import ru.micord.ervu.security.esia.service.PersonalDataService;
import ru.micord.ervu.security.esia.token.EsiaTokensStore;
import ru.micord.ervu.security.webbpm.jwt.UserIdsPair;
import ru.micord.ervu.security.webbpm.jwt.util.SecurityUtil;
import javax.servlet.http.HttpServletRequest;
@ -30,38 +35,66 @@ import javax.servlet.http.HttpServletRequest;
*/
@RestController
public class ExtractController {
private final PersonalDataService personalDataService;
private final ReplyingKafkaService<Object, Bytes> replyingKafkaService;
private final AuditService auditService;
@Value("${ervu.kafka.registry.extract.empty.request.topic}")
private String registryExtractEmptyRequestTopic;
@Value("${ervu.kafka.registry.extract.request.topic}")
private String registryExtractRequestTopic;
@Value("${ervu.kafka.registry.extract.reply.topic}")
private String registryExtractReplyTopic;
public ExtractController(ReplyingKafkaService<Object, Bytes> replyingKafkaService, AuditService auditService) {
public ExtractController(
PersonalDataService personalDataService,
ReplyingKafkaService<Object, Bytes> replyingKafkaService,
AuditService auditService) {
this.personalDataService = personalDataService;
this.replyingKafkaService = replyingKafkaService;
this.auditService = auditService;
}
@GetMapping(value = "/extract/{formatRegistry}")
public ResponseEntity<Resource> getExtract(HttpServletRequest servletRequest, @PathVariable String formatRegistry) {
String ervuId = SecurityUtil.getErvuId();
UserIdsPair userIdsPair = SecurityUtil.getUserIdsPair();
String ervuId = userIdsPair.getErvuId();
String fileName = null;
ByteString file;
int size = 0 ;
if (ervuId == null) {
return ResponseEntity.noContent().build();
}
try {
if (ervuId != null) {
ExtractRequestDto request = new ExtractRequestDto(ervuId, formatRegistry);
byte[] reply = replyingKafkaService.sendMessageAndGetReply(registryExtractRequestTopic,
registryExtractReplyTopic, request).get();
int size = 0;
String fileName = null;
try {
ResponseData responseData = ResponseData.parseFrom(reply);
ExtractRegistry extractRegistry = responseData.getDataRegistryInformation()
.getExtractRegistry();
ByteString file = extractRegistry.getFile();
size = file.size();
fileName = extractRegistry.getFileName();
file = extractRegistry.getFile();
}
else {
String esiaUserId = userIdsPair.getEsiaUserId(); // esiaUserid is not null here
String esiaAccessToken = EsiaTokensStore.getAccessToken(esiaUserId);
PersonModel personModel = personalDataService.getPersonModel(esiaAccessToken);
ExtractEmptyRequestDto emptyRequest = new ExtractEmptyRequestDto(
personModel.getLastName(),
personModel.getFirstName(), personModel.getMiddleName(), personModel.getBirthDate(),
personModel.getSnils(), formatRegistry
);
byte[] reply = replyingKafkaService.sendMessageAndGetReply(registryExtractEmptyRequestTopic,
registryExtractReplyTopic, emptyRequest).get();
rtl.pgs.ervu.proto.emptyrequest.ResponseData responseData = rtl.pgs.ervu.proto.emptyrequest.ResponseData
.parseFrom(reply);
rtl.pgs.ervu.proto.emptyrequest.ExtractRegistry extractRegistry = responseData.getDataRegistryInformation()
.getExtractRegistry();
fileName = extractRegistry.getFileName();
file = extractRegistry.getFile();
}
String encodedFilename = URLEncoder.encode(fileName, StandardCharsets.UTF_8);
InputStreamResource resource = new InputStreamResource(file.newInput());
auditService.processDownloadEvent(servletRequest, size, fileName, formatRegistry,

View file

@ -5,6 +5,8 @@ import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import org.springframework.util.StringUtils;
import proto.ervu.rp.summons.RecruitmentInfo;
import ru.micord.ervu.dto.Restriction;
import ru.micord.ervu.dto.SubpoenaResponseDto;
import org.springframework.stereotype.Component;
@ -28,6 +30,7 @@ public class SummonsResponseDataConverter {
private static final String ACTUAL_ADDRESS_CODE = "_3";
public SubpoenaResponseDto convert(SummonsResponseData responseData) {
RecruitmentInfo recruitmentInfo = responseData.getRecruitmentInfo();
SubpoenaResponseDto.Builder builder = new SubpoenaResponseDto.Builder()
.personName(responseData.getFirstName(), responseData.getMiddleName(),
responseData.getLastName()
@ -39,10 +42,11 @@ public class SummonsResponseDataConverter {
.issueOrg(responseData.getIssueOrg())
.issueIdCode(responseData.getIssueIdCode())
.militaryCommissariatName(responseData.getRecruitmentInfo().getMilitaryCommissariatName())
.recruitmentStatusCode(
Integer.parseInt(responseData.getRecruitmentInfo().getRecruitmentStatusCode()))
.recruitmentStartDate(responseData.getRecruitmentInfo().getRecruitmentStart())
.militaryCommissariatName(recruitmentInfo.getMilitaryCommissariatName())
.recruitmentStatusCode(StringUtils.hasText(recruitmentInfo.getRecruitmentStatusCode())
? Integer.parseInt(recruitmentInfo.getRecruitmentStatusCode())
: 0)
.recruitmentStartDate(recruitmentInfo.getRecruitmentStart())
.residenceAddress(getAddressByCode(responseData.getAddressesList(), RESIDENCE_ADDRESS_CODE))
.stayAddress(getAddressByCode(responseData.getAddressesList(), STAY_ADDRESS_CODE))

View file

@ -0,0 +1,8 @@
package ru.micord.ervu.dto;
/**
* @author r.latypov
*/
public record ExtractEmptyRequestDto(String lastName, String firstName, String middleName,
String birthDate, String snils, String formatExtractRegistry) {
}

View file

@ -1,10 +1,13 @@
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.kafka.requestreply.ReplyingKafkaTemplate;
import org.springframework.kafka.requestreply.RequestReplyFuture;
import ru.micord.ervu.kafka.service.ReplyingKafkaService;
@ -13,18 +16,25 @@ import ru.micord.ervu.kafka.service.ReplyingKafkaService;
* @author gulnaz
*/
public abstract class BaseReplyingKafkaService<T, V> implements ReplyingKafkaService<T, V> {
private static final Logger LOGGER = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
@Override
public V sendMessageAndGetReply(String requestTopic, String replyTopic, T requestMessage) {
long startTime = System.currentTimeMillis();
RequestReplyFuture<String, T, V> replyFuture = getTemplate().sendAndReceive(
getProducerRecord(requestTopic, replyTopic, requestMessage));
try {
return Optional.ofNullable(replyFuture.get())
V 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

@ -18,6 +18,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 org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -50,7 +51,7 @@ import ru.micord.ervu.security.webbpm.jwt.helper.SecurityHelper;
import ru.micord.ervu.security.webbpm.jwt.service.JwtTokenService;
import ru.micord.ervu.security.webbpm.jwt.model.Token;
import static ru.micord.ervu.security.webbpm.jwt.util.SecurityUtil.getCurrentUsername;
import static ru.micord.ervu.security.webbpm.jwt.util.SecurityUtil.getCurrentUserEsiaId;
/**
* @author Eduard Tihomirov
@ -239,18 +240,13 @@ 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(), signSecret, requestAccessToken, verifySecret);
}
long requestPersonData = 0, requestIdERVU = 0;
PersonModel personModel = null;
try {
long startTime = System.currentTimeMillis();
personModel = personalDataService.getPersonModel(esiaAccessTokenStr);
requestPersonData = System.currentTimeMillis() - startTime;
startTime = System.currentTimeMillis();
Response ervuIdResponse = getErvuIdResponse(personModel);
requestIdERVU = System.currentTimeMillis() - startTime;
createTokenAndAddCookie(response, prnOid, ervuIdResponse.getErvuId(), expiresIn);
auditService.processAuthEvent(
request, personModel, AuditConstants.SUCCESS_STATUS, AuditConstants.LOGIN_EVENT_TYPE
@ -272,10 +268,6 @@ public class EsiaAuthService {
HttpStatus.FORBIDDEN
);
}
finally {
LOGGER.info("Thread {}: RequestPersonData: {}ms RequestIdERVU: {}ms",
Thread.currentThread().getId(), requestPersonData, requestIdERVU);
}
}
public void getEsiaTokensByRefreshToken(HttpServletRequest request, HttpServletResponse response) {
@ -409,18 +401,13 @@ public class EsiaAuthService {
}
}
public Response getErvuIdResponse(PersonModel personModel) {
try {
public Response getErvuIdResponse(PersonModel personModel) throws JsonProcessingException {
Person person = copyToPerson(personModel);
String kafkaResponse = replyingKafkaService.sendMessageAndGetReply(requestTopic,
requestReplyTopic, objectMapper.writeValueAsString(person)
);
return objectMapper.readValue(kafkaResponse, Response.class);
}
catch (Exception e) {
throw new EsiaException(e);
}
}
private Person copyToPerson(PersonModel personModel) {
Person person = new Person();
@ -439,7 +426,7 @@ public class EsiaAuthService {
private String getMessageId(Exception exception) {
return Integer.toUnsignedString(Objects
.hashCode(getCurrentUsername()), 36)
.hashCode(getCurrentUserEsiaId()), 36)
+ "-"
+ Integer.toUnsignedString(exception.hashCode(), 36);
}

View file

@ -1,5 +1,6 @@
package ru.micord.ervu.security.esia.service;
import java.lang.invoke.MethodHandles;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
@ -8,6 +9,8 @@ import java.time.Duration;
import java.util.Base64;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.micord.ervu.security.esia.exception.EsiaException;
import ru.micord.ervu.security.esia.config.EsiaConfig;
import ru.micord.ervu.security.esia.model.EsiaAccessToken;
@ -23,6 +26,7 @@ import org.springframework.stereotype.Service;
*/
@Service
public class EsiaPersonalDataService implements PersonalDataService {
private static final Logger LOGGER = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
@Autowired
private EsiaConfig esiaConfig;
@ -32,6 +36,7 @@ public class EsiaPersonalDataService implements PersonalDataService {
@Override
public PersonModel getPersonModel(String accessToken) {
long startTime = System.currentTimeMillis();
try {
EsiaAccessToken esiaAccessToken = readToken(accessToken);
String prnsId = esiaAccessToken.getSbj_id();
@ -39,9 +44,11 @@ public class EsiaPersonalDataService implements PersonalDataService {
personModel.setPassportModel(
getPassportModel(prnsId, accessToken, personModel.getrIdDoc()));
personModel.setPrnsId(prnsId);
LOGGER.info("Thread {} - RequestPersonData: {} ms", Thread.currentThread().getId(), System.currentTimeMillis() - startTime);
return personModel;
}
catch (Exception e) {
LOGGER.error("Thread {} - RequestPersonData: {} ms", Thread.currentThread().getId(), System.currentTimeMillis() - startTime);
throw new RuntimeException(e);
}
}

View file

@ -17,8 +17,11 @@ public class JwtAuthentication implements Authentication {
private final Authentication authentication;
private final String token;
private final UserIdsPair userIdsPair;
public JwtAuthentication(Authentication authentication, String userAccountId, String token) {
this.userAccountId = userAccountId;
this.userIdsPair = new UserIdsPair(userAccountId);
this.authentication = authentication;
this.token = token;
}
@ -31,6 +34,10 @@ public class JwtAuthentication implements Authentication {
return userAccountId;
}
public UserIdsPair getUserIdsPair() {
return userIdsPair;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return authentication.getAuthorities();

View file

@ -0,0 +1,36 @@
package ru.micord.ervu.security.webbpm.jwt;
public class UserIdsPair {
private final String esiaUserId;
private final String ervuId;
public UserIdsPair(String idsConcatenated) {
if (idsConcatenated == null) {
this.esiaUserId = null;
this.ervuId = null;
}
else {
String[] ids = idsConcatenated.split(":");
this.esiaUserId = ids[0];
this.ervuId = ids.length == 2 ? ids[1] : null;
}
}
public UserIdsPair(String esiaUserId, String ervuId) {
this.esiaUserId = esiaUserId;
this.ervuId = ervuId;
}
public String getEsiaUserId() {
return esiaUserId;
}
public String getErvuId() {
return ervuId;
}
public String getIdsConcatenated() {
return esiaUserId + (ervuId == null ? "" : ":" + ervuId);
}
}

View file

@ -15,6 +15,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import ru.micord.ervu.security.esia.token.EsiaTokensStore;
import ru.micord.ervu.security.webbpm.jwt.UserIdsPair;
import ru.micord.ervu.security.webbpm.jwt.model.Token;
import ru.cg.webbpm.modules.resources.api.ResourceMetadataUtils;
@ -42,16 +43,17 @@ public class JwtTokenService {
}
public Token createAccessToken(String userAccountId, Long expiresIn, String ervuId) {
String idsConcatenated = new UserIdsPair(userAccountId, ervuId).getIdsConcatenated();
Date expirationDate = new Date(System.currentTimeMillis() + 1000L * expiresIn);
String value = Jwts.builder()
.setSubject(userAccountId + ":" + ervuId)
.setSubject(idsConcatenated)
.setIssuer(tokenIssuerName)
.setIssuedAt(new Date(System.currentTimeMillis()))
.setExpiration(expirationDate)
.signWith(SIGNING_KEY)
.compact();
return new Token(userAccountId + ":" + ervuId, tokenIssuerName, expirationDate, value);
return new Token(idsConcatenated, tokenIssuerName, expirationDate, value);
}
public boolean isValid(Token token) {
@ -64,8 +66,8 @@ public class JwtTokenService {
LOGGER.info("Token {} is expired ", token.getValue());
return false;
}
String[] ids = token.getUserAccountId().split(":");
return EsiaTokensStore.validateAccessToken(ids[0]);
String esiaUserId = new UserIdsPair(token.getUserAccountId()).getEsiaUserId();
return EsiaTokensStore.validateAccessToken(esiaUserId);
}
public Token getToken(String token) {
@ -89,8 +91,8 @@ public class JwtTokenService {
String authToken = extractAuthToken(request);
if (authToken != null) {
String[] ids = getToken(authToken).getUserAccountId().split(":");
return ids[0];
String esiaUserId = new UserIdsPair(getToken(authToken).getUserAccountId()).getEsiaUserId();
return esiaUserId;
}
else {
throw new RuntimeException("Failed to get auth data. User unauthorized.");

View file

@ -8,6 +8,7 @@ import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.util.WebUtils;
import ru.micord.ervu.security.webbpm.jwt.JwtAuthentication;
import ru.micord.ervu.security.webbpm.jwt.UserIdsPair;
public final class SecurityUtil {
public static final String AUTH_TOKEN = "auth_token";
@ -23,17 +24,13 @@ public final class SecurityUtil {
return cookie != null ? cookie.getValue() : null;
}
public static String getErvuId() {
public static UserIdsPair getUserIdsPair() {
return Optional.ofNullable(SecurityContextHolder.getContext().getAuthentication())
.map(a -> ((JwtAuthentication) a).getUserAccountId())
.map(userAccountId -> {
String ervuId = userAccountId.split(":")[1];
return "null".equals(ervuId) ? null : ervuId;
})
.map(a -> ((JwtAuthentication) a).getUserIdsPair())
.orElse(null);
}
public static String getCurrentUsername() {
public static String getCurrentUserEsiaId() {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth != null && auth.isAuthenticated()) {
return auth.getName();

View file

@ -31,7 +31,9 @@ public class SubpoenaService {
}
public SubpoenaResponseDto getSubpoenaData() {
String ervuId = SecurityUtil.getErvuId();
String ervuId = SecurityUtil.getUserIdsPair() == null
? null
: SecurityUtil.getUserIdsPair().getErvuId();
if (ervuId == null) {
return new SubpoenaResponseDto.Builder().build();

View file

@ -0,0 +1,27 @@
syntax = "proto3";
package rtl.pgs.ervu.proto.emptyrequest;
import "google/protobuf/timestamp.proto";
option java_multiple_files = true;
option java_outer_classname = "LkrpUnknownRecruitResponse";
option java_package = "rtl.pgs.ervu.proto.emptyrequest";
message ExtractRegistry {
string fileName = 1;
string fileType = 2;
string fileDatetime = 3;
bytes file = 4;
};
message DataRegistryInformation {
ExtractRegistry extractRegistry = 1;
};
message ResponseData {
string lastName = 1;
string firstName = 2;
string middleName = 3;
string birthDate = 4;
DataRegistryInformation dataRegistryInformation = 5;
};

View file

@ -784,7 +784,8 @@ JBPM использует 3 корневых категории логирова
- `ERVU_KAFKA_RECRUIT_HEADER_CLASS` - класс для идентификации в заголовке запроса на получение данных о повестке, временных мерах и воинском учете
- `ERVU_KAFKA_SUBPOENA_EXTRACT_REQUEST_TOPIC` - топик для отправки запроса на получение выписки из Реестра повесток
- `ERVU_KAFKA_SUBPOENA_EXTRACT_REPLY_TOPIC` - топик для получения выписки из Реестра повесток
- `ERVU_KAFKA_REGISTRY_EXTRACT_REQUEST_TOPIC` - топик для отправки запроса на получение выписки из Реестра воинского учета
- `ERVU_KAFKA_REGISTRY_EXTRACT_EMPTY_REQUEST_TOPIC` - топик для отправки запроса на получение выписки из Реестра воинского учета при отсутствии ErvuId
- `ERVU_KAFKA_REGISTRY_EXTRACT_REQUEST_TOPIC` - топик для отправки запроса на получение выписки из Реестра воинского учета при наличии ErvuId
- `ERVU_KAFKA_REGISTRY_EXTRACT_REPLY_TOPIC` - топик для получения выписки из Реестра воинского учета
- `ERVU_KAFKA_EXTRACT_HEADER_CLASS` - класс для идентификации в заголовке запроса на получение выписки из Реестра повесток/Реестра воинского учета
- `AUDIT_KAFKA_AUTHORIZATION_TOPIC` - топик для отправки аудита в журнал авторизации

39
config/local.env Normal file
View file

@ -0,0 +1,39 @@
TZ=Europe/Moscow
# App datasource
DB_APP_USERNAME=ervu_lkrp_fl
DB_APP_PASSWORD=ervu_lkrp_fl
DB_APP_HOST=10.10.31.119
DB_APP_PORT=5432
DB_APP_NAME=ervu_lkrp_fl
ESIA_SCOPES=snils, fullname, birthdate, id_doc
ESIA_BASE_URI=https://esia-portal1.test.gosuslugi.ru/
ESIA_ISSUER_URL=http://esia-portal1.test.gosuslugi.ru/
ESIA_CLIENT_ID=MNSV93
ESIA_CLIENT_CERT_HASH=CF35A98C48E48665EA73530537BAFBB51F911C434ADC89215C2F86DCD04E28C5
ESIA_REDIRECT_URL=http://localhost:8080/
SIGN_URL=https://ervu-sign-dev.k8s.micord.ru/sign
SIGN_VERIFY_URL=https://ervu-sign-dev.k8s.micord.ru/verify
ERVU_KAFKA_BOOTSTRAP_SERVERS=local-kafka:9094
ERVU_KAFKA_USERNAME=user2
ERVU_KAFKA_PASSWORD=Blfi9d2OFG
ERVU_KAFKA_SASL_MECHANISM=PLAIN
ERVU_KAFKA_SECURITY_PROTOCOL=PLAINTEXT
ERVU_KAFKA_GROUP_ID=ervu-lkrp-fl-new
ERVU_KAFKA_REPLY_TOPIC=ervu.lkpr.person.search.response
ERVU_KAFKA_REQUEST_TOPIC=ervu.lkpr.person.search.request
ERVU_KAFKA_REPLY_TIMEOUT=5
ERVU_KAFKA_RECRUIT_REQUEST_TOPIC=ervu.recruit.info.request
ERVU_KAFKA_RECRUIT_REPLY_TOPIC=ervu.recruit.info.response
ERVU_KAFKA_RECRUIT_HEADER_CLASS=Request@urn://rostelekom.ru/RP-SummonsTR/1.0.5
ERVU_KAFKA_REGISTRY_EXTRACT_EMPTY_REQUEST_TOPIC=ervu.extract.empty.request
ERVU_KAFKA_REGISTRY_EXTRACT_REQUEST_TOPIC=ervu.extract.info.request
ERVU_KAFKA_REGISTRY_EXTRACT_REPLY_TOPIC=ervu.extract.info.response
ERVU_KAFKA_EXTRACT_HEADER_CLASS=request@urn://rostelekom.ru/ERVU-extractFromRegistryTR/1.0.3
ERVU_KAFKA_DOC_LOGIN_MODULE=org.apache.kafka.common.security.plain.PlainLoginModule
ESIA_TOKEN_CLEAR_CRON=0 0 */1 * * *
COOKIE_PATH=/fl

View file

@ -28,6 +28,7 @@ ERVU_KAFKA_REPLY_TIMEOUT=30
ERVU_KAFKA_RECRUIT_REQUEST_TOPIC=ervu.recruit.info.request
ERVU_KAFKA_RECRUIT_REPLY_TOPIC=ervu.recruit.info.response
ERVU_KAFKA_RECRUIT_HEADER_CLASS=Request@urn://rostelekom.ru/RP-SummonsTR/1.0.5
ERVU_KAFKA_REGISTRY_EXTRACT_EMPTY_REQUEST_TOPIC=ervu.extract.empty.request
ERVU_KAFKA_REGISTRY_EXTRACT_REQUEST_TOPIC=ervu.extract.info.request
ERVU_KAFKA_REGISTRY_EXTRACT_REPLY_TOPIC=ervu.extract.info.response
ERVU_KAFKA_EXTRACT_HEADER_CLASS=request@urn://rostelekom.ru/ERVU-extractFromRegistryTR/1.0.3

View file

@ -75,6 +75,7 @@
<property name="ervu.kafka.recruit.request.topic" value="ervu.recruit.info.request"/>
<property name="ervu.kafka.recruit.reply.topic" value="ervu.recruit.info.response"/>
<property name="ervu.kafka.recruit.header.class" value="Request@urn://rostelekom.ru/RP-SummonsTR/1.0.5"/>
<property name="ervu.kafka.registry.extract.empty.request.topic" value="ervu.extract.empty.request"/>
<property name="ervu.kafka.registry.extract.request.topic" value="ervu.extract.info.request"/>
<property name="ervu.kafka.registry.extract.reply.topic" value="ervu.extract.info.response"/>
<property name="ervu.kafka.extract.header.class" value="request@urn://rostelekom.ru/ERVU-extractFromRegistryTR/1.0.3"/>

View file

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

View file

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

View file

@ -18,7 +18,7 @@ export class LoadForm extends Container {
private ervuDataService: ErvuDataService;
private subscription: Subscription;
private fields: any[];
private fieldDataList: FieldData[] = [];
private fieldDataList: FieldData[];
constructor(el: ElementRef, cd: ChangeDetectorRef) {
super(el, cd);
@ -30,7 +30,7 @@ export class LoadForm extends Container {
}
protected loadContainer(): Promise<any> {
return Promise.resolve(this.loadData());
return this.fieldDataList ? this.loadData() : Promise.resolve();
}
initialize() {
@ -39,6 +39,7 @@ export class LoadForm extends Container {
this.ervuDataService = this.injector.get(ErvuDataService);
this.subscription = this.ervuDataService.message.subscribe(value => {
if (value) {
this.fieldDataList = [];
this.fields.forEach(field => {
let fieldData: FieldData = new FieldData();
fieldData.componentGuid = field.objectId;

View file

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

View file

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

View file

@ -1008,12 +1008,6 @@
</value>
</item>
</value>
</entry>
<entry>
<key>visible</key>
<value>
<simple>false</simple>
</value>
</entry>
</properties>
</scripts>
@ -1324,6 +1318,57 @@
</entry>
</complex>
</value>
</entry>
</complex>
</value>
</item>
<item id="57305b6c-cb1c-4d2f-8922-94b08469dab2" removed="false">
<value>
<complex>
<entry>
<key>_isGroupSelected</key>
<value>
<simple>false</simple>
</value>
</entry>
<entry>
<key>one</key>
<value>
<complex>
<entry>
<key>conditionFirstPart</key>
<value>
<complex>
<entry>
<key>objectValue</key>
<value>
<complex>
<entry>
<key>behavior</key>
<value>
<simple>{"objectId":"a28b93c3-fbbc-43d2-ab0c-9b0abcae5106","packageName":"component.field","className":"TextField","type":"TS"}</simple>
</value>
</entry>
<entry>
<key>method</key>
<value>
<simple>"getValue"</simple>
</value>
</entry>
</complex>
</value>
</entry>
</complex>
</value>
</entry>
<entry>
<key>operation</key>
<value>
<simple>"IS_NOT_EMPTY"</simple>
</value>
</entry>
</complex>
</value>
</entry>
</complex>
</value>
@ -1820,12 +1865,6 @@
<value>
<simple>"Запросить выписку"</simple>
</value>
</entry>
<entry>
<key>visible</key>
<value>
<simple>false</simple>
</value>
</entry>
</properties>
</scripts>
@ -4128,6 +4167,7 @@
<componentRootId>8ae57bdb-4acb-4f34-9641-9b5031b408d3</componentRootId>
<name>VB - 1.1.3.1 (вы состоите на учете) сценаций</name>
<container>true</container>
<expanded>false</expanded>
<childrenReordered>false</childrenReordered>
<scripts id="bf098f19-480e-44e4-9084-aa42955c4d0f">
<properties>
@ -4632,12 +4672,6 @@
</value>
</item>
</value>
</entry>
<entry>
<key>visible</key>
<value>
<simple>false</simple>
</value>
</entry>
</properties>
</scripts>
@ -4753,12 +4787,6 @@
<value>
<simple>null</simple>
</value>
</entry>
<entry>
<key>visible</key>
<value>
<simple>false</simple>
</value>
</entry>
</properties>
</scripts>
@ -4918,12 +4946,6 @@
<value>
<simple>"Запросить выписку"</simple>
</value>
</entry>
<entry>
<key>visible</key>
<value>
<simple>false</simple>
</value>
</entry>
</properties>
</scripts>
@ -5699,7 +5721,7 @@
<entry>
<key>behavior</key>
<value>
<simple>{"objectId":"63871032-9206-4f76-8c93-c8ab1b8200d2","packageName":"component.field","className":"NumberField","type":"TS"}</simple>
<simple>{"objectId":"a28b93c3-fbbc-43d2-ab0c-9b0abcae5106","packageName":"component.field","className":"TextField","type":"TS"}</simple>
</value>
</entry>
<entry>
@ -5722,7 +5744,7 @@
<key>staticValue</key>
<value>
<implRef type="TS">
<className>number</className>
<className>string</className>
<packageName></packageName>
</implRef>
<simple>0.0</simple>
@ -5734,7 +5756,7 @@
<entry>
<key>operation</key>
<value>
<simple>"EQUALS"</simple>
<simple>"IS_NOT_EMPTY"</simple>
</value>
</entry>
</complex>
@ -5743,7 +5765,24 @@
</complex>
</value>
</item>
<item id="7d9187ca-f2e5-48ff-8670-93d9fc8bcf85" removed="false">
<item id="7d9187ca-f2e5-48ff-8670-93d9fc8bcf85" removed="true"/>
<item id="94f9c8a4-2825-4ab1-874f-b7141e206799" removed="false">
<value>
<complex>
<entry>
<key>_isGroupSelected</key>
<value>
<simple>true</simple>
</value>
</entry>
<entry>
<key>group</key>
<value>
<complex>
<entry>
<key>conditions</key>
<value>
<item id="9f0c2f9b-3ee6-48fe-88be-b42fb236e578" removed="false">
<value>
<complex>
<entry>
@ -5790,6 +5829,74 @@
</entry>
</complex>
</value>
</entry>
</complex>
</value>
</item>
<item id="9159dca3-746f-49f0-bc84-db0ee17ed9cb" removed="false">
<value>
<complex>
<entry>
<key>_isGroupSelected</key>
<value>
<simple>false</simple>
</value>
</entry>
<entry>
<key>one</key>
<value>
<complex>
<entry>
<key>conditionFirstPart</key>
<value>
<complex>
<entry>
<key>objectValue</key>
<value>
<complex>
<entry>
<key>behavior</key>
<value>
<simple>{"objectId":"63871032-9206-4f76-8c93-c8ab1b8200d2","packageName":"component.field","className":"NumberField","type":"TS"}</simple>
</value>
</entry>
<entry>
<key>method</key>
<value>
<simple>"getValue"</simple>
</value>
</entry>
</complex>
</value>
</entry>
</complex>
</value>
</entry>
<entry>
<key>conditionSecondPart</key>
<value>
<complex>
<entry>
<key>staticValue</key>
<value>
<implRef type="TS">
<className>number</className>
<packageName></packageName>
</implRef>
<simple>0.0</simple>
</value>
</entry>
</complex>
</value>
</entry>
<entry>
<key>operation</key>
<value>
<simple>"EQUALS"</simple>
</value>
</entry>
</complex>
</value>
</entry>
</complex>
</value>
@ -5804,6 +5911,22 @@
</entry>
</complex>
</value>
</entry>
</complex>
</value>
</item>
<item id="aed64e39-e66a-44b0-bd2a-7afe960e78d3" removed="true"/>
<item id="3404b012-e85d-4507-b479-ba8720fb7e98" removed="true"/>
</value>
</entry>
<entry>
<key>logicalOperation</key>
<value>
<simple>"AND"</simple>
</value>
</entry>
</complex>
</value>
</entry>
<entry>
<key>thenActions</key>
@ -7162,313 +7285,6 @@
</value>
</entry>
</complex>
</value>
</item>
</value>
</entry>
</properties>
</scripts>
</children>
<children id="315c5087-825a-4ade-99d9-7dbe09f87226">
<prototypeId>98594cec-0a9b-4cef-af09-e1b71cb2ad9e</prototypeId>
<componentRootId>315c5087-825a-4ade-99d9-7dbe09f87226</componentRootId>
<name>AC - для найденного пользователя в ерву</name>
<container>false</container>
<childrenReordered>false</childrenReordered>
<scripts id="37dff5c8-1599-4984-b107-c44a87b6da2e">
<properties>
<entry>
<key>elseActions</key>
<value>
<item id="15082312-b39c-473a-b08a-f0690c5d37d2" removed="true"/>
</value>
</entry>
<entry>
<key>eventRefs</key>
<value>
<item id="ca97a9f3-5f25-4f75-b4a0-c98aac1b1e57" removed="false">
<value>
<complex>
<entry>
<key>behavior</key>
<value>
<simple>{"objectId":"a28b93c3-fbbc-43d2-ab0c-9b0abcae5106","packageName":"component.field","className":"TextField","type":"TS"}</simple>
</value>
</entry>
<entry>
<key>propertyName</key>
<value>
<simple>"valueChangeEvent"</simple>
</value>
</entry>
</complex>
</value>
</item>
</value>
</entry>
<entry>
<key>ifCondition</key>
<value>
<complex>
<entry>
<key>conditions</key>
<value>
<item id="ff5d074b-77d4-48c6-a7c4-3ca7e585d8c9" removed="false">
<value>
<complex>
<entry>
<key>_isGroupSelected</key>
<value>
<simple>false</simple>
</value>
</entry>
<entry>
<key>one</key>
<value>
<complex>
<entry>
<key>conditionFirstPart</key>
<value>
<complex>
<entry>
<key>objectValue</key>
<value>
<complex>
<entry>
<key>behavior</key>
<value>
<simple>{"objectId":"a28b93c3-fbbc-43d2-ab0c-9b0abcae5106","packageName":"component.field","className":"TextField","type":"TS"}</simple>
</value>
</entry>
<entry>
<key>method</key>
<value>
<simple>"getValue"</simple>
</value>
</entry>
</complex>
</value>
</entry>
</complex>
</value>
</entry>
<entry>
<key>conditionSecondPart</key>
<value>
<complex>
<entry>
<key>staticValue</key>
<value>
<implRef type="TS">
<className>string</className>
<packageName></packageName>
</implRef>
<simple>"null"</simple>
</value>
</entry>
</complex>
</value>
</entry>
<entry>
<key>operation</key>
<value>
<simple>"IS_NOT_EMPTY"</simple>
</value>
</entry>
</complex>
</value>
</entry>
</complex>
</value>
</item>
<item id="af4102d7-698c-420e-a7fe-ca9bf69a29a7" removed="true"/>
</value>
</entry>
<entry>
<key>logicalOperation</key>
<value>
<simple>null</simple>
</value>
</entry>
</complex>
</value>
</entry>
<entry>
<key>thenActions</key>
<value>
<item id="7654b087-130d-4441-9acf-cdd831c65374" removed="false">
<value>
<complex>
<entry>
<key>behavior</key>
<value>
<simple>{"objectId":"cfb60860-1b04-4eb5-9ccf-1e6436c27b09","packageName":"component.button","className":"Button","type":"TS"}</simple>
</value>
</entry>
<entry>
<key>method</key>
<value>
<simple>"setVisible"</simple>
</value>
</entry>
<entry>
<key>value</key>
<value>
<complex>
<entry>
<key>staticValue</key>
<value>
<implRef type="TS">
<className>boolean</className>
<packageName></packageName>
</implRef>
<simple>true</simple>
</value>
</entry>
</complex>
</value>
</entry>
</complex>
</value>
</item>
<item id="83e45626-89e0-4dd6-9caf-a17d6c474a72" removed="false">
<value>
<complex>
<entry>
<key>behavior</key>
<value>
<simple>{"objectId":"dd701bad-b22d-40c9-b00b-b92f070890db","packageName":"ervu.component.textwithdialoglinks","className":"TextWithDialogLinks","type":"TS"}</simple>
</value>
</entry>
<entry>
<key>method</key>
<value>
<simple>"setVisible"</simple>
</value>
</entry>
<entry>
<key>value</key>
<value>
<complex>
<entry>
<key>staticValue</key>
<value>
<implRef type="TS">
<className>boolean</className>
<packageName></packageName>
</implRef>
<simple>true</simple>
</value>
</entry>
</complex>
</value>
</entry>
</complex>
</value>
</item>
<item id="8d08e1aa-8fdc-4c49-b995-f1e1f40452d1" removed="false">
<value>
<complex>
<entry>
<key>behavior</key>
<value>
<simple>{"objectId":"d68b5c38-9ed6-4596-9b0c-dd1dc542c5ef","packageName":"component.button","className":"Button","type":"TS"}</simple>
</value>
</entry>
<entry>
<key>method</key>
<value>
<simple>"setVisible"</simple>
</value>
</entry>
<entry>
<key>value</key>
<value>
<complex>
<entry>
<key>staticValue</key>
<value>
<implRef type="TS">
<className>boolean</className>
<packageName></packageName>
</implRef>
<simple>true</simple>
</value>
</entry>
</complex>
</value>
</entry>
</complex>
</value>
</item>
<item id="d0250c79-e72e-4997-8d8e-0dcd9ea93f42" removed="false">
<value>
<complex>
<entry>
<key>behavior</key>
<value>
<simple>{"objectId":"fea5aebc-c206-48bc-a613-ab31813fd639","packageName":"component.container","className":"HBox","type":"TS"}</simple>
</value>
</entry>
<entry>
<key>method</key>
<value>
<simple>"setVisible"</simple>
</value>
</entry>
<entry>
<key>value</key>
<value>
<complex>
<entry>
<key>staticValue</key>
<value>
<implRef type="TS">
<className>boolean</className>
<packageName></packageName>
</implRef>
<simple>true</simple>
</value>
</entry>
</complex>
</value>
</entry>
</complex>
</value>
</item>
<item id="9d3d9d9b-772e-4db7-841d-63d12caa1422" removed="false">
<value>
<complex>
<entry>
<key>behavior</key>
<value>
<simple>{"objectId":"d5fa2655-8dd8-4004-9dec-217a41e5b9ed","packageName":"component","className":"Text","type":"TS"}</simple>
</value>
</entry>
<entry>
<key>method</key>
<value>
<simple>"setVisible"</simple>
</value>
</entry>
<entry>
<key>value</key>
<value>
<complex>
<entry>
<key>staticValue</key>
<value>
<implRef type="TS">
<className>boolean</className>
<packageName></packageName>
</implRef>
<simple>true</simple>
</value>
</entry>
</complex>
</value>
</entry>
</complex>
</value>
</item>
</value>