java.lang.RuntimeException: wXb6Vnl31u :: Ошибка для HTML= 0001 0003 0004 0005 0006 0007 0008 0009
0010

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

0011 0012

Переменные окружения (далее п.о.) задаются для запуска 0013 API-сервера. В таблице перечислен минимальный набор п.о. с 0014 примерами значений

0015 0016 0017 0018 0019 0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 0040 0041 0042 0045 0046 0047 0048 0049 0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 0070 0071 0072 0073 0074 0075 0076 0077
Переменная окруженияПример значения
MYBPM_COMPANY_CODEgreetgo
MYBPM_ZOOKEEPER_SERVERSlocalhost:10012
MYBPM_KAFKA_SERVERSlocalhost:10011
MYBPM_MONGO_SERVERSmongodb://mybpm:123@192.168.111.1:11017, 0044 192.168.111.2:11018, 192.168.111.3:11019/admin
MYBPM_AUX1_DB_NAMEmybpm_aux1
MYBPM_AUX1_HOSTlocalhost
MYBPM_AUX1_PORT10018
MYBPM_AUX1_USER_NAMEmybpm
MYBPM_AUX1_PASSWORD4jk3hb2145hj23bv4123jkb4
MYBPM_ELASTIC_SEARCH_SERVERSlocalhost:10016
0078 0079

В следующей таблице указан более расширенный пример доступа к 0080 кафке:

0081 0082 0083 0084 0085 0086 0087 0088 0089 0090 0091 0092 0093 0094 0095 0096 0097 0098 0100 0101 0102 0103 0104 0105 0106 0107 0108 0109 0110 0111 0112 0113 0114 0116 0117 0118 0119 0120 0121 0122 0123
Переменная окруженияПример значения
MYBPM_KAFKA_SERVERSlocalhost:10011
MYBPM_KAFKA_CON_001sasl.jaas.config = 0099 TXT:org.apache.kafka.common.security.plain.PlainLoginModule...
MYBPM_KAFKA_CON_002sasl.mechanism = TXT:PLAIN
MYBPM_KAFKA_CON_003security.protocol = TXT:SASL_SSL
MYBPM_KAFKA_CON_004ssl.truststore.location = Base64_to_file 0115 :4hJ1/v324gHkjY43bjk51b5v234v423v4...
MYBPM_KAFKA_CON_005ssl.truststore.password = TXT :SuperSecret
0124 0125

Ниже смотрите детальное описание п.о.:

0126 0127
0128

MYBPM_APP_PREFIX

0129 0130

Префикс для БД

0131 0132
Возможные значения:
0133 0134
0135  [a-z][a-z1-9]*
0136  
0137  
0138  
0139  
0140 0141

Данный префикс используется для определения баз данных, например 0142 если указать префикс tor, то в MongoDB будут использоваться базы 0143 данных tor_mybpm, tor_mybpm_aux1 и так далее для всех БД. Если 0144 префикс не указать, то имена будут использоваться без префикса. Это 0145 нужно, чтобы можно было на одной среде развернуть несколько 0146 независимых друг от друга платформ MyBPM.

0147 0148
0149

MYBPM_LICENCE_NUMBER

0150 0151

Номер лицензии платформы MyBPM

0152 0153
Возможные значения:
0154 0155
0156  6120b632-f91a-416d-a7d0-180ffd7ce380
0157  
0158  
0159  
0160  
0161 0162

Для активации функционирования платформы MyBPM в соответствии с 0163 закупленной лицензией, необходимо номер этой лицензии указать в 0164 данной п.о.

0165 0166

Так же необходимо обеспечить доступ платформы к лицензионному 0167 сервису платформы MyBPM. Или настроить прокси-сервер к одному или 0168 нескольким адресам лицензионного сервиса.

0169 0170
0171

0172 MYBPM_LICENCE_SERVICE_ADDRESSES

0173 0174

Альтернативные адреса лицензионного сервиса.

0175 0176
Возможные значения:
0177 0178
0179  http://some-host:port,https://some-another-host
0180  
0181  
0182  
0183  
0184 0185

ИЛИ

0186 0187
0188  X,http://some-host:port,https://some-another-host
0189  
0190  
0191  
0192  
0193 0194

Список адресов лицензионного сервиса разделённые запятой. Так же 0195 в начале можно поставить X (большая латинская буква "икс") с 0196 запятой - это отменит использование пред-настроенных адресов 0197 лицензионного сервиса.

0198 0199

Если не указать эту п.о., то будут использоваться 0200 пред-настроенные адреса лицензионного сервиса.

0201 0202

Платформа по очереди будет вызывать адреса лицензионного 0203 сервиса. И как только один адрес сработает, то произойдёт 0204 полноценная активация платформы в соответствии с лицензией, номер 0205 которой указан в п.о. MYBPM_LICENCE_NUMBER. Если ни 0206 один адрес не сработает, то произойдёт полная блокировка работы 0207 платформы.

0208 0209

Если необходимо иметь возможность просматривать данные, которые 0210 ходят на лицензионный сервис, то можно сделать прокси сервер 0211 перенаправляющий REST-запросы на один из адресов лицензионного 0212 сервиса. Прокси сервер может работать как на протоколе HTTP, так и 0213 на протоколе HTTPS.

0214 0215

Важно чтобы прокси сервер перебрасывал заголовок 0216 signature как в запросе, так и в ответе запроса - без 0217 него платформа не сможет убедиться в актуальности лицензионного 0218 сервиса, и будет заблокирована.

0219 0220
0221

MYBPM_ALL_CONSUMERS_OFF

0222 0223

Отключение всех исторических consumer-ов

0224 0225
Возможные значения:
0226 0227
0228  true, false
0229  
0230  
0231  
0232  
0233 0234

Исторический consumer - это такой consumer, который считывает 0235 данные из кафки с начала времён. Каждое сообщение в таком 0236 consumer-е обрабатывается только один раз на одном сервере, даже 0237 если настроено несколько серверов обрабатывающих данный 0238 consumer.

0239 0240

Данная п.о. позволяет отключить все исторические consumer-ы, вне 0241 зависимости от того, что установлено в конфигурации ZooKeeper. 0242 Чтобы это сделать, нужно установить данную п.о. в значение true 0243 (см. kz.greetgo.mybpm_util_light.etc.Env.envBool).

