Leasing

Traduzindo literalmente Leasing é um empréstimo, mas como veremos ainda neste post, não é somente isso que esse conceito contempla no Jini.

Segundo o livro, essa é uma maneira do componente registrar que estão vivos e garantir caso eles sejam classificados como “time-out”ou até mesmo inacessíveis. Leasing também é a maneira dos mecanismos acessarem recursos em um determinado período de tempo.

Portanto podemos dizer que Leasing é sempre um pedido que pode ser realizado por um período de tempo, como funciona com o lookup service por exemplo.

O serviço pode requisitar o tempo que necessita através do metodo register(), inserindo o quanto deseja ou utilizando esses dois especiais valores


Lease.ANY // O serviço deixa o lookup service decidir o tempo
Lease.FOREVER // A requisição nunca expira.

Para cancelar o empréstimo, utiliza

 .cancel();

Caso o empréstimo acabe e seja necessário renovar, utilize

.renew()

 

O capítulo é bem mais completo do que narrei acima, mas para o meu uso por enquanto isso é suficiente.

A busca do cliente

Agora partirei da idéia que o cliente já encontrou um lookup service e necessita agora encontrar um serviço.

Imagine que o cliente já possua um objeto ServiceRegistrar que recebeu do lookup service. Ele irá utilizar esse objeto para realizar a sua busca, através do método

 lookup()


public Class ServiceRegistrar {
public java.lang.Object lookup(ServiceTemplate tmpl)throw java.rmi.RemoteException;
public ServiceMatches lookup(ServiceTemplate tmpl,int maxMatches)throws java.rmi.RemoteException;
}

Esses métodos usam a casse ServiceTemplate para especificar o serviço que ela está procurando, como abaixo:

package net.jini.core.lookup;
public Class ServiceTemplate {
	public ServiceID serviceID;
	public java.lang.Class[] serviceTypes;
	public Entry[] attributeSetTemplates;
	ServiceTemplate(ServiceID serviceID,
		java.lang.Class[] serviceTypes,
		Entry[] attrSetTemplates);
}

Se não conhecido o ID do seerviço, deve ser setado como nulo.

O atributo attributeSetTemplates é um conjunto de entradas usado para chocar os atributos.

O atributo de lookup() é um template e isso é um pouco complexo de entender, vamos por partes.

A classe que oriunda o serviço, como por exemplo Imprimir, Lavar, Secar, todas as que você possa imaginar, descrevem o que o serviço deve ter. Quem implementar essa classe, como por exemplo ImpressoraColorida, ImpressoraLaser, entre outrar, é que dizem como se faz a impressão. para que o cliente encontre a qual ele deseja, é necessário criar uma classe:


Class[] impressoraClasses = new Class[1];
impressoraClasses = Imprimir.class;

ServiceTemplate template = new ServiceTemplate(null, impressoraClasses, null);

Esse atributo sera utilizado para a criação de um template e passado para o lookup:


Imprimir imp = null;
imp = (Imprimir) registrar.lookup(template) ;

O objeto que imp receber será o objeto do serviço ao qual ele procura.

Existem ainda mais alguns detalhes de como o cliente escolhe o serviço, mas por hora isso já é suficiente.

Registro de Serviço

O próximo tópico do livro aborda como o registro do serviço é feito e como ele fica disponível para os clientes.

ServiceRegistrar:

Uma classe já falada antes mas que agora irá ser abordada de maneira mais completa. Seu objeto é retornado pelo lookup service para que ela sirva de proxy. Isso é feito com o famoso método .register().

Esse método necessita de um parametro que é na verdade um objeto da classe ServiceIntem, e esse objeto tem que ser visto de maneira mais completa:

ServiceItem:

Essa classe apresenta um atributo chamado serviceID que de inicio é setado como NULL. Quando o lookup service entrar em ação ele passara para esse atributo um valor não nulo. Esse valor é usado como um identificador único do serviço.

Outro atributo importante é o service, que é o objeto que está sendo registrado naquele momento. Esse objeto será serializado e enviado para o servidor de serviços para ser armazenado e quando o cliente requisitar ele será enviado.

ServiceRegistration

É um objeto criado pelo lookup service que é retornado e executado no servidor de serviços. Ele é um proxy que mantém a informação do estado do serviço para o lookup service.

Ele pode ser utilizado para  atualizar os valores do objeto ServiceItem já instanciado:


void addAttributes(Entry[] attrSets);
void modifyAttributes(Entry[] attrSetTemplates, Entry[] attrSets);
void setAttributes(Entry[] attrSets);

 

Informações sobre o Objeto

Agora irei abordar o tópico do livro chamado Entry Objects. Verei bem por cima nesse momento pois não é essencial para o trabalho agora mas mesmo assim é bom saber a idéia.

