Метаданные

Метаданные - это составляющая, которая позволяет нам создававать мобильные системы клиент/сервер. Мобильные — это самоописываемые, динамичные, реконфигурируемые системы. Такая система помогает компонентам исследовать друг друга во время выполнения, она предоставляет информацию, которая помогает им взаимодействовать. Мобильная система позволяет вам писать клиентское ПО, не опираясь на специфичные вызовы конкретного сервера. Наконец, она обеспечивает информацию о метаданных, которая может использоваться инструментальными средствами для создания и управления компонентами.

Мобильная система отличается от традиционной системы клиент/сервер повсеместным использованием метаданных для согласованного описания всех доступных сервисов, компонентов и данных. Метаданные позволяют независимо разработанным компонентам динамически обнаруживать присутствие друг друга и взаимодействовать между собой. Повсеместное распространение метаданных является ключевой cocтавной частью в инфраструктуре распределенных компонентов. Без метаданных мы имеем жестко спроектированные системы клиент/cepвер, не обладающие какой-либо гибкостью.

CORBA представляет собой такую мобильную систему. Чтобы удовлетворять стандарту CORBA, любой создаваемый вами компонент должен быть самоописываемым. Любой объект или сервис системного уровня, который живет на шине CORBA должен также быть самоописываемым. Даже сама шина CORBA обладает этим свойством. В результате CORBA представляет собой полностью самоописываемую систему. Язык метаданных CORBA - это язык описания интерфейса (Interface Definition Language - IDL). Библиотека метаданных CORBA - это Репозитарий Интерфейсов (Interface Repository). Это не что иное, как база данных времени выполнения, содержащая спецификации интерфейса каждого объекта, который может быть опознан ORB. Представьте библиотеку интерфейсов как опрашиваемую и модифицируемую базу данных этапа выполнения, которая содержит IDL-сгенерированную информацию.

Прекомпилятор IDL и Репозитарий Интерфейсов представляют собой базовые сервисы ORB, которые поставляются со всеми CORBA-совместимыми ORB. Повсеместное использование IDL и Репозитария Интерфейсов делает CORBA более самоописываемой, чем любая другая форма промежуточного программного обеспечения (middleware) клиент/сервер. Здесь описаны CORBA IDL и Репозитарий Интерфейсов. Мы также подробно коснемся новых сервисов CORBA, определенных для того, чтобы сделать метаданные Репозитария Интерфейсов доступными ORB разных производителей.

CORBA IDL: Более внимательный взгляд

Как мы упоминали в ранее, IDL - это контрактный язык, который позволяет задать границы компонентов и их интерфейс с потенциальными клиентами. CORBA IDL не зависит от языка программирования и полностью декларативный. Это означает, что он не определяет деталей реализации. IDL предоставляет независимые от операционной системы и языка программирования интерфейсы для всех сервисов и компонентов, расположенных на шине CORBA.

Что подразумевает контракт IDL?

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

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

IDL — это описательный язык, который поддерживает синтаксис C++ для констант, типов и объявления операций. Однако, IDL не содержит каких-либо процедурных структур или переменных. Обратите внимание, поскольку в нем отделены реализация и спецификации, IDL представляет хороший нотационный инструмент для разработки ПО. Большинство нотационных языков предоставляют только описание интерфейса. В противоположность этому, CORBA IDL обеспечивает; прямой путь между архитектурой ПО, определяемой интерфейсом, и скомпилированным кодом, который ее реализует. Из описаний IDL предкомпилятор может сгенерировать непосредственно клиентские имитаторы и серверные скелеты. IDL предоставляет также прекрасную возможность инкапсулировать API нижнего уровня и устаревшие программные системы. Архитекторы систем клиент/сервер сочтут CORBA IDL очень полезным и разносторонним инструментальным средством.

Структура CORBA IDL

Репозитарий Интерфейсов хранит метаданные, которые идентичны описываемым вами в IDL компонентам. Фактически, Репозитарий Интерфейсов является просто активной БД, которая содержит скомпилированные версии метаданных, описанных посредством IDL. Прежде чем перейти к структуре библиотеки интерфейсов, давайте бросим быстрый взгляд на то, что находится внутри файла CORBA IDL.

Далее показаны основные элементы, составляющие CORBA IDL. Давайте по ним пройдем:

Структура файла  CORBA IDL

 module <identifier> {
       <type declarations>;
       <constant declarations>;
       <exception declarations>;

       interface <identifier> [:<inheritance>] {
               <type declarations>;
               <constant declarations>;
               <attribute declarations>;
               <exception declarations>;

               [<op_type>]<identifier>(<parameters>)
               [raises exception] [context]
               .
               .
               [<op_type>]<identifier>(<parameters>)
               [raises exception] [context]
               .
               .
       }

       interface <identifier> [:<inheritance>]
               .
               .
  }