0244 0245

Если эта п.о. не установлена или имеет другое значения, то 0246 consumer-ы запускаются и настраиваются по конфигурации из 0247 ZooKeeper.

0248 0249

0250 MYBPM_ALL_KAFKA_NOTIFICATIONS_OFF

0251 0252

Отключение всех consumer-ов-оповещений

0253 0254
Возможные значения:
0255 0256
0257  true, false
0258  
0259  
0260  
0261  
0262 0263

Consumer-оповещение - это такой consumer, который считывает 0264 данные из кафки с момента запуска. Притом каждое сообщение 0265 считывается ВСЕМИ серверами, которые обрабатывают этот 0266 consumer-оповещение.

0267 0268

Данная п.о. позволяет отключить все consumer-оповещения, вне 0269 зависимости от того, что установлено в конфигурации ZooKeeper. 0270 Чтобы это сделать, нужно установить данную п.о. в значение true 0271 (см. kz.greetgo.mybpm_util_light.etc.Env.envBool).

0272 0273

Если эта п.о. не установлена или имеет другое значения, то 0274 consumer-ы-оповещения запускаются и настраиваются по конфигурации 0275 из ZooKeeper.

0276 0277

ВНИМАНИЕ: Серверы, которые обрабатывают WebSocket-ы, должны 0278 иметь все consumer-оповещения ВКЛЮЧЁННЫМИ.

0279 0280

Данная переменная окружения применяется для тех серверов, 0281 которые обрабатывают только исторические consumer-ы. На таких 0282 серверах, не нужны оповещения, так как они не работают с 0283 пользователями. И желательно их отключить данной п.о.

0284 0285
0286

MYBPM_PLUGINS

0287 0288

Активация установленных плагинов

0289 0290
Возможные значения:
0291 0292
0293  Идентификаторы плагинов через запятую без пробелов
0294  
0295  
0296  
0297  
0298 0299

Чтобы установить плагин, недостаточно его jar-файл поместить на 0300 место загружаемых библиотек, нужно ещё его активировать. Для этого 0301 нужно его идентификатор указать в списке активируемых 0302 идентификаторов в этой п.о.

0303 0304
0305

MYBPM_DISABLE_CACHE

0306 0307

Отключение всего кэша

0308 0309
Возможные значения:
0310 0311
0312  true, false
0313  
0314  
0315  
0316  
0317 0318

Установка данной п.о. в значение true (см. 0319 kz.greetgo.mybpm_util_light.etc.Env.envBool) позволяет полностью 0320 отключить все кэши в системе.

0321 0322
0323

MYBPM_USE_SHENANDOAH

0324 0325

Использовать SHENANDOAH

0326 0327
Возможные значения:
0328 0329
0330  yes, чё-то другое
0331  
0332  
0333  
0334  
0335 0336

SHENANDOAH - это прогрессивный сборщик мусора, но по-умолчанию в 0337 виртуальной Java-машине активирован другой. Чтобы активировать 0338 этот, нужно установить данную п.о. в значение yes. Другие значения 0339 и отсутствие данной п.о. активируют сборщик мусора по 0340 умолчанию.

0341 0342
0343

MYBPM_CONSUMER_DIR

0344 0345

Имя директории куда помещаются конфиги консьюмеров

0346 0347
Возможные значения:
0348 0349
0350  строка из латинских символов, цифр и деления (/)
0351  
0352  
0353  
0354  
0355 0356

По умолчанию система располагает файлы конфигурации консьюмеров 0357 в ZooKeeper по пути:

0358 0359
0360  /mybpm/consumers
0361  
0362  
0363  
0364  
0365 0366

Это расположение можно поменять. Например, если задать данной 0367 п.о. значение:

0368 0369
0370  MYBPM_CONSUMER_DIR=hello/world
0371  
0372  
0373  
0374  
0375 0376

То расположение файлов конфигурации измениться на следующее:

0377 0378
0379  /mybpm/consumers-hello/world
0380  
0381  
0382  
0383  
0384 0385

Т.е. к прежнему значению добавиться тире ("-") и после него то, 0386 что в п.о.

0387 0388
0389

MYBPM_AD_USER и 0390 MYBPM_AD_PASS

0391 0392

Параметры доступа к Active Directory (AD)

0393 0394
Возможные значения:
0395 0396
0397  строка из латинских символов, цифр
0398  
0399  
0400  
0401  
0402 0403

Параметры доступа к AD находятся ZooKeeper-е в файле 0404 конфигурации:

0405 0406
0407  /mybpm/configs/AdConfig.txt
0408  
0409  
0410  
0411  
0412 0413

Кроме всего прочего имя пользователя и пароль доступа задаются в 0414 параметрах: adUsername, adPassword в открытом виде. Но в этом файле 0415 их можно не задавать, а передать через указанные п.о. и они будут 0416 приоритетными по сравнению со значениями из файла конфигурации.

0417 0418
0419

MYBPM_JAVA_DEBUG

0420 0421

Активация Java-отладки

0422 0423
Возможные значения:
0424 0425
0426  yes, чё-то ещё
0427  
0428  
0429  
0430  
0431 0432

По умолчанию Java-машина запускается без внешнего отладчика. Для 0433 его активации необходимо установить данную п.о. в значение yes. Это 0434 запустит отладчик на порту 5005.

0435 0436

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

0439 0440

Так же есть возможность запустить систему в остановленном 0441 режиме, т.е. система остановиться на первой команде и работать не 0442 будет, а будет ждать подключения отладчика, чтобы он запустил её 0443 дальше или посмотрел, что происходить в самом начале, для этого 0444 нужно установить п.о. MYBPM_JAVA_DEBUG_SUSPEND=y

0445 0446
0447

MYBPM_JAVA_DEBUG_SUSPEND

0448 0449

Остановки при запуске

0450 0451
Возможные значения:
0452 0453
0454  y, n
0455  
0456  
0457  
0458  
0459 0460

Эта п.о. используется совместно с MYBPM_JAVA_DEBUG. Установив 0461 данную п.о. в значение 'y' система запуститься в остановленном 0462 режиме, т.е. система остановиться на первой команде и дальше 0463 работать не будет, а будет ждать подключения отладчика, чтобы он 0464 запустил её дальше или посмотрел, что происходить в самом 0465 начале.

0466 0467
0468

