• Nenhum resultado encontrado

Métodos em Objectos Remotos

N/A
N/A
Protected

Academic year: 2021

Share "Métodos em Objectos Remotos"

Copied!
26
0
0

Texto

(1)

8/28/2003

José Alves Marques

Métodos em Objectos Remotos

8/28/2003

José Alves Marques

Departamento de Engenharia Informática

Invocação de Métodos em Objectos Remotos

• Um sistema de objectos distribuídos é uma extensão ao

conceito de RPC

• Um objecto invoca um método noutro objecto localizado

remotamente.

• Num sistema de objectos o RPC designa-se normalmente

Remote Method Invocation ou RMI

• A IDL é uma linguagem orientada aos objectos

tipicamente baseada em C++, Java, ou C#.

(2)

8/28/2003

José Alves Marques

m4 m5 m6

Interface

Remota

m1 m2 m3

Código

dos

métodos

Dados

Objecto remoto

Invocação de Objectos Remotos

Departamento de Engenharia Informática

Diferenças Relevantes

• Granularidade

– Mais fina do que em servidores que tipicamente disponibilizam

interfaces para programas com alguma complexidade

• Invocação dinâmica

– Sistemas cliente-servidor  ligação é forte (tightly coupled):

• Clientes não podem invocar serviços para os quais não tenham os

stubs (estabelecidos quando IDL foi compilada)

– Sistemas de objectos

 desenvolvimento incremental / loosely

coupled

• Permitem um objecto invocar dinamicamente outros de que obtém a

interface em tempo de execução

(3)

8/28/2003

José Alves Marques

Principais Sistemas de Objectos Remotos

• Corba

• RMI (Java / J2EE)

