Esquema CIM

Os elementos do metaesquema são classes, propriedades e métodos. O metaesquema também suporta indicações e associações como tipos de classes e referências como tipos de propriedades.

As classes podem ser organizadas em uma hierarquia de generalização que representa relações de subtipo entre as classes. A hierarquia de generalização é um gráfico direcionado com raiz que não suporta várias heranças.

Uma classe regular pode conter propriedades escalares ou de matriz de qualquer tipo intrínseco, como booleano, inteiro, string e outros. Ela não pode conter classes embutidas ou referências a outras classes.

Uma associação é uma classe especial que contém duas ou mais referências. Ela representa uma relação entre dois ou mais objetos. Devido à forma como as associações são definidas, é possível estabelecer uma relação entre classes sem afetar nenhuma das classes relacionadas. Isto é, a adição de uma associação não afeta a interface das classes relacionadas. Somente associações podem ter referências.

O fragmento do esquema na ilustração a seguir mostra as relações entre alguns objetos CIM que o ZfD usa.


O esquema CIM como é mapeado para um esquema RDBMS

A ilustração mostra como o esquema CIM é mapeado para um esquema DBMS relacional. As classes são mostradas com o nome da classe como o título da caixa. As associações são etiquetadas dentro das linhas entre duas classes.

A hierarquia de herança deste fragmento de esquema é mostrada na ilustração a seguir do esquema CIM 2.2. As referências mostradas como tipo Ref estão em negrito com cada subtipo de associação especificando o tipo da referência.


O esquema CIM 2.2 e sua hierarquia de herança


Mapeamento CIM-para-Relacional

CIM é um modelo de objeto completo com classes, herança e polimorfismo. O mapeamento gerado para um esquema relacional preserva esses recursos ao máximo. Os dois aspectos a seguir são parte do mapeamento relacional:

Uma tabela no banco de dados representa cada classe na hierarquia CIM. Uma coluna do tipo apropriado na tabela representa cada propriedade não herdada na classe. Cada tabela também possui uma tecla primária, id$, que é um inteiro de 64 bits que identifica uma instância de forma exclusiva. Uma instância de uma classe CIM é representada por uma linha em cada tabela que corresponde a uma classe em sua hierarquia de herança. Cada linha possui o mesmo valor para id$.

Cada classe CIM também é representada por uma visualização que usa id$ para juntar linhas das várias tabelas na hierarquia de herança e gerar um conjunto composto de propriedades (herdadas mais locais) para uma instância dessa classe. A visualização também contém uma coluna extra, class$, do tipo inteiro que representa o tipo da classe (a “mais” folha) real da instância.

Associações são mapeadas da mesma forma que as classes regulares, com uma propriedade de referência representada por uma coluna com o campo id$ da instância de objeto referida. Assim, as associações podem ser percorridas através de uma junção entre o campo de referência na associação e o campo id$ na tabela referida.

A ilustração a seguir descreve uma consulta típica usando esse mapeamento.


Uma consulta para encontrar todos os computadores em uma rede

Essa consulta encontra todos os computadores anexados a um segmento de rede específico. As classes e relacionamentos envolvidos são destacados com bordas.

Os tópicos a seguir descrevem os dois tipos de esquema:


Esquema lógico

O esquema lógico é o esquema do banco de dados conforme visto pelos usuários do banco de dados e do aplicativo. O esquema consiste em procedimentos e visualizações armazenados. As tabelas subjacentes não são visíveis ao aplicativo.

Geralmente, cada classe CIM possui o seguinte:

Os componentes do ZfD Inventory usam JDBC* para emitir instruções SQL para o RDBMS e para fazer a conversão entre tipos de dados RDBMS e tipos de dados Java*. O uso de JDBC com procedimentos e visualizações armazenados fornece um nível de abstração que isola o código do aplicativo da tecnologia do banco de dados subjacente e de mudanças no esquema físico.

Os vários elementos do esquema lógico são discutidos mais detalhadamente nas seções a seguir:


Nomeando elementos do esquema

Recomendamos que você use os nomes CIM não modificados no esquema do banco de dados. Alguns problemas talvez ainda permaneçam devido às diferenças na nomeação dos esquemas, tais como as seguintes:

A maioria desses problemas são evitados durante a geração de esquemas, preservando as maiúsculas/minúsculas de nomes CIM, abreviando quaisquer nomes que tenham mais de 30 caracteres e colocando aspas duplas em torno de qualquer nome que esteja nos conjuntos de palavras reservadas.

