Delphi
Firebird
SQL
MacOS
Firemonkey
Android
Oracle
Indy
RavenLink
iOS
Midnight  Raven  Software
 
Общая информация об архитектуре распределенной системы RavenLink

Внимание: для работы RavenLink необходимо:
    1.    версия Delphi не ниже 10.2 любой редации (включая community).
    2.    библиотека Indy (ставится при установке Delphi)

Рассмотрим типичный случай распределенного приложения RavenLink.

Предположим, у нас есть Firebird сервер и уже разработанная база данных Firebird со всей необходимой структурой и данными. (Вместо базы Firebird у нас может быть база Oracle, текстовый файл, датчик температуры, в общем, любой ресурс, на который можно передать и с которого можно получить данные.)

Также у нас есть клиентское приложение, с которого мы хотим обращаться к серверу Firebird. Для этой цели и используется сервер RavenLink, который служит средним слоем, то есть промежуточным звеном между клиентским приложением и сервером Firebird.

Сервер RavenLink представляет собой приложение или Windows сервис. Для обработки запросов от клиентского приложения вводится термин "Задача". Задача представляет собой сущность, которая отвечает за обработку определенной группы запросов. В рамках сервера RavenLink может быть запущена одна или несколько задач. В нашем конкретном случае должна быть задача для доступа к серверу Firebird.  Для работы задачи необходимы следующие данные, которые должны быть прописаны в настройках сервера:


    - Наименование задачи
    - ГУИД задачи. ГУИД задачи должен быть включен в запрос от клиентского приложения для того, чтобы сервер знал: как нужно обрабатывать запрос
    - Плагин, обрабатывающий запросы. В состав релиза RavenLink входит плагин RavenLinkFB.dll, который обеспечивает доступ к серверу Firebird. Он подойдет для нашего случая.
    - Дополнительная информация. В нашем случае это будут параметры доступа к базе данных Firebird.

Плагин для сервера RavenLink должен содержать описание класса, который собственно и осуществляет реализацию задач сервера RavenLink.
При запуске сервера RavenLink, для каждой задачи запускается один или несколько экземпляров класса, описанного в плагине задачи. В терминологии RavenLink такой экземпляр класса называется "слот".
Таким образом, при запуске сервер RavenLink создает одну или несколько задач. Каждая задача создает один или несколько слотов. 

Клиентское приложение связывается с RavenLink сервером, используя компонент TRLQuery, который входит в библиотеку компонентов RavenLink.bpl
Компонент является потомком от TDataset, содержит свойство SQL   и может использовать как DML команды (insert, update, delete и т.д.), так и получать табличные данные с сервера командой select.

Запрос к БД осуществляется следующим образом:

В рамках алгоритма клиентское приложение подготавливает параметры запроса, а именно: у компонента типа TRLQuery заполняются поля SQL и Params. Также у компонента TRLQuery должны быть заполнены свойства:

    - HOST - ip адрес или DNS имя сервера RavenLink
    - PORT - порт RavenLink сервера RavenLink
    - Guid - идентификатор задачи на RavenLink сервере, которая обслуживает запросы к нашей FB базе
    - Другие свойства типа UserName, Password для доступа и т.д.


Затем вызывается метод Open для получения табличных данных или ExecSQL для корректировки данных. Далее запрос к серверу осуществляется следующим образом:

    1. Осуществляется соединение с сервером RavenLink, используя свойства HOST и PORT. Серверу передаются данные запроса (SQL текст с параметрами, ГУИД задачи,параметры доступа и т.д.)
    2. Сервер RavenLink по ГУИД-у определяет: какая задача должна обрабатывать запрос. Далее, у этой задачи ищется свободный слот (тот, который в данный момент не занят обработкой другого запроса). Если свободного слота не находится, то создается новый. Найденному слоту передается запрос для обработки.
    3. Слот соединяется с сервером Firebird и осушествляет выполнение SQL выражения с параметрами из данных запроса.
    4. После выполнения SQL запроса к серверу Firebird формируются данные для отправки клиенту. Если запрос требует получения табличных данных (команда OPEN), то соответственно в список данных включаются таблица результатов запроса. Если запрос к серверу БД завершился с ошибкой, то в данные также включается текст ошибки. Сформированные таким образом данные передаются обратно в слот.
    5. Слот сервера передает данные клиенту - компоненту TRLQuery в клиентском приложении.
    6. Если результаты запроса содержат табличные данные, то компонент TRLQuery как потомок TDataset открывает эти данные.
    7. Если запрос завершился с ошибкой (текст которой входит в состав возвращенных данных), то поднимается соответствующее исключение

Установка библиотеки RavenLink
    - Необходимо распаковать релиз в удобное для Вас место. Далее инструкция будет предполагать, что Вы распаковали релиз в c:\RavenLink.
    - Закрыть IDE Delphi
    - Запустить c:\RavenLink\RMSInstaller.exe для установки библиотеки RavenLink в системе. Если в системе  более одной версии Delphi, то будет выведено меню для выбора версии, в которую будет установлена библиотека.

