• No se han encontrado resultados

Conceptos Fundamentales en el Servicio 33 Identificación

Tipos y Herencias. ... 35

Claves ... 36

Uso del Servicio de Persistencia ... 36

Acceso al Servicio de Persistencia ... 37

Transacciones ... 38

Construcciones en PSDL ... 38

Características de las construcciones básicas PSDL ... 39

AbstractStorageObject ... 39

AbstractStorageHome ... 40

StorageObject ... 40

StorageHome ... 41

Mapeo del lenguaje PSDL a un lenguaje concreto ... 41

Diferencias entre C++ y Java del servicio de persistencia ... 41

Críticas a la especificación ... 42

Notas finales sobre el servicio de estado persistente ... 43

Alternativas a PSS en Java ... 43

Referencias ... 45

n 1997 OMG creó un RFP (Request for Proposal) para la creación de un servicio CORBA. Se trató de un servicio de persistencia de objetos [PSS01]; Una RFP consiste en el llamado a entidades a participar en la creación de una nueva especificación.

El servicio de persistencia de CORBA tiene el objeto de facilitar y unificar la forma de hacer persistente el estado de los servants [CORBA01] y fue denominado: Servicio de Estado Persistente (Persistent State Service) PSS.

El hacer persistente el estado del objeto significa que su estado sobrevive o se mantiene sin importar cuantas veces el objeto sea encarnado o destruido. No debe confundirse el persistir referencias a servants, con el hacer persistente el estado de un objeto. El hacer persistente las referencias a los servants significa guardar en forma persistente una referencia a un servant y no el estado del mismo.

En el año 2000, PSS reemplazó una especificación anterior del año 1994, denominada POS Persistent Object Service [POS01], que fue muy poco aceptada y ampliamente criticada [KjPfTp]. Actualmente está definida la revisión 2 de PSS que data de Septiembre del 2002.

PSS no intenta ser una interfase a una base de datos orientada a objetos OODBMS, sino el de proveer una forma estándar de hacer persistentes a los objetos. No define los conceptos fundamentales en OODBMS como transacciones y consultas [BgVaDk]. Su fundamento es la separación de intereses (separation of concerns) que está presente en todas la arquitectura y especificaciones de servicios CORBA [CORBA01]. De esta forma, si se tienen requerimientos transaccionales, éstos no serán implementados por este servicio sino que este servicio se conectará o comunicará con el servicio de transacciones CORBA [TS01]. Una de las características que fue mas ampliamente criticada a POS fue no usar los otros servicios que CORBA provee [KjPfTp].

PSS está basado en dos lenguajes de programación: C++ y Java. Aunque su modelo tiene mas similitudes con el segundo que con el primero.

C

ONCEPTOS

F

UNDAMENTALES EN EL

S

ERVICIO

Según la especificación, los clientes de los servants son ajenos a este servicio y no tienen forma de saber si se está usando el mismo. El PSS es visible solo dentro de la implementación de los servants. Según muestra el Gráfico 1, el cliente de la ORB que accede al servant, no accede al PSS directamente sino que lo hace a través del Servant.

In te rfa c e P S S ( P S D L )

Dominio de ORB Dominio de PSS

Servant In te rfa c e O R B e x te rn a ( ID L ) Cliente ORB Objeto del dominio PSS

GRÁFICO 1 - INTERACCIÓN CON LA ORB

En PSS, la información persistente se presenta como objetos almacenados (Storage Objects) en almacenes (Storage Homes), que a su vez se encuentran ubicados en repositorios de datos (DataStores) tales como una base de datos o un conjunto de archivos. Este modelo está representado en el Gráfico 2.

E

Data Store o Repositorio de Datos Objeto Almacenado Almacen o Storage Home Objeto Almacenado Objeto Almacenado Almacen o Storage Home Objeto Almacenado

GRÁFICO 2 - MODELO LÓGICO

Dentro de un repositorio de datos pueden existir múltiples almacenes y a su vez dentro de los almacenes pueden existir múltiples objetos almacenados. Conceptualmente, un repositorio de datos es un conjunto de almacenes, cada almacén contiene objetos de un tipo definido dentro del repositorio. Dentro del repositorio, un almacén es un Singleton [Gamma01], es decir que existe a lo sumo una única instancia de un almacén por tipo de objeto almacenado.

