Показаны сообщения с ярлыком TM Forum. Показать все сообщения
Показаны сообщения с ярлыком TM Forum. Показать все сообщения

понедельник, 2 июля 2012 г.

Policy

Приступая к описанию Policy, следует отметить, что Policy от SID это НЕ просто. По этой причине, я ограничу описание самыми необходимыми для понимания функциональности Policy аспектами, игнорируя такие вопросы как спецификация Policy и использование OCL, поскольку последние требуют отдельного изложения.
Для понимания базовой функциональности Policy, рассмотрим следующую диаграмму:
 
Для понимания функциональности PolicyRule можно выделить следующие три подсистемы:

Класс
Назначение
PolicyEvent
Представляет собой контекст выполнения Policy, предоставляя доступ к своим атрибутам, как на чтение, так и на запись. Может быть представлено PolicyEventComposite, содержащим вложенные PolicyEvent
PolicyCondition
Определяет булевское выражение, при выполнении которого Policy считается успешно выполненным
PolicyAction
Определяет последовательность действий, выполняемых над PolicyEvent при выполнении PolicyCondition

Таким образом, можно видеть, что PolicyRule позволяет декларативно связать произвольное булевское выражение, определяемое PolicyCondition с набором действий, определяемых PolicyAction, выполняемых над PolicyEvent в случае, если это булевское выражение истинно по отношению к PolicyEvent. Следующая диаграмма показывает, что Policy представляет собой набор именованных PolicyRule:


 
Являясь наследником абстрактных классов Policy и PolicySet, PolicyRule определяет следующие атрибуты:

Атрибут
Назначение
policyName
Уникальное имя, которое может использоваться для идентификации Policy
keywords
Набор ключевых слов (таких как: Security, Authentication, Accounting, Audit, Error и т.п.), используемых для разделения Policy по категориям
isMandatoryEvaluation
Булевский флаг показывающий, является ли Policy обязательным для выполнения
usage
Строка, описывающая функциональность Policy в свободной форме
isCNF
Булевский признак, показывающий, что PolicyCondition строится как конъюнктивная нормальная форма (набор конъюктов, соединенных логическим оператором “и”)
hasSubRules
Булевский флаг, показывающий наличие вложенных PolicyRule

Метод isPolicySetWellFormed позволяет выполнить проверку корректности построения PolicySet. Прежде чем переходить к описанию построения PolicyCondition и PolicyAction, следует рассказать о PolicyStatement, используемом двумя этими сущностями:
 
Если говорить просто, PolicyStatement связывает PolicyVariable (позволяющую получить некоторое значение из PolicyEvent, например, по имени) со значениями PolicyValue некоторым оператором PolicyOperator. Для opType, определяющего тип выполняемой операции, в рамках SID? предопределены следующие значения:

Значение
Назначение
1
Match
2
Greater than
3
Greater than or equals
4
Less than
5
Less than or equals
6
Equals
7
Not equals
8
IN
9
NOT IN
10
SET
11
CLEAR

PolicyStatement предоставляет метод isStatementWellFormed, позволяющий выполнить проверку корректности построения оператора. Использование PolicyStatement при построении PolicyCondition описывается следующей диаграммой:


Исходя из этой диаграммы, мы видим, что PolicyCondition может быть представлен как PolicyConditionComposite (представляющей собой набор вложенных PolicyCondition объединенных в конъюнктивную или дизъюнктивную нормальную форму), так и PolicyConditionAtomic, непосредственно соединенный с некоторым PolicyStatement. Для PolicyCondition определены следующие атрибуты:

Атрибут
Назначение
isNegated
Признак логического отрицания
groupNumber
Порядковый номер PolicyCondition в упорядоченном списке, в рамках PolicyRule
conditionIsCNF
Определяется в PolicyConditionComposite и является признаком того, что используется конъюнктивная нормальная форма
conditionSequenceNumber
Порядковый номер PolicyConditionAtomic в упорядоченном списке в рамках PolicyConditionComposite
hasEvaluated
Текущее состояние PolicyConditionAtomic:
0 – не вычислено
1 – TRUE
2 – FALSE

PolicyAction строится в соответствии со следующей диаграммой:




К уже знакомым классам Composite и Atomic добавляется PolicyActionVendor, позволяющий разработчику определить некоторое произвольное действие. В качестве PolicyStatement могут использоваться операторы, построенные на основе SET и CLEAR PolicyOperator. Для PolicyAction определяются следующие атрибуты:
Атрибут
Назначение
actionSequence
Определяется в PolicyActionComposite и показывает, как должна использоваться упорядоченность вложенных PolicyAction:
0 – Unknown
1 – Mandatory
2 – Recommended
3 – Best Effort
actionExecutionStrategy
Определяется в PolicyActionComposite и показывает, как должна выполняться обработка вложенных PolicyAction:
0 – Unknown
1 – Do until success
2 – Do all
3 – Do until failure
4 – Do all without failure or Do Nothing
hasSubPolicyActions
Булевский флаг, показывающий наличие вложенных PolicyAction
actionSequenceNumber
Порядковый номер PolicyAction в рамках упорядоченного списка PolicyActionComposite
hasExecuted
Состояние выполнения PolicyActionAtomic:
0 – not yet executed
1 – executed with no errors
2 – executed with errors but successfully rollback
3 -  executed with errors and did not rollback
4 - did not complete execution but successfully rolled back
5 - did not complete execution and did not roll back
actionData
Этот атрибут предоставляет стандартную возможность расширения функциональности PolicyAction разработчиком. Формат этого атрибута определяется значением OID, передаваемым в actionEncoding
actionEncoding
OID определяющий формат и семантику значения атрибута actionData
actionResponse
Логическое значение, передаваемое в PolicyRule при выполнении PolicyActionVendor

понедельник, 25 июня 2012 г.

Об Архитектуре

Сегодня я хотел бы начать разговор об архитектурных паттернах и о том, каким образом они могут оказаться полезны в жизни. Я не буду ничего говорить о паттернах GoF  (которые, безусловно, нужны и полезны всем тем, кто вслед за Бандой разрабатывает “визуальные редакторы документов, построенные по принципу WYSIWYG  и аналогичные приложения”), а сосредоточусь на не менее интересных (но возможно несколько менее известных) документах TM Forum (а именно SID), позволяющих описать предметную область приложений, работающих в сфере телекоммуникаций.

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

Сущность



Исходя из SID-а, Сущность (Entity) представляет собой абстрактный класс, наследуемый от RootEntity, предоставляющий get-еры и set-еры к нескольким атрибутам, а также сохраняющий строковое значение версии. С RootEntity связаны следующие атрибуты:


Атрибут
Назначение
commonName
Обязательный атрибут сохраняющий “дружественное” описание объекта, составленное в соответствии с принятыми в разрабатываемой системе правилами именования объектов и используемое, например, при отображении объекта в GUI
description
Необязательный атрибут, описывающий, в свободной форме, назначение объекта
objectID
Обязательный атрибут, содержащий уникальный идентификатор объекта, используемый приложением во внутренних целях