Данное приложение проделает следующее:

    - компиляция пакета RavenLink.dpk
    - установка компонентов пакета RavenLink.bpl в Delphi
    - установка пути к исходникам библиотеки RavenLink.dpk
    - установка RavenLink.chm в IDE Help Delphi
    - компиляция сервера RavenLink
    - компиляция плагина сервера RavenLink
    - компиляция приложения RLSQLMonitor.dpr для SQL мониторинга запросов к серверу RavenLink
    - компиляция демонстрационного приложения RLDemo.dpr
Описание настроек сервера RavenLinkServer.ini

Формат файла настроек
Файл настроек имеет формат, аналогичный стандартным ini файлам. Он делится на секции, заголовок которых обрамлен квадратными скобками. Например: [SERVER]
Комментарии начинаются с символа ";".
Внутри каждой секции описаны параметры, которые представляют собой пару: имя параметра, символ "=", значение параметра.
Например: PASSWORD=masterkey

Общая структура файла настроек
Файл настроек делится на секции. Каждая секция описывает задачу. Кроме того, имеется две дополнительные секции: [SERVER], которая описывает параметры непосредственно сервера и [EXECUTOR.DEFAULT], которая описывает параметры по умолчанию для секций задач

Расширения, улучшающие гибкость и смотрибельность файла настроек
Директива #include
Директива указывает серверу RavenLink, что при чтении файла настроек вместо директивы будет включен другой файл настроек, имя которого указывается после директивы. Подключаемый файл в свою очередь также может включать директивы #include.

Макроподстановка %FollowDir%
В процессе чтения файла настроек, макроподстановка будет заменена на каталог файла RavenLinkServer.exe.
    Например:
    LogFile=%FollowDir%\RavenLinkServer.log
Использование макроподстановки позволяет использовать один и тот же файл настроек, независимо от каталога, в котором он находится

Шифрование параметров
Вероятно Вам захочется чтобы значения некоторых параметров не были  видны в файле настроек. К примеру пароль доступа к БД.
Для этой цели запустите приложение  PasswordToClipboard.exe из релиза RavenLink.  Введите (дважды) текст, который Вы хотите зашифровать. После этого в буфере обмена окажется зашифрованный текст. Вы можете вставить его в файл настроек.
Обратите внимание на то, что зашифрованный текст начинается с символов &&&. Эти три символа означают, что далее идет зашифрованный текст.

Секция [SERVER]
Секция содержит параметры описывающие общий функционал сервера.  Описание параметров ниже.
    MODE. Параметр может иметь одно из следующих значений
    MODE=SERVER. Приложение RavenLinkServer.exe будет запущено в виде отдельного приложения.
    MODE=SERVICE. Программа будет работать как Windows сервис. Соответственно, параметр командной строки /INSTALL регистрируют сервис, а /UNINSTALL удаляет сервис из списка сервисов
    MODE=CONTROL. Программа работает не как сервер RavenLink, а как приложение, управляющее другим сервером RavenLink. В этом режиме приложение использует параметры Host, Port и RefreshTime для доступа к удаленному серверу RavenLink.
    Host. ip адрес или DNS имя удаленного сервера RavenLink. Параметр используется только для режима управления удаленным сервером RavenLink (MODE=CONTROL)
    Port. Порт удаленного сервера RavenLink. Параметр используется только для режима управления удаленным сервером RavenLink (MODE=CONTROL)
    RefreshTime. Время (в секундах) обновления статистической информации сервера RavenLink
    LogFile. Имя файла, в который будет записываться важная информация и исключения, возникающие в процессе работы сервера

Секция [EXECUTOR.DEFAULT]
Сервер RavenLink может содержать несколько задач, каждая из которых описывается рядом параметров. При этом, некоторые параметры могут быть одинаковыми для нескольких задач. Для того, чтобы не описывать их каждый раз для каждой задачи отдельно, их можно описать в данной секции.
Однако, если в секции какой то задачи есть описание такого же параметра, как и в  [EXECUTOR.DEFAULT], то значение параметра будет использовано из секции задачи, как более приоритетной

Секция, описывающая задачу сервера
Заголовок секции не важен. Вы можете назвать задачу так, как Вам угодно. К примеру:
[Моя любимая задача]
Есть несколько параметров, которые должны быть обязательно описаны в каждой задаче:
    Active. Может принимать значение Active=1 или Active=0. Если Active=0, то задача не будет запущена при старте сервера RavenLink
    Guid. Пример: Guid={EFA1EB87-9027-4D7F-9E73-D626B4ED0C88}. Это идентификатор задачи. Он должен соответствовать ГУИД-у компонента TRLQuery в клиентском приложении.  Совет: для основной задачи сервера используйте ГУИД:  {00000000-0000-0000-0000-000000000000}. Такой ГУИД установлен в плагине TRLQuery по умолчанию. Соответственно, в клиентском приложении Вам не нужно будет устанавливать ГУИД в компоненте TRLQuery.
    Vendor. Плагин, который обрабатывает запросы данной задачи. Пример:    Vendor=%FollowDir%\plugins\RavenLinkFB.dll
Другие параметры задачи. К примеру, для задачи, которая работает с БД Firebird, понадобятся параметры доступа к базе данных.
RavenLinkServer.exe
Программа в зависимости от настроек может выступать в трех различных ипостасях, которые будут описаны ниже.

