
# Установка сервера приложений

Автономный режим используется, когда нагрузка позволяет использовать один экземпляр сервера приложений.

## Необходимое программное обеспечение
**ПО под ОС Astra Linux / Debian:**
- PostgreSQL-client (версия клиента должна совпадать с версией сервера);
- JRE 21 или JDK 21:
  - Axiom JDK (Liberica) <https://axiomjdk.ru/pages/downloads/#/java-21-lts>;
  - другой дистрибутив на основе OpenJDK <https://jdk.java.net/java-se-ri/21>.
- expect;
- htop;
- iotop;
- sysstat;
- ssh (клиент и сервер SSH);
- mc (Midnight Commander);
- tar;
- zip;
- unzip;
- cifs-utils;
- sudo.

Для работы с большим количеством прикрепленных файлов, необходимо подключить дополнительный раздел большого объема.
Например, сетевой ресурс **samba/cifs**.

Пример подключения через конфигурационный файл `/etc/fstab`:

```text
# share global attach
//172.16.1.120/globalfiles /mnt/attach cifs _netdev,username=global@testdomain.local,password=123Global321,iocharset=utf8,file_mode=0777,dir_mode=0777 0 0
```

## Установка

1. Скачайте архив дистрибутива и прикладного решения с предоставленного ресурса (Предоставляется через контактное лицо, файлы `globalserver.zip` и `applib.zip`).

2. Подключитесь терминалом к серверу Global.

3. Создайте временную директорию и загрузите файлы дистрибутива на сервер:

```bash
sudo mkdir -p /tmp/global
```

4. Создайте пользователя и группу `global`:

```bash
sudo groupadd global
sudo useradd -g global global
```

5. Распакуйте сервер приложений:

```bash
sudo mkdir -p /opt/global/globalserver
sudo unzip /tmp/global/globalserver.zip -d /opt/global/globalserver
```

6. Распакуйте образ прикладного решения:

```bash
sudo mkdir -p /opt/global/globalserver/application/applib /opt/global/globalserver/application/applibBin
sudo unzip /tmp/global/applib.zip -d /opt/global/globalserver/application/applib
```

7. Назначьте владельца:

```bash
sudo chown -R global:global /opt/global/globalserver
```

8. Выдайте разрешение на запуск:

```bash
sudo chmod ug+x /opt/global/globalserver/start.sh 
sudo chmod ug+x /opt/global/globalserver/stop.sh
sudo chmod ug+x /opt/global/globalserver/globalscheduler.sh
```

## Настройка сервисов

Сервис нужен для работы системы **Global** в качестве фонового процесса.

### Сервис global

Для настройки сервиса нужно скопировать файл: `/opt/global/globalserver/admin/linux/global3.service.origin` в каталог `/lib/systemd/system` и переименовать `global3.service`:

```bash
sudo cp /opt/global/globalserver/admin/linux/global3.service.origin /lib/systemd/system/global3.service
```

Или создать новый файл:

```bash
sudo touch /usr/lib/systemd/system/global3.service
```

Содержимое:

```text
[Unit]
Description=Система Global
After=multi-user.target

[Service]
User=global
Group=global
AmbientCapabilities=CAP_NET_BIND_SERVICE

# Env Vars
Environment=JAVA_OPTS=-Dfile.encoding=UTF-8
Type=idle
WorkingDirectory=/opt/global/globalserver
ExecStart=/opt/global/globalserver/start.sh
ExecStop=/opt/global/globalserver/stop.sh
TimeoutStopSec=110

[Install]
WantedBy=multi-user.target
```

Разрешите автозагрузку сервиса:

```bash
sudo systemctl daemon-reload
sudo systemctl enable global3
```

### Сервис globalscheduler