Все это хорошо, но душа жаждет большего (например, использования при проектировании интерфейсов (почему при разработке приложений стоит использовать интерфейсы и когда их использовать не стоит – темы для отдельных обширных дискуссий). Поскольку SID не догма, а руководство к действию видоизменим диаграмму, добавив в нее интерфейсы и некоторую дополнительную функциональность:




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

Хочу специально обратить внимание, что IEntity не наследует IRootEntity. Поскольку аналогичное наследование есть на уровне абстрактных классов, наследование интерфейсов не даст нам ничего принципиально нового, но помешает создавать объекты хранящие списки именованных значений, но не имеющие идентификаторов.

Итак, наша сущность умеет хранить уникальный идентификатор и список именованных значений. Но как нам узнать какие именно именованные значения хранит Сущность? В этом нам поможет Спецификация.


Спецификация



 
Согласно SID-у абстрактный класс Specification наследуется от RootEntity (то есть имеет имя и уникальный идентификатор) и является родителем EntitySpecification (дополнительный уровень наследования введен, поскольку специфицировать может понадобиться не только сущности). С EntitySpecification может быть ассоциировано 0 и более Entity.


Абстрактный класс Specification определяет следующие атрибуты:
Атрибут
Назначение
specValidFor
Период действия спецификации
specLifeCycleStatus
Текущий статус спецификации (в рамках ее жизненного цикла)
specVersion
Версия спецификации
 
Согласно тому-же SID-у, спецификация предназначена для описания инвариантных характеристик Entity (таких как атрибуты, методы, ограничения и связи). Реализация этого хранения полностью отдана на откуп разработчику, чем мы немедленно и воспользуемся.


Поскольку SID никак не регламентирует функциональность EntitySpecification, у нас полностью развязаны руки при определении ее интерфейса. Приведенное определение IEntitySpecification ни в коем случае не должно рассматриваться как что-то стандартное, но, на мой взгляд, предоставляет необходимый минимум методов для спецификации сущностей, хранимые атрибуты которых ограничены строковым типом. Рассмотрим эти методы подробнее:


Метод
Назначение
getTypeName
Этот метод, у нас, будет возвращать строковый objectID из RootEntity, который мы будем называть типом сущности. Как будет показано далее, для типов сущностей имеет смысл определять иерархию.
Так, например, тип ‘ri’ может быть ассоциирован с корневой спецификацией, описывающей объекты Resource Inventory, а ‘ri.device’ ее дочерней спецификацией, описывающей устройства.
Можно пойти еще дальше и определить, например, спецификацию ‘ri.device.valid’ описывающую исправные устройства (мы вернемся к этому моменту, когда будем рассматривать взаимосвязь Specification и Policy)
getParentSpecification
Используя этот метод, мы всегда сможет получить родительскую спецификацию. При вызове этого метода у корневой спецификации, можно бросать исключение
getAttributeNames
Этот метод будет возвращать коллекцию имен атрибутов сохраняемых описываемой сущностью
isMandatoryAttribute
Зная имя атрибута, и используя этот метод, мы можем проверить, является ли атрибут обязательным. Ситуация кода Entity не сохраняет значение для обязательного атрибута должна рассматриваться как ошибка
isConstantAttribute
Этот метод показывает, разрешено ли изменение значения для данного атрибута. Константные атрибуты будут использоваться нами далее для идентификации сущностей
getDefaultValue
Используя этот метод, можно получить значение по умолчанию, которое следует использовать, если сущность не сохраняет значение для данного атрибута


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


Идентификация




Попробуем прочитать эту загадочную картинку. Итак, с сущностью Entity связано некоторое количество EntityIdentification, содержащих значения, совокупность которых уникально идентифицирует экземпляр сущности. С другой стороны, EntityIdentificationSpecification ассоциирует наборы этих значений со спецификациями EntitySpecification. Для EntityIdentificationSpecification определены следующие атрибуты:
Атрибут
Назначение
name
Имя EntityIdentificationSpecification (как экземпляра RootEntity)
description
Описание, понятное человеку
validFor
Период действия
  
Какова главная цель использования EntityIdentificationSpecification? По всей видимости, он должен помочь нам, имея экземпляр сущности и некоторые априорные знания о ее типе (например, спецификацию родительского типа) получить точную спецификацию сущности. Определим это явно в форме интерфейса:
Зная имя родительской спецификации (например ‘ri’) и используя экземпляр, реализующий IEntity, мы получаем экземпляр спецификации (например, имеющий тип ‘ri.device’), наиболее полно описывающий сущность.
Как мы можем этого добиться? В этом нам сильно помогут константные атрибуты (фактически описывающие значения EntityIdentification). Действительно, мы можем определить правило проверки константного атрибута (например ‘TYPE_ID’), которое будет заключаться в том, что если значение TYPE_ID = 1 для экземпляра сущности Resource Inventory, то этот экземпляр следует рассматривать как устройство (‘ri.device’).
Другой важной задачей идентификации является валидация экземпляра сущности. Спецификация не возвращается до тех пор, пока EntityIdentificationSpecification не проверит корректность заполнения атрибутов (например, наличие всех обязательных полей и корректность константных значений атрибутов). В случае если экземпляр сущности не валиден, EntityIdentificationSpecification бросит исключение.
По завершении идентификации, мы можем связать сущность с полученной спецификацией:
 
Являясь наследником IEntity, SpecifiedEntity позволит работать лишь с теми значениями, имена атрибутов которых описаны в спецификации, а также подставит значения по умолчанию для отсутствующих не обязательных значений.