Запуск сервера RavenLinkServer.exe как отдельного приложения
RavenLinkServer.exe будет запущен как сервер RavenLink в виде отдельного приложения, если в настройках RavenLinkServer.ini в секции [SERVER] должен быть параметр MODE=SERVER.
Окно приложения будет выглядеть следующим образом:
1. Список задач сервера RavenLink
    Ст. - Статус задачи. Включена ли она или нет
    SQLMon - включен ли SQL мониторинг задачи
    Название задачи - ну тут понятно.
2. Лог работы сервера RavenLink
3. Статистика текущейзадачи (на которой установлен курсор)
4. Текст последней ошибки работы сервера RavenLink

В  нижней части окна приложения указаны кнопки для запуска / остановки задачи, а также для включения и выключения SQL мониторинга текущей задачи.

Запуск RavenLinkServer.exe как Windows сервиса
RavenLinkServer.exe можно также запустить как Windows сервер, если в настройках RavenLinkServer.ini в секции [SERVER] должен быть параметр MODE= SERVICE.
Запустите приложение с ключом /INSTALL для регистрации сервиса. После этого, Вы можете запускать RavenLink сервер как обычный Windows сервис.
Но нужно понимать, что Windows сервис не имеет окна, с помощью которого Вы могли бы контролировать приложение (хотя разумеется файл логирования будет вести лог работы сервера).
Однако, Вы можете контролировать сервис с помощью RavenLinkServer.exe, запущенного как управляющая программа.

Запуск RavenLinkServer.exe как управляющей программы для другого удаленного сервера RavenLink
RavenLinkServer.exe можно также запустить как программу, управляющую сервером RavenLink. Для этого, в настройках RavenLinkServer.ini в секции [SERVER] должен бьыть параметр MODE= SERVICE. Помимо этого, нужно знать ip адрес и порт RavenLink сервера, чтобы им управлять. Для этого в секции [SERVER] должны быть соответственно параметры Host и Port.
Важный момент: если Вы хотите управлять сервером RavenLink удаленно, то на сервере должна быть запущена специальная задача с плагином управления сервером. Секция описания такой задачи выглядит следующим образом:
[Управление сервером]
Active=1
Guid={00000000-0000-0000-0000-000000000001}
Vendor=%FollowDir%\plugins\RLServerControl.dll
Remote_User_Name=admin
Remote_Password=admin
SQLMonitor=0

Важный момент: Guid задачи управления должен быть именно таким, как в примере, поскольку именно по этому ГУИД-у управляющая программа сможет давать команды и получать информацию от сервера.
Также следует обратить внимание на два параметра: Remote_User_Name и Remote_Password. При попытке управляющей программы обратиться к удаленному серверу, будет выведено окошко авторизации:
Необходимо ввести имя и пароль, которые соответствуют параметрам на сервере RavenLink и после этого откроется управляющее окно следующего вида:
В заголовке окна будет указан ip адрес и порт сервера, которым управляет программа. Вы можете запускать и останавливать задачи, включать и выключать SQL мониторинг, а также просматривать статистику работы задач сервера.
Разработка плагинов RavenLink сервера (на примере написания плагина доступа к Oracle)
Итак, у нас есть Delphi версии не ниже 10.2 и редакции не ниже Enterprise. Все это необходимо, чтобы написать плагин RavenLink для доступа к Oracle серверу. Далее будем считать, что релиз RavenLink распакован в папку c:\RavenLink.

1.    Запустите Delphi и выберите пункты File -> New -> Other -> Dynamic Library. Затем выберите File -> Save Project As: выберите папку c:\RavenLink\source\plugins\RavenLinkORA\. Выберите название проекта, к примеру RavenLinkORA. Откройте свойства проекта и в свойстве Output Directory выставьте значение: "..\..\..\out\RavenLinkServer\plugins". Теперь откомпилируйте проект и убедитесь в существовании файла "c:\RavenLink\out\RavenLinkServer\plugins\RavenLinkOra.dll". Все Вы создали шаблон плагина RavenLinkOra.dll

2.    Создадим Datamodule, на который Мы положим компоненты для доступа к базе данных. Я назвал Datanodule - DM, и сохранил его в файл DMS.pas.

3.    Положим на Datamodule компонент TFDConnection. Назовем его Connection (разумеется, Вы вправе сами давать имена компонентам, формам и Datamodule-ям). Откройте выпадающий список свойства DriverName у компонента TFDConnection и выберите значение Ora. Щелкнете по компоненту Connection и выберите пункт меню Connection editor. Введите следующие свойства:

Database    - алиас соединения из файла TNSNames.ORA
User_Name - имя пользователя
Password - пароль


4.    Проверьте с помощью кнопки test доступ к базе Oracle. Далее закройте форму редактира соединений, установите у Connection свойство LoginPrompt = FALSE. Затем откройте и закройте соединение с помощью свойства Connected.

5.    Теперь нам необходимо создать задачу на RavenLink сервере для доступа к Oracle серверу. Откройте для редактирования файл RavenLinkServer.ini. Создайте секцию для описания нашей задачи: [Доступ к Oracle] Установите следующие свойства в секции задачи:

Active=1
Guid={00000000-0000-0000-0000-00000000000B}   ; ГУИД задачи должен отличаться от ГУИД-а всех остальных задач
Vendor=%FollowDir%\plugins\RavenLinkORA.dll
Database=<Алиас базы данных из TNSNAMES.ORA>
User_Name=<Имя пользователя для доступа к БД Oracle>
Password=<Пароль для доступа к БД Oracle>
SQLMonitor=1

6.    Добавим также в Datamodule следующие компоненты:

    - Компонент  Transaction: TFDTRansaction. Убедитесь, что в компоненте Connection свойство Transaction = Transaction
    - Query: TFDQuery. Убедитесь, что свойства Connection и Transaction компонента ссылаются на соответствующие компоненты

7.    Теперь необходимо описать класс в плагине, который собственно и содержит в себе полный функционал плагина. Для этого вставьте в секцию uses файла dpr следующие мрдули: System.SysUtils, System.Classes, RLPluginInterface.

8.    Вставьте в dpr секцию следующий текст:
function NewObject(): IRLConnect;
begin
  Result := TRLPlugin.Create;
end;

exports
  NewObject;


9.    Создайте новый unit Delphi. Сохраните его как main.pas. В секции uses модуля main.pas добавьте следующие модули: RLPluginBase, Data.DB, System.Classes, RLConst, RLPluginInterface, FlexMem, System.SysUtils, System.Variants, DMS.

10.    Создайте в модуле main.pas новый класс:

type
  TRLPlugin = class(TRavenLinkPlugin)
  private
    FDM: TDM;
  protected
    procedure DoConnect(aConnectParams: String); override;
    procedure PrepareRequest(const aConnectParams: TRequestParams); override;
    procedure DoExecSQL; override;
    function  DoOpen: TDataset; override;
    function  InTransaction: boolean; override;
    procedure StartTransaction; override;
    procedure Commit; override;
    procedure RollBack; override;
    procedure DoCheckConnect;  override;
  public
    constructor Create; override;
    destructor Destroy; override;
  end;

Вызовите из меню по правой кнопке пункт "Complete Class at cursor"

11.    Итак, у нас есть полный шаблон плагина. Остается реализовать все методы класса TRLPlugin. Начнем с Datamodule. Поскольку у нас не приложение, а динамическая библиотека, то Datamodule не будет создаваться автоматически. Необходимо создавать и уничтожать его. В private секции Вы уже вставили переменную FDM : TDM. Вставьте в консттуктор TRLPlugin-а следующий текст:

constructor TRLPlugin.Create;
begin
  inherited;
  FDM := TDM.Create(nil);
end;

А в деструктор

destructor TRLPlugin.Destroy;
begin
  FDM.Free;
  inherited;
end;



12.    Теперь последовательно реализуем все методы класса TRLPlugin. В этом и заключается функционал плагина

Метод DoConnect
Вызывается при создании очередного слота задачи. В качестве параметра в метод передается текст секции файла настройки, который описывает задачу. В нашем случае, нам нужно вытащить из текста параметры коннекта к БД Oracle и используя их открыть соединение с БД.
В метод Connect нужно также вставить инициализацию глобальной переменной FDManager и переменной IsMultiThread. Это нужно для корректной работы методов плагина в нескольких потоках одновременно. Для этого добавим в секцию uses модуль FireDAC.Comp.Client.
У нас получился примерно такой код метода Connect.

procedure TRLPlugin.DoConnect(aConnectParams: String);
Var Strings: TStringList;
begin
  IsMultiThread := true;
  if not FDManager.Active then FDManager.Active := true;

  Strings := TStringList.Create;
  try
    Strings.Text := aConnectParams;
    FDM.Connection.Params.DriverID := 'Ora';
    FDM.Connection.Params.Database := Strings.Values['Database'];
    FDM.Connection.Params.UserName := Strings.Values['User_Name'];
    FDM.Connection.Params.Password := Strings.Values['Password'];
  finally
    Strings.Free;
  end;
  FDM.Connection.LoginPrompt := false;
  FDM.Connection.Open();
end;


Метод PrepareRequest
Вызывается при подготовке к обработке запроса от клиента.
В качестве параметра передается ссылка на структуру (запись), которая содержит параметры запроса.
В нашем случае, метод заполняет параметры SQL и PARAMS компоненты Query  из Datamodule.

Код метода выглядит следующим образом:

procedure TRLPlugin.PrepareRequest(const aConnectParams: TRequestParams);
Var FParams: TFlexParams;
    i: integer;
    P: TFDParam;
begin
  FDM.Query.Close;
  FDM.Query.SQL.Text := aConnectParams.SQL;
  FParams.AsString := aConnectParams.Params;
  for i := 0 to FParams.Count-1 do
  begin
    P := FDM.Query.Params.FindParam(FParams.Items[i].Name);
    if P <> nil then
    begin
      P.DataType := FParams.Items[i].DataType;
      P.Value := FParams.Items[i].Value;
    end;
  end;
end;


