- Создал(а) Неизвестный пользователь (pavel.shevchenko), редактировал(а) Неизвестный пользователь (a.s.voronin@rt-sk.ru) янв 07, 2025

## Функциональные возможности

- ### Печать

- ### Штамп

- ### Конвертация

### Печать

В режиме печати происходит получения шаблона и json из входных данных.

возможна обработка двух типов docx и html

Будем рассматривать на примере шаблона docx.

Заполнение шаблонного документа docx формата данными из json формата. значения заключенные в двойные фигурные скобки внутри docx заменяются на соответствующие значения из json
Пример:

Тело docx документа

?

`Директору ООО Шайки-лейки` `от {{document.applicant.lastName}} {{document.applicant.firstName}} {{document.applicant.middleName}}` `жалоба.` `Доношу до вашего сведения информацию об отвратительном состоянии инвентаря в бане № {{document.subject_number}}`
`Полки не мыты. Полы залиты.`
`Крайне недоволен. Исправьте ситуацию.`
`{{document.``date``}} {{document.applicant.shortFIO}}`

Данные в виде json

?

`{` `` `"document"``:` `` `{` `` `"applicant"``:` `` `{`
`` `"firstName"``:` `"Иван"``,`
`` `"lastName"``:` `"Иванов"``,`
`` `"middleName"``:` `"Иванович"`
`` `},`
`` `"subject_number"``: 4,`
`` `"shortFIO"``:``"Иванов И. И."``,`
`` `"date"``:``"03.01.2023"`
`` `}`
`}`

### Штамп

в режиме штамп на входящий документ накладывается дополнительный текст, а также сформированное изображение из сертификата, которое отражает инициалы подписавшего и срок действия сертификата

Возможные типы входящих документов для версии 2.0.0

pdf, docx

Штамп успешно накладывается и регулируется входными и параметрами настройки в случае,

если контент внутри документа является текстовым.

Если внутри документа содержится изображение масштабированное на весь лист (например скан), то для такого документа корректное наложение штампа не предусмотрено.

Параметры для наложения штампа на документ следующие

certificate - Сертификат подписанта в Base64
s3url - ссылка на s3, например s3://bucket/templateResolution-b559615a-af21-417f-9a63-e5f6eca42342.docx
stampWidth - ширина штампа в пикселях (если не указано, то по умолчанию 220)
stampHeight - высота штампа в пикселях (если не указано, то по умолчанию 85)
stampAlign - размещение штампа на странице (если не указано, по умолчанию справа [LEFT/RIGHT])
rightText - Текст для вывода слева от штампа
leftText - Текст для вывода слева от штампа

pageNumber - Номер страницы для печати (Последняя страница по дефолту)
leftMargin - Отступ от левого края для текста слева страницы (в символах)
rightMargin - Отступ от правого края для текста справа страницы (в символах)

Также предусмотрен функционал совместной последовательной печати и штампа.

### Конвертация

Под конвертацией понимается преобразование одного типа документа в другой.

В данный момент возможны следующие направления конвертации:

HTML → PDF

HTML → DOCX

DOCX → PDF

В любом из функциональных возможностей обязательно указание направление конвертации

в виде двух параметров

inputFormat

outputFormat

inputFormat для функционала Печать также позволяет определить тип передаваемого шаблона

outputFormat указывает в какой тип файла будет в результате.

Если указанные параметры конвертации будут указаны неверно, то возникает ошибка с указанием о этом.

##
Режимы работы

### Кафка

В режиме работы через kafka, выполняется разбор сообщений поступающих в топики

printer.process.print - функционала печати

printer.process.stamp - функционал штампа

printer.process.print-stamp - функционал последовательного применения печати и штампа

Выполняется функциональное действие соответствующее каждому топику

Результат в виде готового файла размещается в хранилище s3, ссылка на результат прикладывается в отчет о выполнении.

Сам отчет в виде сообщения кафки публикуется в топик printer.report

Функционалы печать, штамп, печать+штамп можно включить или выключить в зависимости от настроек экземпляра сервиса, которые требуются для него.

При масштабирования сервиса, возможна конкуренция за вычитку сообщений из топиков, поэтому для каждого экземпляра назначается свой consumer-group-id, на основе переменной окружения POD_NAME.

Также добавлена возможность идемпотентной обработки (MODE_KAFKA_IDEMPOTENCY), для избежания дублирующих заданий на печать/штамп с последующим результатом в s3 и топик printer.report

Предусмотрен таймаут выполнения одного задания при работе через kafka (KAFKA_PRINT_TASK_EXECUTION=4m)

### HTTP REST

