Разработка компонента сервиса сообщений

Компонент сервиса сообщений предоставляет модулю не зависящий от оператора ЭДО слой отправки и получения электронных сообщений.

Компонент данного типа непосредственно взаимодействует с оператором ЭДО. При взаимодействии выполняется передача и получение сообщений электронного обмена, в т.ч. содержащих электронные документы (входящие и исходящие).

Данный компонент должен реализовывать программный интерфейс IMessageService. Методы реализуемого интерфейса вызываются при получении и отправке сообщений оператору ЭДО.

Вариант реализации данного компонента содержится в сборке DocsVision.Edi.Runtime.Diadoc.dll (добавляется при установке "Коннектор к Диадок").

Фактическая реализация компонента сервиса сообщений сильно зависит от метода взаимодействия с оператором ЭДО и предоставляемого им API.

Далее приведена часть исходного кода (только публичные методы) примера реализации интерфейса IMessageService для работы с оператором Диадок.

public class MessagesService: IMessageService (1)
{
    private DiadocSession DiadocSession (2)
    {
        get
        {
            if (diadocSession != null && !diadocSession.IsAlive())
            {
                diadocSession = null;
            }

            if (diadocSession == null)
            {
                if (!settings.ContainsKey(DiadocSettings.ApiUrl))
                {
                    throw Error.InvalidOperation(Resources.NoConnectionData);
                }

                if (!settings.ContainsKey(DiadocSettings.Login))
                {
                    throw Error.InvalidOperation(Resources.NoConnectionData);
                }

                diadocSession = new DiadocSession(
                    settings[DiadocSettings.ApiUrl],
                    settings[DiadocSettings.Login],
                    settings[DiadocSettings.Password],
                    settings.ContainsKey(DiadocSettings.ProxyUrl) ? settings[DiadocSettings.ProxyUrl] : null,
                    settings.ContainsKey(DiadocSettings.ProxyLogin) ? settings[DiadocSettings.ProxyLogin] : null,
                    settings.ContainsKey(DiadocSettings.ProxyPassword) ? settings[DiadocSettings.ProxyPassword] : null);
            }

            return diadocSession;
        }
    }
(3)
    public void Initialize(Dictionary<string, string> settings) (4)
    {
        this.settings = settings;
    }

    public void SendMessage(MessageData messageData) (5)
    {
        DiadocSession.SendMessage(messageData);
    }

    public void SendSignatureReply(MessageData messageData) (6)
    {
        DiadocSession.SendSignatureReply(messageData);
    }

    public void SendReceipt(MessageData messageData) (7)
    {
        DiadocSession.SendReceipt(messageData);
    }

    public void SendRevocation(MessageData messageData) (8)
    {
        DiadocSession.SendRevocation(messageData);
    }

    public void SendCorrection(MessageData messageData) (9)
    {
        DiadocSession.SendCorrection(messageData);
    }

    public int GetNewEventsCount(string boxId, string lastEventId) (10)
    {
        return DiadocSession.GetNewEventsCount(boxId, lastEventId);
    }

    public string GetLastEventId(string boxId) (11)
    {
        return DiadocSession.GetLastEventId(boxId, null);
    }

    public bool EventExists(string boxId, string eventId) (12)
    {
        return DiadocSession.EventExists(boxId, eventId);
    }

    public ItemCollection<MessageData> GetNewEvents(string boxId, string lastEventId, DateTime? fromDate) (13)
    {
        return DiadocSession.GetNewEvents(boxId, lastEventId, fromDate);
    }

    public MessageFile GenerateInvoiceReceipt(string boxId, string messageId, string entityId, X509Certificate2 certificate, string positionName) (14)
    {
        return DiadocSession.GenerateInvoiceReceipt(boxId, messageId, entityId, certificate, positionName);
    }

    public MessageFile GenerateRevocationRequest(string boxId, string messageId, string entityId, (15)
        X509Certificate2 certificate, string positionName, string comment)
    {
        return DiadocSession.GenerateRevocationRequest(boxId, messageId, entityId, certificate, positionName, comment);
    }

    public MessageFile GenerateInvoiceReply(string boxId, string messageId, string entityId, X509Certificate2 certificate, string documentType, string replyData) (16)
    {
        return DiadocSession.GenerateInvoiceReply(boxId, messageId, entityId, certificate, documentType, replyData);
    }

    public MessageFile GenerateSignatureRejection(string boxId, string messageId, string entityId, (17)
        X509Certificate2 certificate, string positionName, string comment)
    {
        return DiadocSession.GenerateSignatureRejection(boxId, messageId, entityId, certificate, positionName, comment);
    }

    public MessageFile GenerateCorrectionRequest(string boxId, string messageId, string entityId, (18)
        X509Certificate2 certificate, string positionName, string comment)
    {
        return DiadocSession.GenerateCorrectionRequest(boxId, messageId, entityId, certificate, positionName, comment);
    }
}
1 Компонент сервиса сообщение.
2 Точка доступа к API Диадок.
3 Реализация интерфейса IMessageService.
4 Инициализация компонента.
5 Реализация метода отправки сообщения оператору ЭДО.
6 Реализация метода отправки ответной подписи.
7 Реализация метода отправки квитанции.
8 Реализация метода отправки запроса на аннулирование.
9 Реализация метода отправки запроса на уточнение.
10 Реализация метода получения количества новых событий.
11 Реализация метода получения идентификатора последнего события в ящике организации.
12 Реализация метода проверки наличия события в ящике.
13 Реализация метода получения новых событий из ящика.
14 Реализация метода формирования извещения.
15 Реализация метода формирования запроса на аннулирование.
16 Реализация метода формирования ответной подписи для поступившего документа.
17 Реализация метода формирования сообщения с отказом в подписании.
18 Реализация метода формирования запроса на уточнение.

Далее приведена часть исходного кода класса DiadocSession, в котором показан принцип взаимодействия с оператором ЭДО через его API на примере получения идентификатора последнего сообщения.

public class DiadocSession
{
    private readonly DiadocApi DiadocApi; (1)
    private readonly string AuthToken;

       public DiadocSession(string apiUrl, string login, string password, string proxyUrl, string proxyLogin, string proxyPassword)
    {
        WinApiCrypt diadocCrypt = new WinApiCrypt();
        DiadocApi = new DiadocApi(DefaultClientId, apiUrl, diadocCrypt);

        if (!string.IsNullOrEmpty(proxyUrl))
        {
            DiadocApi.DisableSystemProxyUsage();
            DiadocApi.SetProxyUri(proxyUrl);
            if (!string.IsNullOrEmpty(proxyLogin))
                DiadocApi.SetProxyCredentials(proxyLogin, proxyPassword);
        }

        AuthToken = DiadocApi.Authenticate(login, password);
    }

       public string GetLastEventId(string boxId, string lastEventId) (2)
    {
        while (true)
        {
            BoxEventList eventList = DiadocApi.GetNewEvents(AuthToken, boxId, lastEventId);
            if (eventList == null || eventList.TotalCount == 0)
                return lastEventId;

            lastEventId = eventList.Events[eventList.Events.Count -- 1].EventId;
            if (eventList.TotalCount == eventList.Events.Count)
                return lastEventId;
        }
    }

}
1 DiadocApi — объект API Диадок, проксирующий работу с веб-сервисом Диадок.
Описание API Диадок приведено на странице с документацией Диадок API.
2 Получаем идентификатор последнего события в ящике организации.