Также придется добавить в секцию uses модуль FireDAC.Stan.Param.
Хочется обратить внимание на один важный момент. Имя и пароль доступа к БД Oracle хранятся в файле настройки задачи. Но клиент RavenLink посылая запрос, также посылает параметры авторизации (имя и пароль). Эти параметры также содержатся в параметре aConnectParams.
В данном описании, я не буду рассматривать вопрос авторизации и почему сделано так, а не иначе. Скажу лишь, что в данном описании создания плагина не приводится решения об организации доступа (как это сделано, можно увидеть в исходниках плагина RavenLinkFB.dll).
Более подробно на эту тему написано в разделе "Система доступа и авторизации"

Метод DoExecSQL.
Нетрудно догадаться, что метод реализует функционал выполнения SQL запроса.
Код  метода весьма прост:

procedure TRLPlugin.DoExecSQL;
begin
  FDM.Query.ExecSQL;
end;


Опытные программисты непременно зададутся вопросом: а где и как мы обработаем возможные исключения. На самом деле все просто. Метод DoExecSQL - это виртуальный метод, описанный в предке класса TRLPlugin. Откройте реализацию класса TRavenLinkPlugin. Вы увидите во-первых, что метод DoExecSQL объявлен как абстрактный, то есть его описание к Oracle БД.
А во-вторых увидим использование метода в TRavenLinkPlugin.Request, который описывает обработку запроса клиента. Вот там есть все необходимое, включая обработку исключений. 

Метод DoOpen
Метод получает табличные данные. Должен вернуть ссылку на потомка от TDataset. Реализуем метод следующим образом:

function TRLPlugin.DoOpen: TDataset;
begin
  FDM.Query.Open;
  Result := FDM.Query;
end;


Метод InTransaction
Возвращает TRUE, если открыта транзакция по текущему соединению слота.
Реализуем следующим образом:

function TRLPlugin.InTransaction: boolean;
begin
  Result := FDM.Transaction.Active;
end;

Метод StartTransaction
Стартует явную транзакцию

procedure TRLPlugin.StartTransaction;
begin
  FDM.Transaction.StartTransaction;
end;


Метод Commit

Здесь понятно. Завершение явной транзакции

procedure TRLPlugin.Commit;
begin
  FDM.Transaction.StartTransaction;
end;


Метод Rollback
Откат явной транзакции

procedure TRLPlugin.RollBack;
begin
  FDM.Transaction.Rollback;
end;


Метод DoCheckConnect
Проверяет соединение с БД. Метод используется для поддержания соединения с сервером БД. В случае разрыва соединения, сервер RavenLink предпримет попытки возобновить соединение с сервером.
В нашем случае реализация проста: мы просто пытаемся выполнить простой SQL запрос на сервере БД Oracle:

procedure TRLPlugin.DoCheckConnect;
begin
  FDM.Query.Close;
  FDM.Query.SQL.Text := 'select count(*) cou from dual';
  FDM.Query.Open;
  if FDM.Query.Fields[0].AsInteger <> 1 then
    raise Exception.Create('Ошибка разрыва соединения');
  FDM.Query.Close;
end;

13.    Собственно, реализовав последовательно методы класса TRLPlugin, мы создали RavenLink плагин для доступа к БД Oracle. Далее: на всякий случай очищаем свойства FDM.Connection.Params - Database, Password и UserName. Эти свойства должны заполняться в методе DoConnect. Проверяем работу плагина. Для этой цели запускаем сервер RavenLink: c:\RavenLink\out\RavenLinkServer\RavenLinkServer.exe. Должна открыться форма, со списком задач. Среди которых должна быть и наша задача "Доступ к БД Oracle" со статусом "Вкл". То есть задача запустилась, создала слот, в рамках которого было осуществлено успешное соединение с БД Oracle.
Попробуем осуществить запрос к БД Oracle: для чего создадим новое Windows VCL Application. На форму положим компонент TRLQuery. Присвоим компоненту следующие свойства:

Guid - должен соответствовать GUID-у нашей задачи.  В нашем случае это
{00000000-0000-0000-0000-00000000000B}
Host и Port - по умолчанию, если мы используем локальный сервер RavenLink
SQL - текст SQL запроса, которым мы хотим получить табличные данные
Active = TRUE - собственно отсылаем запрос и получаем табличные данные

Если запрос прошел успешно, то  свойство Active будет установлено в TRUE. В противном случае будет поднято исключение с описанием ошибки.

Положим на форму TDatasource и TDBGrid. Соединим их с нашим компонентом TRLQuery. Если все успешно, то Вы увидите в табличке запрошенные данные.

Все, мы закончили разрабатывать плагин доступа к БД Oracle (вопросы модульного тестирования и проблем доступа и авторизации не входят в данную инструкцию)