В этом варианте присутствуют два режима обработки, синхронный и асинхронный.

В синхронном режиме входными параметрами являются шаблон и json-параметры для функционала печати,

для функционала штампа документ и параметры штампа.

Запрос блокируются до окончания выполнения и получения готового документа либо ошибки во время выполнения.

В асинхронном режиме, проверяется направление конвертации, затем параллельно запускается обработка задания на печать (наложение штампа)

Если конвертация не поддерживается то сразу возвращается ошибка о неприменимости такого действия (http 406)

По окончании задания на печать формируется отчет в топик кафки printer.report

Возможно прямое перенаправление асинхронных запросов в топики кафки. (MODE_REST_KAFKA_REDIRECT)

Предполагается, что это предотвратит потерю результата в момент рестарта сервиса и не законченном задании на печать.

## Конечные точки

/normalize

Очищает плейсхолдеры в docx шаблоне от форматирования синхронно.
Ворд может разбивать текст на отдельные блоки форматирования, ломая mustache.
Метод вырезает все xml-теги между фигурными скобками, присваивая стиль всему плейсхолдеру, как у открывающейся скобки.

/sync/{input}/to/{output}

Печатает шаблон синхронно в указанном формате (input) и конвертирует его в указанный формат (output), немедленно возвращает распечатанный документ как файл в http ответе

/stamp/sync/{input}/to/{output}
Добавляет штамп в документ синхронно в указанном формате (input) и конвертирует его в указанный формат (output), немедленно возвращает распечатанный документ как файл в http ответе

/sync/stamp-print/{input}/to/{output}
Печатает шаблон синхронно в указанном формате (input), накладывает штамп и конвертирует его в указанный формат (output), немедленно возвращает распечатанный документ как файл в http ответе

/async/{input}/to/{output}
Принимает шаблон в асинхронную печать

/stamp/async/{input}/to/{output}
Принимает документ для асинхронной печати штампа в указанном формате (input) и конвертирует его в указанный формат (output) и отсылает сообщение о статусе печати вместе с ссылкой на скачивание из S3 в Kafka Topic

/async/stamp-print/{input}/to/{output}
Принимает шаблон в асинхронную печать в указанном формате (input), накладывает штамп и конвертирует его в указанный формат (output) и отсылает сообщение о статусе печати вместе с ссылкой на скачивание из S3 в Kafka Topic

/selftest
самодиагностика сервиса

возращает результат проверки функциональных возможностей
{
docxPrint: SUCCESS,
htmlPrint: SUCCESS,
pdfStamp: SUCCESS,
docxStamp: SUCCESS,
htmlStampAfterPrint: SUCCESS,
docxStampAfterPrint: SUCCESS
}

/swagger-ui
Доступен сваггер c описанием REST-методов

/health
Проверка работоспособности сервиса от micronaut

/prometheus
Точка предоставления метрик для Prometheus

## Настройки

?