Los objetos almacenados se manipulan a través de instancias de una clase definida en el lenguaje de implementación del programa o proceso que utilice el servicio. Estas instancias representan en un momento dado un objeto existente en el repositorio de datos, mediante el cual se accede al estado persistido. Las instancias de objetos que estén ligadas a un objeto en el repositorio se llaman encarnaciones, al cambiar un atributo de una de estas instancias se está cambiando el estado del objeto almacenado en el repositorio.

Los almacenes de objetos también son manipulados mediante instancias de los mismos. Estas instancias son provistas por catálogos. Para acceder a las instancias de los objetos almacenados desde del proceso o programa se requiere de una conexión con el repositorio de datos, denominada sesión. El Gráfico 3 define la relación entre el modelo lógico y el modelo real de la aplicación.

Data Store o Repositorio de Datos Almacenes o Storage Homes Objetos Almacenados Objetos Almacenados Programa o Proceso Catálogo sesión Encarnaciones Instancia de Almacen Encarnaciones Instancia de Almacen

GRÁFICO 3 - SESIÓN PARA ACCEDER AL DATASTORE

Muchos de los conceptos existentes en PSS, fueron tomados del estándar SQL3 o SQL 1999 [EisenbergMelton01]. SQL3 fue una extensión propuesta al estándar SQL en el año 1999, que agrega conceptos de los lenguajes de programación orientados a objetos. Las bases de datos que lo soportan son llamadas Object-Relational DBMS u ORDBMS [Ramakanth01]. Las tablas en SQL3 permiten tipos de datos

más ricos llamados ADT (Abstract Data Type) que soportan herencia. Los almacenes de PSS son el análogo a las tablas de SQL3, mientras que los objetos almacenados son los registros o tipos de datos de SQL3.

Todos los objetos definidos por el servicio de persistencia implementan la interfase LocalInterface [CORBA01]. Según la especificación de CORBA, todos los objetos que implementen dicha interfase tienen su ciclo de vida limitado al proceso en el que fueron engendrados. De esta forma, es imposible para un servant exportar un objeto definido en el dominio del servicio de persistencia. Esta es otra forma de encapsular el servicio de persistencia sólo dentro de la implementación de los servants.

I

DENTIFICACIÓN

Dado que existen múltiples instancias de objetos dentro de un repositorio y de un almacén, es necesaria una forma de diferenciarlos.

Cada objeto almacenado posee un número único que lo identifica dentro del almacén al que pertenece denominado short-pid (Short Process Identifier o Identificador corto de Proceso). Además posee un identificador único dentro del repositorio en el que existe, que es denominado pid (Process Identifier o Identificador de Proceso). El alcance de este pid está limitado a todas las instancias que pueden ser accedidas por el mismo catálogo.

El concepto de pid es análogo al de oid dentro de CORBA. Una forma simple de relacionar un objeto CORBA con un objeto del servicio de persistencia (un objeto persistente) es directamente por sus identificadores (oid igual al pid).

T

IPOS Y

H

ERENCIAS

.

Los tipos estén separados en dos grandes categorías abstractos y concretos, los primeros implican definiciones que no pueden ser instanciadas, las segundas son las construcciones que serán instanciadas en el programa que utilice el servicio.

custom Herencia Diamante

«i nterface» A «i nterface» B «interface» C «i nterface» D «interface» A' «i nterface» B' «i nterface» C' «interface» D' «interface» E'

GRÁFICO 4 - HERENCIA DIAMANTE DE INTERFASES EN CORBA

Este modelo es muy similar al modelo de herencia del lenguaje de programación Java, los tipos abstractos son análogos a las interfases de Java, mientras que los concretos son análogos a las clases. Al igual que las interfases, los tipos abstractos admiten herencia múltiple, mientras que los concretos solo pueden heredar a lo sumo de un único tipo concreto. De igual forma que las clases, los tipos concretos pueden “implementar” múltiples interfases. La herencia múltiple incluye el modelo de herencia diamante.

