agentes moveis - aspectos de desenvolvimento

38
Agentes Móveis Aspectos de Desenvolvimento Componentes Componentes : Luiz Matos, Marcelo Almeida, Margarete Sá Salvador, 2007 Universidade Federal da Bahia Especialização em Sistemas Distribuídos Computação Móvel

Upload: luiz-matos

Post on 13-Jun-2015

1.794 views

Category:

Technology


2 download

DESCRIPTION

Seminário apresentado na disciplina de Computação Móvel.Introdução a Agentes Móveis, Aglets, Exemplos.

TRANSCRIPT

Page 1: Agentes Moveis - Aspectos De  Desenvolvimento

Agentes Móveis

Aspectos de Desenvolvimento

ComponentesComponentes: Luiz Matos, Marcelo Almeida, Margarete Sá

Salvador, 2007

Universidade Federal da Bahia

Especialização em Sistemas Distribuídos

Computação Móvel

Page 2: Agentes Moveis - Aspectos De  Desenvolvimento

2

Organização do estudo

Introdução a Agentes Móveis Princípios básicos Quando usar Porque usar Aspectos de segurança

Desenvolvimento de Agentes Móveis Agentes Móveis baseados em Java Frameworks e Aplicações existentes Aglets: uma visão geral Demonstração: Desenvolvendo um agente móvel com Aglets

Considerações Finais

Referências

Page 3: Agentes Moveis - Aspectos De  Desenvolvimento

3

Introdução a Agentes Móveis Princípios básicos Quando usar Porque usar Aspectos de segurança

Page 4: Agentes Moveis - Aspectos De  Desenvolvimento

4

Princípios básicos

Crescimento das redes de informação; Desenvolvimento de aplicações distribuídas; Remote Procedure Calling (RPC); Remote Method Invocation (RMI);

Figura 1. Funcionamento RPC (WHITE, 1996)

1. Permite que um computador chame procedimentos em outro.

2. Uma requisição inclui os argumentos do procedimento.

3. A resposta inclui os resultados.

Cada interação entre cliente e servidor consiste de duas conexões; A comunicação deve ser contínua.

Contextualização

Page 5: Agentes Moveis - Aspectos De  Desenvolvimento

5

A alternativa é permitir que um computador além de chamar procedimentos em outro, forneça os procedimentos a serem executados.

Figura 2. Funcionamento Agentes Móveis (WHITE, 1996)

A interação não requer uma comunicação contínua;

1. Um agente do cliente visita o servidor;

2. O agente possui procedimentos e argumentos;

3. O servidor o executa local-mente, podendo enviar seu próprio agente para outro computador.

Princípios básicos

Contextualização

Page 6: Agentes Moveis - Aspectos De  Desenvolvimento

6

É um programa em execução que passa de um computador para outro, realizando uma tarefa em nome de alguém e finalmente retornando com os resultados obtidos a esse alguém. (COULOURIS e outros, 2007)

São programas de computador auto-contidos e identificáveis que podem se mover dentro da rede e agir em nome do usuário ou de uma outra entidade. (PHAM e KARMOUCH, 1998)

Princípios básicos

Definição

Agente

Interações Locais

Cliente

Interações de Rede

Figura 3. Representação Agentes Móveis

Carrega consigo:

– seu código;

– informação de estado de execução;

– estado dos dados;

Servidor

Page 7: Agentes Moveis - Aspectos De  Desenvolvimento

7

Agência: É o ambiente de execução dos agentes, dando suporte ao seu ciclo de vida – recebe, executa, envia, controla recursos, etc.

Places: Ambiente de execução específico de uma agência, que disponibiliza um conjunto de serviços (recursos). Uma agência pode ter vários places, dando um contexto ao agente.

Agents: Consiste de Código + Estado, tem atributos como identidade, localização, autoridade e permissões.

Travel: É a transferência de um agente de um lugar para outro, que só ocorre se o agente está autorizado a visitar o destino.

Princípios básicosConceitos

Figura 5. Representação Places (WHITE, 1996)

Figura 6. Representação Agents (WHITE, 1996)

Figura 7. Representação Travel (WHITE, 1996)

Agente

Serviços/Recursos

Figura 4. Representação Agência

Page 8: Agentes Moveis - Aspectos De  Desenvolvimento

8

Migração de Código