MYBPM_JAVA_CONSOLE

0469 0470

Активировать консоль jconsole на порту 1099

0471 0472
Возможные значения:
0473 0474
0475  yes, пусто
0476  
0477  
0478  
0479  
0480 0481

Если установить данную п.о. в значение yes, то после запуска 0482 системы к ней можно будет подключиться с помощью утилиты jconsole 0483 по порту 1099.

0484 0485
0486

MYBPM_MAIN_CLASS

0487 0488

Сменить главный класс: 0489 kz.greetgo.mybpm.server.war.app.MybpmServer

0490 0491
Возможные значения:
0492 0493
0494  Полное имя класса с фунцией main
0495  
0496  
0497  
0498  
0499 0500

По умолчанию система запускается с класса:

0501 0502
0503  kz.greetgo.mybpm.server.war.app.MybpmServer
0504  
0505  
0506  
0507  
0508 0509

Который поднимает сервер приложения на порту 8080. Этот класс 0510 можно сменить, указав другой через эту п.о. - это позволит 0511 запустить какие-нибудь альтернативные сервера или задачи.

0512 0513
0514

MYBPM_JAVA_OPTS

0515 0516

Дополнительные опции к Java-машине

0517 0518
Возможные значения:
0519 0520
0521  Опции к Java-машине, которые обычно начинаются с -X
0522  
0523  
0524  
0525  
0526 0527

В данной переменной можно указать дополнительные опции к 0528 Java-машине, например по ограничению занимаемой памяти.

0529 0530

Например:

0531 0532
0533  MYBPM_JAVA_OPTS="-Xms16G -Xmx16G"
0534  
0535  
0536  
0537  
0538 0539

Позволяет ограничить кучу в 16-ю гигабайтами ОЗУ.

0540 0541
0542

MYBPM_COMPANY_CODE

0543 0544

Код главного аккаунта

0545 0546
Возможные значения:
0547 0548
0549  greetgo
0550  
0551  
0552  
0553  
0554 0555

Эту переменную всегда нужно устанавливать и устанавливать в 0556 значение greetgo.

0557 0558

Ранее можно было выбирать главные аккаунты, но с какого-то 0559 момента, добавилась возможность добавлять аккаунты динамически и 0560 главный аккаунт навсегда закрепился за greetgo.

0561 0562
0563

0565 MYBPM_AUX1_HOST, MYBPM_AUX1_PORT, MYBPM_AUX1_DB_NAME, 0566 MYBPM_AUX1_USER_NAME, MYBPM_AUX1_PASSWORD

0567 0568

Доступ к PostgreSQL

0569 0570
Возможные значения:
0571 0572
0573  строка из латинских символов, цифр
0574  
0575  
0576  
0577  
0578 0579

Данные переменные окружения определяют параметры доступа к БО 0580 PostgreSQL AUX1. А именно:

0581 0582 0596 0597

Первые три переменные определяют строку доступа к БД. Она 0598 получается такой:

0599 0600
0601  jdbc:postgresql://${HOSTS_PORTS}/${MYBPM_AUX1_DB_NAME}?ApplicationName=MyBPM
0602  
0603  
0604  
0605  
0606 0607

Тут параметр HOSTS_PORTS вычисляется из переменных 0608 MYBPM_AUX1_HOST и MYBPM_AUX1_PORT по 0609 следующему алгоритму.

0610 0611
    0612
  1. Берётся переменная MYBPM_AUX1_HOST и делиться по 0613 запятым - получается массив
  2. 0614 0615
  3. в этом массиве в тех значениях, в которых нет двоеточия, в 0616 конце добавляется порт MYBPM_AUX1_PORT через 0617 двоеточие
  4. 0618 0619
  5. Полученный новый массив обратно соединяется через запятые и 0620 получается переменная HOSTS_PORTS
  6. 0621
0622 0623

Таким образом получается, что переменная 0624 MYBPM_AUX1_PORT используется как порт по умолчанию для 0625 тех мест из MYBPM_AUX1_HOST, в которых порт не 0626 указан.

0627 0628

Пусть например у нас есть база данных mybpm на трех серверах 0629 кластера PostgreSQL:

0630 0631
    0632
  1. Адрес 10.100.1.101 порт 0633 5432
  2. 0634 0635
  3. Адрес 10.100.1.102 порт 0636 5432
  4. 0637 0638
  5. Адрес 10.100.1.103 порт 0639 5432
  6. 0640
0641 0642

Тогда нужно задать следующие переменные окружения:

0643 0644 0651 0652

И по этим переменным окружениям будет генерироваться следующая 0653 URI доступа к базе данных:

0654 0655
0656  jdbc:postgresql://10.100.1.101:5432,10.100.1.102:5432,10.100.1.103:5432/mybpm?ApplicationName=MyBPM
0657  
0658  
0659  
0660  
0661 0662

Теперь допусти порты на серверах разные, например такие:

0663 0664
    0665
  1. Адрес 10.100.1.101 порт 0666 1234
  2. 0667 0668
  3. Адрес 10.100.1.102 порт 0669 4567
  4. 0670 0671
  5. Адрес 10.100.1.103 порт 0672 1001
  6. 0673
0674 0675

Тогда нужно задать следующие переменные окружения:

0676 0677 0685 0686

И по этим переменным окружениям будет генерироваться следующая 0687 URI доступа к базе данных:

0688 0689
0690  jdbc:postgresql://10.100.1.101:1234,10.100.1.102:4567,10.100.1.103:1001/mybpm?ApplicationName=MyBPM
0691  
0692  
0693  
0694  
0695 0696

Подробнее про URI доступа к базе данных PostgreSQL смотрите по 0697 ссылке:

0698 0699

0701 https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING-URIS

0702 0703
0704

0706 MYBPM_ELASTIC_SEARCH_SERVERS, MYBPM_ELASTIC_SEARCH_USER, 0707 MYBPM_ELASTIC_SEARCH_PASS, MYBPM_ELASTIC_SEARCH_CA_CRT

0708 0709

Параметры доступа к эластику

0710 0711
Возможные значения:
0712 0713
0714  строка из латинских символов, цифр
0715  
0716  
0717  
0718  
0719 0720

Данные п.о. определяют параметры доступа к серверу эластика. 0721 Главным п.о. является MYBPM_ELASTIC_SEARCH_SERVERS - в зависимости 0722 от его значения используются другие п.о.

