Пример разработки сервиса, решателя, агентов и шаблонов сообщений

Данный документ описывает содержимое агентов/сообщений/решателя/сервиса для задачи шифрования целого числа (путём сложения с другим числом):
взять целое (исходное) число из входного инфоресурса, применить к нему операцию сложения с кодовым числом, извлекаемым из собственного инфоресурса, доступного на чтение, результат (полученное число) сохранить в выходной инфоресурс, а исходное число также сохранить в собственный инфоресурс (с полным доступом) и во временный ресурс (который будет удалён по завершении работы сервиса, однако если бы в решателе после выполнения данной задачи работали другие агенты - они могли бы его извлекать как из собственного так и из временного ресурсов).

Примечание: для краткости в данном примере не указываются полные пути к инфоресурсам.

Содержание

Инфоресурсы

Сервис, использующий решатель

(задается как часть инфоресурса Пользователи и сервисы - в виде одного его сервисов в Тестовой ПО)
Сервис на тестовый решатель <<< Платформа IACPaaS / Ядро платформы / Структура сервиса
{
  решатель {
    Структура решателя [ -> Тестовый решатель$ ; ]
  }
  входные инфоресурсы {
    инфоресурс [ -> Входной ресурс - исходное число$; ]
  }
  выходные инфоресурсы {
    инфоресурс [ -> Выходной ресурс - результирующее число$; ]
  }
  папка по умолчанию ["Тесты/МАС"]
}

Решатель

Тестовый решатель <<< Платформа IACPaaS / Ядро платформы / Структура решателя
{
  корневой агент { 
    Структура агента [ -> ТестКорнАгент$ ; ] 
  }
  входные инфоресурсы {
    инфоресурс [ -> Мета - одно число$; ]
  }
  выходные инфоресурсы {
    инфоресурс [ -> Мета - одно число$; ]
  }
  собственные инфоресурсы {
    инфоресурс [ -> Собств - много чисел$; ]
  }
  собственные инфоресурсы на чтение {
    инфоресурс [ -> Собств - одно число$; ]
  }
  временные инфоресурсы {
    инфоресурс [ -> Мета - одно число$; ]
  }
}

Обрабатываемые инфоресурсы

Метаинформация (формальный параметр) и сформированная по ней информация с входными и выходными данными (фактический параметр) - для инфоресурсов с одним числом (входной, выходной, собственный на чтение):
Мета - одно число
{
  ~one a [int]
}

Входной ресурс - исходное число <<< Мета - одно число
{
  a [1]
}

Выходной ресурс - результирующее число <<< Мета - одно число
{
  #данные в исходное состояние инфоресурса не заносятся - число будет записано агентом
}


Метаинформация и сформированная по ней информация с выходными данными (формальный параметр), содержащая целое число:
Тестовая предметная область / Тесты / МетаВыходРесурс {
    ~one res [int]
}
 
Тестовая предметная область / Тесты / Выходной ресурс1 <<< Тестовая предметная область / Тесты / МетаВыходРесурс {
    res [0]
}

Агенты

Тестовая предметная область / Тесты / ТестКорнАгент <<< Платформа IACPaaS / Ядро платформы / Структура агента {
    внутреннее имя ["TestRootAgent"]
    описание ["Корневой агент тестового решателя"]
    множество продукций {
        блок продукций [1] {
            описание ["Обработка иниц. сообщения - посылка сообщения с заданием агенту шифровальщику"]
            шаблон входного сообщения {
                Структура шаблона сообщения [ -> Платформа IACPaaS / Ядро платформы / Шаблон Инициализирующее сообщение<math>; ]
            }
            шаблоны выходных сообщений {
                Структура шаблона сообщения [ -> Тестовая предметная область / Тесты / Шаблон Задание</math>; ]
            }
        }
        блок продукций [2] {
            описание ["Обработка сообщения c шифровкой - сохранение результата и посылка финализирующего сообщения"]
            шаблон входного сообщения {
                Структура шаблона сообщения [ -> Тестовая предметная область / Тесты / Шаблон Шифровка<math>; ]
            }
            шаблоны выходных сообщений {
                Структура шаблона сообщения [ -> Платформа IACPaaS / Ядро платформы / Шаблон Финализирующее сообщение</math>; ]
            }
        }
    }
}
 