Qualquer nome que tenha mais de 28 caracteres será abreviado para um nome raiz de 28 ou menos caracteres, para que possa ter um prefixo de dois caracteres. Assim, todos os elementos do esquema SQL associados poderão usar o mesmo nome raiz. O algoritmo de abreviação reduz um nome, de forma que se torne mnemônico, reconhecível e, também, exclusivo em seu escopo. O nome abreviado recebe um caractere # como sufixo (observe que # é um caractere ilegal no CIM) para evitar conflito com outros nomes. Se dois ou mais nomes dentro do mesmo escopo gerarem a mesma abreviação, um dígito adicional será anexado para torná-lo exclusivo. Por exemplo, AttributeCachingForRegularFilesMin é abreviado para AttCacForRegularFilesMin#.

Todos esses nomes abreviados são gravados na tabela de nomes abreviados, para que o programa possa procurar o nome CIM real e recuperar o nome abreviado para ser usado com o SQL.

Visualizações são os elementos de esquema mais freqüentemente manipulados pelas consultas e pelo código do aplicativo. Elas usam o mesmo nome que a classe CIM que representam. Por exemplo, a classe CIM_UnitaryComputerSystem é representada por uma visualização chamada CIM.UnitaryComputerSystem.

Quando necessário, os nomes de índices e tabelas auxiliares são criados através da concatenação do nome da classe e da propriedade separados pelo caractere $. Esses nomes costumam ser abreviados. Por exemplo, NetworkAdapter$NetworkAddresses é abreviado para NetAdapter$NetAddresses#. Isso não prejudica de forma alguma os usuários do esquema do ZfD.


Usuários e funções

No SQL, um usuário com o mesmo nome que o esquema é o proprietário de cada esquema, por exemplo, CIM, ManageWise®, ZENworks® e outros.

Além disso, há um usuário MW_DBA que possui privilégios e direitos do Administrador do Banco de Dados para todos os objetos esquema. A função MW_Reader possui acesso apenas leitura a todos os objetos esquema e a função MW_Updater possui acesso leitura-gravação-execução a todos os objetos esquema.

Aplicativos devem acessar o banco de dados como MW_Reader ou MW_Updater para um banco de dados Sybase, MWO_Reader ou MWO_Updater para um banco de dados Oracle e MWM_Reader ou MWM_Updater para um banco de dados MS SQL Server 2000, dependendo de seus requisitos.


Tipos de dados

Tipos de dados CIM são mapeados para os tipos de dados mais apropriados fornecidos pelo banco de dados. Normalmente, o aplicativo Java não exige o tipo porque ele usa o JDBC para acessar os dados.

Java não suporta originalmente tipos não assinados; portanto, você deve usar classes ou tipos inteiros do próximo tamanho para representá-los. Da mesma forma, verifique se há problemas durante a leitura ou gravação no banco de dados. Por exemplo, a leitura ou gravação de um número negativo em um campo não assinado no banco de dados provavelmente causará erro.

Strings no CIM e no Java são Unicode*; portanto, o banco de dados é criado usando o conjunto de caracteres UTF8. A internacionalização não apresenta nenhum problema, entretanto, ela pode causar problemas na distinção entre maiúsculas e minúsculas em consultas.

Todos os bancos de dados preservam as maiúsculas/minúsculas de dados de string armazenados dentro deles, mas podem acessar os dados com distinção entre maiúsculas e minúsculas ou durante as consultas. No ZfD, os componentes Consulta de Inventário e Exportação de Dados não são afetados, pois os dados consultados são recuperados do banco de dados antes de serem consultados. Assim, a distinção entre maiúsculas e minúsculas é automaticamente ativada.

No CIM, as strings podem ser especificadas com ou sem um tamanho máximo em caracteres. Muitas strings não possuem tamanho especificado, o que significa que podem ter um tamanho ilimitado. Por questões de eficiência, essas strings ilimitadas são mapeadas para uma string disponível com um tamanho máximo de 254 caracteres. As strings CIM com tamanho máximo são mapeadas para strings do banco de dados variáveis do mesmo tamanho. O tamanho no banco de dados é em bytes e não em caracteres, pois um caractere unicode pode requisitar mais de um byte para armazenamento.


Visualizações

Cada classe CIM é representada no banco de dados por uma visualização que contém todas as propriedades não-matriciais herdadas e locais dessa classe. A visualização tem o mesmo nome da classe CIM. Por exemplo, CIM_System da classe CIM representa uma visualização SQL chamada CIM.System, como mostrado na ilustração a seguir.

A visualização CIM.System é criada com atributos selecionados de várias tabelas. Esses atributos incluem: id$ selecionado de cim.t$ManagedSystemElement,class$ é preenchido automaticamente usando a função mw_dba.extractClass, Caption selecionado de cim.t$ManagedSystemElement, Description selecionado de cim.t$ManagedSystemElement, InstallDate selecionado de cim.t$ManagedSystemElement, Status selecionado de cim.t$ManagedSystemElement, CreationClassName selecionado de cim.t$System, Name selecionado de cim.t$ManagedSystemElement. NameFormat selecionado de cim.t$System.NameFormat, PrimaryOwnerContact selecionado de cim.t$System e PrimaryOwnerName selecionado de cim.t$System. A visualização é criada através da junção das tabelas CIM.t$ManagedSystemElement e CIM.t$System, onde id$ é o mesmo nas duas tabelas.