Мониторинг разрыва соединения задачи
Наиболее естественным предназначением сервера RavenLink является использование его в качестве среднего звена между клиентом и SQL сервером. В релиз RavenLink входит плагин RavenLink для доступа к серверу Firebird.
Также в разделе "Разработка плагинов RavenLink сервера (на примере написания плагина доступа к Oracle)" подробно описано: как самому написать плагин для доступа к Oracle серверу.
В обоих случаях, для доступа к удаленным базам данным используется библиотека FireDac. В эту библиотеку уже встроены средства для поддержания постоянного соединения с базой данных. Тем не менее, разработчики RavenLink сервера посчитали необходимым встроить в RavenLink сервер собственные средства восстановления соединения после разрыва.
Для этой цели, интерфейс основного класса плагина должен поддерживать метод CheckConnect для проверки соединения с базой данных.
Выглядит это следующим образом:

    - Возьмите релиз и распакуйте релиз RavenLink, например в папку C:\RavenLink
    - Переименуйте папку с:\RavenLink\out\RavenLinkServer\plugins\EmbeddedFirebird. Это нужно сделать, чтобы при запуске сервера плагин доступа к FB серверу не нашел Embedded Firebird сервер, на доступ к которому он настроен.
    - Запустите RavenLink сервер: c:\RavenLink\out\RavenLinkServer\RavenLinkServer.exe

Откроется следующее окно сервера:
Вы увидите, что две задачи перешли в статус разрыва соединения. При этом раз в несколько секунд сервер будет пытаться восстановить соединение с сервером.
Переименуйте папку с Embedded сервером обратно. Соединение с сервером будет автоматически восстановлено.
Описание компонентов библиотеки RavenLink
Во время установки библиотеки RavenLink (при запуске RMSInstaller) в палитру компонентов IDE Delphi устанавливается два компонента: TRLQuery и TRLConnection. Ниже их описание:

TRLQuery
Компонент является потомком от TDataset, содержит свойство SQL   и может использовать как выполнения DML команд (insert, update, delete и т.д.), так и получать табличные данные с сервера командой select.

Свойства компонента:

AddParams:   Дополнительные параметры запроса, помимо SQL выражения. Разумеется плагин Raven Link сервера должен уметь их обрабатывать.

ConnectTimeOut: Время в миллисекундах ожидания соединения с сервером Raven Link. Если в течение данного времени не получено ответа от сервера - генерируется ошибка. Если значение свойства = 0, то время ожидания неограниченно.

Guid: Свойство определяет GUID задачи на сервере Raven Link, которая должна обрабатывать запрос.

Host: Свойство определяет GUID задачи на сервере Raven Link, которая должна обрабатывать запрос.

IndexFieldNames: Свойство предназначено для сортировки данных уже полученных с сервера. Присвойте свойству IndexFileName список полей, разделенных запятыми и полученные данные будут отсортированы в указанном порядке. При этом, обращения к серверу не будет, сортировке подвергаются уже полученные данные. Возможно использование ключевых слов DESC и NULLS FIRST, которые применяются для каждого конкретного поля в списке. Пример: "LASTNAME,FIRSTNAME NULLS FIRST,BIRTHDAY DESC"

Params: Список параметров для SQL запроса. Если в SQL выражении присутствуют параметры в виде ":ParamName", то в списке параметров появляется соответствующее значение, для которого можно задать тип и значение. Пример: SQL содержит запрос: "select * from people where lastname = :lastname" Вы можете задать значение параметра следующим образом:

       Params.ParamByName('lastname').DataType := ftString;
       Params.ParamByName('lastname').Value := 'Иванов';

Password: Свойство используется как дополнительный параметр запроса к Raven Link серверу. Возьмем для примера запросы к задаче RL сервера, которая обрабатывается плагином RavenLinkFB.dll. Предположим на сервере есть задача "Доступ к тестовой БД RLTest.fb" (она на самом деле есть на демо версии сервера). В настройках задачи указаны параметры доступа к Firebird серверу, включая логин и пароль (Для embedded сервера не обязательно). Все запросы будут фактически использовать этот логин и пароль к FB серверу. Но Вы возможно заходите реализовать более сложную систему авторизации для своей системы. Для этой цели Вы можете использовать свойства UserName и Password для передачи в запрос. Значения этих свойств будут переданы в сервер Firebird как котекстные переменные "USER_NAME" и "PASSWORD". Тип переменных "USER_SESSION". Если же Вы пишете свой собственный плагин для Raven Link сервера, то Вы должны сами придумать способ обрабатывать свойства UserName и Password, если конечно захотите их использовать. *

Port: Порт сервера, к которому будет коннектиться компонент RLQuery

ReadTimeOut: Время в миллисекундах ожидания чтения данных с сервера Raven Link. Если в течение данного времени не получено ответа от сервера - генерируется ошибка. Если значение свойства = 0, то время ожидания неограниченно

RLConnection: Ссылка на компонент TRLConnection. Компонент TRLConnection призван упростить соединение с сервером Raven Link, если у Вас используется много компонентов TRLQuery. Для того, чтобы не заполнять свойства Host, Port, UserName и Password для каждого компонента в отдельности, Вы можете заполнить все эти свойства у компонента TRLConnection, а затем указать ссылку на этот компонент в свойстве RLConnection у всех экземпляров TRLQuery.

SQL: SQL выражение содержит команду для Raven Link сервера. Плагин RL сервера, который будет обрабатывать запрос должен разумеется уметь это делать. Если для обработки запроса используется например плагин "RavenLinkFB.dll", то текст SQL выражения напрямую передается как команда Firebird сервера.

