From 11883a72ad84285612d6a8f0f40a336112d27247 Mon Sep 17 00:00:00 2001 From: gulnaz Date: Sun, 18 Aug 2024 23:25:57 +0300 Subject: [PATCH] SUPPORT-8412: add rpc for extract button; fix standalone --- .../controller/ErvuDataController.java | 4 +- .../ervu_lkrp_fl/rpc/ExtractRpcService.java | 72 ++ .../service/KafkaProducerService.java | 24 +- config/patches/default.cli | 5 + config/standalone/dev/standalone.xml | 5 + .../component/button/ExtractLoadService.ts | 83 ++ .../LK RP FL/screen-form-fl.page | 720 +++++++++++++++++- 7 files changed, 907 insertions(+), 6 deletions(-) create mode 100644 backend/src/main/java/ervu_lkrp_fl/ervu_lkrp_fl/rpc/ExtractRpcService.java create mode 100644 frontend/src/ts/ervu/component/button/ExtractLoadService.ts diff --git a/backend/src/main/java/ervu_lkrp_fl/ervu_lkrp_fl/controller/ErvuDataController.java b/backend/src/main/java/ervu_lkrp_fl/ervu_lkrp_fl/controller/ErvuDataController.java index 67ece54..978b56f 100644 --- a/backend/src/main/java/ervu_lkrp_fl/ervu_lkrp_fl/controller/ErvuDataController.java +++ b/backend/src/main/java/ervu_lkrp_fl/ervu_lkrp_fl/controller/ErvuDataController.java @@ -32,6 +32,8 @@ public class ErvuDataController { @Value("${kafka.ervu.recruit.reply.topic}") private String replyTopic; + @Value("${kafka.ervu.subpoena.timeout:10}") + private int timeout; public ErvuDataController(KafkaProducerService kafkaProducerService, ConsumerFactory consumerFactory, @@ -56,7 +58,7 @@ public class ErvuDataController { try (Consumer consumer = consumerFactory.createConsumer("fl-recruit", null)) { consumer.subscribe(Collections.singletonList(replyTopic)); - ConsumerRecords consumerRecords = consumer.poll(Duration.ofSeconds(10)); + ConsumerRecords consumerRecords = consumer.poll(Duration.ofSeconds(timeout)); consumerRecords.forEach(record -> { try { diff --git a/backend/src/main/java/ervu_lkrp_fl/ervu_lkrp_fl/rpc/ExtractRpcService.java b/backend/src/main/java/ervu_lkrp_fl/ervu_lkrp_fl/rpc/ExtractRpcService.java new file mode 100644 index 0000000..2f350ec --- /dev/null +++ b/backend/src/main/java/ervu_lkrp_fl/ervu_lkrp_fl/rpc/ExtractRpcService.java @@ -0,0 +1,72 @@ +package ervu_lkrp_fl.ervu_lkrp_fl.rpc; + +import java.time.Duration; +import java.util.Collections; +import java.util.concurrent.atomic.AtomicReference; + +import com.google.protobuf.InvalidProtocolBufferException; +import ervu_lkrp_fl.ervu_lkrp_fl.dto.FileData; +import ervu_lkrp_fl.ervu_lkrp_fl.dto.PersonWithFormatRequestDto; +import ervu_lkrp_fl.ervu_lkrp_fl.service.KafkaProducerService; +import org.apache.kafka.clients.consumer.Consumer; +import org.apache.kafka.clients.consumer.ConsumerRecords; +import org.apache.kafka.common.utils.Bytes; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.kafka.core.ConsumerFactory; +import rtl.pgs.ervu.proto.ExtractRegistry; +import rtl.pgs.ervu.proto.LkrpResponse; +import rtl.pgs.ervu.proto.ResponseData; + +import ru.cg.webbpm.modules.webkit.annotations.RpcCall; +import ru.cg.webbpm.modules.webkit.annotations.RpcService; +import ru.cg.webbpm.modules.webkit.beans.Behavior; + +/** + * @author gulnaz + */ +@RpcService +public class ExtractRpcService extends Behavior { + + @Autowired + private KafkaProducerService kafkaProducerService; + @Autowired + private ConsumerFactory consumerFactory; + + @Value("${kafka.ervu.subpoena.extract.reply.topic}") + private String subpoenaExtractReplyTopic; + @Value("${kafka.ervu.registry.extract.reply.topic}") + private String registryExtractReplyTopic; + @Value("${kafka.ervu.extract.timeout:20}") + private int timeout; + + @RpcCall + public FileData getExtract(PersonWithFormatRequestDto request) { + kafkaProducerService.sendRequestForExtract(request); + AtomicReference fileDataRef = new AtomicReference<>(); + + try (Consumer consumer = + consumerFactory.createConsumer("fl-extract", null)) { + String topic = request.formatExtractRegistry().equals("1") + ? subpoenaExtractReplyTopic + : registryExtractReplyTopic; + consumer.subscribe(Collections.singletonList(topic)); + ConsumerRecords consumerRecords = consumer.poll(Duration.ofSeconds(timeout)); + consumerRecords.forEach(record -> { + + try { + ResponseData responseData = ResponseData.parseFrom(record.value().get()); + ExtractRegistry extractRegistry = responseData.getDataRegistryInformation().getExtractRegistry(); + fileDataRef.set(new FileData(extractRegistry.getFileName(), extractRegistry.getFileType(), + extractRegistry.getFile().toByteArray())); + } + catch (InvalidProtocolBufferException e) { + throw new RuntimeException("Failed to parse data", e); + } + }); + consumer.commitSync(); + } + + return fileDataRef.get(); + } +} diff --git a/backend/src/main/java/ervu_lkrp_fl/ervu_lkrp_fl/service/KafkaProducerService.java b/backend/src/main/java/ervu_lkrp_fl/ervu_lkrp_fl/service/KafkaProducerService.java index 6b045ff..200c4c4 100644 --- a/backend/src/main/java/ervu_lkrp_fl/ervu_lkrp_fl/service/KafkaProducerService.java +++ b/backend/src/main/java/ervu_lkrp_fl/ervu_lkrp_fl/service/KafkaProducerService.java @@ -4,6 +4,7 @@ import java.nio.charset.StandardCharsets; import java.util.UUID; import ervu_lkrp_fl.ervu_lkrp_fl.dto.PersonRequestDto; +import ervu_lkrp_fl.ervu_lkrp_fl.dto.PersonWithFormatRequestDto; import org.apache.kafka.clients.producer.ProducerRecord; import org.springframework.beans.factory.annotation.Value; import org.springframework.kafka.core.KafkaTemplate; @@ -19,16 +20,33 @@ public class KafkaProducerService { private final KafkaTemplate kafkaTemplate; @Value("${kafka.ervu.recruit.request.topic}") - private String requestTopic; + private String recruitRequestTopic; @Value("${kafka.ervu.recruit.header.class}") - private String headerClass; + private String recruitHeaderClass; + @Value("${kafka.ervu.subpoena.extract.request.topic}") + private String subpoenaExtractRequestTopic; + @Value("${kafka.ervu.registry.extract.request.topic}") + private String registryExtractRequestTopic; + @Value("${kafka.ervu.extract.header.class}") + private String extractHeaderClass; public KafkaProducerService(KafkaTemplate kafkaTemplate) { this.kafkaTemplate = kafkaTemplate; } public void sendRequest(PersonRequestDto request) { - ProducerRecord record = new ProducerRecord<>(requestTopic, + sendRequest(request, recruitRequestTopic, recruitHeaderClass); + } + + public void sendRequestForExtract(PersonWithFormatRequestDto request) { + String topic = request.formatExtractRegistry().equals("1") + ? subpoenaExtractRequestTopic + : registryExtractRequestTopic; + sendRequest(request, topic, extractHeaderClass); + } + + private void sendRequest(Object request, String topic, String headerClass) { + ProducerRecord record = new ProducerRecord<>(topic, UUID.randomUUID().toString(), request); record.headers().add("class", headerClass.getBytes(StandardCharsets.UTF_8)); kafkaTemplate.send(record); diff --git a/config/patches/default.cli b/config/patches/default.cli index 4303201..ddee4d9 100644 --- a/config/patches/default.cli +++ b/config/patches/default.cli @@ -71,3 +71,8 @@ xa-data-source add \ /system-property=kafka.ervu.recruit.request.topic:add(value="ervu.recruit.info.request") /system-property=kafka.ervu.recruit.reply.topic:add(value="ervu.recruit.info.response") /system-property=kafka.ervu.recruit.header.class:add(value="Request@urn://rostelekom.ru/RP-SummonsTR/1.0.5") +/system-property=kafka.ervu.subpoena.extract.request.topic:add(value="ervu.subpoena.info.request") +/system-property=kafka.ervu.subpoena.extract.reply.topic:add(value="ervu.subpoena.info.response") +/system-property=kafka.ervu.registry.extract.request.topic:add(value="ervu.extract.info.request") +/system-property=kafka.ervu.registry.extract.reply.topic:add(value="ervu.extract.info.response") +/system-property=kafka.ervu.extract.header.class:add(value="Request@urn://rostelekom.ru/ERVU-extractFromRegistryTR/1.0.3") diff --git a/config/standalone/dev/standalone.xml b/config/standalone/dev/standalone.xml index 0163485..b81715d 100644 --- a/config/standalone/dev/standalone.xml +++ b/config/standalone/dev/standalone.xml @@ -63,6 +63,11 @@ + + + + + diff --git a/frontend/src/ts/ervu/component/button/ExtractLoadService.ts b/frontend/src/ts/ervu/component/button/ExtractLoadService.ts new file mode 100644 index 0000000..e73755a --- /dev/null +++ b/frontend/src/ts/ervu/component/button/ExtractLoadService.ts @@ -0,0 +1,83 @@ +import { + AbstractButton, + AnalyticalScope, + Behavior, + Event, + NotNull, + Visible +} from "@webbpm/base-package"; +import {ExtractRpcService} from "../../../generated/ervu_lkrp_fl/ervu_lkrp_fl/rpc/ExtractRpcService"; + +// TODO remove; replace REQUEST_JSON with user id from token +const REQUEST_JSON = { + "common": { + "lastName": "Иванов", + "firstName": "Сергей", + "middleName": "Федорович", + "birthDate": "12.01.2005", + "snils": "08301894460", + "idERN": "111666898287" + }, + "document": { + "series": "4502", + "number": "160381", + "issueDate": "12.01.2019" + }, + "formatExtractRegistry": "1" +} + +@AnalyticalScope(AbstractButton) +export class ExtractLoadService extends Behavior { + + @Visible("false") + public successEvent: Event = new Event(); + @Visible("false") + public errorEvent: Event = new Event(); + @NotNull() + public formatExtractRegistry: string; + + private button: AbstractButton; + private rpc: ExtractRpcService; + private onClickFunction: Function; + + initialize() { + super.initialize(); + this.button = this.getScript(AbstractButton); + this.rpc = this.getScript(ExtractRpcService); + this.onClickFunction = () => { + REQUEST_JSON.formatExtractRegistry = this.formatExtractRegistry; + this.rpc.getExtract(REQUEST_JSON) + .then(fileData => { + const newBlob = new Blob([fileData['file']], + { type: fileData['fileType'] }); + + if (window.navigator && window.navigator.msSaveOrOpenBlob) { + window.navigator.msSaveBlob(newBlob); + } + else { + const data = window.URL.createObjectURL(newBlob); + const link = document.createElement("a"); + link.href = data; + link.download = fileData['fileName']; + link.click(); + URL.revokeObjectURL(data); + link.remove(); + this.successEvent.trigger(); + } + }) + .catch(() => { + this.errorEvent.trigger(); + }); + } + } + + bindEvents() { + super.bindEvents(); + this.button.addClickListener(this.onClickFunction); + } + + unbindEvents() { + super.unbindEvents(); + this.button.removeClickListener(this.onClickFunction); + } +} diff --git a/resources/src/main/resources/business-model/LK RP FL/screen-form-fl.page b/resources/src/main/resources/business-model/LK RP FL/screen-form-fl.page index 5106564..4b161e0 100644 --- a/resources/src/main/resources/business-model/LK RP FL/screen-form-fl.page +++ b/resources/src/main/resources/business-model/LK RP FL/screen-form-fl.page @@ -429,7 +429,6 @@ cefc3626-d99a-434e-983e-224ac0c15a4c FS - 1.1.1 (Повестки) true - false false @@ -1306,6 +1305,340 @@ + + + + + + 98594cec-0a9b-4cef-af09-e1b71cb2ad9e + 05edf991-97e8-46e9-b772-21dc3a2085e9 + AC - ошибка загрузки выписки + false + false + + + + eventRefs + + + + + + behavior + + {"objectId":"cfb60860-1b04-4eb5-9ccf-1e6436c27b09","packageName":"ervu.component.button","className":"ExtractLoadService","type":"TS"} + + + + propertyName + + "errorEvent" + + + + + + + + + ifCondition + + + + conditions + + + + + + logicalOperation + + null + + + + + + + thenActions + + + + + + behavior + + {"objectId":"0684bad5-3100-43c9-a1e8-0efe6eb62ae6","packageName":"component","className":"Text","type":"TS"} + + + + method + + "setVisible" + + + + value + + + + staticValue + + + boolean + + + true + + + + + + + + + + + + + + + + 98594cec-0a9b-4cef-af09-e1b71cb2ad9e + a0a3b0de-7f6e-4a1c-8c97-67286dd27629 + AC - показать загрузку + false + false + + + + eventRefs + + + + + + behavior + + {"objectId":"cfb60860-1b04-4eb5-9ccf-1e6436c27b09","packageName":"component.button","className":"Button","type":"TS"} + + + + propertyName + + "clickEvent" + + + + + + + + + ifCondition + + + + conditions + + + + + + logicalOperation + + null + + + + + + + thenActions + + + + + + behavior + + {"objectId":"0684bad5-3100-43c9-a1e8-0efe6eb62ae6","packageName":"component","className":"Text","type":"TS"} + + + + method + + "setVisible" + + + + value + + + + staticValue + + + boolean + + + false + + + + + + + + + + + + + behavior + + {"objectId":"8ed0924a-73dc-4732-8426-0a7217654309","packageName":"component.container","className":"HBox","type":"TS"} + + + + method + + "setVisible" + + + + value + + + + staticValue + + + boolean + + + true + + + + + + + + + + + + + + + 98594cec-0a9b-4cef-af09-e1b71cb2ad9e + bbec6bfa-4f30-421b-ad69-fc980a7b516a + AC - спрятать загрузку + false + false + + + + eventRefs + + + + + + behavior + + {"objectId":"cfb60860-1b04-4eb5-9ccf-1e6436c27b09","packageName":"ervu.component.button","className":"ExtractLoadService","type":"TS"} + + + + propertyName + + "successEvent" + + + + + + + + + + behavior + + {"objectId":"cfb60860-1b04-4eb5-9ccf-1e6436c27b09","packageName":"ervu.component.button","className":"ExtractLoadService","type":"TS"} + + + + propertyName + + "errorEvent" + + + + + + + + + ifCondition + + + + conditions + + + + + + logicalOperation + + null + + + + + + + thenActions + + + + + + + behavior + + {"objectId":"8ed0924a-73dc-4732-8426-0a7217654309","packageName":"component.container","className":"HBox","type":"TS"} + + + + method + + "setVisible" + + + + value + + + + staticValue + + + boolean + + + false + + + + + + + + + @@ -1416,6 +1749,30 @@ + + +ExtractLoadService +ervu.component.button + + true + true + + + formatExtractRegistry + + "1" + + + + + + +ExtractRpcService +ervu_lkrp_fl.ervu_lkrp_fl.rpc + + true + true + fd7e47b9-dce1-4d14-9f3a-580c79f59579 @@ -1528,6 +1885,7 @@ c3fc56e5-4aec-44e3-92ed-5fb7b6a68519 FS - 1.1.2 (Временные меры) true + false false @@ -3538,7 +3896,6 @@ 304824d5-9f9f-4af9-9b08-6232f7536774 FS - 1.1.3 (Воинский учёт) true - false false @@ -4500,6 +4857,30 @@ + + +ExtractLoadService +ervu.component.button + + true + true + + + formatExtractRegistry + + "2" + + + + + + +ExtractRpcService +ervu_lkrp_fl.ervu_lkrp_fl.rpc + + true + true + fd7e47b9-dce1-4d14-9f3a-580c79f59579 @@ -5190,6 +5571,340 @@ + + + + + + 98594cec-0a9b-4cef-af09-e1b71cb2ad9e + e3897ec9-927e-463b-b93c-9dbec04cba19 + AC - ошибка загрузки выписки + false + false + + + + eventRefs + + + + + + behavior + + {"objectId":"d68b5c38-9ed6-4596-9b0c-dd1dc542c5ef","packageName":"ervu.component.button","className":"ExtractLoadService","type":"TS"} + + + + propertyName + + "errorEvent" + + + + + + + + + ifCondition + + + + conditions + + + + + + logicalOperation + + null + + + + + + + thenActions + + + + + + behavior + + {"objectId":"f7303dfe-f3ef-42a6-bb59-8b818f38708b","packageName":"component","className":"Text","type":"TS"} + + + + method + + "setVisible" + + + + value + + + + staticValue + + + boolean + + + true + + + + + + + + + + + + + + + + 98594cec-0a9b-4cef-af09-e1b71cb2ad9e + 159eb91b-77f2-4bd4-93d4-98564fadb8b5 + AC - показать загрузку + false + false + + + + eventRefs + + + + + + behavior + + {"objectId":"d68b5c38-9ed6-4596-9b0c-dd1dc542c5ef","packageName":"component.button","className":"Button","type":"TS"} + + + + propertyName + + "clickEvent" + + + + + + + + + ifCondition + + + + conditions + + + + + + logicalOperation + + null + + + + + + + thenActions + + + + + + behavior + + {"objectId":"f7303dfe-f3ef-42a6-bb59-8b818f38708b","packageName":"component","className":"Text","type":"TS"} + + + + method + + "setVisible" + + + + value + + + + staticValue + + + boolean + + + false + + + + + + + + + + + + + behavior + + {"objectId":"9efda70f-bb28-4d82-964f-a2a5380bf5c1","packageName":"component.container","className":"HBox","type":"TS"} + + + + method + + "setVisible" + + + + value + + + + staticValue + + + boolean + + + true + + + + + + + + + + + + + + + 98594cec-0a9b-4cef-af09-e1b71cb2ad9e + c2119ea5-0827-430b-85b0-e500d7409c87 + AC - спрятать загрузку + false + false + + + + eventRefs + + + + + + behavior + + {"objectId":"d68b5c38-9ed6-4596-9b0c-dd1dc542c5ef","packageName":"ervu.component.button","className":"ExtractLoadService","type":"TS"} + + + + propertyName + + "successEvent" + + + + + + + + + + behavior + + {"objectId":"d68b5c38-9ed6-4596-9b0c-dd1dc542c5ef","packageName":"ervu.component.button","className":"ExtractLoadService","type":"TS"} + + + + propertyName + + "errorEvent" + + + + + + + + + ifCondition + + + + conditions + + + + + + logicalOperation + + null + + + + + + + thenActions + + + + + + + behavior + + {"objectId":"9efda70f-bb28-4d82-964f-a2a5380bf5c1","packageName":"component.container","className":"HBox","type":"TS"} + + + + method + + "setVisible" + + + + value + + + + staticValue + + + boolean + + + false + + + + + + + + + @@ -5222,6 +5937,7 @@ dbe60a18-ce7a-4423-9e5e-816edb7b0b4f VB - 1.2 true + false false