CORBA IDL представляет собой исчерпывающий и краткий язык. Полное описание языка занимает 36 страниц (см. CORBA: Architecture and Specification (OMG, 1996)). Оно включает определение грамматики IDL и всех типов данных CORBA.

Типовые коды: самоописываемые данные CORBA

CORBA определяет типовые коды (type codes}, которые представляют каждый тип данных, определенный в IDL. Типовые коды исползуются для создания самоописываемых данных, которые можно передать разным операционным системам, ORB и в Репозитории Интерфейсфов. Каждый типовой код имеет глобально уникальный репозитарный идентификатор (Repository ID). Типовые коды используются CORBA в любой ситуации, где требуются самоописываемые данные. Например, они используются:

Интерфейс TypeCode архитектуры CORBA определяет набор методов для работы с типовыми кодами, их сравнения и получения их описаний (табл 5). Например, вы можете вызвать операцию content_type для массива или последовательности, чтобы получить типы содержащихся в них элементов. Обратите внимание, что многие операции специфичны для определенных типов данных. Например, операции «member» могут быть вызваны только для структур, объединений и перечислений (structures, unions, enumerated).

Табл. 5. Интерфейс TypeCode

equal TypeCode member_count
kind member_name
id member_type
name member_label
length  
content_type  
param_count  
parameters

 

Что такое Репозитарий Интерфейсов?

Репозитарий Интерфейсов (Interface Repository) CORBA представляет собой постоянно активную БД определений объектов. Создать эти определения вы можете непосредственно из компилятора IDL или с помощью функций записи библиотеки интерфейсов - CORBA совершенно не волнует способ внесения информации. Однако спецификации CORBA детально описывают структуру этой информации и способы ее извлечения из репозитария. Для этого существует набор классов, чьи экземпляры представляют находящуюся в репозитарии информацию. Иерархия этих классов отражает спецификацию IDL. Результатом является чрезвычайно гибкая объектная база данных, хранящая коллекцию объектов организованных такими же строками, как это имеет место в IDL. Естественно, все объекты репозитария представляют собой скомпилированные версии информации, содержащейся в исходном файле IDL.

Кому нужен Репозитарии Интерфейсов?

ORB обязан понимать определения объектов, с которыми он работает. Один из способов получить такие определения состоит во встраивании этой информации в имитаторы. Другой способ получить требуюмую информацию - постоянно доступный Репозитарии Интерфейсов. Что делает ORB с репозитарной информацией? Он может использовать определения объектов следующим образом:

Репозитарии Интерфейсов могут обслуживаться локально или как ресурсы ведомства или предприятия. Они выступают ценными источниками метаданных о структуре класса и интерфейсе компонента.ORB может потребоваться доступ к нескольким Репозитариям Интерфейсов.

Классы библиотеки интерфейсов: иерархия включения

Репозитарии Интерфейсов реализована как набор объектов, представляющих ее информацию. Эти объекты должны быть постоянными, т.е. должны храниться на энергонезависимом носителе (в постоянной памяти). CORBA группирует метаданные в модули, которые представляют пространства имен. Имена репозитарных объектов уникальны в пределах модуля. CORBA определяет интерфейс для каждой из восьми структур IDL:

В дополнение к восьми приведенным интерфейсам, которые представляют структуры IDL, CORBA определяет интерфейс Repository, который является корнем для всех модулей, содержащихся в библиотечном пространстве имен. Каждый Репозитарии Интерфейсов представлена глобальным корневым репозитарным объектом. На рис. 9 показана иерархия включения для объектов, принадлежащих этим интерфейсам (или классам). Вы уже заметили, что некоторые из этих объектов, например, экземпляры класса Repository, содержат другие объекты. Некоторые объекты, например, экземпляры класса ModuleDef, является как контейнерами, так и составными частями других объектов. Наконец, некоторые объекты, например, экземпляры класса ExceptionDef, всегда являются составной частью других объектов, но сами не содержат других объектов.

Рис. 9. Иерархия

Иерархия классов Репозитария Интерфейсов