La herencia diamante (gráfico 4) está definida en la especificación de CORBA [CORBA01], se utiliza principalmente para la definición de interfases.

AlmacenTipoA TipoA TipoB AlmacenTipoB TipoC AlmacenTipoC AlmacenConcreto TipoConreto almacena almacena almacena almacena Implementa Implementa Implementa Implementa

Hereda Hereda Hereda

Hereda

GRÁFICO 5 - TIPOS Y MODELO DE HERENCIA EN PSS

Tanto los objetos almacenados como los almacenes son tipados con tipos abstractos o concretos, según si son abstractos o concretos respectivamente.

Cada objeto almacenado tiene un tipo asociado, este tipo define el estado y las operaciones que poseen todas las instancias de este tipo. A su vez un tipo puede ser derivado de otros tipos definidos en el repositorio.

Cada almacén a su vez está definido por un tipo, el cual define los tipos de objetos que el almacén puede contener o manejar junto con las operaciones que pueda realizar. De igual forma que los tipos de objetos, los tipos de almacenes también pueden derivar de otros tipos de almacenes definidos dentro del repositorio.

Dentro de un repositorio, un almacén puede manejar tanto las instancias de sus objetos almacenados como las de sus subtipos, que se denomina familia de almacenes.

En el gráfico 5 se muestra la herencia de tipo diamante soportada por el servicio de persistencia CORBA.

C

LAVES

Un almacén puede definir que una serie de atributos de los objetos que maneja, definen una clave que representa un identificador único para cualquier instancia de los objetos existentes en el almacén. Los almacenes pueden definir tantas claves como deseen. Hay una clave implícita que es el short-pid. Un concepto muy importante, es que las claves no están definidas por los objetos almacenados, sino por el almacén donde se encuentran. Esto permite que diferentes almacenes definan diferentes claves. Una implicación importante es que la unicidad de los objetos sólo es válida dentro del almacén en el que existen.

U

SO DEL

S

ERVICIO DE

P

ERSISTENCIA

Para hacer uso del servicio de persistencia, se requiere que el usuario defina los tipos que usará en un programa, la especificación propone dos formas para definir los tipos de objetos.

- mediante el uso del lenguaje programación en el que se quiera acceder al servicio.

PSDL es una ampliación al IDL estándar de CORBA, que agrega cuatro construcciones: abstract storage object, abstract storage home, storage object y storage home. En el caso de utilizar la primera forma de definir los tipos, la implementación del servicio deberá proveer una herramienta o compilador que transforme el código definido en PSDL al código fuente que utilice el servicio.

En el caso de utilizar la segunda, también llamada persistencia transparente, el usuario será responsable de programar las clases que usará el servicio de persistencia.

Ambas alternativas son igualmente válidas, la segunda no requiere que el usuario entienda el lenguaje PSDL. Tiene algunas limitaciones ya que no hay un estándar para cada lenguaje, que defina cómo hacer uso de algunas de las funcionalidades que provee el servicio, tales como definir claves adicionales a las implícitas. Este problema surge porque el servicio requiere que el usuario sea quien defina y provea los tipos y no alcanza con solo llamar a una rutina del servicio. A cualquier usuario acostumbrado a trabajar con CORBA le es natural utilizar el lenguaje IDL y por consiguiente le debiera ser relativamente sencillo aprender a utilizar PSDL.

Según la especificación del servicio, las aplicaciones que utilicen el servicio de persistencia solo deberían tratar con los tipos abstractos, de esta forma se puede lograr una aplicación aislada o separada de la implementación del servicio. Por otro lado, los tipos concretos son mapeados a construcciones definidas en el lenguaje de implementación del servicio (Java o C++). Algunas de estas construcciones están definidas en el mapeo de PSDL al lenguaje concreto, pero otras no, y en este punto es donde se pierde la independencia de la implementación del servicio de persistencia.

A

CCESO AL

S

ERVICIO DE

P

ERSISTENCIA

