Симметричный линк между объектами одного типа

Наткнулся на проблему и задумался над способом решения. Надо создать симметричный линк между объектами одного класса. Для объектов разного класса линк всегда симметричный. Поскольку выглядит например так (id, server_id, person_id) у соответствующих классов в соответствующем атрибуте будет key_to_me=server_id у класса сервер и key_to_me=person_id у персоны. Если в объекте класса сервер задать линк на персону то у персоны появится соответствующий линк на сервер.

Отлично. Но пусть теперь нам нужен линк Сервер-Сервер. Мы не можем создать линк-класс вида (id,server_id,server_id), поля в базе не могут иметь одинаковые названия. Можем сделать только (id,left_server_id,right_server_id) но в классе сервер у нас соответствующий линку атрибут должен быть один, например, key_to_me=left_server_id.

Но тогда мы увидим линк только в том сервере на котором его задали, в “партнере” его не будет, поскольку его id записан в другом поле в left_server_id его нет.

Вот я и задумался, как эту проблему объехать. Один из способов оверлоадить в описании класса lnkServerToServer метод, который создает новый объект, чтобы прямо в нем создать еще одну симметричную запись в базе. Но засада в том, что на ITOP ни фига нет документации (или я не знаю, где ее найти).

Собственно вопрос:
где найти описание? или может, кто знает, как решить эту проблему? Или сталкивался с аналогичным по сути случаем, когда надо было оверлоадить создание объекта. Откровенно говоря на вскидку по исходникам я не понял какая именно функция занимается созданием объекта. Я смотрел в cmdbAbstractClass но не понял. Если кто знает - ткните пальцем.
Пока я вижу самым простым решением сделать внешнюю утилиту, которая будет проверять наличие симметричного линка и добавлять его в таблицу линк-класса, если он отсутствует. Это можно сделать через json. У них этот интерфейс хоть как-то описан.

И, пожалуйста, не пишите в стиле “зачем это нужно”, “да это и не нужно вовсе”. Это нужно. Излагать всю историю зачем и почему - утомлять читателей, которым и так понятно, и уходить от сути вопроса

Ладно. я почти нашел.

<method id="DBInsert">

            <static>false</static>
            <access>public</access>
            <type>Overload-DBObject</type>
            <code><![CDATA[    public function DBInsert(){
                        $this->DBInsertNoReload(); 
                        $this->Reload();
                        $oMyClone = clone $this;
                       ......
                        $oMyClone->DBInsertNoReload();
                        $oMyClone->Reload(); 
                        return $this->m_iKey;
            } ]]></code>
        </method>

Вопрос остался с этим многоточием. Мне надо махнуть местами значения двух атрибутов в $oMyClone, Но я не понимаю сделать get и set для атрибута в объекте $oMyClone
Должно быть что-то вроде $oMyClone->GetAttributeValue($AttCode) и $oMyClone->SetAttributeValue($AttCode, $value). Но как это правильно пишется?

Ладно. Методои перебора вариантов установил:
$oMyClone->Get($AttName)
$oMyClone->Set($AttName,$AttValue)
Всё отлично работает. Проблема решена.
Хотелось бы конечно справочник по классам иметь :frowning:

На одну связь между двумя объектами два объекта-ссылки? Рационально.
Об изменении/удалении подумали?

Кстати, хорошо получилось. Даже в историю обоих связанных объектов пишется, что линк добавлен, когда и кем. Всё как положено. Правильную функцию оверлоадил.

Очень даже рационально. Именно так сделано в Altiris CMDB, которая сейчас Symantec. Удаление также можно оверлоадом сделать.
А вот то, что свойство ссылки “направленная” или “симметричная” фактически определяется классами линкуемых объектов, это полный пипец. У нормальных людей просто два типа ссылок определяются и можно явно указать какая ссылка. Но как говорится "дареному коню …"
И да симметричная ссылка реализуется двумя строками в таблице. Так, что велосипед изобретать не надо.
Кстати надо теперь delete оверлоадить. Щас сделаю.

http://www.combodo.com/documentation/api-ref-extensions/classes/iApplicationObjectExtension.html

Сложно говорить аргументированно, не зная конечно цели этой задачи.

Если проблема только в выводе, не проще ли этот самый вывод и подправить?

Я думаю не проще. Там ведь не только вывод. Там еще связанные операции с элементами списка. Всякие добавить/удалить. Я думал оставить одну строку на линк и поправить презентацию. Но потом решил не изобретать велосипед и сделать как в других системах, две строки на симметричный линк.
Мне нужно задавать пары несовместимых объектов. Это симметричное отношение. Речь идет об управлении бизнес-ролями. Есть такая штука - несовместимые роли, ну типа исполнитель-контролер. Собственно модуль я уже написал. Нормально всё работает. И в процессах управления изменениями всё вставилось. Я их с тикетами тоже связал.
Вот мелочи сейчас приделываю. А вопросы такие детские, так я просто этот itop неделю назад увидел первый раз. Подумал, вроде подходящая система. Вот только с докой тихий ужас. Учитывая. что я PHP вообще не знаю по коду тяжеловато разбираться. Если бы хоть знать где искать нужные куски кода :slight_smile:

Да, там не только вывод. Потому и спрашиваю. Как я понял, линк Сервер-Сервер приведен просто в кач-ве примера. У айтопа есть логика оценки влияние КЕ друг на друга, которая использует линки. Будьте внимательны, если будете связывать таким образом две функциональные КЕ.
На счет доков - хз, вроде на уровне XML модели данных всё ок. Для более глубокой модификации есть интерфейсы https://wiki.openitop.org/doku.php?id=2_2_0:customization:extensions_api. Можно и вывод ими поправить, и логику. Я бы вместо оверлода использовал их. Ну и вопросы это далеко не детские.

Я специально стандартный FunctionalCI не наследовал. Сделал свой верхнего уровня абстрактный SecurityRole и из него два реальных BusinessRole и ApplicationRole первый для документирования ролей привязанных к Бизнес-процессам второй к Прикладным решениям. К другим типам КЕ роли вязать смысла нет.
В моем случае без оверлоада никак не обойтись. Да и не очень это страшно. Он как я посмотрел повсюду используется. В тех же КЕ закладка со списком активных тикетов оверлоадом делается. Я для ролей такую же сделал. Очень удобно.
А как линки уничтожать я уже схематично разобрался. Можно использовать new DBObjectSet (DBSearch::OQLQwery…) где выбрать по значению атрибутов у this и их симметричному значению. А потом foreach in DBOdjectSet сделать DBSingleObjectDelete. Не сложно.

Так и сделалось в итоге. Вписал оверлоад метода DBObject->AfterDelete(). Получилось чистенько. И линки парные удаляются и в историю изменений линкованых объектов делается запись об удалении также симметрично.
Не пойму как в здешнем интерфейсе код вписать. Если кому интересно, в качестве сниппета он лежит здесь https://bitbucket.org/snippets/esguardian/585qX
Весь модуль в репозитарии вечерком обновлю.

1 лайк

как-то так:

class BidirectionalLinkExtension implements iApplicationObjectExtension
{
   public static function OnDBInsert($oObject, $oChange)
   {
      if ($oObject instanceof lnkSecurityRoleBidirectional)
      {
        $oMyClone = clone $oObject;
        $oMyClone->Set('left_securityrole_id',$oObject->Get('right_securityrole_id'));
        $oMyClone->Set('right_securityrole_id',$oObject->Get('left_securityrole_id'));
        $oMyClone->DBInsertNoReload();
      }
   }
   ...
}
```

Красиво.
А я когда выбираю в меню тег pre code и вставляю код, в окошке предпросмотра получается какая-то ерунда. Половина тегов не рисуется. Надо разобраться.

А про пользование IApplicationObjectExtension он у меня подозрение вызвал из-за расхождения доки с тем, что я увидел в коде класса DBObject. Вот в DBObject есть пустой метод AfterDelete(), специально для оверлоада оставлен и он вызывается из DBSingleObgectDelete() в самом конце. А в доке на IApplicationObjectExtension такого метода нет. То ли дока неверна, то ли интерфейс и правда его не содержит.

Нужно строкой выше и строкой ниже кода вставить ``` (три косых апострофа) или четыре пробела перед каждой строкой.

В IApplicationObjectExtension есть метод OnDBDelete(), дёргается в cmdbAbstractObject перед удалением объекта из базы. Не спорю, можно и в DBObject методы оверлодить. Просто это более “глубокий” уровень, и вопрос в том, насколько сильно вы хотите потом поддерживать ваши доработки. Интерфейсы всё таки описаны разработчиками и точно будут совместимы с последующими версиями. В общем, тут хозяин – барин.

Спасибо. Понял.
С OnDBDelete() проблема как раз в том, что он вызывается перед удалением, а не после. А по поводу интерфейсов согласен. Обычно они более “стабильны”.

Всё. Тему можно закрыть. Если кому интересен конкретный код, он здесь https://bitbucket.org/esguardian/itop-extensions
Кстати, я не профессиональный разработчик. Если есть советы по улучшению кода и “чистописанию”, приму с благодарностью.

Если есть желание, можете создать тему в разделе Модули.

Прочитал описание, пробежал глазами код, но так и не смог понять, может ли мне быть полезен это модуль. Может это потому что я далёк от информационной безопасности? Можете рассказать более подробно о его предназначении? Если я правильно понял, к ролям пользователей в iTop он отношение не имеет, а добавляет новые КЕ из области ИБ?

Ага. Так и есть.

У нас есть целая проблема управления ролями пользователей как в бизнес-процессах, так и в отдельных прикладных системах. Например, в автоматизированной банковской системе. По стандартам ЦБ управление доступом должно быть построено на основе ролевой модели. Собственно для описания этой модели нужны какие-то удобные средства. Обычно это делается в каких-нибудь файлах Excel и ужасно сложно контролировать связи и изменения назначений ролей. Без CMDB это всё расползается в полный бардак.
Кроме того есть проблема конфликтных ролей. Например в платежных процессах нельзя совмещать в одном лице подготовку платежного документа, его контроль и само осуществление платежа. В идеале это три разные роли. Конфликтность назначенных человеку ролей тоже надо проверять.

В CMDB вести учет гораздо проще, но коммерческие системы очень дорого стоят. Мне сейчас как раз нужно средство учета, поскольку у меня тут накопился очень серьезный беспорядок. iTop мне понравился. Хорошая вещь. Как раз подойдет.