• Remoting (C# / .NET)

8/28/2003

José Alves Marques

Departamento de Engenharia Informática

CORBA

• Tem origem no Object Management Group

(OMG) criado em 1989

• Modelo Conceptual é uma síntese entre o modelo

cliente –servidor e as arquitecturas de objectos

• A proposta original do Corba - Object

Management Architecture foi publicada em 1990 e

continha:

– Serviços de suporte ao ciclo de vida dos objectos

– Object request broker

(4)

8/28/2003

José Alves Marques

Object Request Broker

• Novo paradigma: consiste num serviço que auxilia a

invocação de objectos remotos

• O papel do ORB é localizar o objecto, activá-lo se

necessário, enviar o pedido do cliente ao objecto

ORB

Aplicação

Cliente

Serviço

Remoto

(objecto)

Activar serviço

Localizar objecto

(serviço)

Estabelecer

ligação

Comunic.

Departamento de Engenharia Informática

CORBA

CORBA 2.0 publicado em 1996

Os principais elementos da plataforma são:

– IDL – linguagem object oriented com suporte para herança

– Arquitectura – define o ambiente de suporte aos objectos, à invocação, ao

ciclo de vida

– GIOP – General Inter Orb Protocol – protocolo de invocação remota entre

Orb de fabricantes diferentes

– IIOP - Internet Inter Orb Protocol – implementação do GIOP sobre

protocolos TCP/IP

Actualmente

– Actividade de normalização reduzida

– Vários produtos disponíveis

• Visigenic/Visibroker

• IONA

(5)

8/28/2003

José Alves Marques

Modelo de Objectos

Um objecto CORBA implementa uma interface descrita na IDL

CORBA

Um objecto CORBA pode ser invocado remotamente através de uma

referência remota

Os objectos CORBA residem no servidor,

os clientes podem ser objectos ou programas que enviam as mensagens

correctas para os objectos

Os objectos não têm de ser implementados numa linguagem Object

Oriented podem ser em Cobol, C, etc.

Os objectos remotos são transferidos por referência.

– Ou seja permanecem no servidor e apenas é enviada uma referência que

permite invocá-los

– Alternativa (usada para os tipos primitivos): passagem por valor. Quais as

diferenças?

8/28/2003

José Alves Marques

Departamento de Engenharia Informática

Referências Remotas

• Para invocar uma operação remota é necessário que o

objecto invocador tenha uma referência remota para o

objecto

• As referências remotas podem ser passadas como

argumentos ou como resultados de invocações remotas

• Analogia com o binding handle dos RPC

IDL interface type name

Protocol and address details

Object key

interface repository

identifier

IIOP

host domain

name

port number

adapter name

object name

IOR

(6)

8/28/2003

José Alves Marques

CORBA IDL

• A interface é escrita em OMG IDL

– A interface é object-oriented com sintaxe muito

semelhante ao C++

• A herança é suportada

– Especifica um nome de uma interface e um conjunto de

métodos que os clientes podem invocar

– Descreve os parâmetros e o respectivo sentido in, out,

inout

– Os métodos podem ter excepções

Departamento de Engenharia Informática

module Accounts

{

interface Account

{

readonly attribute string number;

readonly attribute float balance;

exception InsufficientFunds (string detail);

float debit (

in float amount) raises (insufficientFunds);

float credit (

in float amount);

}

interface InterestAccount : Account

{

readonly attribute float rate;

}

}

(7)

8/28/2003

José Alves Marques

Arquitectura

Implementation repository interface repository Client program Proxy for A ORB core

client

or dynamic skeleton

o b je c t a d a p te r ORB core

server

s k e le to n Servant A

Request

Reply

Or dynamic invocation

8/28/2003

José Alves Marques

Departamento de Engenharia Informática

Elementos da Arquitectura

ORB – núcleo – run-time da invocação remota, conjunto de funções

residentes quer no cliente quer no servidor

– Implementa a infra-estrutura de comunicação

– O ORB tem funções para ser inicializado e parado

Servidor

– Object adapters - rotina de despacho que recebe as mensagens e invoca os

stubs apropriado

• O nome do object adapter faz parte da referência remota e permite a sua

invocação

• Despacha cada invocação via um skeleton para o método apropriado

– Skeletons

• Funções de adaptação que fazem a conversão dos parâmetros de entrada e saída

e o tratamento das excepções

Client proxies

– Para as linguagens Object-oriented

(8)

8/28/2003

José Alves Marques

Invocação

• A invocação do método tem por omissão uma semântica

at-most-once

• A heterogeneidade é resolvida com a conversão para CDR –

Common Data Representation

– Inclui 15 tipos básicos

– Receiver makes it right

Departamento de Engenharia Informática

index in

sequence of bytes

notes

on representation

0-3

4-7

8-11

12-15

16-19

20-23

24-27

5

“Smit”

“h____”

6

“Lond”

“on____”

1934

4 bytes

length of string “Smith” length of string London unsigned long

Struct Pessoa {

string Nome;

string Lugar;

unsigned long Ano;

};

Representa a struct Person com os valores: {‘Smith’, ‘London’, 1934}

(9)

8/28/2003

José Alves Marques

Elementos da Arquitectura

• Interface repository

– Dá informação sobre as interfaces registadas

– Para uma interface pode dar a informação dos métodos

e dos respectivos parâmetros

– O compilador de IDL atribui um número único a cada

tipo IDL que compila

– Esta facilidade permite a invocação dinâmica em

CORBA. Se um cliente recebe uma referência remota

para um novo objecto CORBA de que não tem um

proxy, pode ir buscar esta informação ao Interface

repository

8/28/2003

José Alves Marques

Departamento de Engenharia Informática

CORBA – Invocação Dinâmica

Para dinamicamente invocar um objecto em tempo de execução existe

a invocação dinâmica

O cliente não precisa de ter os proxies

– As invocações remotas são construídas dinamicamente

– Novos servidores podem ser usados por clientes já existentes

Funcionamento

– O Cliente usa o Interface Repository para obter a informação sobre os

métodos e argumentos.

– Cria a mensagem de acordo com a especificação da interface, e envia o

pedido para o respectivo objecto.

Account_ptr acc = ...; // Obter ref para objecto Account

acc->deposit( 100 ); // Invoc. estática

CORBA::Object_ptr obj = ...;

CORBA::Request_ptr req = obj->_request( "deposit" );

req->add_in_arg( "amount" ) <<= (CORBA::ULong) 100;

req->invoke();

(10)

8/28/2003

José Alves Marques

Invocação

dinâmica

Departamento de Engenharia Informática

(11)

8/28/2003

José Alves Marques

RMI

• Remote Method Invocation: mecanismo de chamada

remota a métodos Java

• Utilizado para RPCs entre objectos Java distribuídos

– Mantém a semântica de uma chamada local, para objectos distantes

– Efectua automaticamente o empacotamento e desempacotamento

dos parâmetros

– Envia as mensagens de pedido e resposta

– Faz o agulhamento para encontrar o objecto e o método pretendido

8/28/2003

José Alves Marques

Departamento de Engenharia Informática

Java RMI

• O RMI Java pressupõe que se utiliza um ambiente

Java de linguagem única, pelo que não se colocam

alguns dos problemas que o CORBA pretende

resolver.

• Apesar do ambiente uniforme um objecto tem

conhecimento que invoca um método remoto

porque tem de tratar RemoteExceptions

• A interface do objecto remoto por sua vez tem de

ser uma extensão da interface Remote

(12)

8/28/2003

José Alves Marques

Java RMI

• No Java RMI os parâmetros de um método assumem-se

como entradas (input) e o resultado do método como

parâmetro de saída (output)

• Quando o parâmetro é um objecto remoto (herda de

java.rmi.Remote)

– é sempre passado como uma referência para um objecto remoto

• Quando o parâmetro é um objecto local (caso contrário)

– é serializado e passado por valor. Quando um objecto é passado

por valor uma nova instância é criada remotamente

– Tem de implementar java.io.Serializable

– Todos os tipos primitivos e objectos remotos são serializáveis.

(java.rmi.Remote descende de java.io.Serializable)

Departamento de Engenharia Informática

Java RMI

• Quando um objecto pode ocorrer que o receptor não tenha

a classe respectiva. Por exemplo?

• Problema: Como “des-serializar” o objecto?

• Solução: quando um objecto é serializado, é enviado

(juntamente com a informação sobre a sua classe) a

localização da classe (URL) de onde é feito o seu

carregamento dinâmico.

(13)

8/28/2003

José Alves Marques

import java.rmi*;

import java.util.Vector;

public interface Shape extends

Remote {

int getVersion() throws

RemoteException;

GraphicalObject getAllState() throws

RemoteException;

}

public interface ShapeList extends

Remote {

Shape newShape(GraphicalObject g) throws RemoteException;

Vector allShapes() throws

RemoteException;

int getVersion() throws

RemoteException;

}

Remote interfaces de Shape e ShapeList

8/28/2003

José Alves Marques

Departamento de Engenharia Informática

JNDI

Java Naming and Directory Interface

• Mecanismo de nomes do J2EE

• Utilizado para associar nomes a recursos e

objectos de forma portável

– Identificação, localização, partilha

• Mapeia nomes em referências para objectos

• Uma instância do registry deve executar-se em

todos servidores que têm objectos remotos.

• Os clientes têm de dirigir as suas pesquisas para o

servidor pretendido

(14)

8/28/2003

José Alves Marques

Funções do registry

void rebind (String name, Remote obj)

– Usado pelos servidores para registar a associação entre o objecto e o seu nome.

void bind (String name, Remote obj)

– Igual ao anterior mas lança excepção se já existe a associação.

void unbind (String name, remote obj)

– Retira uma associação existente.

Remote lookup (String name)

– Usado pelos clientes para localizar um objecto remoto pelo seu nome. Retorna a

referência para o objecto remoto.

String [ ] list ( )

– Retorna um vector de strings com os nomes presentes no registry.

Departamento de Engenharia Informática

import java.rmi.*;

public class ShapeListServer{

public static void main(String args[]){

System.setSecurityManager(new RMISecurityManager());

try{

ShapeList aShapeList = new ShapeListServant();

Naming.rebind(“ShapeList”, aShapeList );

System.out.println(“ShapeList server ready” );

}catch(Exception e) {System.out.println(“ShapeList

server main” + e.getMessage());}

}

}

classe ShapeListServer com o método main

Criar um gestor de segurança

para evitar problemas com classes

que são carregadas a partir de

outros sites.

(15)

8/28/2003

José Alves Marques

Implementação do Servidor em Java

• A implementação dos métodos da interface remota é uma

classe “servant”

• No exemplo seguinte o método newShape pode ser

chamado uma factory porque permite ao cliente criar

objectos remotos.

8/28/2003

José Alves Marques

Departamento de Engenharia Informática

import java.rmi.*;

import java.rmi.server.UnicastRemoteObject;

Import java.util.Vector;

public class ShapeListServant extends UnicastRemoteObject implements ShapeList {

private Vector theList; //contains the list of Shapes private

int version;

public ShapeListServant()throws

RemoteException{...}

public Shape newShape(GraphicalObject g) throws

RemoteException {

version++;

Shape s = new ShapeServant( g, version);

theList.addElement(s);

return s;

}

public Vector allShape()throws RemoteException{...}

public int getVersion() throws RemoteException{...}

}

Classe ShapeListServant implementa a interface

ShapeList

(16)

8/28/2003

José Alves Marques

import java.rmi.*;

import java.rmi.server.*;

import java.util.Vector;

public class ShapeListClient{

public static void main(String args[]){

System.setSecurityManager(new RMISecurityManager());

ShapeList aShapeList = null;

try{

aShapeList = (ShapeList)

Naming.lookup(“//host/ShapeList”);

Vector sList = aShapeList.allShapes();

}catch(RemoteException e) {System.out.println(e.getMessage());

}catch(Exception e){System.out.println(“Client:”+e.getMessage());}

}

}

Cliente da classe ShapeList

Departamento de Engenharia Informática

Java RMI – mecanismo de Reflexão

• A reflexão é usada para passar informação nas mensagens

de invocação sobre o método que se pretende executar

• API de reflexão permite, em run-time:

– Determinar a classe de um objecto.

– Obter informação sobre os métodos / campos de uma classe /

interface

– Criar uma instância de uma classe cujo nome é desconhecido antes

da execução

(17)

8/28/2003

José Alves Marques

Reflexão no RMI – como usar

• Visão de 10,000 pés:

– Obter instâncias das classes genéricas “Class” e “Method”

– Cada instância de Method representa as características de um

método (classe, tipo dos argumentos, valor de retorno, e

excepções)

– Invocar métodos remotos com o método “invoke” da classe

“Method”. Requer dois parâmetros:

• O primeiro é o objecto a invocar

• O segundo é um vector de Object contendo os argumentos

• Mais detalhes em

http://java.sun.com/docs/books/tutorial/reflect/

8/28/2003

José Alves Marques

Departamento de Engenharia Informática

Contexto: J2EE

• Até agora vimos arquitecturas cliente-servidor

– Simples, mas…

– difícil de fazer evoluções

– difícil de reutilizar a lógica de negócio ou de

apresentação

• J2EE é uma plataforma para desenvolver e

executar aplicações distribuídas multi-nível

(18)

8/28/2003

José Alves Marques

Páginas HTML dinâmicas

Páginas JSP

Enterprise Beans

Base de Dados

Aplicação J2EE Multi-nível

Cliente

Servidor

J2EE

Servidor de

Base de Dados

Camada cliente

Camada Web

Camada de negócio

Camada EIS

Departamento de Engenharia Informática

Tecnologias Principais do J2EE

• Servlets

• Java Server Pages (JSP)

• Enterprise Java Beans (EJB)

• Java Database Connectivity (JDBC)

• Remote Method Invocations (RMI)

• XML

(19)

8/28/2003

José Alves Marques

Arquitectura J2EE

8/28/2003

José Alves Marques

(20)

8/28/2003

José Alves Marques

.NET Remoting

• Equivalente ao RMI para C# / Plataforma .NET

• Semelhante ao RMI. Vamo-nos concentrar nas novas

opções fornecidas

Departamento de Engenharia Informática

Objectos Remotos

• Qualquer objecto pode ser usado remotamente derivando-o de

MarshalByRefObject ou de MarshalByValObject

• MarshallByValue

– Objectos serializáveis, são copiados para o cliente

– Pode ser muito ineficiente

• MarshallByRef

– Quando o cliente recebe uma referência de um objecto remoto ele está

efectivamente a receber uma referência a um objecto proxy local criado

automaticamente pelo .NET Remoting.

– Esse proxy é encarregue de passar as chamadas dos métodos para o

servidor.

(21)

8/28/2003

José Alves Marques

Utilização de Objectos Remotos

• Requer a respectiva activação

• Dois modos:

• Singleton

– Apenas uma instância em cada instante

– Criada aquando da primeira invocação

– Requer sincronização no acesso a estado partilhado

• SingleCall

– Uma nova instância é criada para cada pedido.

– Após a execução de uma chamada, a próxima chamada será

servida por outra instância.

8/28/2003

José Alves Marques

Departamento de Engenharia Informática

Tempo de Vida dos Objectos

• Tempo de vida dos objectos Singleton

determinado por sistema de leases.

– Ao expirar um lease, este deve ser renovado, caso

contrário a memória ocupada pelo objecto é recuperada

pelo garbage collector.

– Java RMI escolheu solução mais complexa: contagem

de referência distribuída. Problema: falhas na rede e nos

servidores?

(22)

8/28/2003

José Alves Marques

Canais

A comunicação entre dois processos

distintos é realizada através de canais,

cuja função é:

– Empacotar a informação de acordo com

um tipo de protocolo

– Enviar esse pacote a outro computador.

Dois tipos pré-definidos:

– TcpChannel (que envia os dados por TCP

em formato binário).

– HttpChannel (que utiliza o protocolo

HTTP em formato XML).

Maior flexibilidade do que no RMI na

escolha dos mecanismos de serialização

e protocolos de transmissão

Departamento de Engenharia Informática

Resumo das Opções

• MarshallByRef vs. MarshallByValue

• Canais – TcpChannel vs. HttpChannel vs. Custom

• Activação – Singleton vs. Single Call

(23)

8/28/2003

José Alves Marques

Exemplo: Interface

public interface i_ola {

string MetodoOla();

}

8/28/2003

José Alves Marques

Departamento de Engenharia Informática

Exemplo: Servidor

class ser {

static void Main() {

TcpChannel chan1 = new TcpChannel(8086);

ChannelServices.RegisterChannel(chan1);

RemotingConfiguration.RegisterWellKnownServiceType(typeof(c_ola),

“Ola", WellKnownObjectMode.Singleton);

System.Console.WriteLine("<enter> para sair...");

System.Console.ReadLine();

}

}

public class c_ola : MarshalByRefObject, i_ola

{

public string MetodoOla() {

return “ola!”;

}

(24)

8/28/2003

José Alves Marques

Exemplo: Cliente

class cl {

static void Main() {

TcpChannel chan = new TcpChannel();

ChannelServices.RegisterChannel(chan);

i_ola obj = (i_ola) Activator.GetObject(typeof(i_ola),

"tcp://localhost:8086/Ola");

if (obj == null)

System.Console.WriteLine("Could not locate server");

else

Console.WriteLine(obj.MetodoOla());

}

}

Departamento de Engenharia Informática

Comparação – IDL

package SimpleStocks; import java.rmi.*; import java.util.*;

public interface StockMarket

extends java.rmi.Remote {

float get_price( String symbol ) throws RemoteException; } module SimpleStocks { interface StockMarket {

float get_price( in string symbol ); }; }; using System; namespace SimpleStocks {

public interface StockMarket { float get_price(string symbol); }

Java/RMI -Interface definition CORBA -IDL

(25)

8/28/2003

José Alves Marques

// // StockMarketClient // // importjava.rmi.*; import java.rmi.registry.*; import SimpleStocks.*; public classStockMarketClient

{

public static void main(String[] args)throws Exception { if(System.getSecurityManager() == null) { System.setSecurityManager(new RMISecurityManager()); } StockMarket market = (StockMarket)Naming.lookup("rmi://local host/NASDAQ");

System.out.println( "The price of MY COMPANY is "

+ market.get_price("MY_COMPANY") ); } } // // StockMarketClient // // importorg.omg.CORBA.*; import org.omg.CosNaming.*; import SimpleStocks.*; public classStockMarketClient

{

public static void main(String[] args)

{ try {

ORB orb = ORB.init(); NamingContext root = NamingContextHelper.narrow( orb.resolve_initial_references("NameS ervice") );

NameComponent[] name = new NameComponent[1] ; name[0] = new NameComponent("NASDAQ",""); StockMarket market = StockMarketHelper.narrow(root.resolve (name)); System.out.println("Price of MY COMPANY is " +

market.get_price("MY_COMPANY")); } catch( SystemException e ) { System.err.println( e ); } } } // // StockMarketClient // // namespace SimpleStocks {

public classStockMarketClient

{

static void Main() { try { StockMarket market = (StockMarket)Activator.GetObject( typeof(StockMarket), “tcp://localhost:8086/NASDAQ”); System.Console.WriteLine("The price of MY COMPANY is " +

market.get_price("MY_COMPANY") ); }

}

8/28/2003

José Alves Marques

Departamento de Engenharia Informática

// // // StockMarketServer // // package SimpleStocks; import java.rmi.*; import java.rmi.server.UnicastRemoteObject; public class StockMarketImplextends UnicastRemoteObjectimplements StockMarket

{

public float get_price( String symbol )

{

float price = 0;

for( int i = 0; i < symbol.length(); i++ )

{

price += (int) symbol.charAt( i ); }

price /= 5; return price; }

public StockMarketImpl( String name ) throws RemoteException

{ try {

Naming.rebind( name, this );

} catch( Exception e ) { System.out.println( e ); } } } // // // StockMarketServer // // import org.omg.CORBA.*; import SimpleStocks.*;

public class StockMarketImpl extends _StockMarketImplBase

{

public float get_price( String symbol ) { float price = 0; for(int i = 0; i < symbol.length(); i++) {

price += (int) symbol.charAt( i ); }

price /= 5; return price; }

public StockMarketImpl( String name ) { super( name ); } } // // // StockMarketServer // // using System.Runtime.Remoting;

public class StockMarketImpl : MarshalByRefObject, SimpleStocks.StockMarket

{

public float get_price( string symbol )

{

float price = 0;

for( int i = 0; i < symbol.length(); i++ )

{

price += (int) symbol.charAt(i); }

price /= 5; return price; }

}

Java/RMI - Server implementation CORBA - Server implementation

(26)

8/28/2003

José Alves Marques

// // StockMarketServer Main // // using System.Runtime.Remoting; class StockMarketServer {

static void Main(string[] args) {

TcpChannel chan1 = new TcpChannel(8086); ChannelServices.RegisterChannel (chan1); RemotingConfiguration.RegisterWel lKnownServiceType(typeof(StockMar ket),“NASDAQ",WellKnownObjectMode .Singleton); System.Console.WriteLine("<enter> para sair..."); System.Console.ReadLine(); } } // // StockMarketServer Main // // importjava.rmi.*; import java.rmi.server.UnicastRemoteObject; import SimpleStocks.*;

public class StockMarketServer {

public static voidmain(String[] args) throws Exception { if(System.getSecurityManager() == null) { System.setSecurityManager(new RMISecurityManager()); }

StockMarketImpl stockMarketImpl = new StockMarketImpl("NASDAQ"); } } // // StockMarketServer Main // // importorg.omg.CORBA.*; import org.omg.CosNaming.*; import SimpleStocks.*; public class StockMarketServer {

public static voidmain(String[] args) {

try {

ORB orb = ORB.init(); BOA boa = orb.BOA_init();

StockMarketImpl stockMarketImpl = new StockMarketImpl("NASDAQ"); boa.obj_is_ready( stockMarketImpl ); org.omg.CORBA.Object object = orb.resolve_initial_references("NameSer vice"); NamingContext root = NamingContextHelper.narrow( object ) ; NameComponent[] name = new

NameComponent[1];

name[0] = new NameComponent("NASDAQ", ""); root.rebind(name, stockMarketImpl); boa.impl_is_ready(); } catch( Exception e ) { e.printStackTrace(); } } }

Referências

Documentos relacionados

Enquanto componente da formação geral de todos os cursos científico-humanísticos do ensino secundário, a disciplina de Filosofia deve ser considerada uma atividade

Através do menu Interface de Segurança I/O, você também pode acessar a Interface de Segurança USB para bloquear ou desbloquear portas e dispositivosa. NOTA: Definindo a USB

Tal aumento na velocidade de liberação pode ser devido a dois fatores: (1) a presença da argila hidrofílica aumenta também a hidrofila de todo o material, o

O Programa das Sextas Acadêmicas compõem componentes curriculares e extracurriculares como cursos online para o desenvolvimento das compe- tências pessoais e profissionais (CPPs

De acordo com a Resolução Normativa 279, publicada pela Agência Nacional de Saúde Suple-mentar (ANS) em 25/11/2011, com vigência a partir de 01 de junho de 2012, que

A Resolução 3.427 em seu artigo terceiro determina que as Instituições Financeiras devem manter estrutura de governança compatível com o seu porte, a natureza

ÓRGÃOS COLEGIADOS ÓRGÃOS COLEGIADOS Secretaria-Executiva Secretaria-Executiva do Conselho Nacional de Saúde Gabinete do Ministro Consultoria Jurídica Consultoria Jurídica Secretaria

&amp; Barros Filho, T.E.P.: Osteoma osteóide vertebral: localização topográfica pela tomografia axial computadorizada. &amp; Barros Filho, T.E.P.: Osteoma osteóide