La puerta de entrada al servicio es el ConnectorRegistry (o registro de conectores). Este objeto es un Singleton registrado en la ORB como una referencia inicial [CORBA01]. El nombre de la referencia depende de la implementación del servicio, pero generalmente es PSS. Como su nombre lo indica, el ConnectorRegistry tiene un registro de los conectores que tiene registrados el servicio de persistencia.

ConectorRegistry Connector CatalogBase

Session SessionPool TransactionalSession ORB Refencia inicial Tiene registrados Provee

GRÁFICO 6 - ACCESO AL SERVICIO

El conector (Connector) determina el tipo de servicio de persistencia que se usará. Se dice que el conector define la implementación del servicio de persistencia a utilizar. Un conector típico podría ser uno que se conecte a una base de datos relacional o uno que utilice un sistema de archivos para almacenar el estado de los objetos. Los conectores son responsables de crear los catálogos (CatalogBase) que se

usarán para trabajar con el servicio de persistencia. El tipo de catálogo que se cree, será dependiente del conector y el método que se utilice para crearlo.

La sesión, o sea la conexión lógica entre el o los repositorios y el proceso, tiene credenciales de uso, como por ejemplo, solo lectura o lectura-escritura. Las sesiones pueden a su vez ser de tipo transaccional (TransactionalSession) mediante el uso del servicio de transacciones CORBA, o sesiones donde la atomicidad de las operaciones dependa del conector utilizado, por ejemplo, con acceso de tipo archivo (Session), donde cada operación se hace inmediatamente persistente.

El acceso a las sesiones puede ser en forma explícita o implícita. Cuando se trabaja con sesiones implícitas (ya sean transaccionales o no) el usuario del servicio de persistencia es el encargado de crearlas, escribiendo código en el lenguaje utilizado. Cuando se maneja en forma implícita, un pool de sesiones es el encargado de administrarlas (SessionPool). Un pool de sesiones tiene el objeto de permitir la reutilización de las conexiones o sesiones a un repositorio, ya sea dentro de la misma aplicación o no. Por lo general, su existencia tiene dos justificaciones: la creación de una sesión puede ser costosa en términos de recursos involucrados para crearla, y cómo y dónde conectarse puede ser centralizado en un sólo punto, permitiéndole a la aplicación desentenderse de ello.

El servicio de persistencia puede ser utilizado también mediante un contenedor de componentes CORBA [CCM01, CCM02], tanto en forma explícita como implícita.

T

RANSACCIONES

Las transacciones en el servicio de persistencia están presentes a través del servicio de transacciones CORBA [TS01]. Esto implica que los objetos almacenados pueden ser accedidos en el contexto de una transacción. Para interactuar con el servicio de transacciones es necesario registrar en él los recursos que serán utilizados en la transacción.

En el caso de que se trate de sesiones explícitas, las instancias de los objetos almacenados están relacionadas con una transacción por medio de una sesión transaccional. Esta sesión está asociada a una transacción de datos (datastore transaction), que es el recurso que se registra con el servicio de transacciones. En el modo de trabajo explícito, la sesión transaccional provee operaciones explícitas para interactuar directamente con el servicio de transacciones.

El escenario anterior no es el más típico, por lo general, cuando se trabaja con transacciones se utiliza un proveedor de las mismas, y es el pool de sesiones el que se comunica con este servicio. En el caso de utilizar el pool (sesiones implícitas), éste es el encargado de verificar cuando es necesario iniciar una transacción y no se tiene control programado del manejo de transacciones.

C

ONSTRUCCIONES EN

PSDL

PSDL define el módulo CosPersistentState, que contiene todas las construcciones propias del lenguaje. Las principales son:

CatalogBase, Connector, Session, SessionPool, TransactionalSession, AccessMode,

ParameterList, StorageHomeBase, StorageObjectBase, StorageObjectFactory, StorageHomeFactory, SessionFactory, NotFound, TypeId, Pid, ShortPid, ConnectorRegistry.

A continuación, voy a hacer una breve descripción de las construcciones que agrega PSDL a IDL no definidas hasta este punto.

