# Описание параметров конфигурации сервера приложений

Файл /standalone/configuration/standalone.xml

## Общие

- `webbpm.security.login.case_sensitive`. Default value = true. Параметр отвечающий за чувствительность к регистру при обработке логина пользователя.
  - true - Login и login, обрабатываются как разные логины.
  - false - Login и login, обрабатывается как один и тот же логин.
- `webbpm.db.pool_size`. Нужен только для `webbpm.mode` = development.
- `webbpm.mode`. Режим работы приложения. Значения - development, production.
  - development - в этом режиме используется соединение к БД проекта, заданное в Studio.
  - production - в этом режиме используется соединение к БД проекта, заданное с помощью jndi имени.

## jBPM

- `com.arjuna.ats.arjuna.allowMultipleLastResources`
- `webbpm.jbpm.audit-log.disabled` - флаг, отвечающий за включение/отключение аудита jBPM
- `webbpm.jbpm.cleaner_cron` - cron расписание автоматической очистки БД JBPM, по умолчанию "-" т.е. выключен. Очищаются незавершенные процессы.
- `webbpm.jbpm.cleaner_timeout` - время, спустя которое процесс считается устаревшим. По умолчанию - 10 часов.
- `webbpm.jbpm.finished_process_cleaner_cron` - cron расписание автоматической очистки аудита процессов в БД JBPM, по умолчанию "-" 
  т.е. выключен
- `webbpm.jbpm.finished_process_cleaner_timeout` - время, спустя которое процесс считается устаревшим. По умолчанию - 10 часов.

Пример:

```xml
<property name="com.arjuna.ats.arjuna.allowMultipleLastResources" value="true"/>
<property name="webbpm.db.pool_size" value="5"/>
<property name="webbpm.mode" value="development"/>
```

### jBPM Runtime Strategy

Возможные варианты runtime strategy:

- SINGLETON
- PER_REQUEST (значение по умолчанию)
- PER_PROCESS_INSTANCE
- PER_CASE

Пример:

```xml
<property name="webbpm.jbpm.runtime_strategy" value="PER_PROCESS_INSTANCE"/>
```

## Способ аутентификации

- authentication.method - способ аутентификации. Поддерживаемые способы аутентификации: form, kerberos, cert_over_db, cert_over_ldap

### По логину и паролю

Пример конфигурации:

```xml
<property name="authentication.method" value="form"/>
```

### По сертификату

- cert_over_db - проверка наличия пользователя в базе данных безопасности
- cert_over_ldap - проверка наличия пользователя в базе данных безопасности и в LDAP

Примеры:

```xml
<property name="authentication.method" value="cert_over_db"/>
<property name="authentication.method" value="cert_over_ldap"/>
```

Параметр способа аутентификации authentication.method должен быть также установлен на клиентской части приложения в app-config.json

Также для аутентификации по сертификату нужны свойства для хранилища сертификатов:

- certificate.keystore.location - путь до java key store. Key store - это хранилище доверенных сертификатов, с помощью которых можно проверить корневой сертификат. Сертификат устанавливается с помощью команды:
  
  ```text
  keytool -importcert -alias myAlias -file Example.cer -keystore exampleKeyStore  
  ```

- certificate.keystore.password - пароль для keystore, установленный при импорте сертификата

Примеры:

```xml
<property name="certificate.keystore.location" value="${jboss.home.dir}/mfc"/>
<property name="certificate.keystore.password" value="mfc_auth"/>
```

### Kerberos

Получите от администратора Kerberos .keytab файл, из которого командой `klist -k http.keytab` можно получить список principal-ов  
Проверить успешность авторизации principal-а можно командой `kinit -t -i http.keytab %principal%`.  
В
случае успешной авторизации команда `klist` в качестве default principal которым проводилась авторизация.
После этого в standalone.xml поправить параметр `app.service-principal` на principal, которым успешно авторизовались. principal имеет формат: `HTTP/%hostname%@%REALM%`

Пример конфигурации:

```xml
<property name="app.service-principal" value="HTTP/oleg-rxserver.alt.dom@ALT.DOM"/>
<property name="app.keytab-location" value="${jboss.home.dir}/http.keytab"/>
<property name="authentication.method" value="kerberos"/>
```

- app.service-principal. Пример - HTTP/oleg-rxserver.alt.dom@ALT.DOM
- app.keytab-location - расположение keytab файла. Пример - ${jboss.home.dir}/
- http.keytab.

Также необходимо в настройках браузера на клиенте задать параметр `network.negotiate-auth.trusted-uris` задать значение `.%domain%`.
Пример:

```xml
.ALT.DOM
```

### Ldap

Аутентификация происходит посредством логина и пароля синхронизированного пользователя Ldap.
Логин и пароль введенные в форму входа, будут проверены сервисом Ldap.

Пример конфигурации:

```xml
<property name="ldap.url" value="ldap://localhost:389"/>
<property name="ldap.base" value="dc=example,dc=org"/>
<property name="ldap.username" value="cn=admin,dc=example,dc=org"/>
<property name="ldap.password" value="admin"/>
<property name="authentication.method" value="form"/>
```

#### Настройка сервера приложений для работы с Kerberos

1. создать учетные записи в домене:
   
   - тестовые для проверки работоспособности функционала (пользователи домена, почтовые ящики):
   
   `User1 pass1 user1@example.com`
   
   `User2 pass2 user2@example.com`
   
   - сервисную для доступа сервиса(приложения) к MS AD - (пользователь домена - снять устаревание пароля, ограничение по времени действия, почтовый ящик):
   
   `serviceUser servicePass serviceuser@example.com`
   
   ---

2. завести учетную запись машины `appserver.machine.name` (fqdn-имя сервиса) в AD (вручную, как запись в computer) и в DNS (A-запись)
   
   `appserver.machine.name 10.250.216.91`

