Figura 1 - L'iter concettuale proposto nella sezione Integrazione di MokaByte
Figura 1 - L'iter concettuale proposto nella sezione Integrazione di MokaByte

WS: stato dell'arte

Un Web Service è un servizio di business riutilizzabile che può essere richiamato attraverso tecnologie Internet e che dialoga in XML [MOKA_WS]. La rappresentazione dei dati nei Web Services (WS) avviene mediante il linguaggio XML e per questo sono definiti "language-neutral". Come protocollo di comunicazione i WS non utilizzano protocolli proprietari bensì i protocolli standard Internet (es: HTTP) e per questo sono definiti "platform-neutral".

Figura 2 - Architettura Web Services
Figura 2 - Architettura Web Services
Figura 3 - Le principali specifiche WS
Figura 3 - Le principali specifiche WS

Il Web Service Definition Language [MOKAWS], [MOKASOA] ricopre un ruolo importante nell'architettura dei web service perché descrive il contratto tra il Service Consumer (l'entità che richiede il servizio) ed il Service Provider (l'entità che fornisce il servizio) in modalità indipendente dal linguaggio di sviluppo e dalla piattaforma utilizzata.

In pratica, il WSDL descrive come interagire con il servizio, definendo le operazioni e i messaggi relativi e specificando i "binding" delle operazioni sui protocolli esposti.

Partendo dal documento WSDL è possibile generare le classi stub da usare lato client utilizzando l'opportuno tool WSDL-to-<linguaggio target> che permette di semplificare notevolmente lo sviluppo di un client riducendo la quantità di codice da scrivere e senza fare riferimento diretto alle API di basso livello di gestione dati/protocollo [MOKA_INT].

Ad esempio in Java è possibile utilizzare il tool Axis WSDL2Java, mentre per C# l'eseguibile Microsoft wsdl.exe. Le classi generate automaticamente dal tool possono essere utilizzate dal client per invocare in modo facile ed agevole il servizio.

Combinando un Design SOA con la tecnologia Web Services possiamo abbattere le barriere tecnologiche tra le varie piattaforme grazie ad una esposizione dei servizi omogenea e interoperabile. Ovviamente i servizi devono avere un'interfaccia chiara e comprensibile. Capire il significato di un servizio e dei suoi dati non è così banale come potrebbe sembrare. Ad esempio, un servizio con una signature criptica come questa è praticamente inutilizzabile:

<wsdl:message name="myOperationRequest"> <wsdl:part name="param1" type="xsd:anyType" /> <wsdl:part name="param2" type="xsd:anyType" /> <wsdl:part name="param3" type="xsd:anyType" /> </wsdl:message> <wsdl:message name="myOperationResponse"> <wsdl:part name="myOperationReturn" type="xsd:anyType" /> </wsdl:message> <wsdl:operation name="myOperation"> <wsdl:input name="myOperationRequest"> </wsdl:input> <wsdl:output name="myOperationResponse"> </wsdl:output> </wsdl:operation> <wsdl:service name="MyWS"></wsdl:service>

interface MyWS
{

	public Object myOperation (Object param1, Object param2, Object param3);

}

interface MokabyteBooks {

public double getPrice (String ISBN, String title, int year);

} <wsdl:message name="getPriceRequest"> <wsdl:part name="ISBN" type="xsd:string" /> <wsdl:part name="title" type="xsd:string" /> <wsdl:part name="year" type="xsd:int" /> </wsdl:message> <wsdl:message name="getPriceResponse"> <wsdl:part name="getPriceReturn" type="xsd:double" /> </wsdl:message> <wsdl:operation name="getPrice" parameterOrder="ISBN title year"> <wsdl:input message="impl:getPriceRequest" name="getPriceRequest" /> <wsdl:output message="impl:getPriceResponse" name="getPriceResponse" /> </wsdl:operation> <wsdl:service name="MokabyteBooksService">

interface MokabyteBooks2
{

	public double getPrice (BookID isbn, BookTitle title, Date year);

}
Ovviamente è sempre fondamentale fornire l'opportuna documentazione; ad esempio utilizzando il comando javadoc (o Maven!) che può generare automaticamente a partire dal codice (scritto bene) una buona documentazione in modo comodo ed immediato.

UDDIProxy proxy = new UDDIProxy();

Vector names = new Vector();

names.add(new Name("CheckEmail"));

. . . FindQualifiers findQualifiers = new FindQualifiers();

Vector qualifier = new Vector();

qualifier.add(new FindQualifier("caseSensitiveMatch"));

findQualifiers.setFindQualifierVector(qualifier);

. . . // Find businesses by name. Setting the maximum rows to be returned as 5. BusinessList businessList = proxy.find_business(names, null, null, null,null,findQualifiers,5);

Vector businessInfoVector = businessList.getBusinessInfos().getBusinessInfoVector();

for( int i = 0; i < businessInfoVector.size(); i++ ){

. . . . . } Il tipo di dato OrderRequest è un tipo complesso che ha al suo interno il numero del cliente ("customerNo") di tipo intero (xs:integer) ed una lista (minOccurs="1" maxOccurs="unbounded") di prodotti da ordinare (orderItem) di tipo Item. Item a sua volta è costituito da un identificativo (UPC) di tipo stringa (xs:string) e da una quantità (xs:integer). La risposta è OrderResponse, un tipo di dato di tipo stringa (xs:string) che può assumero i valori Confirmed, Pending o Rejected (<xs:enumeration value="Confirmed" /><xs:enumeration value="Pending" /><xs:enumeration value="Rejected" />). <wsdl:types> . . . <xs:element name="OrderRequest" sawsdl:modelReference="http://www.w3.org/2002/ws/sawsdl/spec/ontology/purchaseorder#OrderRequest" . . .

La classe <owl:Class rdf:ID="OrderRequest" /> è in relazione con la classe LineItem attraverso la proprietà hasLineItems e con la classe Customer attraverso la proprietà hasCustomer.
<owl:ObjectProperty rdf:ID="hasLineItems">
	<rdfs:domain rdf:resource="#OrderRequest" />
	<rdfs:range rdf:resource="#LineItem" />
	</owl:ObjectProperty>
<owl:FunctionalProperty rdf:ID="hasCustomer">
<rdfs:domain rdf:resource="#OrderRequest" />
	<rdfs:range rdf:resource="#Customer" />
	<rdf:type rdf:resource="http://www.w3.org/2002/07/owl#ObjectProperty" />
	</owl:FunctionalProperty>

[MOKA_SOA] S. Rossini - M. Piraccini, "SOA. I parte: Introduzione", MokaByte 100, Ottobre 2005 S. Rossini - M. Piraccini, "SOA. II parte: Metodologia", MokaByte 101, Novembre 2005 S. Rossini - M. Piraccini, "SOA. III parte: Il SOA Maturity Model", MokaByte 102, Dicembre 2005 S. Rossini - M. Piraccini, "SOA. IV parte: La SOA Roadmap", MokaByte 103, Gennaio 2006 S. Rossini - M. Piraccini, "SOA. V parte: Integrazione a servizi (SOI)", MokaByte 104, Febbraio 2006 S. Rossini - M. Piraccini, "SOA. VI parte: Il Service Bus (I)", MokaByte 105, Marzo 2006 S. Rossini - M. Piraccini, "SOA. VII parte: Il Service Bus (II)", MokaByte 106, Aprile 2006 S. Rossini - M. Piraccini, "SOA. VIII parte: Strategie di adozione", MokaByte 107, Maggio 2006 S. Rossini - M. Piraccini, "SOA. IX parte: Esempio Pratico (I)", MokaByte 108, Giugno 2006 S. Rossini - M. Piraccini, "SOA. X parte: Esempio Pratico (II)", MokaByte 109, Luglio 2006 S. Rossini, "SOA: Riuso e granularità dei servizi SOA", MokaByte 116, Marzo 2007