Modelos Mobilidade fraca – Quando ocorre a transferência de código e

dados para a Agência destino.

Mobilidade forte – O agente (código, dados e estado de execução) é transportado para a Agência destino. Assim, a sua execução continua a partir da instrução seguinte àquela que causou a migração.

Razões para o uso Melhora no Desempenho

permitir a distribuição de tarefas a vários computadores eliminando o processamento centralizado.

Flexibilidade a divisão da aplicação em diferentes partes (por arquitetura

de multicamadas).

Princípios básicos

Page 9: Agentes Moveis - Aspectos De  Desenvolvimento

9

Quando usar Gerência de redes – monitoramento, filtragem e notificação;

Processamento paralelo – particionamento e alocação dinâmica de tarefas;

Comércio eletrônico – negociação, transação e busca;

Entretenimento – busca de informações, jogos em ambientes virtuais distribuídos, Etc..

Reduzir custos de comunicação;

Ganhar performance através da delegação de tarefas;

Reduzir a carga de rede e superar a latência de comunicação;

Descentralização do Processamento, Etc..

Porque usar

Page 10: Agentes Moveis - Aspectos De  Desenvolvimento

10

Dados armazenados nos computadores; Dados armazenados no agente; A integridade do agente; A não interrupção indevida do agente; A não personificação indevida do agente; A não utilização indevida de recursos computacionais.

Aspectos de segurança

O que devemos proteger*?

Compilar o código localmente; Verificar executáveis em ambientes controlados; Autenticação de usuários; Criar políticas de acesso a recursos; Criptografia e assinatura de mensagens.

Como podemos proteger*?

* Adaptado de Cunha (2005).

Page 11: Agentes Moveis - Aspectos De  Desenvolvimento

11

Representação das ameaças

Sistema de Agentes Móveis

Entidades Externas

Aspectos de segurança

1. ameaças do servidor contra o agente;2. ameaças do agente contra o servidor;3. ameaças do agente contra outro agente sendo executado no mesmo servidor; 4. outras ameaças contra o sistema de agentes.

Personificação, negação de serviço, alteração de dados ou código, acesso não autorizado, entre outros.

Figura 8. Ameaças em Agentes Móveis (UTO, 2003)

Page 12: Agentes Moveis - Aspectos De  Desenvolvimento

12

Desenvolvimento de Agentes Móveis Agentes Móveis baseados em Java Frameworks e Aplicações existentes Aglets: uma visão geral Demonstração: Desenvolvendo um agente

móvel com Aglets

Page 13: Agentes Moveis - Aspectos De  Desenvolvimento

13

Agentes móveis baseados em Java

A escolha da linguagem Java para o desenvolvimento de Agentes Móveis está fortemente relacionada às suas características de:

Portabilidade; Suporte a requisitos de rede; Mecanismos de serialização; etc

Page 14: Agentes Moveis - Aspectos De  Desenvolvimento

14

Em Java:

Aglets - IBM, Japão

Odyssey - General Magic, EUA

Voyager - ObjectSpace, EUA

Em outras linguagens:

Telescript - General Magic, EUA

D’Agents - Dartmouth College, Inglaterra

TACOMA - Universidade de Cornell, EUA

Frameworks e Aplicações existentes

Page 15: Agentes Moveis - Aspectos De  Desenvolvimento

15

Conceitos básicos

Plataforma de agentes móveis baseados na linguagem de programação Java;

Lançada em 1996, resultado de trabalhos desenvolvidos nos laboratórios da IBM do Japão;

Utilizam contexto-aglet (espaço de trabalho dos Aglets) onde os agentes são gerenciados;

Código aberto disponibilizado pela IBM em licença pública;

Aglet = AGent + appLET.

Aglets: uma visão geral

Page 16: Agentes Moveis - Aspectos De  Desenvolvimento

16

Aglet:

Autônomo por possuir sua própria thread de execução;

Objeto Java com capacidade de se deslocar por nodos da web;

Reativo pela capacidade de responder mensagens.

Proxy:

Representante local do Aglet;

Usado para proteger o acesso aos métodos públicos deste;

Provê transparência de localização (é um objeto estático enquanto que um Aglet é móvel).

Aglets: uma visão geral

Conceitos básicos

Page 17: Agentes Moveis - Aspectos De  Desenvolvimento

17

Contexto:

É o habitat do Aglet (agência), onde o mesmo não só vive como obtém informações sobre seu ambiente atual.

É um objeto estacionário que monitora os Aglets e mantém o ambiente seguro contra invasões.

Mensagem:

Objeto passado entre Aglets de forma síncrona ou assíncrona, usado para a colaboração entre eles.

Itinerário:

É o caminho que o Aglet tem que percorrer.

Identificador:

Identidade única do Aglet usado em toda a sua vida.

Aglets: uma visão geral

Conceitos básicos

Page 18: Agentes Moveis - Aspectos De  Desenvolvimento

18

O ato de mover/migrar um Aglet de um contexto para o outro é feito de forma ativa ou passiva.

Migração ativa: O próprio Aglet decide migrar o estado corrente de sua execução para um novo contexto através da operação dispatch;

Migração passiva: O contexto (agência) invoca o método retract para requisitar que o agente volte ao seu local de origem;

A migração de um Aglet é feita por mobilidade fraca utilizando serialização de classes.

Aglets: uma visão geral

Mobilidade

Page 19: Agentes Moveis - Aspectos De  Desenvolvimento

19

Aglets: uma visão geral

Ciclo de Vida

Figura 9. Ciclo de Vida de um Aglet (JUNG, [s.d.])

O Aglet toma seu lugar em um contexto, ganha seu identificador e é inicializado.

Um aglet nasce igual o pai exceto ID e estado.

Ação de despachar um Aglet de um contexto e inseri-lo em outro, onde este reiniciará sua execução.

Um Aglet, previamente despachado, é trazido de volta a um contexto e seu estado volta junto.

Um Aglet é retirado temporariamente de seu contexto e é colocado em um contexto secundário.

Um Aglet desativado pode ser reativado, voltando a executar apartir do seu estado no momento da esativação.

O Aglet é retirado de seu contexto e morre. Seu estado é perdido para sempre.

Page 20: Agentes Moveis - Aspectos De  Desenvolvimento

20

Modelo de programação baseado em eventos de callback manipulados através de tratadores denominados listeners;

Eventos atuam durante as várias fases do ciclo de vida do Aglet;

Programador utiliza tais eventos para ligar ações aos Aglets;

Listeners podem ser combinados para executar tarefas complexas;

Há três tipos de listeners:

CloneListener:

MobilityListener:

PersistenceListener:

Aglets: uma visão geral

Modelo de Eventos

Page 21: Agentes Moveis - Aspectos De  Desenvolvimento

21

CloneListener:

Gerencia os eventos associados à clonagem.

Métodos utilizados:

onCloning (logo antes da clonagem);

onClone (durante a clonagem);

onCloned (depois da clonagem).

Aglets: uma visão geral

Tipos de Listeners

Page 22: Agentes Moveis - Aspectos De  Desenvolvimento

22

MobilityListener:

Gerencia os eventos associados à mobilidade.

Métodos utilizados:

onDispatching (logo antes do despacho);

onReverting (logo antes da retratação);

onArrival (assim que o Aglet chega ao destino).

Aglets: uma visão geral

Tipos de Listeners

Page 23: Agentes Moveis - Aspectos De  Desenvolvimento

23

PersistenceListener:

Gerencia os eventos associados à persistência do Aglet no contexto.

Métodos utilizados:

onDeactivating (logo antes da desativação);

onActivation (logo depois da ativação);

Outros métodos utilizados:

onCreation e onArrival (métodos automaticamente acionados quando um Aglet chega ao contexto destino).

Aglets: uma visão geral

Tipos de Listeners

Page 24: Agentes Moveis - Aspectos De  Desenvolvimento

24

Baseado no paradigma de pedido/resposta (request/reply) entre máquinas.

Operações suportados pelo protocolo:

Aglets: uma visão geral

ATP – Agent Transfer Protocol

Figura 10. Operações do ATP (JUNG, [s.d.])

solicita a um sistema de agentes destino quereconstrua um agente a partir do conteúdo de uma requisição e inicie sua execução.

solicita a um sistema de agentes destino que envie de volta um determinado agente ao emissor.

solicita a um receptor que este recupere e envie alguma informação. Similar ao método GET do HTTP.

usado para transmitir uma mensagem a um agenteidentificado por um agent-id e retornar alguma resposta à ação.