3. сгенерировать keytab (утилита ktpass) для аутентификации сервисов(приложения) для единой точки входа - `serviceUser` - с именем test.file.name.keytab - привязав к ней пользователя serviceUser
   
   например, так:
   
   ```
   ktpass -princ http/appserverMachineName.example.com@example.com -mapuser example.com\serviceUser -pass "пароль_уз_serviceUser" -crypto All -ptype KRB5_NT_PRINCIPAL -out "путь_к_директории_выгрузки_файла\test.file.name.keytab"
   ```

##### Kerberos FAQ

- В случае, если авторизация не проходит и в логах сервера приложений присутствует следующий вывод:
  
  ```
  2019-05-14 05:33:36,588 INFO  [security.controller.KerberosAuthenticationController] (default task-3) Authentication request header Authorization not exists
  2019-05-14 05:33:36,588 INFO  [security.controller.KerberosAuthenticationController] (default task-3) Authentication object is not presented
  ```
  
  необходимо проверить настройку браузера firefox `network.negotiate-auth.trusted-uris`, она должна соответствовать домену из principal-а.
  Для этого в поисковую строку браузера вводим "about:config", в открывшемся окне нажимаем "accept with risk and continue", в поисковой строке открывшейся страницы ввести `network.negotiate-auth.trusted-uris`.
  Пример: для principal-а `HTTP/oleg-rxserver.alt.dom@ALT.DOM` настройка в браузере должна быть `.alt.dom`, приложение в браузере должно открываться по `http:\\oleg-rxserver.alt.dom:8080\...`

- если в логах сервера приложений есть ошибка:
  
  ```xml
  2019-05-13 14:13:07,095 WARN  [org.springframework.security.kerberos.web.authentication.SpnegoAuthenticationProcessingFilter] (default task-1) Negotiate Header was invalid: Negotiate TlRMTVNTUAABAAAAl4II4gAAAAAAAAAAAAAAAAAAAAAKAGNFAAAADw==: org.springframework.security.authentication.BadCredentialsException: Kerberos validation not successful
  ...
  
  Caused by: java.security.PrivilegedActionException: GSSException: Defective token detected (Mechanism level: GSSHeader did not find the right tag)
   at java.security.AccessController.doPrivileged(Native Method) [rt.jar:1.8.0_211]
   at javax.security.auth.Subject.doAs(Subject.java:422) [rt.jar:1.8.0_211]
   at org.springframework.security.kerberos.authentication.sun.SunJaasKerberosTicketValidator.validateTicket(SunJaasKerberosTicketValidator.java:68) [spring-security-kerberos-core-1.0.1.RELEASE.jar:1.0.1.RELEASE]
   ... 66 more
  Caused by: GSSException: Defective token detected (Mechanism level: GSSHeader did not find the right tag)
   at sun.security.jgss.GSSHeader.(GSSHeader.java:97) [rt.jar:1.8.0_211]
   at sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.java:306) [rt.jar:1.8.0_211]
   at sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.java:285) [rt.jar:1.8.0_211]
   at org.springframework.security.kerberos.authentication.sun.SunJaasKerberosTicketValidatorKerberosValidateAction.run(SunJaasKerberosTicketValidator.java:170) [spring-security-kerberos-core-1.0.1.RELEASE.jar:1.0.1.RELEASE]
   at org.springframework.security.kerberos.authentication.sun.SunJaasKerberosTicketValidatorKerberosValidateAction.run(SunJaasKerberosTicketValidator.java:153) [spring-security-kerberos-core-1.0.1.RELEASE.jar:1.0.1.RELEASE]
   ... 69 more
  ```
  
  необходимо проверить правильность указанного в standalone.xml principal-а.

### Комбинации нескольких способов аутентификации

Приложение может обрабатывать запросы на несколько способов аутентификации. Для этого необходимо переичислить нужные профили через запятую.
Примеры:

```xml
<property name="authentication.method" value="form,cert_over_db"/>
<property name="authentication.method" value="form,cert_over_ldap"/>
<property name="authentication.method" value="kerberos,cert_over_db"/>
<property name="authentication.method" value="kerberos,cert_over_ldap"/>
```

### Время жизни токенов аутентификации

```xml
<property name="webbpm.security.access_token.duration.minutes" value="60"/>
<property name="webbpm.security.refresh_token.duration.days" value="30"/>
<property name="webbpm.security.session.active.count" value="2"/>
```

`webbpm.security.access_token.duration.minutes` - опциональный параметр (значение по умолчанию 60), время жизни в минутах, сколько будет действителен токен, после истечения этого времени токен будет обновлён `webbpm.security.refresh_token.duration.days` - опциональный параметр (значение по умолчанию 30), время жизни в днях, после истечения этого времени с последнего обновления, пользователю будет необходимо повторно войти `webbpm.security.session.active.count` - опциональный параметр (значение по умолчанию 1), количество сохраняемых в базу токенов обновления (количество активных сессий)

Примечания.

- Нельзя использовать одновременно профили cert_over_db c cert_over_ldap и kerberos с form.

## Синхронизация пользователей с LDAP

```xml
<property name="ldap.auto.sync.enabled" value="true"/>
<property name="ldap.synchronizer.cron" value="0 0 * * * *"/>
<property name="ldap.url" value="ldap://localhost:389"/>
<property name="ldap.base" value="dc=alt,dc=dom"/>
<property name="ldap.username" value="uid=test,ou=People,dc=alt,dc=dom"/>
<property name="ldap.password" value="password"/>
<property name="webbpm.ldap.implementation" value="open-ldap"/>
```

Настройки подключения к LDAP:

- `ldap.auto.sync.enabled` - включает/отключает автоматическую синхронизацию с LDAP
- `ldap.synchronizer.cron` - cron расписание автоматической синхронизации с LDAP
- `ldap.url`. Пример - ldap://localhost:389
- `ldap.base`. Пример - dc=alt,dc=dom
- `ldap.username`. Пример - uid=test,ou=People,dc=alt,dc=dom
- `ldap.password`
- `webbpm.ldap.implementation`. Допускается два значения: open-ldap и active-directory.