Тестовая предметная область / Тесты / Агент шифровальщик <<< Платформа IACPaaS / Ядро платформы / Структура агента {
    внутреннее имя ["CipherAgent"]
    описание ["Шифрующий агент тестового решателя"]
    множество продукций {
        блок продукций [1] {
            описание ["Обработка сообщения с заданием и посылка сообщения с результатом обратно"]
            шаблон входного сообщения {
                Структура шаблона сообщения [ -> Тестовая предметная область / Тесты / Шаблон Задание<math>; ]
            }
            шаблоны выходных сообщений {
                Структура шаблона сообщения [ -> Тестовая предметная область / Тесты / Шаблон Шифровка</math>; ]
            }
        }
    }
}

Шаблоны сообщений

Тестовая предметная область / Тесты / Шаблон Задание <<< Платформа IACPaaS / Ядро платформы / Структура шаблона сообщения
{
    внутреннее имя ["Task"]
    !{
        ~list ~gen число [int]
     }
}
 
Тестовая предметная область / Тесты / Шаблон Шифровка <<< Платформа IACPaaS / Ядро платформы / Структура шаблона сообщения
{
    внутреннее имя ["Cipher"]
    !{
        ~one ~gen код [int]
     }
}

Классы агентов и шаблонов сообщений на Java

Корневой агент "ТестКорнАгент"

Базовый класс (сгенерирован Генератором кода агентов и шаблонов сообщений):
public abstract class TestRootAgent
    extends Agent
{
    public TestRootAgent(IRunningService runningService, IInforesource agentInforesource)
    {
        super(runningService, agentInforesource);
    }
 
    // Описание продукций для диспетчера сообщений
    static
    {
        try
        {
            describeProduction(
                ru.dvo.iacp.is.iacpaas.mas.messages.system.InitMessage.class,
                InitMessageResultCreator.class,
                TestRootAgent.class);
            describeProduction(
                ru.dvo.iacp.is.iacpaas.mas.messages.CipherMessage.class,
                CipherMessageResultCreator.class,
                TestRootAgent.class);
        }
        catch(NoSuchMethodException ex)
        {
            throw new RuntimeException(ex);
        }
    }
 
    /**
     * Создатель результатов для блока-обработчика сообщения "Платформа IACPaaS/Ядро платформы/Шаблон Инициализирующее сообщение"
     */
    public final static class InitMessageResultCreator
        extends ResultCreator
    {
        public final TaskMessage.Creator taskMessage;
 
        public InitMessageResultCreator(MasFacet mas, IRunningService runningService)
            throws
            MasException
        {
            super(mas, runningService);
            taskMessage = new TaskMessage.Creator(this);
        }
    }
 
    /**
     * Создатель результатов для блока-обработчика сообщения "Тестовая ПО / Тест / Шаблон Шифровка"
     */
    public static final class CipherMessageResultCreator extends ResultCreator
    {
        public final FinalizeMessage.Creator finalizeMessage;
 
        public CipherMessageResultCreator(MasFacet mas, IRunningService runningService)
            throws
            MasException
        {
            super(mas, runningService);
            finalizeMessage = new FinalizeMessage.Creator(this);
        }
    }
 
    // Заготовки для блоков продукций
 
    /**
     * Обработка сообщения "Платформа IACPaaS / Ядро платформы / Шаблон Инициализирующее сообщение"
     *
     * Обработка иниц. сообщения - посылка сообщения с заданием агенту шифровальщику
     */
    public void runProduction(InitMessage msg, InitMessageResultCreator rc)
        throws
        PlatformException
    {
        throw new UnsupportedOperationException(); //TODO: заменить этот код на требуемый код БП
    }
 
    /**
     * Обработка сообщения "Платформа IACPaaS/Ядро платформы/Шаблон Инициализирующее сообщение"
     *
     * Обработка сообщения c шифровкой - сохранение результата и посылка финализирующего сообщения
     */
    public void runProduction(CipherMessage msg, CipherMessageResultCreator rc)
        throws
        PlatformException
    {
        throw new UnsupportedOperationException(); //TODO: заменить этот код на требуемый код БП
    }
}