- AccessMode define el modo de acceso que tendrá garantizado el usuario del servicio sobre una sesión al momento de crearla, mediante el uso de un conector. Puede ser solo lectura, o lectura – escritura.

- ParameterList es simplemente una lista de parámetros variables que le permiten al conector recibir parámetros propios de la implementación del mismo para crear una sesión. Por ejemplo, un conector podría requerir un nombre de usuario y clave para conectarse a un repositorio, si el repositorio es de tipo remoto, podría ser necesario indicarle la ubicación del mismo en la red. - NotFound es una excepción utilizada para indicar que un objeto que se quiere localizar no existe

o no está disponible. Es utilizada tanto por el registro de conectores para indicar que un conector no existe, como por una sesión cuando se quiere ubicar un objeto por su pid.

- TypeId es una cadena de caracteres que identifica un tipo PSDL. El formato de la misma es similar a los ids de los repositorios IDL [CORBA01 ver sección 10.7.1], pero en vez de comenzar con IDL lo hacen con PSDL. Al igual que los ids de repositorios, estos ids incluyen el número de versión al que corresponden. Estos ids son utilizados por los conectores para registrar las fábricas de objetos de un tipo PSDL. Por ejemplo, para un tipo persistido: ar.uba.fi.pmi.corba.pss.prueba1.Persona, en su primer versión podría tener asociado un tipo persistido: PSDL:ar.uba.fi.pmi.corba.pss.prueba1.Persona:1.0. Esta cadena de caracteres será utilizada por el usuario final para registrar la clase Persona en el conector donde quiera utilizarla.

C

ARACTERÍSTICAS DE LAS CONSTRUCCIONES BÁSICAS

PSDL

En este punto se definen las características principales de las definiciones PSDL. La sintaxis de las mismas se podrá consultar en la especificación del servicio [PSS01].

ABSTRACTSTORAGEOBJECT

La sintaxis para definir un objeto de este tipo es prácticamente la misma que para una interfase IDL, salvo que esta no puede contener constantes ni definiciones de subtipos. Un objeto almacenado abstracto puede heredar de múltiples objetos almacenados abstractos, pero sólo puede ser definido como supertipo directo una única vez en la misma definición. No se permite heredar de tipos que contengan estados u operaciones con el mismo nombre, salvo para el caso de la herencia diamante explicada anteriormente. Se permiten definiciones hacia adelante (forward), pero las mismas tienen que estar completas dentro de la misma especificación PSDL (dentro del mismo documento).

Estas definiciones pueden contener definiciones de estados que representan a los atributos persistentes de los objetos almacenados. Los estados pueden ser definidos como lectura – escritura o sólo lectura (explícitamente). Los estados son tipados y los tipos válidos son: un tipo básico (número o carácter), una cadena de caracteres, una referencia a un tipo persistido abstracto, u otra definición local (interfase u objeto almacenado).

Cuando el estado tiene definido un tipo que sea otro tipo persistido, se dice que el objeto está empotrado (embedded) en el otro. Este objeto que representa el estado, no posee identidad propia y no puede ser referenciado fuera del contexto del objeto que lo contiene.

Cuando el tipo del estado es una referencia a otro objeto almacenado mediante el uso de la palabra strong (fuerte), se puede indicar que cuando el objeto almacenado que lo referencia sea destruido también lo sea el referenciado.

La definición puede contener operaciones locales (local operations), que podrán utilizar parámetros de entrada, salida o entrada - salida tal como cualquier operación IDL. Además, podrán utilizar como parámetros, cualquier definición IDL válida o algún objeto almacenado abstracto definido previamente. Las operaciones pueden ser definidas además como constantes, en cuyo caso no se les estará permitido modificar el estado del objeto al que pertenecen. Se les denomina operaciones locales dado que los objetos almacenados definen interfases locales en CORBA.

Toda definición de objeto almacenado abstracto que no herede de otra definición explícitamente, heredará implícitamente del objeto almacenado abstracto StorageObject definido en el módulo CosPersistentState.

ABSTRACTSTORAGEHOME

La definición de un almacén de objetos almacenados debe especificar que tipo de objeto

Documento similar