## WEBGUARD

Для синхронизации пользователей в WEBGUARD и для корректной работы админки необходимо указать настройки соединения к REST API WEBGUARD

```xml
<property name="webguard.url" value="http://wg-host:8081/security-manager"/>
<property name="webguard.user.login" value="wg-user"/>
<property name="webguard.user.password" value="wg-password"/>       
```

## Статистика

### jbpm hibernate statistics

Статистика hibernate jbpm доступна по jmx по пути `org.hibernate:type=Stats,name=jbpm`.
Полный список параметров можно посмотреть через jconsole.

По умолчанию включена, отключить можно настройкой `webbpm.jbpm.hibernate_statistics.enabled`:

```xml
<property name="webbpm.jbpm.hibernate_statistics.enabled" value="false"/>
```

## Schedulers по очистке базы *jbpm*.

- Очистка таблиц аудита от завершенных процессов по истечении таймаута
  
  - `webbpm.jbpm.finished_process_cleaner_cron` - задает расписание (*spring cron*), если настройка не задана - джоб не запускается
  - `webbpm.jbpm.finished_process_cleaner_timeout` - таймаут в часах (*целое числовое значение*)
  
  Пример:
  
  ```xml
  <property name="webbpm.jbpm.finished_process_cleaner_cron" value="0 * * * * *"/>
  <property name="webbpm.jbpm.finished_process_cleaner_timeout" value="2"/>
  ```
  
  ## Ограничения для запросов БД.

- `webbpm.db.query_limit_enabled` - флаг, отвечающий за вывод сообщений о превышении лимитов на количество возвращаемых записей. По умолчанию - false.

- `webbpm.db.select_records_max_limit` - максимальный лимит возвращаемых строк для запросов в БД, при превышении/равенстве данного лимита будет выброшена ошибка (*целое числовое значение*). По умолчанию - 100000

- `webbpm.db.select_records_min_limit` - минимальный лимит возвращаемых строк для запросов в БД, при превышении/равенстве данного лимита в логи будет выведен warning (*целое числовое значение*). По умолчанию - 1000

- `webbpm.db.execution_time_threshold`. The threshold for time of executing a statement. Система выводит сообщение в логи при превышении. Действует для запросов, созданных в jOOQ. По умолчанию - 1000 миллисекунд

- `webbpm.db.result_read_time_threshold`. The threshold for time of fetching a set of records from a ResultSet.
  . Система выводит сообщение в логи при превышении. Действует для запросов, созданных в jOOQ. По умолчанию - 50 миллисекунд

- `webbpm.db.results_count_threshold`. Система выводит сообщение в логи при превышении. Действует для запросов, созданных в jOOQ. По умолчанию - 1000 записей

- `webbpm.db.full_time_threshold`. Ограничение на полное время выполнения запроса. Система выводит сообщение в логи при превышении. Действует для запросов, созданных в jOOQ. По умолчанию sum(webbpm.db.result_read_time_threshold, webbpm.db.execution_time_threshold) миллисекунд

- `webbpm.db.query_timeout`. Ограничение на время выполнения запроса. При превышении запрос будет отклонен. Действует для запросов, созданных в jOOQ в dev режиме. По умолчанию 120 секунд.

Пример:

```xml
<property name="webbpm.db.query_limit_enabled" value="false"/>
<property name="webbpm.db.select_records_max_limit" value="100000"/>
<property name="webbpm.db.select_records_min_limit" value="1000"/>
<property name="webbpm.db.execution_time_threshold" value="1000"/>
<property name="webbpm.db.results_count_threhold" value="50"/>
<property name="webbpm.db.result_read_time_threshold" value="50"/>
<property name="webbpm.db.full_time_threshold" value="300"/>
<property name="webbpm.db.query_timeout" value="120"/>
```

## Добавление версии приложения в URL при запросах к backend-у

При сборке приложения с профилем enable-version-in-url в URL будет добавляться версия приложения, указанная в pom.xml.  
Шаблон URL:

```
<protocol>//<hostname>:<port>/backend<app-version>/<some-controller>
```

## Включение регистрации пользователя

1. Укажите конфигурацию почтового сервера для отправки писем с подтверждением регистрации. 
Для этого в файле проекта *jndi-resources.xml* добавьте ресурс SmtpConfiguration. 
Шаблон:
```
<jndi-resource name="java:comp/env/webbpm/testResource" type="bpmn.handler.common.SmtpConfiguration">{"host":"host","port":1234,"login":"user","password":"password","from":"email_from","senderName":"sender_name","isSecured":true}</jndi-resource>
```
Почтовый сервер - зарегистрированный актуальный почтовый адрес. В поле password нужно указывать не пароль для входа в почту, а создать пароль для приложений в учетке почты и указать его.
2. Для включения регистрации добавьте в *standalone.xml* свойство
```
<property name="registration.enabled" value="true"/>
```
3. Также в *standalone.xml* укажите ресурс для отправки писем для подтверждения регистрации (из п.1) 
```
<property name="mail.jndi.resource.name" value="java:comp/env/webbpm/testResource"/>
```
4. При необходимости, отредактируйте шаблон письма для подтверждения регистрации 
(resources/src/main/resources/mail/confirmation.html)

5. При необходимости, отредактируйте шаблон письма для восстановления пароля
(resources/src/main/resources/mail/reset_password.html)


#### Настройка браузера для входа в систему с помощью Kerberos