`micronaut:` `` `application:` `` `name:` `printer` `` `default-charset:` `UTF-8` `` `server:`
`` `port:` `$``{``SERVICE_PORT``:``8080``}`
`` `metrics:`
`` `enabled:` `true`
`` `export:`
`` `prometheus:`
`` `enabled:` `true`
`` `step:` `PT1M`
`` `descriptions:` `true`
`` `heartbeat:`
`` `enabled:` `false`
`` `health:`
`` `monitor:`
`` `enabled:` `true`
`` `router:`
`` `static-resources:`
`` `swagger-ui:`
`` `paths:` `classpath``:``/swagger-ui`
`` `mapping:` `/swagger-ui/**`
`` `security:`
`` `enabled:` `$``{``SECURITY_ENABLED``:``true``}` `# вкл\выкл безопасности`
`` `token:`
`` `enabled:` `true` `# включаем token-based безопасность`
`` `jwt:`
`` `enabled:` `true`
`` `bearer:`
`` `enabled:` `true`
`logger:`
`` `levels:`
`` `root:` `$``{``PRINT_LOG_LEVEL``:``INFO``}`
`` `sx.microservices:` `$``{``SX_LOG_LEVEL``:``INFO``}`
`s3:`
`` `enabled:` `$``{``AWS_S3_ENABLED``:``true``}`
`` `url:` `$``{``AWS_ENDPOINT``:```http``:``//localhost``:``9011```}`
`` `urlExternal:` `$``{``AWS_ENDPOINT_EXTERNAL``:```http``:``//localhost``:``9011```}`
`` `key:` `$``{``AWS_ACCESS_KEY_ID``:``}`
`` `secret:` `$``{``AWS_SECRET_ACCESS_KEY``:``}`
`` `bucket:` `$``{``AWS_S3_BUCKET``:``printed-documents``}`
`` `bucket-suffix-enabled:` `$``{``AWS_S3_BUCKET_SUFFIX_ENABLED``:``false``}`
`` `bucket-create-if-not-exist:` `$``{``AWS_S3_BUCKET_CREATE_IF_NOT_EXIST``:``true``}`
`` `url-expire-in-seconds:` `$``{``AWS_S3_URL_EXPIRE_SECONDS``:``604800``}`
`` `url-presigned-enabled:` `$``{``AWS_S3_URL_PRESIGNED_ENABLED``:``true``}`
`` `health:`
`` `enabled:` `$``{``AWS_S3_HEALTH_ENABLED``:``true``}`
`` `timeout:` `$``{``AWS_S3_HEALTH_TIMEOUT``:``3000ms``}`
`` `retries:` `$``{``AWS_S3_HEALTH_RETRIES``:``2``}`
`redis:`
`` `uri:` `$``{``REDIS_CONNECTION_STRING``:```redis``:``//localhost```}`
`` `caches:`
`` `print-processing-cache:`
`` `expire-after-write:` `2h`
`` `stamp-processing-cache:`
`` `expire-after-write:` `2h`
`swagger:`
`` `merge-files:` `false`
`` `sso-endpoint:` `$``{``SSO_CLIENT_URL_HOST``:```https``:``//pgs2-uat-sso.test.gosuslugi.ru```}`
`#Настройки режима работы экземпляра сервиса`
`mode:`
`` `#Режим работы через кафка`
`` `kafka:`
`` `enabled:` `true`
`` `#Обработка заполнения шаблона, с последующей конвертацией`
`` `print:`
`` `enabled:` `true`
`` `#Обработка подписания (наложения штампа подписанта)`
`` `stamp:`
`` `enabled:` `true`
`` `#Обработка заполнения шаблона, затем наложения штампа`
`` `print-stamp:`
`` `enabled:` `true`
`` `#Вкючить режим идемпотентной обработки сообщений`
`` `idempotency:` `true`
`` `#Режим работы через REST`
`` `rest:`
`` `enabled:` `true`
`` `#перенаправлять асинхроные запросы в kafka топики`
`` `kafka-redirect:` `true`
`printer-topics:`
`` `report:` `$``{``KAFKA_TOPIC_PREFIX``:``}``printer.report`
`` `print-consumer:` `$``{``KAFKA_TOPIC_PREFIX``:``}``printer.process.print`
`` `stamp-consumer:` `$``{``KAFKA_TOPIC_PREFIX``:``}``printer.process.stamp`
`` `print-stamp-consumer:` `$``{``KAFKA_TOPIC_PREFIX``:``}``printer.process.print-stamp`
`kafka:`
`` `group-id-prefix:` `$``{``KAFKA_GROUP_PREFIX``:``}`
`` `group-id-suffix:` `_$``{``POD_NAME``:``}`
`` `bootstrap:`
`` `servers:` `$``{``KAFKA_HOSTS``:```localhost``:``9092``,``localhost``:``9093``,``localhost``:``9094```}`
`` `health:`
`` `enabled:` `$``{``KAFKA_ENABLED``:``true``}`
`` `producers:`
`` `default:`
`` `retries:` `3`
`` `health-timeout:` `4500ms`
`` `max:`
`` `poll:`
`` `records:` `500`
`` `interval:`
`` `ms:` `300000`
`` `#Таймаут на выполнение одного задания на печать, при работе через кафка`
`` `print-task-execution:` `4m`
`secure-configuration:`
`` `token-validation:`
`` `enabled:` `true`
`` `trusted-issuers:` `$``{``TRUSTED_ISSUERS``:``}`
`` `scopes:`
`` `-` `printer`
`` `userinfo-roles:`
`` `enabled:` `true`
`` `path:` `/userinfo`
`# Конфигурация библиотеки client-token-manager`
`token-manager:`
`` `enabled:` `true`
`` `# В случае невозможности использовать автоматическую конфигурацию OIDC, тут указывается Token Endpoint.`
`` `token-endpoint:` `$``{``SSO_CLIENT_URL_HOST``:```http``:``//sso-service```}``/token`
`` `# Зарегистрированный client_id.`
`` `client-id:` `$``{``SSO_CLIENT``:``printer-client``}`
`` `# Зарегистрированный client_secret.`
`` `client-secret:` `$``{``SSO_CLIENT_SECRET``:``93456662-5e0c-4ea1-883c-fd6be4c82d29``}`
`` `# Необходимые для работы приложения скоупы.`
`` `scope:` `openid``,``ClientScope1``,``service`
`` `# За сколько секунд до окончания времени жизни токена нужно будет получить новый. По умолчанию 15 секунд.`
`` `token-expires-in-skew:` `$``{``SSO_CLIENT_REFRESH_TOKEN_BEFORE``:``60s``}`
`jackson:`
`` `date-format:` `yyyy-MM-dd``'T'``HH``:``mm``:``ss.SSSXXX`
`endpoints:`
`` `loggers:`
`` `enabled:` `true`
`` `health:`
`` `enabled:` `true`
`` `sensitive:` `false`
`` `details-visible:` `ANONYMOUS` `# show details for everyone`
`` `metrics:`
`` `enabled:` `false`
`` `sensitive:` `true`
`` `prometheus:`
`` `enabled:` `true`
`` `sensitive:` `false`
`tracing:`
`` `jaeger:`
`` `enabled:` `$``{``JAEGER_ENABLED``:``false``}`
`` `exclude-paths:`
`` `-` `/health`
`` `-` `/prometheus`
`` `-` `/favicon.ico`
`` `-` `/api`
`` `-` `/swagger-ui`
`` `sampler:`
`` `probability:` `$``{``JAEGER_SAMPLER_PROBABILITY``:``1``}`
`` `sender:`
`` `agentHost:` `$``{``JAEGER_HOST``:``localhost``}`
`` `agentPort:` `$``{``JAEGER_PORT``:``6831``}`
`libreoffice:`
`` `enabled:` `$``{``LIBREOFFICE_ENABLED``:``true``}`
`` `office-home:` `/usr/lib/libreoffice`
`` `portNumbers:` `8105``,``8104``,``8103``,``8102``,``8101`
`` `maxTasksPerProcess:` `100`
`` `taskExecutionTimeout:` `30000`
`` `process-timeout:` `5000`
`` `startFailFast:` `true`
`` `remote:`
`` `enabled:` `false`
`` `url:` `'http://libreoffice.online'`
`` `connectTimeout:` `60000` `# минута`
`` `socketTimeout:` `12000` `# 2 минуты`
`` `poolSize:` `1`
`#Предпочтения конвертеров`
`converters:`
`` `#input`
`` `html:`
`` `#output`
`` `pdf:`
`` `-` `HtmlToPdfLibreOfficeConverter`
`` `-` `OpenHtmlToPdfConverter`
`` `-` `WkHtmlToPdfConverter`
`` `-` `SauseHtmlToPdfConverter`
`` `docx:`
`` `-` `HtmlToDocxLibreOfficeConverter`
`` `-` `HtmlToDocxConverter`
`` `#input`
`` `docx:`
`` `#output`
`` `pdf:`
`` `-` `DocxToPdfLibreOfficeConverter`
`` `-` `ApacheDocxToPdfConverter`

