4. Первые шаги в написании собственного приложения

Вы можете писать свои приложения для управления сетью.

4.1. Введение

Так как RUNOS написан на языке с++, то для эффективности приложения дописываются к существующему коду, то есть после написания вашего приложения вам придется пересобирать RUNOS.

Примечание

Необходимо Выполнить команду make, команду make prefix выполнять не обязательно.

Предполагается, что вы хорошо владеете языком C++ и фреймворком qt. Так же полезны базовые знания утилиты cmake.

Все файлы, которые вы создаете, вам необходимо указывать в подходящем CMakeList.txt, в соответствии с тем, в какой директории находится ваш модуль.

После этого RUNOS будет компилироваться с вашими файлами.

4.2. класс Application

Приложение в RUNOS это класс, который наследован от абстрактного класса Application, который объявлен в файле Application.hh:

class Application : public QObject

Вам необходимо вставить макрос внутрь вашего класса (как в Q_OBJECT), для того, чтобы ваш класс удовлетворял необходимым требованиям :

SIMPLE_APPLICATION(your_klass, provides_val)

your_klass – Ваш класс.

provides_val – имя вашего класса.

Данный макрос так же добавит в ваш класс статический метод get(Loader *) который позволит остальным приложениями получать доступ к вашему приложению.

Например:

#include "Application.hh"
#include "Loader.hh"

class YourApp : public Application
{
SIMPLE_APPLICATION(YourApp, "your-application-name")
public:
   void init(Loader*, const Config&) override;
};

4.3. Инициализация

void Application::init(Loader *, const Config&)

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

Данный метод должен реализовывать все связи вашего приложения с остальными приложениями (Например connect сигналов или регистрации обработчиков)

Пример:

#include "Common.hh"

void YourApp::init(Loader *, const Config& )
{
     LOG(INFO) << "Hello World";
}

4.4. Старт приложения

void Application::startUp(Loader *)

Данный метод вызывается, когда все приложения проинициализированы.

В нем вам необходимо выполнить все побочные эффекты вашего приложения, например прослушивание портов.

Пример:

#include "Common.hh" // For log

void YourApp::startUp(Loader *)
{
  LOG(INFO) << "All services inited";
}

4.5. Регистрация приложения

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

Для этого необходимо зарегистрировать ваше приложение с помощью макроса

REGISTER_APPLICATION(your_class, list_of_dependeces)

your_class – имя вашего класса.

list_of_depenedeces – Список, приложений, от которых зависит ваше приложение. Последним необходимо указать "".

Внимание

Данный макрос нельзя прописывать в заголовочном файле!

Предупреждение

Нельзя зацикливать зависимости.

Теперь будет создаваться объект вашего приложения, однако все еще не будут вызываться методы Application::init() и Application::startUp(), потому что контроллер не считает нужным запускать ваше приложение.

Вам необходимо указать имя своего приложения в network-settings.json в списке services, чтобы ваше приложение запустилось.

После этого ваше приложение запуститься и может управлять сетью.

4.6. Loader

class Loader

Методы Application::init() и Application::startUp() принимают как параметр указатель на Loader.

Loader это загрузчик приложений, который и инициализирует ваши приложения.

Вы можете получать объекты других приложений с помощью статического метода get этих приложений, и передав им Loader как аргумент.

Например:

#include "Controller.hh"
#include "Loader.hh"
#include "SwitchConnection.hh"
#include "Common.hh"

REGISTER_APPLICATION(YourApp, {"controller", ""})

...

void YourApp::init(Loader *loader, const Config& )
{
  Controller *ctrl = Controller::get(loader);
  QObject::connect(ctrl, &Controller::switchUp,
      [](SwitchConnectionPtr conn, of13::FeaturesReply fr)
      {
          LOG(INFO) << "This is SWITCH!!!!";
      };)
}

Внимание

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

4.7. Работа с конфигурационным файлом

Ваше приложение может считывать настройки из конфигурационного файла.

Type config_get(const Config &config, const std::string &key, const Type &defval)

Считать из файла настроек network-settings.json значение по ключу. Если данный ключ не найдет, будет возвращен defval.

На данный момент поддерживаются следующие типы :

  • std::string
  • int
  • double
  • bool
Config config_cd(const Config &config, const std::string &key)

получить описание объекта json по ключу.

Дополнительные возможности см в документации по json11.