Создатели библиотеки интерфейсов CORBA определили три абстрактных суперкласса (экземпляры абстрактных классов создавать нельзя) IRObject, Contained и Container (рис. 10). Обратите внимание, на этом рисунке показана иерархия наследования в противоположность иерархии включения. Все объекты Репозитария Интерфейсов унаследованы от интерфейса IRObject, который появился только в CORBA 2.0. Этот интерфейс предоставляет операцию для идентификации фактического типа объекта, а также метод destroy. Объекты, являющиеся контейнерами, наследуют навигационные операции от интерфейса Container. Интерфейс Contained определяет поведение объектов, содержащихся в других объектах. Все репозитарные классы унаследованы от Container, от Contained или от обоих сразу посредством множественного наследования. Такая искусная схема позволяет репозитарным объектам координировать свое поведение в соответствии с отношениями включения.

 

рис. 10. Иерархия Наследования Классов Репозитария Интерфейсов

Репозитарий Интерфейсов: внимательный взгляд

Классы Репозитария Интерфейсов обеспечивают операции для чтения, записи и уничтожения метаданных, хранимых в репозитарии. Операция destroy удаляет объект из библиотеки. Если она вызывается для объекта-контейнера, то уничтожается все его содержимое. Интерфейс Contained содержит операцию move для удаления объекта из его текущего контейнера и добавления в контейнер-получатель. Операции -write, destroy и move появились только в CORBA 2.0.

Доступ к метаданным Репозитария Интерфейсов осуществляется вызовом полиморфных методов для объектов различных типов. Благодаря такой удачной конструкции вы можете извлекать информацию из репозитарных объектов всего лишь девятью методами. Пять из них унаследованы от родительских классов Container и Contained. Оставшиеся четыре метода специфичны для интерфейсов InterfaceDef и Repository. Ниже приведены описания методов навигации и чтения:

Совокупность этих методов позволяет проводить навигацию по библиотеке интерфейсов. Вы можете организовать поиск в пространстве имен определенных модулей, чтобы получить объекты, удовлетворяющие условиям поиска. После того, как объект найден, вы можете использовать метод describe для получения информации IDL с его описанием. Помните также, что IRObject, Container и Contained — абстрактные классы, с которыми вы никогда не имеете дело непосредственно. Вместо этого вы вызываете методы объектов библиотеки интерфейсов, которые наследуют свое поведение от этих абстрактных базовых классов.

Как найти интерфейс в первый раз?

Интерфейс объекта можно найти одним из трех способов:

  1. Непосредственно вызывая метод ORB Object::get_interface. Этот метод можно вызывать с любой допустимой объектной ссылкой. Он возвращает объект InterfaceDef, который полностью описывает интерфейс объекта. Этот метод полезен, если вы имеете дело с объектом, чей тип не известен во время компиляции.
  2. Перемещаясь по пространству имен модуля, используя последовательность имен. Например, если вы знаете имя интерфейса, который расположен перед вами, вы можете начать с просмотра корневого модуля библиотеки. Как только интерфейс найден, вызывайте метод InterfaceDef::describe_interface для получения метаданных, которые описывают искомый интерфейс.
  3. Определяя объект InterfaceDef, который соответствует искомому библиотечному идентификатору (Repository ID). Это делается с помощью вызова метода Repository::lookup_id.

Как только вы получили объект InterfaceDef, можете вызывать его итерфейсы для получения необходимых метаданных. Затем эти метаданные вы можете использовать для динамического вызова методов интересующего вас объекта.

Объединения репозитариев интерфейсов

Новые расширения CORBA позволяют создавать межгалактические федерации репозитариев интерфейсов, которые оперируют на множестве ORB. Чтобы избежать конфликтов имен, эти репозитарии назначают глобальным интерфейсам и операциям уникальные идентификаторы, которые называются репозитарными идентификаторами (Repository ID). Эти идентификаторы вы можете использовать для размножения копий метаданных по множеству библиотек, сохраняя при этом согласованное представление о них. Это означает, что уникальная идентификация интерфейса сохраняется вдоль множества ORB и библиотек. Например, имея глобальный библиотечный идентификатор, вы можете получить некоторые метаданные интерфейса из локальной библиотеки. Затем вы можете получить дополнительные метаданные того же интерфейса из удаленной библиотеки.

CORBA гарантирует, что определения IDL в разных библиотеках не содержат каких-либо дубликатов, и для этого определяет следующие соглашения по наименованию:

В следующем разделе описаны механизмы для создания таких глобальных репозитарных идентификаторов.

Как может выглядеть репозитарный идентификатор?

Репозитарный идентификатор представляет собой строку, состоящую из трехуровневой иерархии имен. CORBA определяет два формата репозитарного идентификатора:

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

Директивы pragma для создания репозитарных идентификаторов

Pragma — это специальная директива компилятора. В данном случае pragma сообщает предкомпилятору IDL, как сгенерировать репозитарный идентификатор и сопоставить его с определенным интерфейсом. CORBA определяет три новых директивы pragma IDL, которые помогут вам создать репозитарный идентификатор:

CORBA IDL без мучений

Самая типичная жалоба программистов C++, Java или Smalltalk состоит вот в чем: почему мы должны выполнять лишний шаг описание наших объектов на IDL? Почему ORB не может понять объекты нашего языка? Некоторые поставщики компиляторов удовлетворили эту просьбу, генерируя CORBA IDL непосредственно из классов других языков. Например, компиляторы MetaWare C++ и VisualAgefor C++ могут генерировать CORBA IDL для SOM прямо из C++.

Еще раньше компания Visigenic/Netscape представила Caffeine, который содержит постпроцессор Java2IIOP, который генерирует имитаторы и скелеты CORBA прямо из байт-кода Java. Наконец, OMG тоже работает над стандартом обратного преобразования Java в CORBA (см. документ OMG orbos/96-12-12). Итак, если вам не нравится IDL, помощь — в пути. Естественно, если вы программист С, то вам неоткуда ждать помощи. В этом языке у вас нет способа определить классы, единственный способ — использовать IDL.

САМОАНАЛИЗ ОБЪЕКТОВ CORBA

Объекты CORBA наследуются от корневого интерфейса CORBA - Object. В результате они представляют собой достаточно интеллектуальные объекты, которые могут рассказать о себе очень много. Объект является интроспективным (способным к самоанализу), если может описать свое поведение во время выполнения. Способность к самоанализу делает объекты очень привлекательными для разработчиков инструментальных средств клиент/сервер, сервиса коммерции и динамических клиентов. Интроспективность позволяет во время выполнения исследовать имитаторы, которые прежде распознавались только компиляторами. Интроспективность CORBA включает изобилие информации, которая содержится в библиотеке интерфейсов. Она обеспечивает достаточно подробную информацию для динамического построения и вызова методов во время выполнения.

Интроспективный интерфейс CORBA

Объекты CORBA наследуют свои интроспективные свойства от CORBA:: Object. В дополнение к этому CORBA::ORB предоставляет две полезные вспомогательные функции: object_to_string и string_to_object (методы со светлыми кнопками на табл. 6). Ниже дано быстрое введение в Интроспективность CORBA:

Табл. 6. Методы Интроспекции Объекта CORBA

  • get_implementation
CORBA::Object
  • non_existent
  • get_interface
  • is_equivalent
  • is_nill
  • hash
  • dublicate
  • create_request
  • release
  • _request
  • is_a
 

 

  • object_to_string
CORBA::ORB
  • BOA_init
  • string_to_object
  • list_initial_services
  • create_list
  • resolve_initial_references
  • create_operation_list
  • send_multiple_request_oneway
  • get_default_context
  • send_multiple_request_deferred
  • create_environment
  • poll_next_response
 
  • get_next_response

 

Вы вызываете is_nil, чтобы определить, существует ли объект. Вы также можете вызвать non_existent, чтобы определить, не был ли объект уничтожен. Вы вызываете is__equivalent, чтобы определить, эквивалентны ли две объектные ссылки, ORB возвращает TRUE, если ссылка на ваш объект эквивалентна объектной ссылке, переданной в качестве параметра. Если две объектные ссылки идентичны, то они эквивалентны. Две различные объектные ссылки, которые ссылаются на один и тот же объект, тоже эквивалентны. Для оптимизации поиска объектов ORB может использовать внутренне хеш-значение для объектной ссылки. Если хеш-значения двух объектных ссылок различны, такие ссылки не идентичны. Но обратное верно не всегда. Наконец, вы вызываете is_a, чтобы определить, действительно ли экземпляр имеет указанный вами тип.

 

СORBA ORB обладает стандартными механизмами для генерации и поддержки метаданных. С помощью IDL вы генерируете метаданные, которые описывают ваши компоненты и их интерфейсы. Предкомпилятор IDL автоматически записывает ваши IDL-определенные метаданные в библиотеку интерфейсов. В дальнейшем эти метаданные можно модифицировать, используя операции записи и модификации библиотеки интерфейсов. Клиенты могут обращаться к библиотеке интерфейсов и таким образом узнать, какие интерфейсы доступны и как их вызывать. Эту же библиотеку интерфейсов вы можете использовать для хранения описаний компонентов, начиная с очень мелких системных объектов и кончая крупными прикладными объектами. CORBA предоставляет нам солидную базу для создания объединений библиотек интерфейсов, которые могут функционировать через гетерогенные ORB и операционные системы.


назад | содержание | далее

Hosted by uCoz