A visualização CIM.SYSTEM é a seguinte:

CREATE VIEW CIM.System

{

  id$, 

  class$,

  Caption,

  Description,

  InstallDate,

  Status,

  CreationClassName,

  Name,

  NameFormat,

  PrimaryOwnwerContact,

  PrimaryOwnerName

}

AS SELECT

  CIM.t$ManagedSystemElement.id$

  MW_DBA.extractClass(CIM.t$ManagedSystemElement.id$),

  CIM.t$ManagedSystemElement.Caption,

  CIM.t$ManagedSystemElement.Description,

  CIM.t$ManagedSystemElement.InstallDate,

  CIM.t$ManagedSystemElement.Status,

  CIM.t$System.CreationClassName,

  CIM.t$ManagedSystemElement.Name,

  CIM.t$System.NameFormat,

  CIM.t$System.PrimaryOwnerContact,

  CIM.t$System.PrimaryOwnerName

FROM

  CIM.t$ManagedSystemElement,

  CIM.t$System

WHERE

  CIM.t$ManagedSystemElement.id$ = CIM.t$System.id$

Além das propriedades da classe, a visualização possui os dois campos adicionais a seguir:

Você pode consultar as visualizações usando a instrução SELECT e atualizá-las usando a instrução UPDATE. Como as visualizações não podem ser usadas com as instruções INSERT e DELETE, use os procedimentos construtor e destruidor.


Identificador de objeto Id$

Id$ é um identificador de objeto de 64 bits que identifica uma instância específica de classe de forma exclusiva. Por exemplo, uma instância da classe CIM_Processor. Esse identificador de objeto costuma ser usado como handle opaco de uma instância específica. Id$ é modelado como um número assinado para facilitar a manipulação em Java como tipo de dado longo.

Id$ contém as três partes de informações a seguir e cada uma pode ser extraída chamando o procedimento armazenado apropriado.

O campo id$ é usado em sua totalidade como um handle opaco para uma instância de uma classe. Quando uma classe de associação representa um relacionamento entre instâncias de duas classes, os campos de referência da associação mantêm o id$ das instâncias referenciadas (como os apontadores). Portanto, id$ e esses campos de referência costumam ser usados em condições de associação, durante a construção de consultas do banco de dados que fazem referência a mais de uma visualização.


Construtor

Cada classe CIM (não-abstrata) concreta possui um procedimento armazenado construtor que deve ser chamado para criar uma instância da classe. Esse procedimento armazenado possui parâmetros de entrada que permitem ao usuário especificar um valor para cada propriedade na classe e um único parâmetro de saída que retorna o id$ alocado para a instância criada. O aplicativo usa esse valor de id$ retornado para construir classes de associação que fazem referência a essa instância específica.

O construtor é nomeado usando o prefixo c$ no nome raiz e cada parâmetro é nomeado usando o prefixo p$ no nome de propriedade raiz. Por exemplo, o construtor de CIM_UnitaryComputerSystem, uma subclasse de CIM_System, é nomeado CIM.c$UnitaryComputerSystem e é construído para Oracle, como mostrado no exemplo a seguir:

CREATE PROCEDURE CIM.c$UnitaryComputerSystem

(

p$id$  OUT NUMBER,

p$Caption IN CIM.t$ManagedSystemElement.Caption%TYPE DEFAULT  NULL,

p$Description IN CIM.t$ManagedSystemDescription%TYPE DEFAULT NULL,

p$InstallDate IN CIM.t$ManagedSystemElement.InstallDate%TYPE DEFAULT NULL,

p$Status IN CIM.t$ManagedSystemElement.Status%TYPE DEFAULT NULL,

p$CreationClassName IN CIM.t$System.CreationClassName%TYPE DEFAULT NULL,

p$Name IN CIM.t$ManagedSystemElement.Name%TYPE DEFAULT NULL,

p$PrimaryOwnerContact IN CIM.t$System.PrimaryOwnerContact%TYPE DEFAULT NULL,

p$PrimaryOwnerName IN CIM.t$System.PrimaryOwnerName%TYPE DEFAULT NULL,

p$NameFormat IN CIM.t$System.NameFormat%TYPE DEFAULT NULL,

p$LastLoadInfo IN CIM.t$UnitaryComputerSystem.LastLoadInfo%TYPE DEFAULT NULL,

p$ResetCapability IN CIM.t$UnitaryComputerSystem.ResetCapability%TYPE DEFAULT NULL,

p$PowerManagementSupported IN CIM.t$UnitaryComputerSystem.PowerManagementSupported%TYPE DEFAULT NULL,

p$PowerState IN CIM.t$UnitaryComputerSystem.PowerState%TYPE DEFAULT NULL

)IS

  temp NUMBER;