##
Журналирование

Логирование в json формате включается переменной окружения JSON_ENABLE=true
Уровень логирования указывается в переменной окружения PRINT_LOG_LEVEL=INFO (ERROR,INFO,DEBUG)

## Необходимые ресурсы окружения сервиса

#### sso

переменная окружения TOKEN_MANAGER_TOKEN_ENDPOINT

####
kafka

переменная окружения KAFKA_HOSTS

#### redis

переменная окружения REDIS_CONNECTION_STRING

#### s3

переменные окружения

AWS_ENDPOINT
AWS_ENDPOINT_EXTERNAL

#### jaeger

переменные окружения

JAEGER_HOST
JAEGER_PORT

#### kubernetess

Для старта приложения требуется примерно от 15 до 30 секунд, поэтому стартап проба должна быть от этих значений.

Для остальных проб(readiness,liveness) нужно использовать подготовленный внутри образа скрипт

/readiness.sh

В случае успешной проверки он возвращает exit_code=0 иначе exit_code>0

Внутри скрипта выполняются проверки на соответствие

количества экземпляров libreOffice запущенных сейчас с количеством указанных в настройках при старте экземпляра сервиса.

затем проверка на доступность http, так как он также является индикатором для успешного старта экземпляра сервиса

## Мониторинг

Предусматривает несколько графиков регистрирующих количество запросов функционала (печать,штамп,штамп+печать) и количество ответов, по одному на каждый функционал

Также на каждый функционал имеются графики с ошибками. Их два: первый в разрезе направления конвертации, второй детальный по тексту ошибки и экземплярам сервисов.

Метрики которые реализованы для экспорта в Prometheus (являются счетчиками)

printRequest
stampRequest
printStampRequest

printCompleted
stampCompleted
printStampCompleted

printError
stampError
printStampError

для всех метрик добавляются следующие теги