0723 0724

П.о. MYBPM_ELASTIC_SEARCH_SERVERS может иметь следующие 0725 варианты:

0726 0727

Вариант со схемой доступа http:

0728 0729
0730  MYBPM_ELASTIC_SEARCH_SERVERS=[host1]:[port1],[host2]:[port2],[host3]:[port3]
0731  
0732  
0733  
0734  
0735 0736

или

0737 0738
0739  MYBPM_ELASTIC_SEARCH_SERVERS=http://[host1]:[port1],[host2]:[port2],[host3]:[port3]
0740  
0741  
0742  
0743  
0744 0745

Вариант со схемой доступа https:

0746 0747
0748  MYBPM_ELASTIC_SEARCH_SERVERS=https://[host1]:[port1],[host2]:[port2],[host3]:[port3]
0749  
0750  
0751  
0752  
0753 0754

где:

0755 0756 0762 0763

П.о. MYBPM_ELASTIC_SEARCH_USER и MYBPM_ELASTIC_SEARCH_PASS 0764 используются для указания авторизации и аутентификации.

0765 0766

Если используется схема доступа https, то можно использовать 0767 п.о. MYBPM_ELASTIC_SEARCH_CA_CRT, в которой указать полный путь к 0768 файлу сертификата соединения. Обычно этот файл имеет имя ca.crt

0769 0770
0771

MYBPM_CORS

0772 0773

Отключение проверки CORS

0774 0775
Возможные значения:
0776 0777
0778  ALL, или чё-то другое
0779  
0780  
0781  
0782  
0783 0784

Если установить эту п.о. в значение ALL, то уберётся контроль 0785 CORS с запросов - это нужно для тестирования клиента в режиме 0786 отладки. Любые другие значение, как и отсутствие самой п.о. 0787 контроль CORS оставляет на высоком уровне.

0788 0789
0790

MYBPM_LOG_DIR

0791 0792

Базовый путь размещения файлов логирования системы

0793 0794
Значение по-умолчанию (если п.о. не указана или 0795 пустая):
0796 0797
0798  /var/log/mybpm
0799  
0800  
0801  
0802  
0803 0804
Возможные значения:
0805 0806
0807  абсолютный путь к сущестующей директории, в которую есть доступ на запись
0808  
0809  
0810  
0811  
0812 0813

Определяет пусть к существующей директории, в которой система 0814 будет создавать файлы логирования

0815 0816
0817

0818 MYBPM_ZOOKEEPER_SERVERS, MYBPM_ZOO_AUTH_..., 0819 MYBPM_ZOO_CONF_...

0820 0821

Определяет параметры доступа к кластеру ZooKeeper.

0822 0823

На платформе MyBPM получение доступа к системе происходит с 0824 помощью CuratorFrameworkFactory. Ниже схематично показан псевдокод 0825 подключения к Zookeeper-у.

0826 0827
0828   //@formatter:off
0829    String connectStr = "some-zoo-host:4324,another-zoo-host:6453";
0830  
0831    List<AuthInfo> authInfoList = new ArrayList<>();
0832    authInfoList.add(new AuthInfo("Client", Base64.getDecoder().decode("U2hhcm9uLlN0b25lOmQ1Wmgxa3MwM3Q=")));
0833    authInfoList.add(new AuthInfo("Server", Base64.getDecoder().decode("RGVuLkJyb3duOkRaek41WE1qNEU=")));
0834  
0835    final ZKClientConfig zkClientConfig = new ZKClientConfig();
0836    zkClientConfig.setProperty("zookeeper.sasl.client", "true");
0837    zkClientConfig.setProperty("zookeeper.ssl.quorum.trustStore.location", "/path/to/client-truststore.jks");
0838    zkClientConfig.setProperty("zookeeper.ssl.quorum.trustStore.password", "very-secret");
0839  
0840    try (CuratorFramework client = CuratorFrameworkFactory.builder()
0841                                                          .connectString(connectStr)
0842                                                          .zkClientConfig(zkClientConfig)
0843                                                          .authorization(authInfoList)
0844                                                          .build()) {
0845      // working with client
0846    }
0847  //@formatter:on
0848  
0849  
0850 0851

Где:

0852 0853
0854  base64_to_text( "U2hhcm9uLlN0b25lOmQ1Wmgxa3MwM3Q=" ) равно "Sharon.Stone:d5Zh1ks03t"
0855  base64_to_text( "RGVuLkJyb3duOkRaek41WE1qNEU="     ) равно "Den.Brown:DZzN5XMj4E"
0856  
0857  
0858  
0859  
0860 0861

Чтобы платформа MyBPM подобным образом подключалась к Zookeeper 0862 необходимо передать следующие п.о. (формат docker consumer):

0863 0864
0865  environment:
0866      MYBPM_ZOOKEEPER_SERVERS: "some-zoo-host:4324,another-zoo-host:6453"
0867      MYBPM_ZOO_AUTH_001: "Client : U2hhcm9uLlN0b25lOmQ1Wmgxa3MwM3Q="
0868      MYBPM_ZOO_AUTH_002: "Server : RGVuLkJyb3duOkRaek41WE1qNEU="
0869      MYBPM_ZOO_CONF_001: "zookeeper.sasl.client = TXT: true"
0870      MYBPM_ZOO_CONF_002: "zookeeper.ssl.quorum.trustStore.location = Base64_to_File: h34b2j4b234=="
0871      MYBPM_ZOO_CONF_003: "zookeeper.ssl.quorum.trustStore.password = TXT: very-secret"
0872  
0873  
0874  
0875  
0876 0877

Здесь представьте, что h34b2j4b234== - это Base64 0878 код содержимого файла 0879 /path/to/client-truststore.jks.

0880 0881

Далее детальное описание п.о.:

0882 0883
MYBPM_ZOOKEEPER_SERVERS
0884 0885

Определяет список серверов кластера ZooKeeper.

0886 0887

Возможные значения п.о.:

0888 0889
0890  Разделённый запятыми последовательности хост:порт
0891  
0892  
0893  
0894  
0895 0896
MYBPM_ZOO_AUTH_...
0897 0898