UserName: Свойство используется как дополнительный параметр запроса к Raven Link серверу. Возьмем для примера запросы к задаче RL сервера, которая обрабатывается плагином RavenLinkFB.dll. Предположим на сервере есть задача "Доступ к тестовой БД RLTest.fb" (она на самом деле есть на демо версии сервера). В настройках задачи указаны параметры доступа к Firebird серверу, включая логин и пароль (Для embedded сервера не обязательно). Все запросы будут фактически использовать этот логин и пароль к FB серверу. Но Вы возможно заходите реализовать более сложную систему авторизации для своей системы. Для этой цели Вы можете использовать свойства UserName и Password для передачи в запрос. Значения этих свойств будут переданы в сервер Firebird как котекстные переменные "USER_NAME" и "PASSWORD". Тип переменных "USER_SESSION". Если же Вы пишете свой собственный плагин для Raven Link сервера, то Вы должны сами придумать способ обрабатывать свойства UserName и Password, если конечно захотите их использовать.


TRLConnection.
Компонент призван упростить соединение с сервером RavenLink, если у Вас используется много компонентов TRLQuery. Для того, чтобы не заполнять свойства Host, Port и т.д. для каждоо компонента в отдельности, Вы можете заполнить все эти свойства у компонента TRLConnection, а затем указать ссылку на этот компонент в свойстве RLConnection у всех экземпляров TRLQuery.

Свойства компонента:

ConnectTimeOut: Если компонент TRLQuery ссылается на TRLConnection (свойство TRLQuery.RLConnection), то в качестве значения TRLQuery.ConnectTimeOut используется значение TRLConnection.ConnectTimeOut.

Host: Если компонент TRLQuery ссылается на TRLConnection (свойство TRLQuery.RLConnection), то в качестве значения TRLQuery.Host используется значение TRLConnection.Host.

Password: Если компонент TRLQuery ссылается на TRLConnection (свойство TRLQuery.RLConnection), то в качестве значения TRLQuery.Password используется значение TRLConnection.Password.

Port: Если компонент TRLQuery ссылается на TRLConnection (свойство TRLQuery.RLConnection), то в качестве значения TRLQuery.Port используется значение TRLConnection.Port.

ReadTimeOut: Если компонент TRLQuery ссылается на TRLConnection (свойство TRLQuery.RLConnection), то в качестве значения TRLQuery.ReadTimeOut используется значение TRLConnection.ReadTimeOut.

UserName: Если компонент TRLQuery ссылается на TRLConnection (свойство TRLQuery.RLConnection), то в качестве значения TRLQuery.UserName используется значение TRLConnection.UserName.

  
SQL мониторинг
Технология RavenLink включает в себя очень удобный SQL мониторинг, который (если он включен) записывает все запросы к серверу RavenLink, фиксируя всю необходимую информацию: текст SQL запроса, тип и данные параметров SQL запроса, время начала и окончания выполнения запроса, количество полученных строк данных, название устройства, с которого пришел запрос, наименование клиентского приложение, наименование компонента TRLQuery и его родителя и т.  д. К примеру, Вы можете легко выбрать информацию по всем запросам, которые приходили с компьютера MASHA и которые выполнялись более 10 минут.

Настройка, включение / выключение SQL мониторинга
SQL мониторинг на сервере RavenLink осуществляется отдельной задачей сервера. Задача, должна обслуживаться плагином RavenLinkFB.dll. (В принципе Вы можете разработать свой плагин для SQL мониторинга, для чего необходимо реализовать методы DoSQLMonitoringEnabled, DoBeforeSQLMonitoring и DoAfterSQLMonitoring).
Соответственно, необходима  база данных firebird, с соответствующей структурой, которая будет хранить данные по SQL мониторингу.  В релизе RavenLink есть такая база данных в папке database\RLSQLMonitor.fdb. Также, если Вы откроете файл с настройками RavenLinkServer.ini, то найдете там секцию с описанием задачи [SQL monitoring]. Задача настроена на использованик embedded firebird сервера, так что Вам не нужно настраивать свой сервер. В секции описания задачи, помимо параметров доступа должны быть еще два параметра:
Remote_User_Name=admin
Remote_Password=admin
Эти параметры понадобятся для доступа к данным SQL мониторинга из удаленной программы.
Далее: если Вы хотите, чтобы по какой-то конкретной задаче велся SQL мониторинг, то необходимо в соответствующей задаче добавить два параметра:

SQLMonitorTask={00000000-0000-0000-0000-000000000002}
SQLMonitor=1

Оба этих параметра можно добавить в секцию [EXECUTOR.DEFAULT], тогда они автоматически распространятся на все задачи сервера.
Параметр SQLMonitorTask должен указывать на ГУИД задачи SQL мониторинга
Если параметр SQLMonitor для задачи не равен 1, то SQL мониторинг не включится автоматически при старте сервера, но Вы всегда можете включить его для любой задачи вручную: из окна сервера или с помощью управляющей программы RavenLink.