Процесс настройки сервиса описан в [документации GlobalScheduler](../070_addition/020_scheduler_setup.md#настройка-сервиса-globalscheduler).

## Настройка сервера приложений

### Конфигурация Global

Основной конфигурационный файл системы Global расположен в каталоге `/opt/global/globalserver/application/config/global3.config.xml`.

Пропишите БД в основную конфигурацию:

```xml
<?xml version="1.0" encoding="UTF-8" ?>
<configuration xmlns="http://www.global-system.ru/xsd/global3.config.1.0"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:schemaLocation="http://www.global-system.ru/xsd/global3.config.1.0">
	<databases>
		<database alias="<ПсевдонимБД>" driver="org.postgresql.Driver" schema="PUBLIC"
				  url="jdbc:postgresql://<host>:5432/<ИмяБД>" connectionType="proxyShared" authenticationType="btk">
			<users>
				<user name="<ИмяПользователяБД>" password="<ПарольПользователяБД>"/>
			</users>
			<metaManager
				mode="Xml"
				defaultNamespace="ru.bitec.app.btk"
				sbtName="main"
			/>
			<eclipseLink
				persistenceUnitName="pgdev"
				autoCommit="false"
			/>
		</database>
	</databases>
 
	<sbts>
		<sbt name="main"   
			 sourceMode="Jar"
			 jarFolder="/opt/global/globalserver/application/applib" 
			 binaryFolder="/opt/global/globalserver/application/applibBin"
			 source="/opt/global/globalserver/application/applib"
			 dirWatcherEnabled="false"     
		>    
			<fileStorages>
				<fileStorage name="Default"
				path="/mnt/attach/"/>    
			</fileStorages>  
		</sbt>  
	</sbts>

	<security>
		<!--В секции могут быть указаны значения парметров подключения по умолчанию-->
		<!--user - имя пользователя-->
		<!--password - пароль-->
		<!--dataBase - база данных-->
		<!--application - приложение-->
		<loginDefaults user="admin" password="admin" dataBase="DEVBTK"/>
		<!--Управляет сохранением параметров последнего входа в куках браузера-->
		<loginSavable user="true" password="true"/>
		<!--Ограничения на стойкость паролей.-->
		<!--<passwordStrength-->
		<!--minLength="6"-->
		<!--maxLength="20"-->
		<!--digitCount="1"-->
		<!--specialCharCount="0"-->
		<!--lowercaseCharCount="0"-->
		<!--uppercaseCharCount="0"-->
		<!--rejectUserName="false"-->
		<!--rejectWhitespace="false"-->
		<!--/>-->
		<users>
			<user name="admin" password="admin" roles="ssh,http-monitor"/>
			<!--Роль "system" предоставляет право открытия пользовательских сессий при нахождении сервера в сервисном режиме-->
			<user name="system" password="system" roles="system"/>
		</users>
	</security>

	<quotas>
		<server maxOldGenMemory="0" maxEdenSpaceMemory="80%"/>
		<session maxUiCellCount="100M" maxFormCount="30"/>
		<transaction maxTxCellCount="100M"/>
	</quotas>

	<!--minPoolSize - Минимальное число соединений в пуле-->
	<!--maxPoolSize - Максимальное число соединений в пуле-->
	<!--initialPoolSize - Начальное число соединений в пуле-->
	<!--inactiveConnectionTimeout - Время в течении которого сессия остаётся в пуле после освобождения, в секундах.-->
	<!--poolTimeout - Максимальное время ожидания получения соединения из пула, в секундах.-->
	<!--maxActiveThreadCount - Максимальное количество потоков работающих с базой данных.-->
	<!--activeThreadTimeout - Максимальное время ожидания потока для начала работы с базой данных, в секундах.-->
	<connectionPool minPoolSize="2"
					maxPoolSize="200"
					initialPoolSize="2"
					inactiveConnectionTimeout="60"
					poolTimeout="10"
					maxActiveThreadCount="170"
					activeThreadTimeout="10"/>

	<!--clientTimeout - Максимальное время бездействия сокета. В секундах.-->
	<!--clientPingInterval - Интервал выполнения пинга клиентского приложения, для предотвращения закрытия веб-сокета по таймауту. В секундах.-->
	<!--clientPingEnabled - Если true, сервер будет периодически пинговать клиента, что бы сокет не закрывался-->
	<!--sessionTimeout - Время жизни сессии после разрыва соединения с браузером. Интервал  в секундах.-->
	<!--maxSessionCount - Максимальное число запущенных сессий-->
	<!--maxSessionsPerUser - Максимальное число запущенных сессий для пользователя-->
	<!--                     (лишние будут закрываться при закрытии окна браузера)-->
	<!--cookieExpiresTime - Время жизни Cookies в секундах-->
	<sessionPool clientTimeout="600"
				clientPingInterval="300"
				clientPingEnabled="true"
				sessionTimeout="900"
				maxSessionCount="200"
				passiveSessionsMax="2"
				cookieExpiresTime="86400"
			/>

	<!--host - Адрес web-сервера:порт, на котором запущен сервис построения отчётов FastReport.Mono.
				Этот же адрес должен быть указан на прокси-узле -->
	<!--proxyaddress - Корневой адрес куда клиентское приложение будет посылать запрос на получение отчёта.-->
	<!--               Абсолютный, если необходимо направить запросы напрямую к серверу отчётов или на внешний сервис.-->
	<!--               Относительный, если на текущем web-сервере настроен proxy к серверу отчётов.-->
	<fastReportMonoServer host="http://global3:90" proxyaddress="fastreportmono"/>
	<!--host - Адрес web-сервера:порт, на котором запущен сервис построения отчётов FastReport.VCL.
				Этот же адрес должен быть указан на прокси-узле -->
	<!--proxyaddress - Корневой адрес куда клиентское приложение будет посылать запрос на получение отчёта.-->
	<!--               Абсолютный, если необходимо направить запросы напрямую к серверу отчётов или на внешний сервис.-->
	<!--               Относительный, если на текущем web-сервере настроен proxy к серверу отчётов.-->
	<fastReportServer host="http://global3:8010" proxyaddress="fastreport"/>
	<!--<fastReportServer host="http://localhost:8080/fastreport" handler="CreateReport.ashx" proxyaddress="fastreport"/>-->

	<!--enableNetworkPrinting - Включает режим печати отчётных форм на принтерах в подсети сервера приложений. -->
	<!-- В противном случае печать осуществляется на клиентской стороне.-->
	<printing enableNetworkPrinting="false"/>

	<!--selectionMetaExpireTimeInSeconds - Время, в течение которого в кэше метаданные выборки считаются валидными-->
	<cache selectionMetaExpireTimeInSeconds="300"/>

	<!--operationLevel - Минимальный уровень логов операций отправляемых на клиент-->
	<!--sqlLevel - Минимальный уровень логов SQL отправляемых на клиент-->
	<!--scriptLevel - Минимальный уровень логов скриптовых методов отправляемых на клиент-->
	<clientLog operationLevel="INFO" sqlLevel="OFF" scriptLevel="OFF"/>
	<client>
		<automation metaDataAttributes="false"
					jexlExecution="false"
					operExecution="false"/>
	</client>
	<!--enabled - флаг доступности службы оповещения-->
	<instantMessenger enabled="true"/>

	<development>
		<!--enabled - режим отладки. Делает видимым панель отладки в главном меню приложения-->
		<debugMode enabled="true"/>
		<!--enabled - Доступность флага "Конфигуратор" в диалоге подключения-->
		<configurator enabled="true"/>
	</development>

	<!--jmxServiceUrl - Пользователь/пароль, под которым создаются временные таблицы для olap-кубов-->
	<!--user - пользователь доступа к олап серверу-->
	<!--password - пароль доступа к олап серверу-->
	<olap jmxServiceUrl="service:jmx:rmi:///jndi/rmi://:1999/jmxrmi" user="olap" password="olap"/>

	<!-- Можно вручную указать директорию для временных файлов, используемую Global3 для своих нужд.
	По умолчанию берется директория для временных файлов вашего пользователя.
	На win7/8 это обычно "C:\Users\<yourUserName>\AppData\Local\Temp\.global3"
	Меняйте значение по умолчанию ТОЛЬКО В ТОМ СЛУЧАЕ, если по каким-то причинам вы не имеете доступа к директории по умолчанию.
	Для этого раскомментируйте следующую строку и установите путь к необходимой директории. -->
	<!--<temporaryDir>C:\temp</temporaryDir>-->

	<cluster enabled="false" name="GlobalAppServerCluster">
	<broker>
		<database alias="cluster_broker" driver="org.postgresql.Driver" schema="global_system"
				url="jdbc:postgresql://v39:5432/test">
		<users>
			<user name="test" password="test"/>
		</users>
		</database>
	</broker>
	<node>
		<balancerTypes>["prod","dev"]</balancerTypes>
	</node>
	</cluster>

	<languages>
	<language name="ru-RU"/>
	<language name="en-US"/>
	</languages>

	<ssh defaultDb="PostgreSql" port="22"/>

</configuration>
```

Где:

- \<ПсевдонимБД> - сокращенное название организации, или доменное имя;  
- \<host> - адрес сервера postgres;  
- \<ИмяБД> - имя базы данных, подготовленной для работы Global System;  
- \<ИмяПользователяБД> - пользователь БД;  
- \<ПарольПользователяБД> - пароль пользователя БД.  

### Конфигурация запуска

Параметры запуска расположены в файле `/opt/global/globalserver/default.sh`, их можно переопределить в файле `/opt/global/globalserver/parameters.sh`:

```bash
#!/bin/bash
set -x
# Настройки портов
export JETTY_HTTP_PORT=8080

#память: 1000M - в мегабайтах 1G - в гигабайтах
export globalMemory=3G
```

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

### Конфигурация планировщика заданий

Процесс конфигурации описан в [документации GlobalScheduler](../070_addition/020_scheduler_setup.md#настройка-конфигурационных-файлов).

### Конфигурация утилиты обновления

В дистрибутив сервера приложений Global входит утилита обновления, которая обновляет сам сервер приложений или прикладной код образа проектного решения.  
Для настройки утилиты обновления скопируйте и переименуйте поставочный конфигурационный файл `/opt/global/globalserver/update/config.sh.origin`:

```bash
sudo cp /opt/global/globalserver/update/config.sh.origin /opt/global/globalserver/update/config.sh
```

```bash
#!/bin/sh

#
# Global Postgres update
# параметры утилиты обновления системы
# 

#ssh сервера приложений
sSshHost="localhost"
#ssh порт
sSshPort="2299"
#ssh логин
sSshLogin="admin"
#ssh пароль
sSshPass="admin"
#наименование бд
sDbName="<ПсевдонимБД>"
#наименование SBT
sSbtName="main"

# имя сервиса сервера приложений
sGlobalService="global3"

# имя сервиса менеджера заданий
sSchedulerService="globalscheduler"

# временный каталог обновлений
sTmp="/opt/global/globalupdate"
```

Где:  

- sSshPort - порт внутреннего ssh сервера Global;
- sSshLogin - логин из `global3.config.xml` в разделе security\users;
- sSshPass - пароль из `global3.config.xml` в разделе security\users;
- sDbName - псевдоним БД  из `global3.config.xml` в разделе databases\database:alias;
- sSbtName - имя SBT из `global3.config.xml` в разделе `databases\database\metaManager:sbtName`;
- sGlobalService - имя сервиса сервера приложений;
- sSchedulerService - имя сервиса менеджера заданий.

Выдайте права на запуск:

```bash
sudo find /opt/global/globalserver/update -type f -name '*.sh' -exec chmod a+x {} \;
```

### Шифрование паролей в конфигурационных файлах

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

- global3.config.xml - описан в разделе `Конфигурация Global`;
- quartz.properties - описан в разделе `Конфигурация планировщика заданий`;
- config.sh - описан в разделе `Конфигурация утилиты обновления`.

#### Общие принципы шифрования

Для шифрования пароля необходимо запустить Global 3 Server c параметрами `-encryptPassword` и `-masterPassword`:

```bash
start.sh -encryptPassword password -masterPassword masterpassword
```

Где:

- `-encryptPassword` - пароль, который необходимо зашифровать;
- `-masterPassword` - ключ шифрования, если не указан используется секретный ключ по умолчанию.

Результатом выполнения будет вывод в консоль строки, полученной в результате шифрования пароля переданного параметром `-encryptPassword`.

#### Использование шифрованных паролей

Шифрованные пароли можно использовать во всех местах файла **global3.config.xml** где требуется указание пароля пользователя. Вместо тэга `password` зашифрованный пароль необходимо указывать в тэге `encryptedPassword`.

Пример:

```xml
<databases>
 <database alias="<ПсевдонимБД>" driver="org.postgresql.Driver" schema="PUBLIC"
     url="jdbc:postgresql://<host>:5432/<ИмяБД>" connectionType="proxyShared" authenticationType="btk">
  <users>
   <user name="<ИмяПользователяБД>" encryptedPassword="<ЗашифрованныйПарольПользователяБД>"/>
  </users>
 </database> 
</databases>
```

Мастер-пароль может быть указан следующими способами:

- Параметром запуска сервера приложений  `-masterPassword`:

```bash
start.sh -masterPassword masterpassword
```

- Параметром конфигурационного файла `global3.config.xml` с указанием файла, хранящего мастер пароль:

```xml
<security>
  <masterPassword file="<ПутьКФайлуСПаролем>"/>
</security>
```

#### Шифрование паролей планировщика заданий

В файле quartz.properties зашифрованный пароль может быть указан в отдельном параметре:

```text
ru.bitec.jobscheduler.quartz.dataSource.quartzDS.encryptedpassword=encryptedPassword
```

Ключ шифрования может быть указан следующими способами:

- Параметром запуска планировщика  `-masterPassword`.
- Путь до файла с ключом шифрования указывается в конфигурационном файле в параметре:
  ```text
  ru.bitec.jobscheduler.masterpass.path=/some/path/to/file
  ```
  ```{note}
  Если в пути до файла используются символ \\ (обратный слэш), то его требуется экранировать вторым слэшем.

  Пример пути: ru.bitec.jobscheduler.masterpass.path=C:\\some\\path\\to\\file
  ```

Для шифрования пароля требуется запустить планировщик заданий c параметрами `encryptPassword` и `masterPassword`:

```bash
globalscheduler.sh -encryptPassword password -masterPassword masterpassword
```

Где:

- `-encryptPassword` - пароль, который необходимо зашифровать.
- `-masterPassword` - ключ шифрования, если не указан то используется стандартная логика определения мастер-пароля, так же как и при обычном запуске планировщика.

#### Шифрование паролей утилиты обновления

В файле **config.sh** хранится пароль доступа к ssh сервису сервера приложений в открытом виде и не может быть зашифрован.
Если в этом файле не указывать параметры **sSshLogin** и **sSshPass**, то они будут запрошены у запускающего пользователя.

### Ключи шифрования для токенов

Процесс генерации и установки ключей шифрования для планировщика описан в [документации GlobalScheduler](../070_addition/020_scheduler_setup.md#настройка-сервиса-globalscheduler).

## Первичная инициализация БД

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

Для инициализации выполните следующие действия:

1. Запустите сервер приложений:

```bash
sudo systemctl start global3
```

2. Подключитесь терминалом ssh к серверу приложений. По умолчанию порт 2299, логин admin, пароль admin:

```bash
ssh admin@localhost -p 2299
```

```{note}
Если при подключении к серверу у вас появляется ошибка:

    No matching host key type found. Their offer: ssh-rsa	

То для её исправления добавте в файл конфигурации ssh:

	Host localhost
		PubkeyAcceptedAlgorithms +ssh-rsa
		HostkeyAlgorithms +ssh-rsa

```


Где:

- `admin` - это имя пользователя из конфигурационного файла `global3.config.xml`. 
- `localhost` - адрес сервера Global.

3. Подключитесь к системе в режиме `sys`:

```bash
attach db Global as sys
```

Где `Global` - это псевдоним БД из конфигурационного файла `global3.config.xml`.

4. Выполните команду нагона релиза:

```bash
upgrade
```

## Получение и установка лицензии

Процесс получения и установки лицензии описан в [документации по первому входу в систему.](../080_licensing.md).

## Сброс пароля admin 

Перед сбросом пароля проверьте файл `global3.config.xml`.

В нем должны быть прописаны пользователи в блоке `security`:
```
    <security>
		<users>
			<user name="admin" password="admin" roles="ssh,http-monitor"/>
			<!--Роль "system" предоставляет право открытия пользовательских сессий при нахождении сервера в сервисном режиме-->
			<user name="system" password="system" roles="system"/>
		</users>
	</security>
```

### Пошаговая инструкция
1. Запустить сервер приложения.
2. Подключиться к серверу приложения по ssh:
```
ssh admin@localhost -p 2299
```
 3. Перевести сервер в режим `service`:
```
alter server mode service
```
 4. Зайти под учеткой system, <db_alias> - алиас БД из `global3.config.xml`:
```
login system/system@<db_alias>
```
 5. Выполнить команду:
```
jexl
```
 6. Вставить содержимое файла `reset_admin_pass.jexl`:
```
let sUserName = "admin";
let sRawPassword = "admin";

let idUser = Btk_UserApi.findByMnemoCode(sUserName);
if (isNull(idUser)) {
  raise("Пользователь с именем '" + sUserName + "' не найден.");
}

let ropUser = Btk_UserApi.load(idUser);
if (isNull(ropUser)) {
  raise("Ошибка загрузки пользователя с ID: " + idUser);
}

let idPassType = Btk_UserPassTypeApi.idTemporaryPassword();
if (isNull(idPassType)) {
  raise("Ошибка получения типа временного пароля.");
}

if (isNull(Btk_UserApi)) {
  raise("Ошибка: Btk_UserApi — null");
}
if (isNull(session)) {
  raise("Ошибка: session — null");
}

Btk_UserApi.setsPass(ropUser, sRawPassword, idPassType);

session.commit();
```
 7. Написать `/` и нажать `Enter`.
 8. Перевести сервер в `normal` режим.
```
alter server mode normal
```
 9. Закрыть соединение.
```
exit
```

### Проверка и завершение
После выполнения инструкции, при входе под учетной записью `admin` пароль будет `admin`.

После входа нужно будет заменить пароль на новый.

## Логирование сервера приложений

Логирование в проекте осуществляется с использованием [**Logback**](https://logback.qos.ch/documentation.html). Конфигурация логирования задается в XML-файлах, расположенных в каталоге `{{workspace}}/application/config/`.

Подробнее о конфигурации в разделе: [Логирование сервера приложений](../090_logs.md).