Page 25: Agentes Moveis - Aspectos De  Desenvolvimento

25

Aglets não invocam métodos de outros diretamente;

Utilizam objetos AgletProxy, que agem como representantes do agente;

A classe AgletProxy utiliza métodos como dispatch(), clone(), deactivate() e dispose().

Aglets: uma visão geral

Interações entre Aglets

Figura 11. Relação entre Aglet e proxy

(JUNG, [s.d.])

Page 26: Agentes Moveis - Aspectos De  Desenvolvimento

26

Figura 12. Interface TAHITI

Aglet Server (TAHITI)

Demonstração: Desenvolvendo um agente móvel com Aglets

Cria um novo Aglet.

Exibe caixa de dialogo de um Aglet.

Traz informações sobre o Aglet selecionado.

Elimina um Aglet

Clona um Aglet

Envia um Aglet para um host destino

Traz de volta um Aglet enviado a outro host

Aglet em atividade.

- Demonstração da ferramenta

Page 27: Agentes Moveis - Aspectos De  Desenvolvimento

27

import com.ibm.aglet.*;

public class FirstAglet extends Aglet {

//Metodo run, executado no dispatching

public void run() {

String hello = “oi pessoal”;

System.out.println(hello + "!\n");

for(int i=0; i<3; i++) {

System.out.println(i);

}

System.out.println("Eu falei: " + hello.toUpperCase());

}

}; //Fim da classe FirstAglet

Exemplo 1 – Hello World MóvelDemonstração: Desenvolvendo um agente móvel com Aglets

Importar pacotes da API

Herdar a classe Aglet

Implementar método run()

Page 28: Agentes Moveis - Aspectos De  Desenvolvimento

28

Exemplo 2 – Tratando ListenersDemonstração: Desenvolvendo um agente móvel com Aglets

import com.ibm.aglet.*;import com.ibm.aglet.event.*;

public class MyListener implements MobilityListener, CloneListener, PersistencyListener {

/** * Metodos da interface MobilityListener */public void onArrival(MobilityEvent event) {

System.out.println("O Agente chegou: " + event);}

public void onDispatching(MobilityEvent event) {System.out.println("Antes de mover: " + event);

}

public void onReverting(MobilityEvent event) {System.out.println("Antes de voltar para meu lugar: " + event);

}

//Continua no próximo slide..

Importar pacotes da API

Implementar Interfaces

Implementar métodos

Page 29: Agentes Moveis - Aspectos De  Desenvolvimento

29

/* * Metodos da interface CloneListener */public void onClone(CloneEvent event) {

System.out.println("Eu sou o clone: " + event);}public void onCloned(CloneEvent event) {

System.out.println("Um clone de mim foi criado: " + event);}

public void onCloning(CloneEvent event) {System.out.println("Alguem esta me clonando: " + event);

}

/* * Metodos da interface PersistencyListener */public void onActivation(PersistencyEvent event) {

System.out.println("Ativando: " + event);}

public void onDeactivating(PersistencyEvent event) {System.out.println("Desativando: " + event);

}}; //Fim da classe MyListener

Demonstração: Desenvolvendo um agente móvel com Aglets

Implementar métodos

Implementar métodos

Page 30: Agentes Moveis - Aspectos De  Desenvolvimento

30

import com.ibm.aglet.*;import com.ibm.aglet.event.*;

public class MyListenerTest extends Aglet {public boolean move = true;

public void onCreation(Object init) {//cria um objeto listenerMyListener listener = new MyListener();

//registra um listener mobilitythis.addMobilityListener((MobilityListener)listener);

//registra um listener clonethis.addCloneListener((CloneListener)listener);

//registra um listener persistencythis.addPersistencyListener((PersistencyListener)listener);

}

public void run() {System.out.println("Ola pessoal!");

}}; //Fim da classe (Aglet) MyListenerTest

Demonstração: Desenvolvendo um agente móvel com Aglets

Exemplo 2 – Tratando ListenersImportar pacotes da API

Herdar a classe Aglet

Page 31: Agentes Moveis - Aspectos De  Desenvolvimento

31

Demonstração: Desenvolvendo um agente móvel com Aglets

Exemplo 3 – Tratando Proxys

import com.ibm.aglet.*;

