WS-Discovery enhanced

Continua la saga su WS-Discovery scritta sempre da Alessio Mannelli. Per chi si fosse perso la prima puntata può leggerla qui.

Recap

Ben ritrovati in questa serie di post dedicati alla specifica WS-Discovery. Nella puntata precedente abbiamo fatto conoscenza del modello, dei messaggi e delle interazioni basiche fondamento della specifica.

Abilitare scenari di composizione dinamica, sia a design-time, ma soprattutto a runtime, sono il fulcro alla base della specifica.

In questa nuova puntata andremo a conoscere il supporto di rete previsto in WS-Discovey, il Discovery Proxy, come gestire il concetto degli Scopes, ed introdurremmo gli scenari applicativi che implementeremo nella prossima puntata della serie WS-Discovery.

 

Supporto di rete

Abbiamo già visto nella prima puntata le due modalità operative presenti in WS-Discovery, ad-hoc e managed. La prima si basa completamente sullo scambio di messaggi in Multicast per tutte le peculiarità di Discovery (Hello/Bye/Probe/Match e relative *Resolve), la seconda si basa sulla presenza di un servizio di rete, denominato Discovery Proxy, al quale inviare i messaggi di ricerca (Probe e Resolve).

La specifica identifica le seguenti definizioni per l’invio di messaggi in multicast:

· DISCOVERY_PORT: port 3702

· IPv4 multicast address: 239.255.255.250

· IPv6 multicast address: FF02::C (link-local scope)

I messaggi multicast devono essere inviati utilizzando SOAP over UDP.

Quando la modalità operativa utilizzata è quella ad-hoc, tutti i messaggi di richiesta devono essere inviati come sopra definito, mentre tutte le risposte verranno inviate in unicast al client che ha inviato i messaggi. Per comunicare in unicast verso il client vi sono due possibilità:

· Il client aggiunge un indirizzo di risposta sfruttando l’header di Addressing ReplyTo .

· Il server utilizza l’indirizzo IP e la porta sorgente della connessione UDP ricevuta per rispondere al client.

Nella modalità operativa managed il client dialoga con il Discovery Proxy in unicast, sia in richiesta che in risposta.

 

Client e Discovery Proxy

Il Discovery Proxy, come già descritto, è alla base della modalità operativa cosiddetta managed.

Un client, se non diversamente istruito, si trova normalmente in un stato nel quale non conosce Discovery Proxy; è possibile, chiaramente che riceva un Hello dal Discovery Proxy, riconoscibile da uno specifico Service Type che lo contraddistingue (d:DiscoveryProxy) nel qual caso modificherà radicalmente il modo con il quale invia richieste di Probe e Resolve, secondo il diagramma a stati sotto descritto:

 

image

 

Quindi, una volta che il client si trova a conoscere un Discovery Proxy comunicherà con lo stesso in modalità unicast, evitando quindi di congestionare la rete con messaggi in multicast.

Un DiscoveryProxy, di contro, quando riceve un messaggio di Probe o Resolve in multicast è tenuto a spedire subito un messaggio di Hello (in multicast a sua volta): questo particolare messaggio modifica lo stato dei client in modo tale che utilizzino solamente i Discovery Proxy di cui si fidano, ed ingnorino di contro i messaggi in multicast dei Target Service.

A questo punto sia i Client che i Target Service indirizzeranno le loro comunicazioni (di ricerca, per il client, di connessione/disconnessione dalla rete, per i servizi) al Discovery Proxy. Eventualmente i messaggi di connessione/disconnessione (Hello/Bye) potranno essere inviati ancora in multicast, da parte dei Target Service: il loro peso specifico è talmente basso, cosi come il numero di messaggi inviati, da essere praticamente trascurabili in uno scenario reale.

Tra i vantaggi di avere un’infrastruttura di Discovery managed vi è anche la possibilità di scavalcare il limite di utilizzo delle comunicazioni multicast (overhead di gestione del routing del protocollo fra tutti): inserire alcuni Discovery Proxy tra le varie sottoreti, e sfruttare il modello di discovery, può portare ad allargare gli orizzonti del proprio ambiente operativo.

 

image

 

In questo modo i client possono trovare ed utilizzare servizi non presenti nelle loro sottoreti, senza rendere difficoltosa la gestione dell’infrastruttura.

 

Scopes

Come già accennato, gli scopes, di seguito indicati anche come “ambiti”, possono caratterizzare un servizio nel mondo di WS-Discovery. La specifica identifica solamente i metodi specifici con i quali un Target Service deve confrontare i suoi ambiti, con quelli richiesti dal messaggio di Probe ricevuto, per rispondere, eventualmente, con un messaggio di Match (Probe o Request). Ripetiamo la lista dei modelli di confronto utilizzabili, per riferimento:

· https://docs.oasis-open.org/ws-dd/ns/discovery/2009/01/rfc3986

· https://docs.oasis-open.org/ws-dd/ns/discovery/2009/01/uuid

· https://docs.oasis-open.org/ws-dd/ns/discovery/2009/01/ldap

· https://docs.oasis-open.org/ws-dd/ns/discovery/2009/01/strcmp0

· https://docs.oasis-open.org/ws-dd/ns/discovery/2009/01/none

