﻿# Создание собственного микросервиса

> [HTML Version](create-service.html)

ELMA365 — это решение с микросервисной архитектурой. Оно состоит из небольших, слабо связанных и легко изменяемых модулей — микросервисов. Эти сервисы построены вокруг бизнес-потребностей и в большинстве случаев выполняют одну или несколько элементарных функций. 

Сервисы разворачиваются независимо друг от друга, могут быть написаны на разных языках и использовать разные технологии хранения данных. Подробнее об этом читайте в статье [«Архитектура»](architecture.md). 

Вы можете создать свой сервис и разместить его внутри Kubernetes-кластера. Это позволит расширить функциональные возможности системы. Например, можно создать сервис для работы с файлами **\*.xlsx**. Он будет считывать строки и сохранять их в приложения. 

Создавать свой сервис нужно тогда, когда без него нельзя решить задачу. Например, вам нужно подключить внешнюю библиотеку. Для интеграции с внешними системами достаточно использования [решений](solutions-building.md).

Сервис может быть написан на любом языке программирования, для развёртывания его внутри ELMA365 требуется только Docker-образ.

Ниже приводится пример по созданию сервиса на .NET Core 5.

## Создание сервиса на .NET

Откройте Visual Studio 2019. Создайте новый проект и задайте настройки, как показано на скриншотах ниже.

Так как система ELMA365 разворачивается на Ubuntu, укажите, что нужно включить Docker. Тип контейнера — Linux.

**(service1.png)**

**(service2.png)**

**(service3.png)**

VS создаст проект по умолчанию. Можно запустить его в Docker, чтобы убедиться, что сервис работает и отвечает.

После проверки можно переходить к следующему шагу.

## Подготовка проекта и выгрузка в Docker Hub

Чтобы система могла скачать Docker-образ, его нужно поместить в Docker-хранилище. В нашем примере мы будем использовать публичное хранилище [https://hub.docker.com/](https://hub.docker.com/). В нём необходимо зарегистрироваться.

1. Выберите проект и нажмите на его название правой кнопкой мыши.

2. Выберите **Добавить** — **Поддержка Docker** (в зависимости от целевой платформы). Дождитесь завершения настройки.

3. Нажмите на название проекта правой кнопкой мыши.

4. Выберите **Добавить** — **Поддержка оркестратора контейнеров... (Docker Compose)**. Дождитесь завершения настройки.

5. Нажмите на название проекта правой кнопкой мыши.

6. Выберите **Опубликовать** — **Реестр контейнеров Docker** — **Docker Hub**.

**(service5.png)**

**(service6.png)**

7. Укажите логин и пароль от Docker Hub и опубликуйте проект. 

(service7.png)

8. После нажатия на кнопку **Готово** открывается окно. Перед публикацией в нём можно указать тег для образа. С его помощью можно версионировать сервис.

**(service8.png)**

9. Нажмите **Опубликовать**. VS соберет Docker-образ и отправит его в хранилище [https://hub.docker.com/](https://hub.docker.com/).

Мы использовали публичное хранилище только в качестве примера. Для своих сервисов используйте приватные хранилища или создайте своё собственное с помощью [docker-registry](https://docs.docker.com/registry/).

## Запуск и проверка собственного сервиса

1. Создайте деплоймент для управления подом. Под запускает контейнер на основе предоставленного Docker-образа.

Для этого выполните команду: 

````
kubectl create deployment <microservice\_name> --image=<image\_name> -n <namespace>

````
Где:

- **<microservice\_name>** — название вашего сервиса;

- **<image\_name>** — адрес, где хранится образ (username/repository:tag);

- **<namespace>** — пространство имён, где будет создан сервис.

2. Создайте сервис для доступа к вашему сервису:

````
kubectl create service clusterip <microservice\_name> --tcp=80:80 -n <namespace>

````
Порт назначения может различаться в зависимости от версии Visual Studio и шаблона проекта. Введите порт, указанный в настройках пользовательского сервиса, например, **80:8080**.

3. Убедитесь, что сервис появился в списке подов. Для этого выполните команду:

````
kubectl get pods -n <namespace>

````
Вы увидите список сервисов со статусами, добавленный вами сервис должен быть в статусе **Running**.

4. Проверьте работу сервиса, запустив для примера контейнер с образом \[OBJECT\] в Kubernetes-кластере:

````
kubectl run -i curl --rm --image=curlimages/curl:latest -- curl http://<microservice\_name>.<namespace>:80/api/State

````
Если проверка прошла успешно и сервис отвечает, вы увидите следующее сообщение:

````
\{"type":"GET","version":"47.0.200.1129"\}

````
После завершения проверки можно перейти к следующему шагу.

````
Начало внимание

````
Для создания пользовательских микросервисов в ELMA365 вы также можете использовать функциональные возможности [переносимых сервисов](portable-microservices.md).

````
Конец внимание

## ````
Пример использования сервиса через виджет

Приведём пример использования сервиса. 

Пишем клиентский код. При инициализации виджета будет выполнен серверный метод \[OBJECT\].

**Клиентский скрипт:**

````
async function onInit(): Promise<void> \{  
    await Server.rpc.WeatherForecast();  
\}

````
Также пишем серверный скрипт. 

**Серверный скрипт:**

````
async function WeatherForecast(): Promise<void> \{  
    Context.data.test = "debug";  
    try \{  
        const res = await fetch(\`http://<microservice\_name>.<namespace>:80/WeatherForecast\`);  
        if (\!res.ok) \{  
            Context.data.test = \`request fail: \$\{res.statusText\}\`;  
            return;  
        \}  
        Context.data.test = JSON.stringify(await res.json());  
    \}  
    catch (error) \{         
        Context.data.test = typeof(error) === 'object' ? \`error: \$\{JSON.stringify(error)\}\` : \`\$\{error\}\`;  
    \}  
\}

````
Добавим виджет на страницу и получим следующий результат:

 **(service4.png)**

## Удаление сервиса

Для удаления сервиса выполните следующую команду:

````
kubectl delete deployment <microservice\_name> -n <namespace>

kubectl delete service <microservice\_name> -n <namespace>
````