Определяет параметры авторизации. Платформа MyBPM считывает все 0899 п.о., которые начинаются на MYBPM_ZOO_AUTH_ и каждую 0900 превращает в объект класса AuthInfo (этот класс 0901 имеется в примере кода выше). Все эти объекты складывает в массив и 0902 передаёт коду обеспечения доступа к Zookeeper (он находиться внутри 0903 класса CuratorFramework - это показано на примере кода выше).

0904 0905

Класс авторизации содержит два поля:

0906 0907
0908  public class AuthInfo {
0909      final String scheme;  // схема авторизации
0910      final byte[] auth;    // данные для авторизации
0911  }
0912  
0913  
0914 0915

Эти поля заполняются из значения п.о., которое должно иметь 0916 конкретный формат, а именно:

0917 0918
0919  <schema> : <base64-код>
0920  
0921  
0922  
0923  
0924 0925

Где:

0926 0927

<schema> - это текст содержащий схему 0928 авторизации, и он передаётся в поле 0929 AuthInfo.scheme.

0930 0931

<base64-код> - это текст, представляющий 0932 собой Base64-код массива байтов, который передаётся в поле 0933 AuthInfo.auth.

0934 0935
MYBPM_ZOO_CONF_...:
0936 0937

Определяет конфигурацию подключения к Zookeeper-у. Платформа 0938 MyBPM считывает все п.о., начинающиеся с префикса 0939 MYBPM_ZOO_CONF_, и каждое значение превращает в пару 0940 ключ-значение. Потом эти пары передаются объекту класса 0941 ZKClientConfig с помощью метода 0942 setProperty(...) - тем самым определяя конфигурацию 0943 доступа. На примере кода выше это показано.

0944 0945

Формат значения данных п.о. следующий:

0946 0947
0948  <имя-параметра> = <ТИП> : <значение-параметра>
0949  
0950  
0951  
0952  
0953 0954

Где:

0955 0956

<имя-параметра> - текст, представляющий имя 0957 параметра, который передаётся в качестве ключа в метод 0958 setProperty(...) первым аргументом.

0959 0960

<ТИП> - текст, представляющий тип значения. 0961 Может иметь следующие варианты: TXT, 0962 Base64_To_File - ниже описаны их значения.

0963 0964

<значение-параметра> - тест, который 0965 используется в зависимости от типа. Пробелы всегда обрезаются с 0966 обеих сторон.

0967 0968

Если <ТИП> == 'TXT', то это обозначает, что 0969 <значение-параметра> нужно передать в качестве 0970 значения в метод setProperty(...) вторым 0971 аргументом.

0972 0973

Если <ТИП> == 'Base64_To_File', то это 0974 обозначает, что <значение-параметра> должно 0975 представлять собой Base64-код содержимого некого файла. Платформа 0976 MyBPM возьмёт этот Base64-код, превратит его в массив байт, и 0977 сохранит во временный файл. А в качестве значения в метод 0978 setProperty(...) вторым аргументом подставит 0979 абсолютный путь к этому файлу. После этого система авторизации 0980 внутри класса CuratorFramework сможет получить к нему 0981 доступ и использовать по назначению.

0982 0983

ПРИМЕЧАНИЕ

0984 0985

Иногда для доступа к Zookeeper-у необходимо при запуске 0986 Java-машины определить параметр:

0987 0988
0989  -Djava.security.auth.login.config=/path/to/zookeeper-jaas.conf
0990  
0991  
0992  
0993  
0994 0995

Для этого можно использовать п.о. 0996 MYBPM_SYSTEM_PROPERTY_ (его описание ищите на этой 0997 странице)

0998 0999
1000

MYBPM_KAFKA_SERVERS, 1001 MYBPM_KAFKA_CON_...

1002 1003

Определяют параметры доступа к кафке.

1004 1005
Возможные значения для 1006 MYBPM_KAFKA_SERVERS:
1007 1008
1009  Разделённый запятыми последовательности хост:порт
1010  
1011  
1012  
1013  
1014 1015

Определяет список серверов кластера Kafka. Эта переменная 1016 присваивается параметру

1017 1018
1019  bootstrap.servers
1020  
1021  
1022  
1023  
1024 1025

В списке параметров доступа к Кафке как для поставщика данных 1026 (Producer) так и для потребителя данных (Consumer).

1027 1028

Например, для подключения к Кафке в виде поставщика данных можно 1029 воспользоваться кодом:

1030 1031
1032  void someMethod() {
1033      Map<String, Object> prop = new HashMap<>();
1034  
1035      prop.put("bootstrap.servers", "localhost:13113"); // Вот сюда вставляется значение из п.о. MYBPM_KAFKA_SERVERS
1036      prop.put("key.serializer", StringSerializer.class.getName());
1037      prop.put("value.serializer", StringSerializer.class.getName());
1038      prop.put("request.timeout.ms", "5000");
1039      prop.put("max.block.ms", "5000");
1040      prop.put("metadata.fetch.timeout.ms", "5000");
1041      prop.put("enable.auto.commit", "false");
1042      prop.put("acks", "all");
1043  
1044      try (KafkaProducer<String, String> producer = new KafkaProducer<>(prop)) {
1045          // working with producer ...
1046      }
1047  }
1048  
1049  
1050 1051

В этом коде в параметр bootstrap.servers 1052 вставляется значения из п.о. MYBPM_KAFKA_SERVERS. 1053 Остальные параметры платформа MyBPM генерирует по другой логике, в 1054 зависимости от ситуации.

1055 1056

Может случиться так, что доступ к Кафке предоставляется через 1057 безопасное соединение, и тогда Java-код должен выглядеть примерно 1058 так:

1059 1060
1061   void libraryMethod() {
1062      // ....
1063      Map<String, Object> prop = new HashMap<>();
1064  
1065      prop.put("key.... "); // (здесь параметры не связанные с доступом)
1066  
1067      prop.put("bootstrap.servers", "localhost:13113");
1068  
1069      prop.put("sasl.mechanism", "PLAIN");
1070      prop.put("security.protocol", "SASL_SSL");
1071      prop.put("ssl.truststore.location", "/some/path/to/existing/file/client.truststore.jks");
1072      prop.put("ssl.truststore.password", "111222");
1073      prop.put("sasl.jaas.config", "org.apache.kafka.common.security.plain.PlainLoginModule" +
1074              " required serviceName=\"Kafka\" username=\"alice\" password=\"alice-secret\";");
1075  
1076      try (KafkaProducer<String, String> producer = new KafkaProducer<>(prop)) {
1077          // working with producer ...
1078      }
1079  }
1080  
1081  
1082 1083