public class ProxyInfoChild extends Aglet {

public void run() { print("Rodando..."); }

private void print(String s) { System.out.println(ProxyInfoExample.NAME + " (child): " + s);

}}; //Fim da classe (Aglet) ProxyInfoChild

Importar pacotes da API

Herdar a classe Aglet

Page 32: Agentes Moveis - Aspectos De  Desenvolvimento

32

import com.ibm.aglet.*;import java.util.Enumeration;import java.util.Date;

public class ProxyInfoExample extends Aglet { public void run() { print("STARTING --------------------"); try { print(“Criando o child..."); AgletProxy proxy = getAgletContext().createAglet(getCodeBase(), "examples.ProxyInfoChild", null); print(“Finalizando a criacao do child."); pause();

print(“Usando o proxy diretamente: "); print("Identificador: \'" + proxy.getAgletID() + "\'"); print("Code Base: \'" + "(Depreciated, using aglet.getCodeBase()) " + getCodeBase() + "\'"); print(“Nome da Classe: \'" + proxy.getAgletClassName() + "\'");

pause(); print("... E agora, as informacoes do objeto: ");

AgletInfo info = proxy.getAgletInfo(); print("Identificador: \'" + info.getAgletID() + "\'"); print("Code Base: \'" + info.getCodeBase() + "\'"); print(“Nome da Classe: \'" + info.getAgletClassName() + "\'"); print("Origem: \'" + info.getOrigin() + "\'"); print(“Endereco: \'" + info.getAddress() + "\'"); print(“Hora de Criacao: \'" + new Date(info.getCreationTime()) + "\'");

} //Continua no proximo slide..

Importar pacotes da API

Herdar a classe Aglet

Demonstração: Desenvolvendo um agente móvel com Aglets

Page 33: Agentes Moveis - Aspectos De  Desenvolvimento

33

catch (Exception e) { print(“Falha ao criar o child."); print(e.getMessage()); } }; //Fim do metodo run()

static public String NAME = "ProxyInfoExample";private void print(String s) {

System.out.println(NAME + " (parent): " + s); }

private static long SLEEP = 3000;private void pause() {

try { Thread.sleep(SLEEP); } catch (InterruptedException ie) { }

} //Fim do metodo pause}//Fim da classe ProxyInfoExample

Exemplo 3 – Tratando Proxys

Page 34: Agentes Moveis - Aspectos De  Desenvolvimento

34

Considerações finais

Dificuldades: escassez de conteúdo atualizado e carência na disponibilidade de aplicações.

Agentes Móveis possui uma rápida curva de aprendizado para o desenvolvedor Java.

Provê soluções pontuais, para problemas específicos. Sobreposição por tecnologias ‘da moda’.

Conclusões do Grupo

Desafios na área

Capacidade de controle de agentes; Segurança; Tolerância a falhas; Padrões de Projeto; Novas aplicabilidades.

Page 35: Agentes Moveis - Aspectos De  Desenvolvimento

35

Referências

AGLETS. The IBM Aglets Software Development Kit Version 2.02. Disponível em: <http://www.trl.ibm.com/aglets/>. Acesso em: 04 set. 2007.

BELLONI, Edgardo A. A Multi-paradigm Approach for Mobile Agents Development. Disponível em: <http://journal.info.unlp.edu.ar/Journal/journal4/papers/pap1.pdf>. Acesso em: 06 set. 2007.

CHESS, David; HARRISON, Colin; KERSHENBAUM, Aaron. Mobile Agents: are they a good idea? IBM Research Report, 1995. Disponível em: <http://citeseer.ist.psu.edu/chess95mobile.html>. Acesso em: 15 ago. 2007.

COULOURIS, George; DOLLIMORE, Jean; KINDBERG, Tim. Sistemas distribuídos: conceitos e projeto. 4. ed. Bookman, 2007.

CUNHA, Leonardo Godinho. Segurança em Códigos Móveis. Julho, 2005. Disponível em: <http://www-di.inf.puc-rio.br/~endler/semGSD/monografias/leonardo-godinho.pdf>. Acesso em: 02 set. 2007.

FERRARI, Luca. The Aglets 2.0.2 User’s Manual. Outubro, 2004. Disponível em: <http://aglets.sourceforge.net/>. Acesso em: 05 set. 2007.

FUGGETTA, Alfonso; PICCO, Gian Pietro; VIGNA, Giovanni Vigna. Understanding Code Mobility. IEEE Transactions on Software Engineering, Volume 24, No. 5, p. 342-361, Maio 1998.

JUNG, Galeno. Manual de Utilização do Aglets. Universidade Federal de Santa Catarina, Inteligência Artificial Aplicada à Controle e Automação. Apostila de aula, [s.d.]

LIMA, Emerson Ferreira de Araújo. Formalização e Análise de Padrões de Projeto para Agentes Móveis. Dissertação de Mestrado. Universidade Federal de Campina Grande, Coordenação de Pós-Graduação em Informática, Fevereiro de 2004. Disponível em: <http://copin.ufcg.edu.br/twiki-public/pub/COPIN/DissertacoesMestrado/DissertacaoEmersonFerreiraALima.pdf>. Acesso em: 06 set. 2007.

MAHMOUD, Qusay. Mobile Agents and Java: java is the ideal language for writing mobile agents. Disponível em: <http://www2.sys-con.com/itsg/virtualcd/Java/archives/0211/mahmoud/index.html>. Acesso em: 06 set. 2007.

Page 36: Agentes Moveis - Aspectos De  Desenvolvimento

36

MALUTA, Líliam C. Gaiotto. Aplicação em Computação Móvel para Monitoramento de Pacientes em UTI.Disponível em: <http://www.wirelessbrasil.org/wirelessbr/colaboradores/liliam_maluta/monitor_uti_01.html>. Acesso em: 05 set. 2007.

MENDES, Manuel de Jesus; SILVA, Flávio M. de Assis. Mobile Agents in Autonomous Decentralized Systems. IEEE Autonomous Decentralized Systems, 1999. Integration of Heterogeneous Systems. Proceedings.

MODAK, Vishal D.; LANGAN, David D.; HAIN, Thomas F. A Pattern-based Development Tool for Mobile Agents. ACM SIGCSE Bulletin, Volume 37, p. 72-75, Fev. 2005.

OBJECT Management Group. Agent Technology Green Paper. Agent Platform Special Interest Group, 2000. Disponível em: <http://www.objs.com/agent/agents_Green_Paper_v100.doc>. Acesso em: 06 set. 2007.

OYAMADA, Márcio Seiji; ITO, Sérgio Akira. Aglets: agentes móveis em java. Disponível em: <http://www.inf.ufrgs.br/procpar/disc/cmp134/trabs/T2/981/Aglets/aglets.html>. Acesso em: 05 set. 2007.

PHAM, Vu Anh; KARMOUCH, Ahmed. Mobile Software Agents: an overview. IEEE, 1998.Disponível em: <http://www.comsoc.org/ci/private/1998/jul/Karmouch.html>. Acesso em: 05 set. 2007.

UTO, Nelson. Segurança de Sistemas de Agentes Móveis. Dissertação de Mestrado. Universidade Estadual de Campinas, Instituto de Computação, Abril de 2003. Disponível em: <http://www.las.ic.unicamp.br/paulo/teses/trabalhos-relacionados/NelsonUto.pdf>. Acesso: 06 set. 2007.

Wayne A. Jansen. Countermeasures for Mobile Agent Security. Special Issue on Advanced Security Techniques for Network Protection, Elsevier Science BV, novembro de 2000. In: UTO, Nelson. Segurança de Sistemas de Agentes Móveis. Dissertação de Mestrado. Universidade Estadual de Campinas, Instituto de Computação, Abril de 2003. Disponível em: <http://www.las.ic.unicamp.br/paulo/teses/trabalhos- relacionados/NelsonUto.pdf>. Acesso em: 06 set. 2007.

WHITE, Jim. Mobile Agents White Paper. General Magic, 1996. Disponível em: <http://citeseer.ist.psu.edu/white96mobile.html>. Acesso em: 15 ago. 2007.

WONG, David; PACIOREK, Noemi; MOORE, Dana. Java-based Mobile Agents. Communications Of The Acm, v. 42, n. 3, p. 92-102, mar. 1999.

Referências

Page 37: Agentes Moveis - Aspectos De  Desenvolvimento

37

Figura 5. Representação Places (WHITE, 1996)

Figura 6. Representação Agents (WHITE, 1996)

Figura 7. Representação Travel (WHITE, 1996)

Page 38: Agentes Moveis - Aspectos De  Desenvolvimento

38