BEGIN

  LOOP

  SELECT CIM.s$UnitaryComputerSystem.NEXTVAL INTO temp FROM DUAL;

  SELECT MW_DBA.makeId(240, temp) INTO temp FROM DUAL;

  EXIT WHEN MOD(temp,100) != 0;

  END LOOP; 

  p$id$ := temp;

INSERT INTO CIM.t$ManagedSystemElement (id$, classOid$, Caption, Description, InstallDate, Status, Name)VALUES(p$id$, HEXTORAW('0302100203'), p$Caption, p$Description, p$InstallDate, p$Status, p$Name);

INSERT INTO CIM.t$System (id$, CreationClassName, PrimaryOwnerContact, PrimaryOwnerName, NameFormat)VALUES(p$id$, p$CreationClassName, p$PrimaryOwnerContact, p$PrimaryOwnerName, p$NameFormat);

INSERT INTO CIM.t$UnitaryComputerSystem (id$, LastLoadInfo, ResetCapability, PowerManagementSupported, PowerState) VALUES(p$id$, p$LastLoadInfo, p$ResetCapability, p$PowerManagementSupported, p$PowerState);

END;

Procedimentos armazenados podem ser chamados com argumentos de posição, argumentos de palavra-chave ou com uma combinação de ambos. Se algum argumento de posição for fornecido, ele deverá preceder qualquer argumento de palavra-chave. Sempre use argumentos de palavra-chave quando chamar procedimentos armazenados construtores. Isso fornece um isolamento melhor das mudanças do esquema CIM, que causam a inserção de parâmetros extras ou o registro de parâmetros existentes; qualquer um dos dois pode interromper uma chamada posicional de uma forma provavelmente não detectável. Os procedimentos são gerados de forma que nenhum parâmetro omitido terá padrão NULL.

É permitido usar a notação posicional para o primeiro parâmetro p$id$, que é o parâmetro de saída que retorna o identificador de objeto da nova instância criada.

A seguinte amostra de código JDBC mostra como chamar um procedimento armazenado usando notação posicional para o primeiro argumento e notação de palavra-chave para todos os argumentos subseqüentes no Sybase.

CallableStatement CS = 

conn.prepareCall( "{call CIM.c$UnitaryComputerSystem( ?,  p$Name=?, p$Description=?)}" )

cs.registerOutParameter ( 1, java.sql.Types.BIGINT ); //id$

cs.setString( 2, "Bogus_UCS_1") ; //Name

cs.setString( 3, "Created with mixture of positional & keyword args" ); // Description

cs.executeUpdate();

long id = cs.getLong ( 1 );

SQLWarning w = cs.getWarnings();

if( w != null )

  printWarnings( w );

else

  System.out.println("Created UCS id$ = " + id );

A sintaxe para a notação de palavra-chave difere no Sybase ASA, MS SQL 2000 e Oracle. No Sybase ASA e no MS SQL 2000, a sintaxe é KEYWORD=valor. No Oracle, a sintaxe é KEYWORD => valor. Um código corretamente gravado construirá dinamicamente a string de chamada usando sintaxe apropriada para o banco de dados em uso.


Destruidor

Cada classe CIM não-abstrata possui um procedimento armazenado destruidor que é chamado para destruir uma instância da classe. Esse procedimento armazenado possui somente um parâmetro de entrada que especifica o identificador de objeto (id$) da instância a ser destruída e não retorna valor algum.

O destruidor apaga as linhas apropriadas em todas as tabelas relevantes, incluindo as linhas da cadeia de herança e quaisquer associações que façam referência à instância sendo destruída. Somente a associação é destruída, os objetos associados não são destruídos. Se houver necessidade de destruir a associação, os programadores deverão garantir que eles não sejam destruídos. O destruidor é nomeado usando o prefixo d$ no nome raiz e o parâmetro do identificador de objeto único é nomeado p$id$. Esse procedimento é chamado usando notação posicional. Por exemplo, o destruidor para CIM_UnitaryComputerSystem, uma subclasse concreta de CIM_System, é nomeado CIM.d$UnitaryComputerSystem.


Esquema físico

O esquema físico inclui elementos necessários para implementar o banco de dados. O esquema físico difere em cada banco de dados. Um esquema físico típico consiste em:

O esquema lógico é colocado em camadas sobre o esquema físico, tornando desnecessário para usuários e aplicativos conhecerem o esquema físico.