Использование программы RLSQLMonitor.exe
Программа подключается к RavenLink серверу, к специальной задаче, которая связана с базой данных SQL мониторинга. В релизе RavenLink программа лежит в папке out\SQLMonitor
В папке с программой должен лежать файл RLSQLMonitor.ini, в котором должны быть описаны следующие параметры:
Server -  ip адрес или DNS имя сервера RavenLink
Port - порт сервера RavenLink (прописан в RavenLinkServer.ini сервера)
Guid - ГУИД, который должен совпадать с ГУИД-ом задачи SQL мониторинга на RavenLink сервере.
При запуске программы будет выведено окно авторизации, в которое необходимо ввести имя и пароль.
Имя и пароль, устанавливается в файле настроек сервера RavenLink, в описании секции задачи SQL мониторинга, в параметре rlusers. В этом параметре должно быть имя и пароль, разделенные символом @.
Вы можете сразу нажать кнопку "Получить данные" и получите информацию по запросам, которые были сделаны сегодня. Выглядит  это следующим образом:
Вверху Вы видете список запросов, в нижней части экрана более подробная информация о запросе.
Также Вы можете нажать на кнопку "Открыть параметры фильтра". В верхней части формы откроется панель, на которой Вы можете задать самые изощренные критерии, по которым Вы хотели бы отобрать список запросов:
Ну и кроме прочего, Вы разумеется можете напрямую подсоединиться к базе SQL мониторинга, например IBExpert-ом и вручную делать необходимые Вам выборки.
  
Система контроля доступа и авторизации к БД

На самом деле, тема контроля доступа не совсем напрямую относится к технологии RavenLink. Очевидно, что, как и в Datasnap пользователю необходимо самому реализовать систему авторизации. Тем не менее, авторизация и система доступа является неотъемлемой частью любой, более или менее серьезной распределенной системы. Именно поэтому, принято решение ввести в данное руководство главу о том:  какие идеи на тему авторизации приходят в голову авторам RavenLink.

Итак, Вы разрабатываете распределенную систему, где сервер RavenLink настроен на доступ к серверу Firebird. Архитектура RaveLink предусматривает, что новые соединения с сервером БД открываются только в том случае, если текущих соединений не хватает для обработки запросов от клиентов RavenLink. Если нагрузка на сервер RavenLink не слишком велика, то вполне возможно, что будет открыто только одно соединение с БД Firebird, которое и обработает все запросы. Причем, запросы могут приходить от разных пользователей, с разным уровнем доступа.
Как же организовать систему авторизации ?

Ниже будет показано: как была организована простейшая авторизация в доступе к данным SQL мониторинга.
SQL мониторинг запросов к RavenLink серверу записывается в таблицы специальной базы данных Firebird. Параметры доступа к этой БД описаны в файле настроек RavenLinkServer.ini, в секции задачи SQL мониторинга.  (Необходимо отметить, что это на самом деле просто пример: поскольку в релизе RavenLink для работы с базой SQL мониторинга используется Embedded сервер Firebird, а для доступа используется login SYSDBA). Соответственно, для доступа к БД SQL мониторинга используется плагин RavenLinkFB.dll.

Для использования нашей простейшей системы авторизации нам понадобится в нашей базе данных SQL мониторинга временная таблица rlusers с полями usrname и passwd. (Она в этой базе есть).
Если мы внимательно посмотрим на описание задачи [SQL monitoring] в файле настроек сервера, то обнаружим там параметр rlusers=admin@admin;admin2@admin2. В параметр может быть записано несколько пар login/пароль. Пары разделяются символом ";", а в рамках одной пары: login отделяется от пароля символом "@". Плагин RavenLinkFB.dll, после соединения с БД Firebird, берет параметр rlusers, разбирает список и записывает имена пользователей и пароли в таблицу rlusers.

В компоненте TRLQuery есть поля UserName и Password. Эти поля передаются в сервер RavenLink вместе с другими параметрами запроса. И там они обрабатываются плагином задачи. В нашем случае, это плагин RavenLinkFB.dll.  В данном плагине эти параметры обрабатываются следующим образом: непосредственно перед выполнением SQL запроса, в рамках сессии соединения с сервером Firebird создаются контекстные переменные USER_NAME и PASSWORD значения которых берутся из параметров запроса UserName и Password.
Таким образом, на момент запуска SQL запроса, в таблице rlusers ест ь пользователи с паролями и контекстные переменные USER_NAME и PASSWORD. Осталось проверить права доступа. В базе SQL мониторинга это делается следующим образом:  есть процедура checkpassword, которая проверяет права доступа

  if (not exists(
    select 1 from rlusers
    where usrname = rdb$get_context('USER_SESSION','USER_NAME')
          and passwd = rdb$get_context('USER_SESSION','PASSWORD')
     )) then exception BAD_PASSWORD;


Все запросы, которые пользователь отправляет в БД осуществляются только через процедуры и вьюхи, которые содержат в обязательном порядке процедуру checkpassword.
Разумеется реальная система авторизации и доступа должная быть гораздо более расширенной и сложной: хранить нужно не пароли а хэши, пользователи должны быть привязаны к ролям, в зависимости от роли, должно быть разрешено или запрещено обращение к соответствующим процедурам и вьюхам и т.д.
Авторы RavenLink хотели лишь указать тезисы идей для реализации полноценной авторизации