Класс-реализация:
public final class TestRootAgentImpl
    extends TestRootAgent
{
    public TestRootAgentImpl(IRunningService runningService, IInforesource agentInforesource)
    {
        super(runningService, agentInforesource);
    }
 
    // блоки продукций
    public void runProduction(InitMessage msg, InitMessageResultCreator rc)
        throws
        PlatformException
    {
        // получаем инфоресурс с исходными данными
        IInforesource inIR = runningService.getInputs()[0]; // вывод в лог решателя
 
        info("создаём сообщение агенту шифровальщику по его адресу в фонде"); // вывод в лог решателя
        TaskMessage tm = rc.taskMessage.create("Тестовая предметная область / Тесты / Агент шифровальщик");
 
        info("наполняем сообщение для агента шифровальщика данными"); // вывод в лог решателя
        tm.addNum(inIR.getRoot().getDirectSuccessorByMeta("a", this).getValue());
        tm.addNum(inIR.getRoot().getDirectSuccessorByMeta("b", this).getValue());
    }   // по завершении обработки блока продукций сообщение встало в очередь и будет обработано
 
    public void runProduction(CipherMessage msg, CipherMessageResultCreator rc)
        throws
        PlatformException
    {
        // получаем выходной инфоресурс
        IInforesourceGenerator outIR = runningService.getOutputs()[0];
 
        // пишем в него результат
        outIR.generateFromtRoot().generateWithValue("a", msg.getRes());
 
        info("иниц агент шлет сообщение КОНЕЦ"); // вывод в лог решателя 
        rc.finalizeMessage.create();
    }   // по завершении обработки блока продукций сообщение встало в очередь и будет обработано
}

Имя класса-заготовки совпадает с внутренним именем агента, описанным в инфоресурсе.
Имя класса-реализации совпадает с внутренним именем агента + суффикс "Impl".
Класс InitMessageResultCreator описывает типы сообщений, которые будут отправлены из агента в первом блоке продукций — сообщение по шаблону TaskMessage (см. ниже).
Класс CipherMessageResultCreator описывает типы сообщений, которые будут отправлены из агента во втором блоке продукций — сообщение по шаблону FinalizeMessage (системный шаблон/класс).
Платформенные методы getInputs()/getOutputs() возвращает массив входных/выходных инфоресурсов.

Рабочий агент "Агент шифровальщик"

Базовый класс (сгенерирован Генератором кода агентов и шаблонов сообщений):
public abstract class CipherAgent
    extends Agent
{
    public CipherAgent(IRunningService runningService, IInforesource agentInforesource)
    {
        super(runningService, agentInforesource);
    }
 
    // Описание продукций для диспетчера сообщений
    static
    {
        try
        {
            describeProduction(
                ru.dvo.iacp.is.iacpaas.mas.messages.TaskMessage.class,
                TaskMessageResultCreator.class,
                CipherAgent.class);
        }
        catch(NoSuchMethodException ex)
        {
            throw new RuntimeException(ex);
        }
    }
 
    /**
     * Создатель результатов для блока-обработчика сообщения "Тестовая предметная область / Тесты / Шаблон Задание"
     */
    public final static class TaskMessageResultCreator
        extends ResultCreator
    {
        public final CipherMessage.Creator cipherMessage;
 
        public TaskMessageResultCreator(MasFacet mas, IRunningService runningService)
            throws
            MasException
        {
            super(mas, runningService);
            cipherMessage= new CipherMessage.Creator(this);
        }
    }
 
     // Заготовки для блоков продукций
 
    /**
     * Обработка сообщения "Тестовая предметная область / Тесты / Шаблон Задание"
     *
     * Обработка сообщения с заданием и посылка сообщения с результатом обратно
     */
    public void runProduction(TaskMessage msg, TaskMessageResultCreator rc)
        throws
        PlatformException
    {
        throw new UnsupportedOperationException(); //TODO: заменить этот код на требуемый код БП
    }
}

Класс-реализация:
public final class CipherAgentImpl
    extends CipherAgent
{
    public CipherAgentImpl(IRunningService runningService, IInforesource agentInforesource)
    {
        super(runningService, agentInforesource);
    }
 
     // блоки продукций
 
    public void runProduction(TaskMessage msg, TaskMessageResultCreator rc)
        throws
        PlatformException
    {
        info("создаём сообщение агенту, приславшему задание"); // вывод в лог решателя
        CipherMessage cm = rc.cipherMessage.create(rc.getSender());
 
        info("наполняем сообщение данными"); // вывод в лог решателя
        long a = msg.getNum(0);        
        long b = msg.getNum(1);
        cm.putRes(a * b * (b - a) + 3);
    }   // по завершении обработки блока продукций сообщение встало в очередь и будет обработано
}