from, to, fileName

traceId, podName

для режима работы через кафку также добавляется тэг kafka=true

в режиме обработки через кафку также добавляется тэг retryCount, если он присутствовал в заголовке исходного сообщения кафки.

retryCount ( счетчик повторов для одного задания на печать/штамп)

для метрик с суффиксом Error, добавляется тэг duration и error (с текстом ошибки)

для метрик с суффиксом Completed, добавляется также тэг duration (время в секундах прошедшее с начала обработки задания печати/штампа)

## Примеры:

### Формирование заявления

Для формирования используется шаблон template_HuntingResourcesResult_0_2.docx и данные json из файла HuntingResourcesResult_0_2.json

?

`curl -X POST https:``//pgs2-uat``.``test``.gosuslugi.ru``/service/printer/sync/DOCX/to/DOCX` `\` `-H` `'Authorization: Bearer eyJraWQiOiJzc29rZXkxIiwidHlwIjoiSldUIiwiYWxnIjoiUlM1MTIifQ. .IU1EuZ3Uh8PuZjmkUBktzesiZlU7PilAICuZM6-tKaZq7qS6NmC6tK5-4s5BWPm5BFpE2VkMlzOnBzFVnikjGzKcQ2QY40j8L6kEgUADN6jzE3xpQyI_IGnppFXpkurVgeHUlF2jKFTXrAZpektFClbqDmqYJM4nEvp7HGbLjurFixX23v8EcS5HIIN97lhTJaHqzir1keg427W4FhGL4f9sxkbXWenBDkMxDQA0lzWgNZeFL5khSNgPUr9ovIiHN_CmuKQy3gkS756k7QNe75LANdXd-Chaziz7M4Qmjjv6MM1CGSaPhOrqeVsUZI9cKeCFBlTLGfsxVCXuk_dG6w'` `\`
`-H` `'Content-Type: multipart/form-data'` `\`
`-F` `'template=@template_HuntingResourcesResult_0_2.docx'` `\`
`-F` `'parameters=@HuntingResourcesResult_0_2.json'` `\`
`-o HuntingResourcesResult_0_2.docx`

### Формирование межведомственного запроса

Для формирования используется шаблон template_EGRUL-INN.html и данные json

?

`curl -X POST https:``//pgs2-uat``.``test``.gosuslugi.ru``/service/printer/sync/stamp-print/HTML/to/PDF` `\` `-H` `'Authorization: Bearer eyJraWQiOiJzc29rZXkxIiwidHlwIjoiSldUIiwiYWxnIjoiUlM1MTIifQ. .IU1EuZ3Uh8PuZjmkUBktzesiZlU7PilAICuZM6-tKaZq7qS6NmC6tK5-4s5BWPm5BFpE2VkMlzOnBzFVnikjGzKcQ2QY40j8L6kEgUADN6jzE3xpQyI_IGnppFXpkurVgeHUlF2jKFTXrAZpektFClbqDmqYJM4nEvp7HGbLjurFixX23v8EcS5HIIN97lhTJaHqzir1keg427W4FhGL4f9sxkbXWenBDkMxDQA0lzWgNZeFL5khSNgPUr9ovIiHN_CmuKQy3gkS756k7QNe75LANdXd-Chaziz7M4Qmjjv6MM1CGSaPhOrqeVsUZI9cKeCFBlTLGfsxVCXuk_dG6w'` `\`
`-H` `'Content-Type: multipart/form-data'` `\`
`-F` `'template=@template_EGRUL-INN.html'` `\`
`-F 'parameters={`
`` `"rightText"``:` `"Текст справа"``,`
`` `"leftText"``:` `"Текст слева"``,`
`` `"certificate"``:` `" "`
`}' \`
`-o EGRUL-INN.pdf`

Нравится Станьте первыми кому понравится это

- Нет меток
- Редактировать метки

Написать комментарий...

Добавить комментарий

Обзор
Инструменты контента
{"serverDuration": 93, "requestCorrelationId": "ebf887f0f47f1ab4"}
search
recentlyviewed
attachments
weblink
advanced
image-effects
image-attributes

- Абзац

- Жирный
- Курсив
- Подчеркнутый
- Cредство выбора цвета
  Дополнительные цвета
- Форматирование

- Маркированный список
- Нумерованный список

- Список задач

- Убрать отступ
- Сделать отступ

- Выровнить по левому краю
- Выровнить по центру
- Выровнить по правому краю

- Разметка страницы

- Ссылка

- Таблица

- Вставить

- Разметка страницы

- Отменить
- Восстановить

- Найти/Заменить

- Справка по быстрым ссылкам на клавиатуре

Подключение...