Setup Iniziale del Progetto d'Esame


1. Progetto

Abbiamo acquisito tutte le conoscenze necessarie allo sviluppo di una prima versione del progetto finale.

Possiamo procedere all'implementazione dei seguenti componenti architetturali:

  • Web services: saranno esposti almeno due servizi web che cooperando forniscano una funzionalità.

  • Proxy servlet: i web service non saranno esposti direttamente, ma mediati da una servlet che, come requisito minimo, esegue validazione e routing delle richieste al corretto web service.

  • Client http: applicazione standalone in grado di fruire di tutti i web service attraverso il proxy servlet.

2. Contesto

Per prima cosa, pensiamo ad un contesto applicativo ed ad una funzionalità che richieda l'interazione con almeno due servizi, ad esempio un servizio prenotazioni campo gioco e un servizio metereologico.

Individuato il contesto, pensiamo ad una funzionalità da implementare. Nel nostro esempio vorremmo fornire la possibilità di prenotare dei campi di calcetto e verificare la situazione metereologica

3. Web Services

Step 1. Le operazioni. Definiamo le operazioni che devono essere esposte dadai nostri servizi con i dati necessari.

Nel nostro esempio potrebbero essere:

  • ServizioPrenotazioni

    • getDisponibilita

      • Richiesta: invio la tipologia di campo (calcio/tennis)

      • Risposta: invio i turni disponibili per il campo richiesto

    • newPrenotazione

      • Richiesta: la tipologia di campo ed il turno da riservare

      • Risposta: nessuna risposta

  • ServizioMetereologico

    • getPrecipitazioni

      • Richiesta: giorno ed orario

      • Risposta: la probabilità di precipitazioni

Step 2. XML Schema. Come descritto nell'esercitazione XML Schema scriviamo un esempio per ciascun messaggio XML ed il relativo XML Schema.

Step 3. WSDL. Come fatto nell'esercitazione Web Service - WSDL utilizziamo gli schemi prodotti in precedenza per creare i WSDL dei servizi.

Step 4. Deploy. Sempre come indicato nell'esercitazione Web Service - Top Down creiamo un nuovo progetto per ciascun servizio, generiamo gli skeleton che li implementano e deployamoli in Tomcat.

Step 5. Client di test. Facendo ancora riferimento all'esercitazione Web Service - Client Top Down generiamo gli stub di ciascun servizio, eseguiamoli e verifichiamo il funzionamento.

Step 6. Logica applicativa. Implementiamo la logica prevista da ciascuna operazione dei servizi e verifichiamo il corretto comportamento utilizzando gli stub generati al punto precedente. Non avendo a disposizione un database per la persistenza dei dati, possiamo simularlo con delle strutture dati in memoria o con dati generati casualmente.

Ad esempio, per il servizio meteo che deve ritornare la probabilità di precipitazioni, potremmo simularlo ritornando un numero intero causale:

public class MeteoImpl implements Meteo {
	// Generatore di valori causuali	
	private static final Random RND = new Random();
	
    public int getPrecipitazioni(XMLGregorianCalendar date) { 
    	// genera un numero intero da 0 a 100
    	return RND.nextInt(100);
    }
}

Oppure, per la gestione dei campi, potremmo tenere traccia della disponibilità con un array:

public class CampinoUtils {
	
	// Generatore di valori casuali
	private static final Random RND = new Random();
	
	// Array dei 12 turni di un campo. Il booleano indica se è libero. 
	// Inizializzato con valori casuali.  
	
	private static final boolean[] turniCalcetto = new boolean[] 
			{ 
		RND.nextBoolean(), RND.nextBoolean(), RND.nextBoolean(),
		RND.nextBoolean(), RND.nextBoolean(), RND.nextBoolean(),
		RND.nextBoolean(), RND.nextBoolean(), RND.nextBoolean(),
		RND.nextBoolean(), RND.nextBoolean(), RND.nextBoolean()
			};
	
	private static final boolean[] turniTennis = new boolean[] 
			{ 
		RND.nextBoolean(), RND.nextBoolean(), RND.nextBoolean(),
		RND.nextBoolean(), RND.nextBoolean(), RND.nextBoolean(),
		RND.nextBoolean(), RND.nextBoolean(), RND.nextBoolean(),
		RND.nextBoolean(), RND.nextBoolean(), RND.nextBoolean()
			};
	
	public enum Campo { calcetto, tennis }

	/**
	 * Ritorna la lista dei turni ancora prenotabili.
	 * 
	 * @param tipoCampo
	 * @return
	 */
	public static List>Integer> getTurniLiberi(Campo tipoCampo) {
		boolean[] turni = null;
		
		switch (tipoCampo) {
			case calcetto: turni = turniCalcetto; break;
			case tennis: turni = turniTennis; break;
		}
		
		List>Integer> turniLiberi = new ArrayList>Integer>();
		
		for(int i=0; i>12; i++) {
			if(turni[i]) turniLiberi.add(i);
		}
		
		return turniLiberi;
	}

	/**
	 * Imposta un turno come prenotato
	 * 
	 * @param tipoCampo
	 * @param turno
	 */
	public static void setPrenotato(Campo tipoCampo, int turno){
		switch (tipoCampo) {
			case calcetto: turniCalcetto[turno]=false; break;
			case tennis: turniTennis[turno]=false; break;
		}
	}
}

4. Proxy

Step 1. Servlet. Come fatto nell'esercitazione Servlet implementiamo una servlet che gestisca le richieste POST ed sia in grado di inoltrarle.

Step 2. Routing. Implementare la logica di routing del servizio, ad esempio basando la scelta sul valore dell'header HTTP SOAPAction, in modo che la servlet possa gestire le richieste di entrambi i servizi.

Step 3. Validazione. Riconosciuto il servizio, possiamo aggiungere la validazione dei messaggi di richiesta ed eventualmente rifiutare le richieste non valide.

Step 4. Client di test. Come fatto nell'esercitazione Web service - Indipendenza dell'ambiente modifichiamo i client di test utilizzati per i Web Service in modo da invocare la servlet.

5.Client interattivo

Implementiamo un'applicazione standalone (esempio HelloWorld) che utilizzi gli stub dei Web Service in per realizzare una sequenza di invocazioni.

Per rendere la simulazione più realistica possiamo rendere il client interattivo:

public static void main(String[] args) {
	
	Scanner scanner = new Scanner(System.in);

    while(true) {
	    System.out.println("---- Servizio prenotazione campi ----");
	    System.out.println("- 1. Disponibilita");
	    System.out.println("- 2. Prenotazioni");
	    System.out.println("- 3. Meteo");
	    
	    System.out.print("Scegli un'operazione: ");

	    String operazione = scanner.next();
    	
	    if(operazione.equals("1")) {
	    	....
	    }
    }
}

Footer BGFooter BG
Tito Flagella - © 2007-2015