Ele trata sobre as informações adicionais sobre um serviço que o cliente necessita ter para saber se é aquele serviço que ele necessita. 

Quando um serviço é registrado, o lookup service recebe uma copia do objeto que o serviço oferece e o servidor pode optar por armazenar junto uma serie de atributos sobre o serviço.

Para isso existe a classe Entry, que habilita ao serviço informar suas capacidades.  Para isso crie uma classe que implementa essa classe e descreva nela os métodos que o seu serviço oferece. Como o exemplo do livro:


public Class FileType implements Entry {
public String type; // this is a MIME type
public FileType(String type) {
this.type = type;
}
}

Por enquanto é isso, quando necessário irei aumentar esse post.

MulticastRegister e ServiceRegistrar

O construtor do LookupDiscovery inicia threads para poder “escutar” as respostas da rede. Quando uma resposta chega o listener da thread irá chama o método discovered() da classe MulticastRegister.

Essa classe necessita ser compilada com 2 principais bibliotecas: jsk-plataform.jar e jsk-lib.jar.

Ela é função bem simples de ser entendida, vamos então ver a classe abstrata ServiceRegistrar

ServiceRegistrar

Essa classe é implementada por todos os LookupsServices e seu papel é agir como um proxy para os lookups services. Esse proxy roda na aplicação, seja ela cliente ou serviço.

Essa classe tem 2 principais métodos:

register(): utilizada por um serviço que deseja registrar

lookup(): utilizado por um cliente para procurar um serviço em particular.

Existem outros métodos que nos fornecem informações bem interessantes:


String[] getGroups();
LookupLocator getLocator();
ServiceID getServiceID();
registrar.getLocator().getHost();

Servidores e clientes necessitam encontrar lookup services! Descoberto o lookup service é hora de escolher um protocolo de conexão: Unicast ou Multicast. Unicast é sincrono e Multicast não, sendo que este ultimo necessita de um listener para responder. Quando um service locator é descoberto, isso envia um objeto ServiceRegistrar que pode tanto rodar no cliente ou no serviço. O maior uso do ServiceRegistrar é a função de registrar serviços e ajudar os clientes a encontrar esses serviços.

Multicast Discovery – Cont.

No ultimo post foi abordado por ultimo a classe DiscoveryListener e para continuar os tópicos do livro, agora será visto como tratar as conexões.

DiscoveryEvent

Essa classe possui um metodo muito importante: getRegistrars.  Esse metodo retorna a classe ServiceRegistrar. Essa classe funciona como o objeto retornado no metodo Unicast quando ele requisita um lookup service.

Esse processo é um pouco complexo de entender, então vamos revisar desde o começo da aplicação:

  1. Multicast requisita uma nova conexão para o LookupDiscovey
  2. Este retorna um objeto dizendo que ocorreu a descoberta
  3. O Multicast requisita um DiscoveryListener, para que possa ver os eventos.
  4. Quando um evento ocorre, o LookupDiscovery retorna.
  5. O multicast utiliza o metodo getResistrars e obtem do DiscoveryEvent o objeto que tratamos acima.

Veja que é uma sequencia bem lógica e pode ser visualizada facilmente.

Este é o fim do construtor do DiscoveryListener. A partir desse momento iremos analizar o metodo

main()

e como fazer para que o serviço se mantenha ativo e “vivo”

Jini – Multicast(Broadcast) Discovery

Se não sabemos onde o serviço estará disponível é necessário um serviço “broadcast”. Esse método não deve ser usado em pequenas redes ou redes domésticas, para isso é muito mais simples utilizar o Unicast Discovery. Se for uma rede grande, como por exemplo de uma universidade ou de uma empresa, se faz necessário o uso de um método mais avançado.

Muitos lookups services podem estar disponíveis em uma rede, por isso necessitamos de algumas particularidades, tratadas abaixo:

Grupos:

Define um conjunto de clientes que podem fazer parte de um serviço lookup, restringindo o acesso.

Um serviço pode conter uma lista de grupos aos quais ele pertence, um simples vetor de string pode ser feito:


String [] grupos = {"Grupo 01"};

Essa String é utilizada na como parametro para o construtor da classe LookupDiscovery:


LookupDiscovery(java.lang.String[] groups)

Perceba que não é a mesma classe utilizada no Unicast, que era LookupLocator.

DiscoveryListener

Para ser notificada quando encontra um lookup service, é necessário a presença de um Listener na aplicação, neste caso é realizado pela classe DiscoveryListener.

Essa classe possui 2 importantes métodos:


public abstract interface DiscoveryListener {
public void discovered(DiscoveryEvent e);
public void discarded(DiscoveryEvent e);
}

O primeiro é utilizado quando um serviço for descoberto e o outro para quando o serviço requisitar ou simplesmente sair da conexão.

{Por enquanto eu paro por aqui, amanha terminarei essa parte sobre o Multicast, atualizando este post}