Т.е. нужно передать дополнительные параметры. Притом есть 1084 параметры, которые представляют путь к существующему файлу. Этот 1085 файл нужно подготовить, передать на сервер, и указать к нему 1086 путь.

1087 1088
Значения MYBPM_KAFKA_CON_...
1089 1090

Кроме MYBPM_KAFKA_SERVERS можно ещё определить несколько 1091 дополнительных п.о. которые будут дополнительно добавляться к 1092 списку параметров доступа к Кафке.

1093 1094

Чтобы это сделать нужно указать несколько п.о., которые 1095 начинаются с MYBPM_KAFKA_CON_ и имеют только цифры 1096 после этого префикса, которые нужно для того, чтобы можно было 1097 указать несколько параметров с одним смыслом.

1098 1099

Значения у этих п.о. должны иметь вид:

1100 1101
1102  <имя-параметра> = <ТИП> : <значение-параметра>
1103  
1104  
1105  
1106  
1107 1108

Где:

1109 1110

<имя-параметра> - это строка, которая будет 1111 передаваться в качестве ключа в объект prop (см. 1112 Java-код выше).

1113 1114

<ТИП> - одно из значений: TXT 1115 или Base64_to_File

1116 1117

<значение-параметра> - строка, которая будет 1118 обрабатываться в зависимости от <ТИП>-а.

1119 1120

Если <ТИП> = TXT, то это 1121 обозначает, что <значение-параметра> будет 1122 переходить в prop как есть - один-к-одному.

1123 1124

Если <ТИП> = Base64_to_File, то 1125 это обозначает, что <значение-параметра> должно 1126 представлять собой код Base64. Система возьмёт этот код Base64, 1127 превратит его в последовательность байт, и сохранит его во 1128 временный файл. А в объект prop будет передана строка 1129 с абсолютным путём к этому файлу.

1130 1131

Таким образом Вы можете передать файл, не имея доступа к 1132 серверу.

1133 1134

Другими словами Вы можете сделать так:

1135 1136

Получите из Вашего файла код Base64, например командой:

1137 1138
1139  base64 -w0 имя_исходного_файла > имя_файла_где_будет_сохранён_base64
1140  
1141  
1142  
1143  
1144 1145

Допустим у Вас получился код (Ваш код может быть значительно 1146 длинней):

1147 1148
1149  4kjh32b454/534b256k45b64l3b21434==
1150  
1151  
1152  
1153  
1154 1155

Этот код передайте в переменную окружения следующим образом 1156 (здесь использован синтаксис docker compose):

1157 1158
1159  environment:
1160      MYBPM_KAFKA_CON_004:  "ssl.truststore.location = Base64_to_File:4kjh32b454/534b256k45b64l3b21434=="
1161  
1162  
1163  
1164  
1165 1166

И тогда в объект prop прилетит параметр с ключом 1167 ssl.truststore.location и значением некого абсолютного 1168 пути к файлу, содержимое которого будет соответствовать указанному 1169 Вами коду Base64.

1170 1171

Если у Вас есть доступ к серверу, то вы можете скопировать файл 1172 на сервер, например по пути:

1173 1174
1175  /ssl/client.truststore.jks
1176  
1177  
1178  
1179  
1180 1181

И указать переменную окружения:

1182 1183
1184  environment:
1185      MYBPM_KAFKA_CON_004:  "ssl.truststore.location = TXT:/ssl/client.truststore.jks"
1186  
1187  
1188  
1189  
1190 1191

Путь будет скопирован в объект prop как есть - 1192 один-к-одному.

1193 1194
1195

1197 MYBPM_MONGO_SERVERS, MYBPM_MONGO_DB, MYBPM_MONGO_USER, 1198 MYBPM_MONGO_PASS

1199 1200

Параметры доступа к кластеру MongoDB

1201 1202

Данные переменные окружения определяют параметры доступа к 1203 кластеру MongoDB. Основной переменной окружения является 1204 MYBPM_MONGO_SERVERS - в зависимости от её значение 1205 определяется, будут ли использоваться другие переменные 1206 окружения.

1207 1208

Если MYBPM_MONGO_SERVERS НЕ содержит подстроку 1209 '://', то строка доступа к кластеру определяется по следующей 1210 схеме:

1211 1212

Если MYBPM_MONGO_USER определено и НЕ пустое, то 1213 получается следующая строка доступа:

1214 1215
1216  mongodb://${MYBPM_MONGO_USER}:${MYBPM_MONGO_PASS}@${MYBPM_MONGO_SERVERS}/${MYBPM_MONGO_DB}
1217  
1218  
1219  
1220  
1221 1222

Если MYBPM_MONGO_USER НЕ определено или пустое, то 1223 получается такая строка доступа:

1224 1225
1226  mongodb://${MYBPM_MONGO_SERVERS}/${MYBPM_MONGO_DB}
1227  
1228  
1229  
1230  
1231 1232

Притом /${MYBPM_MONGO_DB} добавляется только в том 1233 случае, если MYBPM_MONGO_DB определено и НЕ 1234 пустое.

1235 1236

В приведённых обозначениях подстановка делается по синтаксису 1237 интерпретатора bash, т.е. в место ${HI} подставляется 1238 значение переменной окружения HI

1239 1240

Если MYBPM_MONGO_SERVERS содержит подстроку '://', 1241 то для доступа к кластеру MongoDB используется только данное 1242 значение. Переменные окружения MYBPM_MONGO_DB, MYBPM_MONGO_USER, 1243 MYBPM_MONGO_PASS будут проигнорированы.

1244 1245

В этом случае значение переменной окружения 1246 MYBPM_MONGO_SERVERS будет использоваться как строка 1247 доступа к MongoDB. Подробное описание данной строки доступа 1248 приводиться в официальной документации по MongoDB, а именно по 1249 ссылке:

1250 1251

1253 https://www.mongodb.com/docs/manual/reference/connection-string/

1254 1255

Если вкратце, то шаблон значения (взятый из приведённой ссылки) 1256 может быть такой:

1257 1258
1259  MYBPM_MONGO_SERVERS = mongodb://[username:password@]host1[:port1][,...hostN[:portN]][/[defaultauthdb][?options]]
1260  
1261  
1262  
1263  
1264 1265

Тут квадратные скобки обозначают не обязательное значение.

1266 1267
1268

1270 MYBPM_MONGO_FILES_SERVERS, MYBPM_MONGO_FILES_DB, 1271 MYBPM_MONGO_FILES_USER, MYBPM_MONGO_FILES_PASS

1272 1273

Параметры доступа к кластеру MongoDB для хранения файлов

1274 1275

Эти п.о. используются так же как и 1276 MYBPM_MONGO_[SERVERS,USER...], но для доступа к кластеру MongoDB, в 1277 котором хранятся файлы.

1278 1279

Если данные п.о. не заданны, то используются переменные 1280 MYBPM_MONGO_[SERVERS,USER...] для доступа к кластеру файлов. Т.е. в 1281 таком случае файлы хранятся там, же где и остальные данные.

1282 1283
1284

MYBPM_SCHEDULER_OFF

1285 1286

Если эта переменна установлена в yes, то шедулер не 1287 запускается

1288 1289
1290

1291 MYBPM_CACHE_REDIS_HOST_PORT

1292 1293

В этой переменной нужно передать хост, порт, логин и пароль 1294 разделённые двоеточием, которые указывают на сервер redis. Он будет 1295 использоваться для кэширования. Если эта переменная окружения не 1296 указана, то будет использоваться внутренний кэш на основе 1297 библиотеки caffeine.

1298 1299

Переменная может содержать только хост, например:

1300 1301
1302  192.168.11.23
1303  
1304  
1305  
1306  
1307 1308

В этом случае система будет обращаться по адресу 1309 192.168.11.23 и порту 6379

1310 1311

Переменная может содержать хост и порт, разделённые двоеточием, 1312 например:

1313 1314
1315  redis.super.host.kz:40110
1316  
1317  
1318  
1319  
1320 1321

В этом случае система будет обращаться по адресу 1322 redis.super.host.kz и порту 1323 40110

1324 1325

Переменная может содержать хост, порт, логин и пароль, 1326 разделённые двоеточием, например:

1327 1328
1329  redis.wood.com:34089:SharonStone:4gjv321gh5v:4v::23
1330  
1331  
1332  
1333  
1334 1335

В этом случае система будет обращаться по адресу 1336 redis.wood.com и порту 34089 под 1337 пользователем SharonStone и паролем: 1338 4gjv321gh5v:4v::23

1339 1340
1341

MYBPM_TOPIC_SUFFIX_REFRESH

1342 1343

Добавление суффикса топику REFRESH

1344 1345
Возможные значения:
1346 1347
1348  строка из латинских символов, цифр
1349  
1350  
1351  
1352  
1353 1354

Данная переменная окружения позволяет добавить суффикс к топику 1355 REFRESH в кафке. Если эта переменная не определена или имеет пустое 1356 значение, то топик так и называется REFRESH. Но если эта переменная 1357 равна например:

1358 1359
1360  MYBPM_TOPIC_SUFFIX_REFRESH = 123
1361  
1362  
1363  
1364  
1365 1366

То топик REFRESH не используется, а вместо него используется 1367 топик REFRESH123.

1368 1369
1370

1371 MYBPM_ELASTIC_NUMBER_OF_REPLICAS

1372 1373

Количество реплик, которые есть у каждого основного шарда в 1374 ElasticSearch.

1375 1376
Возможные значения:
1377 1378
1379  целочисленные значения
1380  
1381  
1382  
1383  
1384 1385

Данная переменная окружения позволяет настройку количества 1386 репликационных шардов при создании основного шарда. Если эта 1387 переменная не указана, значение по умолчанию для данной переменной 1388 окружения является 1. Если значение данной 1389 переменной окружения является:

1390 1391
1392  MYBPM_ELASTIC_NUMBER_OF_REPLICAS = 2
1393  
1394  
1395  
1396  
1397 1398

Тогда при создании индекса, будет создано 2 1399 репликационных шарда для основного шарда.

1400 1401
1402

1403 MYBPM_SCRIPTS_SHOW_PANEL_WITH_OLD_ELEMENTS

1404 1405

Открывает панель с устаревшими компонентами в редакторе 1406 скриптов.

1407 1408
Возможные значения:
1409 1410
1411  yes,no
1412  
1413  
1414  
1415  
1416 1417

Старыми компонентами в скриптах пользоваться нельзя, поэтому 1418 панель для них убрана. НО... если всё-таки сильно хочется, то можно 1419 установить эту переменную окружения со значением yes и 1420 панель станет доступна

1421 1422
1423

MYBPM_SYSTEM_PROPERTY_...

1424 1425

Задаёт системные параметры внутри виртуальной Java-машины

1426 1427
Возможные значения:
1428 1429
1430  <имя-параметра> = <ТИП> : <значение-параметра>
1431  
1432  
1433  
1434  
1435 1436

Где:

1437 1438

<имя-параметра> - это строка, которая будет 1439 передаваться в качестве имени системного параметра

1440 1441

<ТИП> - одно из значений: TXT 1442 или Base64_to_File

1443 1444

<значение-параметра> - строка, которая будет 1445 обрабатываться в зависимости от <ТИП>-а.

1446 1447

Если <ТИП> = TXT, то это 1448 обозначает, что <значение-параметра> будет 1449 переходить как есть - один-к-одному. Другими словами для 1450 значения:

1451 1452
1453  <имя-параметра> = TXT : <значение-параметра>
1454  
1455  
1456  
1457  
1458 1459

Будет устанавливаться следующее значение системного 1460 параметра:

1461 1462
1463  System.setProperty( "<имя-параметра>", "<значение-параметра>" );
1464  
1465  
1466  
1467  
1468 1469

Если <ТИП> = Base64_to_File, то 1470 это обозначает, что <значение-параметра> должно 1471 представлять собой код Base64. Система возьмёт этот код Base64, 1472 превратит его в последовательность байт, и сохранит её во временный 1473 файл. А в системный параметр будет передана строка с абсолютным 1474 путём к этому файлу. Другими словами для значения:

1475 1476
1477  <имя-параметра> = Base64_to_File : jk34hb5hjg4352hv35vj==
1478  
1479  
1480  
1481  
1482 1483