Per maggiori informazioni sugli stessi il capitolo 5 della specifica entra nei dettagli di ogni modello.

Scenari applicativi di utilizzo di WS-Discovery

Fino a qui abbiamo praticamente visto tutti gli aspetti peculiari della specifica WS-Discovery, cerchiamo adesso di focalizzare l’utilizzo della stessa nel mondo reale, proponendo alcuni scenari che normalmente si propongono in un ambiente orientato ai servizi, e che elaboreremo nella prossima puntata:

1. Ricerca a runtime di un servizio che implementa l’interfaccia che ci interessa.

2. Ricerca a runtime di un servizio che, oltre ad implementare l’interfaccia richiesta, è configurato con uno scope specifico.

Il primo scenario è il più frequente in ambito composizione : configurazione degli indirizzi fisici utilizzati dai servizi nei diversi “ambienti operativi” nei quali l’ applicazione verrà eseguita (sviluppo, pre-produzione, produzione e chi più ne ha più ne metta). Il vantaggio che deriva dall’utilizzo di WS-Discovery come asset fondamentale di tutti i servizi e le applicazioni è evidente: ad ogni modifica di “ambiente operativo” l’applicazione ricercherà il servizio specifico ed utilizzerà l’indirizzo recuperato a runtime per il colloquio.

Chiaramente vi possono essere degli accorgimenti capaci di evitare il “dispendio” di messaggi che la ricerca di un’istanza di servizio può aggiungere all’economia del colloquio applicazione – servizio. Talvolta il peso è trascurabile, quando ad esempio il client ha un ciclo di vita molto elevato, tale per cui il peso aggiunto diventa infinitesimale rispetto al resto del peso di comunicazione; altre volte invece è necessario salvare l’indirizzo del servizio recuperato tramite utilizzo di WS-Discovery per poi riutilizzarlo al riavvio dell’applicazione. In questo modo vi è la possibilità che il servizio recuperato in precedenza non sia più “vivo”, nel qual caso si potrà procedere con una nuova interazione Probe – ProbeMatch.

Il secondo scenario è il più “ambizioso” in determinati contesti. Ipotizziamo di avere alcune istanze di uno specifico servizio, distribuite in modo tale da coprire più segmenti della topologia di rete in esame. Per esempio potremmo avere un servizio locale su una macchina, un servizio su una LAN particolare , ed un servizio al centro. Tutti e tre i servizi implementano la stessa interfaccia e gestiscono gli stessi dati ma, data la loro differente collocazione geografica hanno uno SLA (service level agreement) diverso a seconda dei dati che vengono richiesti.

Facciamo un esempio : il servizio locale alla mia macchina avrà lo stato completo dei dati che si generano dalla macchina stessa, il servizio interno alla LAN ha lo stato completo dei dati che si generano all’interno della LAN stessa, e per finire il servizio al centro ha lo stato completo dei dati che si generano fuori dal contesto applicativo specifico. Ogni “livello” diverso si sincronizza e coordina con gli altri tramite un ulteriore flusso dati (che non analizziamo) che rende possibile, con tempi diversi, l’allineamento dei dati su tutte le istanze del servizio ipotizzato.

A questo punto l’applicazione deve capire se e come le tre diverse istanze di servizio possono aiutarlo nell’esecuzione delle sue funzioni. In alcuni casi un servizio fisicamente “vicino” al client può essere un aiuto, se non altro per il ridotto round trip di rete dell’invocazione. Altrimenti, se l’applicazione capisce di avere necessità di dati con specifico SLA può ricercare uno dei servizi specifici.

Bene, l’utilizzo degli scopes, in questo caso, è l’ausilio tecnico alla problematica. Ogni diversa istanza di servizio viene configurata in diversi ambiti (scopes, per l’appunto). In contesti gerarchici, come l’esempio illustrato, gli scopes possono essere definiti con una convenzione come la seguente:

· Servizio al centro rende disponibile lo scope https://ROOT

· Servizio di “filiale” rende disponibile lo scope https://ROOT/BRANCH

· Servizio locale rende disponibile lo scope https://ROOT/BRANCH/MACHINE

In questo scenario si possono poi utilizzare diverse tipologie di confronto tra gli scopes: la tipologia di esatta comparazione delle stringhe, ad esempio, restituirà solo uno delle tre istanze di servizio, piuttosto che la versione RFC3986, la quale restituisce una istanza se almeno uno dei sotto livelli della risorsa richiesta è confrontabile con quello richiesto; in questo caso se chiedo lo scope ROOT, tutti e tre i servizi dell’esempio risponderanno con i loro dettagli.

Tutto dipende da quali sono le necessità applicative, ma le prospettive offerte dall’infrastruttura sono molto interessanti, e flessibili.

Conclusioni

Con questo secondo post abbiamo esaurito l’overview della specifica, e definito alcuni scenari che reputo interessanti e che saranno la base del terzo ed ultimo post della serie WS-DISCOVERY. Analizzeremo l’implementazione di WS-Discovery inserito nella nuova versione del .Net Framework 4.0, attualmente in versione Beta, e realizzeremo gli scenari proposti. Per avvantaggiarvi vi consiglio di leggere e sottoscrivere https://blogs.msdn.com/discovery/, ne avremo bisogno!

A presto,

Alessio