Jini – Unicast Discovery

Pode ser usado quando se conhece a máquina na qual o lookup service reside. Para conectar ao lookup service é necessário o uso do método getRegister da classe LookupLocator, de uma forma bem simples.

Um code-example extraido do livro que já mensionei em posts anteriores:

package net.jini.core.discovery;
public class LookupLocator {
    LookupLocator(java.lang.String url) throws
        java.net.MalformedURLException;
    LookupLocator(java.lang.String host,int port);
}

Para o primeiro construtor a URL deve ser da forma jini://host/ ou jini://host:port e no segundo construtor deve ser separado em argumentos.

Existem dois métodos muito interessantes no LookupLocator, são eles:


String getHost();

int getPort();

No LookupLocator existe o método que eu considero mais trabalhoso de se entender: getRegistrar.

As buscas são realisadas por esse método que sempre retorna um objeto da classe ServiceRegistrar.

Essa classe é bem completa e eu ainda não vi tudo o que ela tem a oferecer, mas o que é simples de ver é que ela realiza uma busca na rede por um lookup service, rede esta informada no construtor do LookupLocator.

Existe mais um code-example no livro, que eu achei muito simples e interessante, percebam que ele instância as 2 classes, lookuplocator e serviceregistrar, depois cria um lookuplocator com o parametro da rede e esse objeto que invoca o método .getRegistrar e joga o objeto dentro da classe serviceregistrar para que essa agora possua as informações sobre o lookupservice.


package basic;
import net.jini.core.discovery.LookupLocator;
import net.jini.core.lookup.ServiceRegistrar;
import java.rmi.RMISecurityManager;
/**
* UnicastRegistrar.java
*/
public class UnicastRegister {
	static public void main(String argv[]) {
		new UnicastRegister();
		}
		public UnicastRegister() {
		LookupLocator lookup = null;
		ServiceRegistrar registrar = null;
		System.setSecurityManager(new RMISecurityManager());
		try {
		lookup = new LookupLocator("jini://localhost");
		} catch(java.net.MalformedURLException e) {
		System.err.println("Lookup failed: " + e.toString());
		System.exit(1);
		CHAPTER 4 ¦ DISCOVERING A LOOKUP SERVICE 41
		}
		try {
		registrar = lookup.getRegistrar();
		} catch (java.io.IOException e) {
		System.err.println("Registrar search failed: " + e.toString());
		System.exit(1);
		} catch (java.lang.ClassNotFoundException e) {
		System.err.println("Registrar search failed: " + e.toString());
		System.exit(1);
		}
		System.out.println("Registrar found");
		// the code takes separate routes from here for client or service
	}
} // UnicastRegister

A primeira vista é um pouco complicado e eu ainda não devo ter explicado da melhor maneira, mas conforme eu for me aperfeiçoando no sistema eu vou melhorando esse post.

Com isso eu termino o meu resumo sobre o unicast discovery, muito interessante para um uso mais específico, que não é o caso do meu TCC, portanto o próximo item a ser analizado é o multicast discovery.

Lookup Service no Jini

Como eu estou refazendo umas partes do meu trabalho, estou acompanhando os capítulos do livo Jini4Programmer, como tinha comentado anteriormente.

O capítulo que estou vendo agora é sovre o serviço de busa do Jini, o chamado Lookup Service.

O lookup service serve basicamente para que os clientes e os serviços sejam encontrados e encotrem o que procuram.

O que o servidor e o cliente devem fazer como primeira tarefa é descobrir um lookup service. Essa busca pode ser feita Unicast ou Multicast , cada um com a sua particularidade.

Unicast basicamente é quando já se sabe o endereço do lookup service e podemos nos conectar a ele diretamente e Multicast é usado quando não sabemos o endereço do servidor e temos que “enviar uma mensagem na rede” para que algum lookup service possa escutar e “responder”.

Lookup service não é nada mais do que um serviço Jini especializado em armanezar e passar para os clientes os serviços que eles procuram.

Pelo padrão Jini existem um serviço chamado reggie , o qual é responsável pelo serviço de Lookup service.

Em outro post irei abordar mais detalhadamente o serviço de Unicast e o Multicast. No meu TCC irei usar o Multicast.

Como que os serviços se comunicam com o Lookup Service

Bom pessoal, eu estava com uma certa dificuldade em entender o procedimento para registro e utilização de um serviço e esta etapa eu acho essencial para o desenvolvimento da aplicação, por isso irei mostrar aqui como o processo funciona. Imagens extraidas do livro Jini4Programmer do Jim:

Aqui um serviço está requisitando ao lookup service para que fique disponível na rede e depois como que um cliente requer um serviço, se comunicando com o lookup servive:

Este slideshow necessita de JavaScript.

Seguir

Get every new post delivered to your Inbox.