1. Запустите браузер firefox.
2. В адресной строке введите about:config, нажать кнопку "я принимаю на себя риск"
3. С помощью поиска найдите параметр network.negotiate-auth.trusted-uris и в качестве значения ввести домен(например для домена example.com надо ввести .example.com)
4. Откройте в браузере приложение. Пример [http://app.example.com/](http://app.example.com/) . Приложение должно открыться без запроса логина/пароля

## Восстановление структуры БД

На основе БД проекта с помощью jOOQ генерируются Java классы для каждого объекта БД. Это происходит по нажатию кнопки Обновить на панели БД в студии. При необходимости можно сформировать DDL на основе данных классов. Пример класса для генерации DDL

```
package ru.cg.webbpm.test_project.db_beans;

import org.jooq.*;
import org.jooq.impl.*;

public class Main {
  public static void main (String args []) {
    DefaultConfiguration defaultConfiguration = new DefaultConfiguration();
    defaultConfiguration.setSQLDialect(SQLDialect.POSTGRES);
    Queries ddl = DSL.using(defaultConfiguration).ddl(DefaultCatalog.DEFAULT_CATALOG);

    for (Query query : ddl.queries()) {
      System.out.println(query);
    }
  }
}
```

** ВНИМАНИЕ: **

- этим способом нельзя восстановить функции/процедуры БД

см. также [Generating DDL from objects](https://www.jooq.org/doc/latest/manual/sql-building/ddl-statements/generating-ddl/)

## Распределенный кэш (Hazelcast)

В платформе подключен кэш. Он используется для подсчёта количества пользователей и кэширования подсистемы безопасности

- `webbpm.cache.hazelcast.port` - входящий порт hazelcast. по дефолту 5701.
- Обязательное задать одно из двух следующих параметров
  - `webbpm.cache.hazelcast.hosts` - список хостов серверов приложений.
    webbpm.cache.hazelcast.hosts = hostname1,hostname2,hostname3
  - `webbpm.cache.hazelcast.kubernetes.service_name` - имя сервиса в среде kubernetes,
    используемый для обнаружения других подов. Подходит как стратегия обнаружения, если используется
    kubernetes
- `webbpm.cache.hazelcast.outbound_port_definitions` - исходящие порты hazelcast. по дефолту не задано, система сама выбирает свободные порты. Задать диапазон 5801 - 5820
- `webbpm.cache.hazelcast.backup_count`. Нужны чтобы когда сервер выключается был доступен бекап. Если предполагается выключать несколько серверов за раз, то нужно увеличить.
  Данный бекап делает копии синхронно с основной записью и операция записи ждет пока будет записана везде. Можно делать бекап асинхронно, настраивается через async_backup_count
  подробнее про бекапы [Hazelcast IMDG Reference Manual](https://docs.hazelcast.org/docs/3.11/manual/html-single/index.html#backing-up-maps) . по дефолту 1
- `webbpm.cache.hazelcast.async_backup_count`
- `webbpm.cache.hazelcast.public_address`
- `webbpm.cache.hazelcast.interfaces`

Пример конфигурации:

```xml
         <property name="webbpm.cache.hazelcast.hosts" value="app1,app2"/>
         <property name="webbpm.cache.hazelcast.outbound_port_definitions" value="5801-5820"/>`
```

## Подключение компоненты адреса в режиме ГАР (Государственный адресный реестр)

Необходимо задать параметры:

- `gar.enable` - флаг, который включает/отключает сервис для работы с ГАР. Должен быть задан для работы компоненты в режиме ГАР. По умолчанию true, для отключения задать false.
- `gar.elastic.url.host` - хост на котором развернут elasticsearch.
- `gar.elastic.password` - пароль для аутентификации elasticsearch.

Дополнительные параметры:

- `gar.elastic.url.port` - порт на котором развернут elasticsearch.
- `gar.elastic.username` - логин для аутентификации elasticsearch.

Пример конфигурации:

```xml
         <property name="gar.enable" value="true"/>
         <property name="gar.elastic.url.host" value="localhost"/>
         <property name="gar.elastic.password" value="password"/>
```

## Метрики

Отчет

Отчет собирается раз в 30 секунд по дефолту, меняется параметром `webbpm.metrics.report_period_ms`.
Все метрики идут за отчетный период, после сбора отчета они сбрасываются.

Получить json со всеми метриками можно по урлу `backend/metrics/v1/all` - метрики будут с последнего собранного отчета, запрос не триггерит сбор отчета - это независимые операции. Отчет содержит только метрики по которым был совершен хотя бы один вызов в отчетный период. То есть, если какая-то операция не была совершена в отчетный период, то соответствующая ей метрика не попадет в отчет - ее не будет в json.

### Значения метрик

Все метрики идут за отчетный период, после сбора отчета они сбрасываются.
Нас в основном интересуют `callsCountSum`, `latencyMin`, `latencyAvg`, `latencyMax`

- `callsCountSum` - количество завершенных вызовов
- `latencyMin` - минимальное время выполнения
- `latencyAvg` - среднее время выполнения
- `latencyMax` - максимальное время выполнения
- `activeCallsCountMax` - количество начатых, но еще не завершенных вызовов.
- `activeCallsLatencyMax` - длительность самого долгого еще не завершенного вызова

### Текущие метрики приложения

- Получение коннекта из пула
  
  - `webbpm.jbpm.db.connection.acquire`
  - `webbpm.security.db.connection.acquire`
  - `webbpm.db.connection.acquire`

- Время с момента получения коннекта до возврата его в пул
  
  - `webbpm.jbpm.db.connection.in_use`
  - `webbpm.security.db.connection.in_use`
  - `webbpm.db.connection.in_use`

- Время выполнения запроса на бд проекта
  
  - `webbpm.db.query.success.execution_time`

- Время выполнения запроса на бд проекта + время получения коннекта из пула
  
  - `webbpm.db.query.success.full_time`

- active-users-count.indicatorMax

- active-users-count-ttl.indicatorMax
  
  # Количество пользователей

- `webbpm.active_users_counter.enabled` - включает подсчет пользователей, нужно чтобы не запускать hazelcast на дев машинах. по дефолту false. На боевых серверах необходимо установить в true.

- `webbpm.active_users_counter.max_time_between_operations_in_seconds` - время, которое пользователь считается активным после действия. по дефолту 15 минут.

- `webbpm.active_users_counter.hazelcast.app_pool_size`. Запись в hazelcast производится асинхронно в отдельном пуле, не блокируя обработку http запроса. Это размер этого пула. по дефолту 4. Можно пока оставить 4 и последить за метриками pool.hazelcast-executor.queue.indicatorMax и pool.hazelcast-executor.activeThreads.indicatorMax. Если очередь будет сильно копиться, то увеличить.

## Настройка логов

Все настройки делаются в файле `standalone.xml`, если не указано иначе.

### Общие настройки

Платформа Web-bpm использует корневую категорию логирования `ru.cg.webbpm`, рекомендуется выставлять ее в уровень `info`. todo check prod config

```xml
<logger category="ru.cg.webbpm">
    <level name="INFO"/>
</logger>
```

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

### Параметры конфигурации

**Рекомендованное использование:** всегда в `info`.

Все параметры конфигурации загружаемые платформой web-bpm и пользовательским приложением через api webbpm логируются категорией `ru.cg.webbpm.modules.core.app_info.api.property.BaseProperty`. Она всегда должна быть выставлена в `info`.

Пример вывода:

```
2017-12-04 16:02:19,074 INFO  [ru.cg.webbpm.modules.core.app_info.api.property.BaseProperty] (EclipseGeminiBlueprintExtenderThread-1) System property [webbpm.active_users_counter.enabled] not set. Using default value [false]
2017-12-04 16:02:19,074 INFO  [ru.cg.webbpm.modules.core.app_info.api.property.BaseProperty] (EclipseGeminiBlueprintExtenderThread-1) System property [webbpm.active_users_counter.hazelcast.hosts] set to [127.0.0.1]
```

### БД проекта

#### Логирование запросов в бд security и бд проекта

**Рекомендованное использование:** только при разработке.

Использовать только при разработке. Категория `org.jooq.tools.LoggerListener` в `debug` уровень.

```xml
<logger category="org.jooq.tools.LoggerListener">
    <level name="DEBUG"/>
</logger> 
```

Пример вывода:

```
2017-12-04 18:21:10,391 DEBUG [org.jooq.tools.LoggerListener] (default task-19) Executing query          : select "department"."department_name", "department"."department_id", "department"."parent_department_id", "department"."parent_department_id", "department"."department_id", (select (count(*) <> ?) from "public"."department" as "$$child" where "$$child"."parent_department_id" = "department"."department_id") as "$$hasChildren" from "public"."department" as "department" limit ?
2017-12-04 18:21:10,395 DEBUG [org.jooq.tools.LoggerListener] (default task-19) -> with bind values      : select "department"."department_name", "department"."department_id", "department"."parent_department_id", "department"."parent_department_id", "department"."department_id", (select (count(*) <> 0) from "public"."department" as "$$child" where "$$child"."parent_department_id" = "department"."department_id") as "$$hasChildren" from "public"."department" as "department" limit 2147483647
2017-12-04 18:21:10,568 DEBUG [org.jooq.tools.LoggerListener] (default task-19) Fetched result           : +-----------------+-------------+--------------------+--------------------+-------------+-------------+
2017-12-04 18:21:10,568 DEBUG [org.jooq.tools.LoggerListener] (default task-19)                          : |department_name  |department_id|parent_department_id|parent_department_id|department_id|$$hasChildren|
2017-12-04 18:21:10,568 DEBUG [org.jooq.tools.LoggerListener] (default task-19)                          : +-----------------+-------------+--------------------+--------------------+-------------+-------------+
2017-12-04 18:21:10,568 DEBUG [org.jooq.tools.LoggerListener] (default task-19)                          : |Головной офис 1  |            8|              {null}|              {null}|            8|true         |
2017-12-04 18:21:10,568 DEBUG [org.jooq.tools.LoggerListener] (default task-19)                          : |Головной офис 2  |            9|              {null}|              {null}|            9|true         |
2017-12-04 18:21:10,568 DEBUG [org.jooq.tools.LoggerListener] (default task-19)                          : |Головной офис 3  |           10|              {null}|              {null}|           10|true         |
2017-12-04 18:21:10,568 DEBUG [org.jooq.tools.LoggerListener] (default task-19)                          : |Подразделение 1.1|           11|                   8|                   8|           11|true         |
2017-12-04 18:21:10,568 DEBUG [org.jooq.tools.LoggerListener] (default task-19)                          : |Подразделение 1.2|           12|                   8|                   8|           12|true         |
2017-12-04 18:21:10,568 DEBUG [org.jooq.tools.LoggerListener] (default task-19)                          : +-----------------+-------------+--------------------+--------------------+-------------+-------------+
2017-12-04 18:21:10,568 DEBUG [org.jooq.tools.LoggerListener] (default task-19)                          : |...55 record(s) truncated...
```

#### Логирование больших запросов

**Рекомендованное использование:** всегда в `info`, с подобранными для проекта значениями. В проде значения должны быть проверены что они не вызывают излишнее логирование.

1. Для отслеживания больших запросов в пользовательскую базу нужно задать параметры что считать большими запросами, логироваться будут запросы больше заданных показателей.
   Чтобы логировать все запросы можно задать значение `-1`. Добавляются как property в раздел `system-properties`:
   
   ```xml
   <property name="webbpm.db.full_time_threshold" value="1050"/>
   <property name="webbpm.db.results_count_threshold" value="1000"/>
   ```
   
   В `info` режиме работают:
   
   - `webbpm.db.full_time_threshold` - полное время выполнения запроса в миллисекундах. Включает построение запроса библиотекой, выполнение и загрузку результатов. Пример сообщения <br>`2023-01-11 13:09:38,361 WARN [ru.cg.webbpm.modules.database.impl.analytics.PerformanceListener] (default task-33) Query full time threshold exceeded. full_time=[6565ms] execution_time=[6565ms] read_time=[0ms] results_count=[4] query=[<your query>]`
   - `webbpm.db.results_count_threshold` - количество записей, которое вернул запрос. Пример сообщения <br>`2023-01-11 13:10:34,088 WARN [ru.cg.webbpm.modules.database.impl.analytics.PerformanceListener] (default task-41) Query results count threshold exceeded. results_count=[11177] query=[<your query>]`
   
   В `debug` режиме дополнительно к работающим в info:
   
   - `webbpm.db.execution_time_threshold` - время выполнения запроса + построения запроса библиотекой.
   - `webbpm.db.result_read_time_threshold` - время чтения результатов запроса

2. После задания настроек нужно настроить логирование - категория `ru.cg.webbpm.modules.database.impl.analytics.PerformanceListener`, уровень `info` или `debug`.
   
   ```xml
   <logger category="ru.cg.webbpm.modules.database.impl.analytics.PerformanceListener">
     <level name="INFO"/>
   </logger>
   ```

### JBPM

#### Основные настройки

JBPM использует 3 корневых категории логирования – `org.jbpm`, `org.drools`, `org.kie`. Все они должны быть выставлены в `warn`.

```xml
<logger category="org.jbpm">
    <level name="WARN"/>
</logger>
<logger category="org.drools">
    <level name="WARN"/>
</logger>
<logger category="org.kie">
    <level name="WARN"/>
</logger>
```

#### Логирование запросов в БД

**Рекомендованное использование:** только при разработке.

Для логирования sql запросов нужно включить категорию `org.hibernate.SQL` в `debug`:

```xml
<logger category="org.hibernate.SQL">
    <level name="DEBUG"/>
</logger>
```

Чтобы вывести параметры запросов и результат выполнения – категорию `org.hibernate.type.descriptor.sql` в `trace`:

```xml
<logger category="org.hibernate.type.descriptor.sql">
    <level name="TRACE"/>
</logger>
```

Пример вывода:

```
18:21:06,938 DEBUG [org.hibernate.SQL] (default task-47) select names0_.Task_Names_Id as Task_Nam7_16_0_, names0_.id as id1_16_0_, names0_.id as id1_16_1_, names0_.language as language2_16_1_, names0_.shortText as shortTex3_16_1_, names0_.text as text4_16_1_ from I18NText names0_ where names0_.Task_Names_Id=?
18:21:06,939 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-47) binding parameter [1] as [BIGINT] - [180]
18:21:06,940 TRACE [org.hibernate.type.descriptor.sql.BasicExtractor] (default task-47) extracted value ([id1_16_1_] : [BIGINT]) - [539]
18:21:06,940 TRACE [org.hibernate.type.descriptor.sql.BasicExtractor] (default task-47) extracted value ([language2_16_1_] : [VARCHAR]) - [en-UK]
18:21:06,940 TRACE [org.hibernate.type.descriptor.sql.BasicExtractor] (default task-47) extracted value ([shortTex3_16_1_] : [VARCHAR]) - [Список записей]
18:21:06,941 TRACE [org.hibernate.type.descriptor.sql.BasicExtractor] (default task-47) extracted value ([text4_16_1_] : [CLOB]) - [Список записей]
18:21:06,941 TRACE [org.hibernate.type.descriptor.sql.BasicExtractor] (default task-47) extracted value ([Task_Nam7_16_0_] : [BIGINT]) - [180]
18:21:06,942 TRACE [org.hibernate.type.descriptor.sql.BasicExtractor] (default task-47) extracted value ([id1_16_0_] : [BIGINT]) - [539]
```

#### Дополнительные логи hibernate

**Рекомендованное использование:** только при разработке в случае необходимости.

1. Время выполнения запроса и количество результатов.
   
   Включаются категорией `org.hibernate.stat` в `debug`. При этом в hibernate должен быть включен сбор статистики.
   Похоже что логируется только hql select запросов.
   
   ```xml
   <logger category="org.hibernate.stat">
     <level name="DEBUG"/>
   </logger>
   ```
   
   Пример вывода:
   
   ```
   18:21:06,858 DEBUG [org.hibernate.stat.internal.ConcurrentStatisticsImpl] (default task-41) HHH000117: HQL: select t from AuditTaskImpl t where t.taskId = :taskId, time: 6ms, rows: 1
   ```

2. Показатели hibernate сессий
   
   Включаются категорией `org.hibernate.engine.internal.StatisticalLoggingSessionEventListener` в `info`.
   При этом в hibernate должен быть включен сбор статистики. Тут может быть интересно количество запросов, флашей и общее время на все запросы сессией.
   
   Пример вывода:
   
   ```
   2017-12-04 17:25:58,493 INFO  [org.hibernate.engine.internal.StatisticalLoggingSessionEventListener] (default task-21) Session Metrics {
     63408365 nanoseconds spent acquiring 17 JDBC connections;
     521509 nanoseconds spent releasing 17 JDBC connections;
     65732621 nanoseconds spent preparing 17 JDBC statements;
     31471897 nanoseconds spent executing 17 JDBC statements;
     0 nanoseconds spent executing 0 JDBC batches;
     0 nanoseconds spent performing 0 L2C puts;
     0 nanoseconds spent performing 0 L2C hits;
     0 nanoseconds spent performing 0 L2C misses;
     297556 nanoseconds spent executing 1 flushes (flushing a total of 16 entities and 0 collections);
     430168 nanoseconds spent executing 1 partial-flushes (flushing a total of 16 entities and 16 collections)
   }
   ```

#### Логирование hbm2ddl

**Рекомендованное использование:** всегда в `trace`.

Должно быть включено всегда. Позволяет убедиться что hibernate не накатывал никакие миграции на базу. Этот функционал отключен у нас в коде.

```xml
<logger category="org.hibernate.tool.hbm2ddl">
    <level name="TRACE"/>
</logger>
```

# Описание параметров конфигурации клиентской части

Свойства задаются в файле frontend/src/resources/app-config.json или frontend.war/src/resources/app-config.json

## Общие

- `dev_mode` - настройка задающая dev_mode для просмотра логов (true/false). При отсутствие оставляет значение при сборке
- `guard.confirm_exit` - выводить или нет диалог подтверждения, если обнаружены несохраненные данные в форме. Значение по умолчанию - false.
- `password.pattern` - Регулярное выражение для валидации пароля.
- `password_pattern_error` - Сообщение об ошибке валидации.
- `show.client.errors` - отвечает за отображение ошибок javascript-a пользователю (должна использоваться только в тестовых контурах) по умолчанию выключена
- 'available_task.single_fetch' - Отвечает за количество запросов available_task при завершении процесса. true - одиночный запрос, false/не указано - 10 запросов(старая реализация).

## Вывод сообщений

- `message_service_error_timeout` время в мс, в течение которого будет отображено сообщение об ошибке. Значение по умолчанию - таймаут не задан (окно не закрывается).
- `message_service_warning_timeout` время в мс, в течение которого будет отображено предупреждающее сообщение. Значение по умолчанию - таймаут не задан (окно не закрывается).
- `message_service_success_timeout` время в мс, в течение которого будет отображено сообщение об успехе. Значение по умолчанию - таймаут не задан (окно не закрывается).
- `message_service_info_timeout` время в мс, в течение которого будет отображено информационное сообщение. Значение по умолчанию - таймаут не задан (окно не закрывается).

## Электронная подпись

### Esmart

- `electronic_sign.esmart_extension_url` - url для создания расширенной подписи. Подробная информация по ссылке [http://demo.esmart.ru](http://demo.esmart.ru)
- `electronic_sign.tsp_address` - адрес сервера службы штампов времени

Пример:

```text
"electronic_sign.esmart_extension_url": "http://dsig.ibsdemo.ru/ibs_dsig/ibs_dSig.asmx"
```

## Способ аутентификации

- `auth_method` - способ аутентификации. Может принимать одно значение из списка: form, kerberos, cert_over_db, cert_over_ldap

## Таймер очистки закешированных значений фильтров

- `filter_cleanup_interval_hours` - время жизни закешированного значения фильтра в часах. По умолчанию - 720 часов,
- `filter_cleanup_check_period_minutes` - период проверки наличия просроченных закешированных значений в минутах. По умолчанию - 30 минут

## Добавление версии приложения в URL при запросах к frontend-у

В модуле frontend в src/resources/app-config.json добавлены 2 переменные

- `"enable.version.in.url": "%enable.version.in.url%"` - подставлять ли версию в URL приложения. По умолчанию false. Если сборка произведена
- `"app.version": "%project.version%"` - версия приложения.  
  с профилем `enable-version-in-url`, то значение будет true.

## Добавление Jivo чат в проект

Свойства задаются в файле frontend/src/resources/app-config.json или frontend.war/src/resources/app-config.json

- `jivo_chat_widget_api_url` - API url для работы Jivo чата. Необходимо заменить {WIDGET_ID} на реальный Widget API ID
- `jivo_chat_widget_enabled` - параметр отвечающий за активацию Jivo чата. По дефолту false, для активации задать true.

Пример:

```json
  "jivo_chat_widget_api_url": "https://code.jivo.ru/widget/{WIDGET_ID}",
  "jivo_chat_widget_enabled": false
```


# Прочее

## Смена удалённого репозитория

1. Смените адрес NPM registry в файле frontend.npmrc. Пример - registry=https://repo.example.com/repository/npm-all/
2. Поменяйте ссылки в блоке , файла pom.xml


#### Подключение базы данных

- `DB_APP_USERNAME` - логин пользователя для подключения к базе данных.
- `DB_APP_PASSWORD` - пароль пользователя для доступа к базе данных.
- `DB_APP_HOST` - адрес сервера базы данных.
- `DB_APP_PORT` - порт, на котором осуществляется подключение к базе данных.
- `DB_APP_NAME` - имя базы данных, к которой необходимо подключиться.


#### Аутентификация через ЕСИА

- `ESIA_SCOPES` - область доступа, позволяющие получить данные о пользователе. Тип данных, к которым система-клиент намерена получить доступ
- `ESIA_ORG_SCOPES` - область доступа, позволяющие получить данные о организации. Тип данных, к которым система-клиент намерена получить доступ
- `ESIA_ORG_SCOPE_URL` - обязательный префикс областей доступа, для получения данных об организации. 
- `ESIA_BASE_URI` - базовый url для обращения в ЕСИА.
- `ESIA_CLIENT_ID` - – идентификатор системы-клиента (мнемоника системы в ЕСИА указанная прописными буквами)
- `ESIA_REDIRECT_URL` - ссылка, по которой должен быть направлен пользователь
  после того, как ЕСИА даст разрешение на доступ к ресурсу.
Важно: `ESIA_REDIRECT_URL` должна содержать полный адрес вплоть до последнего слэша 
- https://lkul.ervu.loc/ - правильное значение параметра
- https://lkul.ervu.loc - неправильное значение параметра
- `ESIA_LOGOUT_REDIRECT_URL` - ссылка, по которой должен быть направлен пользователь после logout-a
  Важно: `ESIA_LOGOUT_REDIRECT_URL` должна содержать полный адрес вплоть до последнего слэша:
> - https://lkul.ervu.loc/home.html - правильное значение параметра
> - https://lkul.ervu.loc - неправильное значение параметра

- `ESIA_UPLOAD_DATA_ROLE` - мнемоника группы, для роли "Сотрудник, ответственный за военно-учетную работу".
- `SIGN_URL` - url для подписания с помощью КриптоПро секрета клиента, необходимого для аутентификации через ЕСИА.
- `ESIA_CLIENT_CERT_HASH` - параметр, содержащий хэш сертификата (fingerprint сертификата) системы-клиента в hex–формате.

#### Взаимодействие с ЕСНСИ в части получения справочника ОКОПФ

- `ESNSI_OKOPF_URL` - url который обращается к еснси для получения справочника и скачивает данные спровочников организации в виде заархивированного json файла.
- `ESNSI_OKOPF_CRON_LOAD` - настройка, которая указывет расписание для загрузки справочника окопф и
  сохранение данных по справкам в БД
- `ESNSI_OKOPF_RETRY_DELAY_LOAD` - настройка, которая указывет на повторную попытку загрузить
  справочник окопф с задержкой. По умолчанию задержка по времени 30000 ms
- `ESNSI_OKOPF_RETRY_MAX_ATTEMPTS_LOAD` - настройка, которая указывет на максимальное кол-во попыток
  повторно загрузить справочник окопф. По умолчанию 3 попытки
  
#### Общие параметры Kafka

- `KAFKA_HOSTS` - список пар хост:порт, использующихся для установки первоначального соединения с кластером Kafka
- `KAFKA_AUTH_SEC_PROTO` - протокол, используемый для взаимодействия с брокерами
- `KAFKA_AUTH_SASL_MECH` - механизм SASL, используемый для клиентских подключений
- `KAFKA_AUTH_SASL_MODULE` - имя класса для входа в систему для SASL-соединений в формате, используемом конфигурационными файлами JAAS
- `KAFKA_USER` - пользователь для подключения к Kafka
- `KAFKA_PASS` - пароль для подключения к Kafka

#### Взаимодействие с WebDav

- `ERVU_FILE_UPLOAD_MAX_FILE_SIZE` - определяет максимальный размер загружаемого файла в байтах. Указывает предел размера для каждого индивидуального файла, который может быть загружен. Если файл превышает этот размер, загрузка будет прервана, и может быть вызвано исключение.
- `ERVU_FILE_UPLOAD_MAX_REQUEST_SIZE` - устанавливает максимальный общий размер всех файлов в одном многозадачном запросе в байтах. Это ограничение на весь запрос, включающий данные и файлы. Если общий размер запроса превышает этот параметр, загрузка файлов будет остановлена.
- `ERVU_FILE_UPLOAD_FILE_SIZE_THRESHOLD` - указывает размер (в байтах), при достижении которого файл будет записан во временное хранилище на диск. Это позволяет улучшить производительность, исключая непосредственную запись мелких файлов на диск, если они не превышают указанного порога. Файлы, меньшие этого значения, могут быть сохранены в памяти.
- `WEBDAV_URLS` - список url для подключения к WebDav
- `WEBDAV_USERNAME` - логин пользователя для подключения к WebDav
- `WEBDAV_PASSWORD` - пароль пользователя для подключения к WebDav
- `WEBDAV_BAD_SERVERS_CACHE_EXPIRE_SECONDS` - время жизни кэша адресов недоступных серверов WebDav (секунды)
- `WEBDAV_CLEANUP_CRON` - крон по очистке WebDav
- `WEBDAV_RETRY_DELAY` - количество попыток по операциям с файлами WebDav
- `FILE_WEBDAV_LIFETIME_SECONDS` - время жизни файла в WebDav (секунды)
- `FILE_WEBDAV_EXTENSIONS` - список расширений файлов, удаляемых с WebDav
- `AV_KAFKA_GROUP_ID` - идентификатор группы потребителей, который отвечает за создание группы для объединения нескольких потребителей
- `AV_KAFKA_MESSAGE_TOPIC_NAME` - топик для записи данных по файлу для перекладчика.
- `AV_KAFKA_DOWNLOAD_RESPONSE` - топик для чтения статусов файла, полученных от перекладчика.

#### Взаимодействие с Kafka ERVU

- `ERVU_KAFKA_GROUP_ID` - идентификатор группы потребителей, который отвечает за создание группы для объединения нескольких потребителей
- `ERVU_KAFKA_REPLY_TIMEOUT` - определяет, сколько времени Kafka будет ожидать ответа от потребителя после отправки сообщения. Значение задается в секундах
- `ERVU_KAFKA_ORG_REQUEST_TOPIC` - топик для записи данных об организации, для получения id организации из ЕРВУ. 
- `ERVU_KAFKA_ORG_REPLY_TOPIC` - топик для чтения id организации из ЕРВУ.
- `ERVU_KAFKA_JOURNAL_REQUEST_TOPIC` - топик для записи запроса для получения данных по журналу взаимодействия
- `ERVU_KAFKA_JOURNAL_REPLY_TOPIC` - топик для чтения данных по журналу взаимодействия
- `ERVU_KAFKA_EXCERPT_REQUEST_TOPIC` - топик для записи запроса для получения выписки по журналу взаимодействия
- `ERVU_KAFKA_EXCERPT_REPLY_TOPIC` - топик для чтения выписки по журналу взаимодействия. Содержит ссылку на S3 с файлом выписки
- `DB.JOURNAL.EXCLUDED.STATUSES` - статусы файла, которые необходимо исключить при получении данных по журналу взаимодействия из базы данных приложения


#### Взаимодействие с Kafka audit
- `AUDIT_KAFKA_AUTHORIZATION_TOPIC` - топик для отправки аудита в журнал авторизации
- `AUDIT_KAFKA_ACTION_TOPIC` - топик для отправки аудита в журнал действий пользователя
- `AUDIT_KAFKA_FILE_UPLOAD_TOPIC` - топик для отправки аудита в журнал обмена файлами 
- `AUDIT_KAFKA_FILE_DOWNLOAD_TOPIC` - топик для отправки аудита в журнал загрузки ЮЛ и ФЛ
- `AUDIT_KAFKA_BOOTSTRAP_SERVERS` - список пар хост:порт, использующихся для установки первоначального соединения с кластером Kafka
- `AUDIT_KAFKA_SECURITY_PROTOCOL` - протокол, используемый для взаимодействия с брокерами
- `AUDIT_KAFKA_DOC_LOGIN_MODULE` - имя класса для входа в систему для SASL-соединений в формате, используемом конфигурационными файлами JAAS
- `AUDIT_KAFKA_USERNAME` - пользователь для подключения к Kafka
- `AUDIT_KAFKA_PASSWORD` - пароль для подключения к Kafka
- `AUDIT_KAFKA_SASL_MECHANISM` - механизм SASL, используемый для клиентских подключений
- `AUDIT_KAFKA_ENABLED` - флажок для включения записи аудита в кафку
