Появилась у нас тут задачка, вывести на портале Incomand данные из разных подсистем (1С, Тезис…) . Конечно можно было бы написать плагины, каждый из которых слазил бы в подсистему, получил данные и показал их на портале - НО - мы бы получили p2p и спагетти, порталу пришлось бы разбираться с форматами и протоколами работы каждой системы….

Источник https://www.confluent.io/blog/apache-kafka-vs-enterprise-service-bus-esb-friends-enemies-or-frenemies/

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

На шине можно создать отдельные программные интерфейсы (API) для работы с каждой внутренней системой. Это исключит анархию, показанную на картинке выше, но является ли это оптимальным решением?

Решая подобную задачу для одного из наших заказчиков, мы поняли, что порталу не обязательно знать о каждом отдельном API, представляющем свою внутреннюю систему. Гораздо проще, если портал будет использовать единую точку входа на корпоративной шине, а шина сама решит в какую внутреннюю систему нужно обратиться за необходимыми данными. Для решения этой задачи лучше всего подошла спецификация OData, которая позволяет легко и изящно манипулировать данными через REST интерфейс. При этом для интеграционной платформы Entaxy совсем не обязательно, чтобы системы-поставщики данных реализовывали эту спецификацию. В профиль потребителя данных (Профиль Incomand на рисунке ниже) добавляется входной odata коннектор. Сам движок (OData engine) реализован на основе библиотеки olingo – через него проходят все запросы, которые он транслирует на профили целевых систем. Перед каждым профилем располагается адаптер, который транслирует OData запросы в формат, который понимает целевая система. Ответы от систем точно так же преобразуются в формат OData и возвращаются потребителю данных (портал Incomand).

Спецификация OData имеет очень широкие возможности работы с данными – фактически это несколько упрощённый язык SQL, работающий по протоколу REST. В отличие от чистого REST в OData можно выполнять сразу несколько операций в рамках одного запроса – это всё включено в реализацию. Например, если вам требуется получить список сущностей и отфильтровать их по одному или нескольким признакам. Для REST потребовалось бы писать дополнительные методы или усложнять реализацию существующих, добавляя дополнительные параметры вызовов и их обработку. В случае OData это легко решается в рамках спецификации при помощи встроенной функции $filter: 

GET serviceRoot/People?$filter=FirstName eq 'Scott'

Или более сложный вариант: 

GET serviceRoot/Airports?$filter=contains(Location/Address, 'San Francisco')

Или ещё более сложный вариант – фильтрация по наследуемым сущностям: 

GET serviceRoot/People?$expand=Trips($filter=Name eq 'Trip in US')

Ещё одним отличным примером возможностей OData является получение связанных сущностей при помощи опции $expand: 

GET serviceRoot/People('keithpinckney')?$expand=Friends

Так же, OData даёт возможность выбора только необходимых полей из сущности. Это можно сделать при помощи опции $select: 

GET serviceRoot/Airports?$select=Name, IcaoCode

Работа со спецификацией OData начинается с получения метаданных: 

{{base_url}}/odata/$metadata

На этот запрос вернётся xml или json со списком сущностей и их параметров: 

<?xml version='1.0' encoding='UTF-8'?>
<edmx:Edmx Version="4.0" xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx">
    <edmx:DataServices>
        <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="odata3-out-connector-CRM">
            <EntityType Name="NeedProject">
                <Key>
                    <PropertyRef Name="id"/>
                </Key>
                <Property Name="id" Type="Edm.Int32" Nullable="false"/>
                <Property Name="car_model" Type="Edm.String"/>
                <Property Name="sell_date" Type="Edm.Date"/>
                <Property Name="count" Type="Edm.Int32" Nullable="false"/>
                <Property Name="car_model_id" Type="Edm.Int32"/>
                <Property Name="status_id" Type="Edm.Int32"/>
                <Property Name="client_id" Type="Edm.Int32" Nullable="false"/>
                <Property Name="custom_id" Type="Edm.String"/>
            </EntityType>
            <EntityContainer Name="Entaxy">
                <EntitySet Name="AktSverkiFilelist" EntityType="onec-rest-file-out-connector-1C.AktSverkiFile"/>
                <EntitySet Name="NeedProjectlist" EntityType="odata3-out-connector-CRM.NeedProject"/>
                <EntitySet Name="SparePartlist" EntityType="onec-rest-spare-part-out-connector-1C.SparePart"/>
                <EntitySet Name="Quantitylist" EntityType="onec-rest-spare-part-out-connector-1C.Quantity"/>
                <EntitySet Name="Contractslist" EntityType="onec-rest-out-connector-1C.Contracts"/>
                <EntitySet Name="Filelist" EntityType="tezis-file-api-out-connector-tezis.File"/>
            </EntityContainer>
        </Schema>
        <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="onec-rest-out-connector-1C">
            <EntityType Name="Contracts">
                <Key>
                    <PropertyRef Name="custom_id"/>
                </Key>
                <Property Name="ID" Type="Edm.Guid"/>
                <Property Name="Code" Type="Edm.String"/>
                <Property Name="Name" Type="Edm.String"/>
                <Property Name="Date" Type="Edm.DateTimeOffset"/>
                <Property Name="Number" Type="Edm.String"/>
                <Property Name="Currency" Type="Edm.String"/>
                <Property Name="Limit" Type="Edm.Int32"/>
                <Property Name="Debt" Type="Edm.Int32"/>
                <Property Name="custom_id" Type="Edm.String"/>
            </EntityType>
            <EntityContainer Name="Entaxy">
                <EntitySet Name="AktSverkiFilelist" EntityType="onec-rest-file-out-connector-1C.AktSverkiFile"/>
                <EntitySet Name="NeedProjectlist" EntityType="odata3-out-connector-CRM.NeedProject"/>
                <EntitySet Name="SparePartlist" EntityType="onec-rest-spare-part-out-connector-1C.SparePart"/>
                <EntitySet Name="Quantitylist" EntityType="onec-rest-spare-part-out-connector-1C.Quantity"/>
                <EntitySet Name="Contractslist" EntityType="onec-rest-out-connector-1C.Contracts"/>
            </EntityContainer>
        </Schema>
    </edmx:DataServices>
</edmx:Edmx>

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

Как итог мы получаем быструю и гибкую работу с совершенно разрозненными данными из различных информационных систем. Эти данные можно легко настраивать для отображения на UI, фильтровать и сортировать: 

Из ключевых возможностей OData можно отметить следующие: 

  • Получение списка сущностей; 

  • Получение записей по каждой сущности; 

  • Получение сущности по ID; 

  • Фильтрация сущностей по признаку; 

  • Получение отдельных атрибутов сущности; 

  • Создание сущности; 

  • Редактирование сущности; 

  • Удаление сущности; 

  • Возможность сортировки и постраничной выдачи сущностей; 

  • Композитные запросы по связанным сущностям; 

  • И многое другое. 

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

Удачных интеграций! 

Комментарии (0)