Имя класса-заготовки совпадает с внутренним именем агента, описанным в инфоресурсе.
Имя класса-реализации совпадает с внутренним именем агента + суффикс "Impl".
Класс TaskMessageResultCreator описывает типы сообщений, которые будут отправлены из агента в первом блоке продукций — сообщение по шаблону CipherMessage (см. ниже).

Шаблон Задание

Большая часть кода класса сгенерирована Генератором кода агентов и шаблонов сообщений, разработчиком написаны лишь методы добавления чисел и их чтения.
public class TaskMessage
    extends Message
{
    public static final Date TEMPLATE_MODIFIED_DATE = new Date(1428494236552L);
 
    public TaskMessage(IInforesource messageInforesource, MasFacet mas)
    {
        super(messageInforesource, mas);
    }
 
    public static final class Creator
        extends Message.Creator
    {
        public Creator(ResultCreator rc)
            throws
            MasException
        {
            super(rc, "Тестовая предметная область / Тесты", "Задание");
        }
 
        /**
         * Создать сообщение для агента \a agentName
         */
        public TaskMessage create(String agentName)
            throws
            MasException
        {
            return (TaskMessage)createInt(agentName);
        }
 
        /**
         * Создать сообщение для экземпляра агента \a agent
         */
        public TaskMessage create(AgentPtr agent)
            throws
            MasException
        {
            return new TaskMessage(createInt(agent).getInforesource(), mas);
        }
    }
 
    // методы, добавленные лично разработчиком шаблона
    // записать число в сообщение
    public void addNum(long num)
        throws
        PlatformException
    {
        // через вызов msgGen() получаем возможность читать и порождать в инфоресурсе сообщения
        msgGen().generateWithValue("число", num);
    }
 
    // получить число из сообщения (по порядковому номеру, начиная с 0)
    public long getNum(int address)
        throws
        PlatformException
    {
        return msgGen().getSetByMeta("число")[address].getValue();
    }
}

Имя класса совпадает с внутренним именем шаблона сообщения, описанным в инфоресурсе, + суффикс "Message".
Код <super(rc, "Тестовая предметная область / Тесты", "Задание");> задает путь к инфоресурсу и имя ресурса без префикса "Шаблон".
Функции addNum(long)/getNum(int) упрощают взаимодействие с содержимым сообщений.

Шаблон Шифровка

Большая часть кода класса сгенерирована Генератором кода агентов и шаблонов сообщений, разработчиком написаны лишь методы добавления числа (результата) и его чтения.
public class CipherMessage
    extends Message
{
    public static final Date TEMPLATE_MODIFIED_DATE = new Date(1428494236553L);
 
    public CipherMessage(IInforesource messageInforesource, MasFacet mas)
    {
        super(messageInforesource, mas);
    }
 
    public static final class Creator
        extends Message.Creator
    {
        public Creator(ResultCreator rc)
            throws
            MasException
        {
            super(rc, "Тестовая предметная область / Тесты", "Шифровка");
        }
 
        /**
         * Создать сообщение для агента \a agentName
         */
        public CipherMessage create(String agentName)
            throws
            MasException
        {
            return (CipherMessage)createInt(agentName);
        }
 
        /**
         * Создать сообщение для экземпляра агента \a agent
         */
        public CipherMessage create(AgentPtr agent)
            throws
            MasException
        {
            return new CipherMessage(createInt(agent).getInforesource(), mas);
        }
    }
 
    // методы, добавленные лично разработчиком шаблона
    // записать число в сообщение
    public void putRes(long res)
        throws
        PlatformException
    {
        // через вызов msgGen() получаем возможность порождать в инфоресурсе сообщения
        IConcept resConc = msgGen().getDirectSuccessorByMeta("res", this)
        if (resConc != null)
            resConc.getEditor(this).setValue(res);
        else
            msgGen().generateWithValue("res", res);
    }
 
    // получить число из сообщения
    public long getRes()
        throws
        PlatformException
    {
        return msgGen().getDirectSuccessorByMeta("res", this).getValue();
    }
}

Имя класса совпадает с внутренним именем шаблона сообщения, описанным в инфоресурсе, + суффикс "Message".
Код <super(rc, "Тестовая предметная область / Тесты", "Шифровка");> задает путь к инфоресурсу и имя ресурса без префикса "Шаблон".
Функции putRes(long)/getRes() упрощают взаимодействие с содержимым сообщений.