Будет устанавливаться следующее значение системного 1484 параметра:

1485 1486
1487  System.setProperty( "<имя-параметра>", "/абсолютный/путь/к/файлу/c/содержимым/jk34hb5hjg4352hv35vj==" );
1488  
1489  
1490  
1491  
1492 1493

С помощью переменных, которые начинаются на 1494 MYBPM_SYSTEM_PROPERTY_ можно передать системные 1495 параметры в виртуальную машину Java - по одному параметру за одну 1496 переменную окружения. Системные параметры внутри виртуальной машины 1497 доступны с помощью функции:

1498 1499
1500  System.getProperty("system.param.key")
1501  
1502  
1503  
1504  
1505 1506

Например, если в docker compose указать переменные 1507 окружения:

1508 1509
1510  environment:
1511    MYBPM_SYSTEM_PROPERTY_001: "some.key = TXT: some-value"
1512    MYBPM_SYSTEM_PROPERTY_002: "test.config = Base64_to_File: jhkb45hj3kB254BV/24hgV355=="
1513  
1514  
1515  
1516  
1517 1518

То внутри Java-машины можно будет вызвать:

1519 1520
1521  System.getProperty("some.key"); 
1522  
1523  
1524  
1525  
1526 1527

И он вернёт строку: "some-value". А если вызвать:

1528 1529
1530  System.getProperty("test.config"); 
1531  
1532  
1533  
1534  
1535 1536

То он вернёт путь к файлу, в котором лежат байты из Base64-кода: 1537 jhkb45hj3kB254BV/24hgV355==

1538 1539
1540

MYBPM_MEMORY_LIMIT

1541 1542

Указание программе сервера ограничение на оперативную память, 1543 которое наложено внешней средой, например Kubernetes-ом.

1544 1545
Возможные значения:
1546 1547
1548  10Gi
1549  
1550  
1551  
1552  
1553 1554

Значение представляет собой целое положительное число, за 1555 которым следует единица измерения информации. Между числом и 1556 единицей измерения можно поставить пробел. А можно не ставить - 1557 писать слитно.

1558 1559

Единицу измерения можно не указывать - оставить одно число. В 1560 этом случае это число будет указывать количество байт.

1561 1562

Ниже в таблице указаны доступные единицы измерения:

1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638
Единица измеренияМасштабный коэффициентПримерЧто пример обозначает
(пусто)135003 500 байтов
Ki102417Ki17 408 байтов
K100017K17 000 байтов
Mi1024 * 102421Mi22 020 096 байтов
M1000 * 100021M21 000 000 байтов
Gi1024 * 1024 * 102413Gi13 958 643 712 байтов
G1000 * 1000 * 100013G13 000 000 000 байтов
Ti1024 * 1024 * 1024 * 102421Ti23 089 744 183 296 байтов
T1000 * 1000 * 1000 * 100021T21 000 000 000 000 байтов
1639 1640

Разделители разрядов (точка или запятая) использовать нельзя. 1641 Если Вы хотите указать: 1.3G, то пишите 1300M

1642 1643

В Kubernetes данную переменную рекомендуется задать следующим 1644 образом:

1645 1646
1647  # .....
1648  spec:
1649    containers:
1650      - name: main
1651        image: hub.mybpm.kz/mybpm-api
1652        resources:
1653          limits:
1654            memory: "1Gi"
1655          requests:
1656            memory: "1Gi"
1657    # .....
1658    env:
1659      - name: MYBPM_MEMORY_LIMIT,
1660        valueFrom: { resourceFieldRef: { containerName: main, resource: limits.memory } }
1661  # ....
1662  
1663  
1664 1665

Что обозначает чтение её значение из самого ограничения. Это 1666 уберёт необходимость указания одного параметра в разных местах. 1667 Подробнее об использовании этой переменной смотрите в разделе 1669 Генерация heap-dump-файлов

1670
1671 1672 at kz.greetgo.md_reader.util.MdUtil.xmlTextToDoc(MdUtil.java:80) at kz.greetgo.md_reader.core.MdConverter.prepareHtmlFileFrom(MdConverter.java:136) at kz.greetgo.md_reader.core.MdConverter.convert(MdConverter.java:208) at kz.greetgo.md_reader.controller.RenderController.downloadToc(RenderController.java:360) at kz.greetgo.md_reader.controller.RenderController.request(RenderController.java:108) at jdk.internal.reflect.GeneratedMethodAccessor7.invoke(Unknown Source) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:568) at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:207) at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:152) at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:884) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797) at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1081) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:974) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1011) at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903) at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564) at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885) at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:205) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) at kz.greetgo.md_reader.interceptors.TextReplaceFilter.doFilter(TextReplaceFilter.java:36) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:166) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:341) at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:390) at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:894) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1741) at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.base/java.lang.Thread.run(Thread.java:833) Caused by: java.io.IOException: Server returned HTTP response code: 429 for URL: http://www.w3.org/TR/xhtml1/DTD/xhtml-symbol.ent at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:2000) at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1589) at java.xml/com.sun.org.apache.xerces.internal.impl.XMLEntityManager.setupCurrentEntity(XMLEntityManager.java:677) at java.xml/com.sun.org.apache.xerces.internal.impl.XMLEntityManager.startEntity(XMLEntityManager.java:1397) at java.xml/com.sun.org.apache.xerces.internal.impl.XMLEntityManager.startEntity(XMLEntityManager.java:1333) at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl.startPE(XMLDTDScannerImpl.java:732) at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl.skipSeparator(XMLDTDScannerImpl.java:2101) at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl.scanDecls(XMLDTDScannerImpl.java:2064) at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl.scanDTDExternalSubset(XMLDTDScannerImpl.java:299) at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$DTDDriver.dispatch(XMLDocumentScannerImpl.java:1165) at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$DTDDriver.next(XMLDocumentScannerImpl.java:1040) at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(XMLDocumentScannerImpl.java:943) at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:605) at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:542) at java.xml/com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:889) at java.xml/com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:825) at java.xml/com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141) at java.xml/com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:247) at java.xml/com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:342) at java.xml/javax.xml.parsers.DocumentBuilder.parse(DocumentBuilder.java:122) at kz.greetgo.md_reader.util.MdUtil.xmlTextToDoc(MdUtil.java:71) ... 48 more