Individua i servizi con il servizio di ricerca Jini

Il servizio di ricerca Jini, il componente centrale dell'infrastruttura di runtime di Jini, offre ai client Jini un modo flessibile e potente per trovare i servizi Jini. Consente ai fornitori di servizi di pubblicizzare i propri servizi e consente ai clienti di individuare e ottenere l'aiuto di tali servizi.

Per interagire con il servizio di ricerca, il client deve prima ottenere un oggetto del registrar del servizio tramite discovery, un protocollo a livello di rete utilizzato dall'infrastruttura runtime di Jini. La discovery consente a client e servizi di individuare i servizi di ricerca. (Per ulteriori informazioni sul rilevamento, vedere Risorse.) L' service registraroggetto, che implementa l' net.jini.core.lookup.ServiceRegistrarinterfaccia, consente al client di interagire con il servizio di ricerca. Per trovare i servizi desiderati, i client creano a ServiceTemplate, un'istanza di classe net.jini.core.lookup.ServiceTemplate, e la passano a uno dei due lookup()metodi dichiarati ServiceRegistrarnell'interfaccia. Ogni lookup()metodo invia il modello di servizio al servizio di ricerca, che esegue la query e restituisce gli oggetti di servizio corrispondenti al client.

In generale, un client cerca un servizio per tipo Java, solitamente un'interfaccia. Ad esempio, se un client deve utilizzare una stampante, compone un modello di servizio che include un Classoggetto per un'interfaccia ben nota ai servizi di stampa. Tutti i servizi di stampa implementano l'interfaccia. Il servizio di ricerca restituisce uno o più oggetti servizio che implementano questa interfaccia. È possibile includere attributi nel modello di servizio per restringere il numero di corrispondenze per tale ricerca basata sul tipo. Il client utilizza il servizio stampante invocando sull'oggetto servizio i metodi dichiarati nella nota interfaccia.

La classe ServiceTemplate

Con la ServiceTemplateclasse è possibile esprimere i criteri di ricerca per le ricerche Jini. La classe consiste esclusivamente di questi tre campi pubblici:

public Entry [] attributeSetTemplates; public ServiceID serviceID; public Class [] serviceTypes;

ServiceTemplatenon ha metodi e le sue istanze servono semplicemente come contenitori simili a "strutture" per le query del servizio di ricerca. Le corrispondenze vengono eseguite come descritto dal seguente estratto dalla ServiceTemplatepagina javadoc di:

Gli elementi nel servizio di ricerca vengono abbinati utilizzando un'istanza di [ ServiceTemplate]. Un articolo di servizio ( item) corrisponde a un modello di servizio ( tmpl) se:

  • item.serviceIDè uguale a tmpl.serviceID(o se tmpl.serviceIDè null)
  • item.service [l'oggetto servizio] è un'istanza di ogni tipo in tmpl.serviceTypes
  • item.attributeSets contiene almeno una voce corrispondente per ogni modello di voce in tmpl.attributeSetTemplates

Una voce corrisponde a un modello di voce se la classe del modello è la stessa o una superclasse della classe della voce e ogni campo non nullo nel modello è uguale al campo corrispondente della voce. Ogni voce può essere utilizzata per abbinare più di un modello. Notare che in un modello di servizio, per serviceTypese attributeSetTemplates, un campo nullo è equivalente a un array vuoto; entrambi rappresentano un carattere jolly.

Come descritto qui, il modello di servizio può includere un riferimento a una matrice di Classoggetti. Questi oggetti indicano al servizio di ricerca il tipo (oi tipi) Java dell'oggetto servizio che il client desidera. Il modello di servizio può anche includere un ID servizio, che identifica un servizio in modo univoco, e attributi, che devono corrispondere esattamente agli attributi caricati dal fornitore di servizi nell'elemento di servizio. Il modello di servizio può anche contenere caratteri jolly per uno qualsiasi di questi campi. Un carattere jolly nel campo ID servizio, ad esempio, corrisponderà a qualsiasi ID servizio.

I metodi lookup ()

La ServiceRegistrar's lookup()metodi prendono due forme sovraccaricate. Le due forme differiscono principalmente per il numero di corrispondenze e articoli di servizio che ciascuna restituisce. Il modulo a due parametri può restituire più corrispondenze della query espressa in ServiceTemplate, mentre il modulo a un parametro restituisce solo una corrispondenza. Inoltre, il modulo a due parametri restituisce interi articoli di servizio; il modulo a un parametro restituisce solo l'oggetto servizio.

La forma a due parametri di lookup ()

Ecco un estratto di javadoc che spiega la forma a due parametri di lookup():

la ricerca pubblica di ServiceMatches (ServiceTemplate tmpl, int maxMatches) genera java.rmi.RemoteException; 

[It] restituisce, al massimo, gli maxMatcheselementi che corrispondono al modello, più il numero totale di elementi che corrispondono al modello. Il valore restituito non è mai nulle l'array degli elementi restituiti è solo nullse maxMatchesè zero. Per ogni articolo restituito, se l'oggetto servizio non può essere deserializzato, il campo servizio dell'elemento viene impostato su nulle non viene generata alcuna eccezione. Allo stesso modo, se un set di attributi non può essere deserializzato, quell'elemento attributeSetsdell'array viene impostato su nulle non viene generata alcuna eccezione.

Ecco la ServiceMatchesclasse:

pacchetto net.jini.core.lookup;

la classe pubblica ServiceMatches estende java.lang.Object implementa java.io.Serializable {

articoli di public ServiceItem []; public int totalMatches; }

Ed ecco la ServiceItemclasse:

pacchetto net.jini.core.lookup;

la classe pubblica ServiceMatches estende java.lang.Object implementa java.io.Serializable {

public Entry [] attributeSets; servizio pubblico java.lang.Object; public ServiceID serviceID; }

Come accennato in precedenza, ogni elemento itemsdell'array restituito dal modulo a due parametri è un articolo di servizio completo, che include l'oggetto servizio, l'ID servizio e tutti i set di attributi. Il maxMatchescampo aiuta i client a gestire il numero di oggetti restituiti da questo lookup().

La lunghezza itemsdell'array ServiceMatchesnell'oggetto restituito è minore o uguale al valore passato a lookup()in maxMatches. Il numero totale di elementi di servizio corrispondenti (restituiti totalMatches) è maggiore o uguale alla lunghezza della itemsmatrice.

Ad esempio, se maxMatchesè 50 e il modello di servizio corrisponde a 25 elementi, la lunghezza itemsdell'array restituito e il valore di totalMatchessono entrambi 25. In alternativa, se maxMatchesè 50 ma il modello di servizio corrisponde a 100 elementi, la lunghezza itemsdell'array restituito è 50 e il valore di totalMatchesè 100. Quando un modello di servizio corrisponde a più maxMatchesarticoli di servizio, gli articoli di servizio restituiti dai due parametri lookup()vengono selezionati casualmente dall'insieme completo di articoli di servizio corrispondenti.

La forma a un parametro di lookup ()

Il lookup()metodo a un parametro restituisce un oggetto servizio corrispondente scelto casualmente da tutte le corrispondenze. Ecco un estratto di javadoc che spiega questo modulo:

public Object lookup (ServiceTemplate tmpl) genera java.rmi.RemoteException; 
Restituisce l'oggetto servizio (cioè, solo ServiceItem.service) da un elemento che corrisponde al modello o nullse non c'è corrispondenza. Se più elementi corrispondono al modello, è arbitrario quale oggetto del servizio viene restituito. Se l'oggetto restituito non può essere deserializzato, UnmarshalExceptionviene generato un messaggio con la semantica RMI standard.

Poiché un parametro lookup()restituisce un solo oggetto servizio corrispondente, i client possono ridurre al minimo il numero di file di classe e di stato dell'oggetto scaricati. Ma poiché l'oggetto del servizio restituito viene selezionato arbitrariamente e non identificato da un ID di servizio o descritto da set di attributi associati, il client deve essere sicuro che qualsiasi oggetto del servizio corrispondente sarà sufficiente.

I metodi di navigazione

In addition to the two lookup() methods, the ServiceRegistrar has three browsing methods, which yield information about registered service items. The three methods -- getServiceTypes(), getEntryClasses(), and getFieldValues() -- are called browsing methods because they enable clients to browse the services and attributes in the lookup service.

The getServiceTypes() method takes a ServiceTemplate (the same ServiceTemplate that is passed to the lookup() methods) and a String prefix. It returns an array of Class instances representing the most specific types (classes or interfaces) of the service objects that match the template. These service objects are neither equal to, nor a superclass of, any of the types specified in the template, and they have names that start with the specified prefix. The service object or objects for which Class instances are returned are all instances of all the types (if any) passed in the template, but the Class instances are all more specific than (and are subclasses or subinterfaces of) those types. Each class appears only once in the returned array, and in arbitrary order.

Here's what getServiceTypes() looks like:

public java.lang.Class[] getServiceTypes(ServiceTemplate tmpl, java.lang.String prefix) throws java.rmi.RemoteException; 

The getEntryTypes() method takes a ServiceTemplate and returns an array of Class instances that represent the most specific classes of entries for the service items that match the template, which either don't match any entry template or are a subclass of one. Each class appears only once in the returned array, again in arbitrary order.

Here's what getEntryClasses() looks like:

public java.lang.Class[] getEntryClasses(ServiceTemplate tmpl) throws java.rmi.RemoteException; 

The getFieldValues() method takes a ServiceTemplate, an integer index, and a String field name. It returns an array of Objects for the named field of all instances of the entry that appears in the ServiceTemplate's Entry[] array at any matching service item's passed index. Each object of a particular class and value appears only once in the returned array, and in arbitrary order.

Here's what getFieldValues() looks like:

public java.lang.Object[] getFieldValues(ServiceTemplate tmpl, int setIndex, java.lang.String field) throws java.lang.NoSuchFieldException, java.rmi.RemoteException; 

The behavior and purpose of these browsing methods can be obscure. You might think of them as tools that incrementally narrow queries of the lookup service.

For example, a client such as a graphical lookup service browser could first invoke getServiceTypes() with an empty template. The getServiceTemplate() method returns all possible service types registered in the lookup service, which the browser could display. The user could select one or more types, then push the Requery button. The browser would add that type (or types) to the service template and invoke getServiceTypes() again. A smaller list of types would be returned and displayed by the browser. The user could select one and press an Entries button. The browser would form a template with the most recently selected service type or types, and then invoke getEntryTypes(). The getEntryTypes() method would return an array of entry classes, which the browser could then display.

The user could select some entries -- and a field of a selected entry -- and push a Fields button. The browser would build a template using the currently selected service and entry types. It would then pass the index of the entry class in which the user selected the field, and the name of the selected field, to getFieldValues(). The browser would display all the values that getFieldValues() returned. With those values the user could further narrow the search for a service, eventually choosing a particular service. Thus, these methods help clients, whether or not a human user is involved, to browse the services registered in a lookup service. The arrays returned from the browsing methods can help the client further refine its queries, ultimately resulting in a ServiceTemplate that, when passed to lookup(), returns the most appropriate service object.

The notify() method

In addition to the lookup and browsing methods, the ServiceRegistrar interface also has a notify() method that notifies clients when new services register or unregister with a lookup service:

public EventRegistration notify(ServiceTemplate tmpl, int transitions, RemoteEventListener listener, MarshalledObject handback, long leaseDuration) throws RemoteException; 

You invoke notify() to register yourself (or another listener) to receive a distributed event whenever the services that match the passed ServiceTemplate undergo a state change described by the transitions parameter.

The transitions parameter is a bitwise OR of any nonempty set of these three values, defined as constants in ServiceRegistrar:

TRANSITION_MATCH_MATCH TRANSITION_MATCH_NOMATCH TRANSITION_NOMATCH_MATCH 

You build the ServiceTemplate for notify() in the same way you build it for lookup(). You can indicate explicit types, a service ID, attributes (which must exactly match), or wild cards (which match anything) in any of those fields. The transitions are based on a change (or nonchange) in the status of whatever matches your ServiceTemplate before and after any operation is performed on the lookup service.

Ad esempio, TRANSITION_MATCH_MATCHindica che almeno un articolo del servizio corrisponde al modello prima e dopo un'operazione. TRANSITION_MATCH_NOMATCHindica che, sebbene almeno un particolare elemento del servizio corrispondesse al modello prima di un'operazione, non corrispondeva più al modello dopo l'operazione. Per ricevere una notifica quando vengono aggiunti nuovi servizi a un servizio di ricerca, è sufficiente specificare un modello che corrisponda a qualsiasi servizio e passare TRANSITION_NOMATCH_MATCHcome transizione al notify()metodo.

SUBHEAD_BREAK: servizio di ricerca e server dei nomi