Déploiement et consommation d’un service WCF sur Windows Azure
Auteur : Ronny KWON. Retrouvez d'autres articles de Ronny sur son blog "Blog in the Cloud : Windows Azure, Silverlight, Azure Services & Interop Java"
1. Pré-requis
Si vous ne disposez pas d’un compte Azure, sachez que les outils Windows Azure pour Microsoft Visual Studio permettent de simuler un environnement “On the Cloud” en local sur votre machine.
2. Introduction
Dans cet article, nous allons voir comment déployer un service WCF en SOAP dans un environnement Azure en local, comment le consommer en Java et PHP et pour finir comment consommer ce même service cette fois-ci hébergé sur Windows Azure.
3. Service WCF exposé en SOAP
3.1 Création du service
Nous allons commencer par créer un projet de type Cloud Service dans Visual Studio :
- Ouvrez Visual Studio en privilège élevé (clic droit et exécuter en tant qu’administrateur
) | |
- Créez un nouveau projet de type Web Cloud Service : Allez dans File > New > Project, repérer l’onglet Cloud Service et sélectionnez Web Cloud Service. Nommez-le SimpleWCFHosting
|
.jpg) |
Le projet Web Cloud Service est un projet qui expose un Web Role sur Windows Azure. Il est accessible depuis un environnement Web tandis que le Worker Cloud Service expose un Worker Role qui est apparenté à un processus fonctionnant en parallèle (il permet par exemple d’effectuer des tâches de traitement). Le projet Cloud Service référence un Web et/ou un Worker Role. Il gère la configuration de l’environnement de ces services. Vous verrez apparaitre dans l’onglet Solution Explorer 2 projets : un Cloud Service et un Web Role. C’est dans le Web Role que nous allons exposer notre service WCF. - Ajoutez un service WCF au Web Role : Clic droit sur la racine du projet Web Role et Add à New Item à WCF Service. Nommez le HelloWorld.svc
|
.jpg) |
Une fois le service créé, il faut modifier son binding en basicHttpBinding (par défaut en wsHttpBinding). Pour cela, éditez le fichier Web.config présent dans le Web Role et repérez l’attribut binding=’’wsHttpBinding’’ dans le tag system.serviceModel. |
.jpg) |
Remplacez cette valeur par ‘’basicHttpBinding’’. |
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="SimpleWCFHosting_WebRole.HelloWorldBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="SimpleWCFHosting_WebRole.HelloWorldBehavior"
name="SimpleWCFHosting_WebRole.HelloWorld">
<endpoint address="" binding="basicHttpBinding" contract="SimpleWCFHosting_WebRole.IHelloWorld">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
</system.serviceModel>
Nous allons maintenant modifier le service afin qu’il nous renvoie un message du type :
04/03/2009 11:38:03 : Hello Bill from Windows Azure
Editez l’interface du service IHelloWorld.cs et remplacer l’opération DoWork par celle-ci :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
namespace SimpleWCFHosting_WebRole
{
// NOTE: If you change the interface name "IHelloWorld" here, you must also update the reference to "IHelloWorld" in Web.config.
[ServiceContract]
public interface IHelloWorld
{
[OperationContract]
String SayHello(String name);
}
}
Dans l’implémentation du service HelloWorld.svc.cs, il faut implémenter l’opération SayHello :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
namespace SimpleWCFHosting_WebRole
{
// NOTE: If you change the class name "HelloWorld" here, you must also update the reference to "HelloWorld" in Web.config.
public class HelloWorld : IHelloWorld
{
public String SayHello(String name)
{
return String.Format("{0} : Hello {1} From Windows Azure", DateTime.Now, name);
}
}
}
3.2 Exposition du service WCF
Compilez et lancez le projet (F5), vous remarquerez que deux processus se lancent : | .jpg) |
Ces 2 processus simulent l’environnement de Windows Azure :
- Le Development Storage simule Windows Azure Storage (Blobs, Table et Queues)
- Le Development Fabric simule l’environnement d’exécution des Web et Worker Roles
Dans cette partie nous allons consommer le service HelloWorld avec une application Java. Trois étapes sont nécessaires :
- modifier le WSDL,
- générer le proxy client du service
- consommer le service.
4.1 Modification du WSDL
A première vue, pour consommer ce service, on aurait tendance à vouloir le générer directement à partir du WSDL exposé. Or celui –ci contient des références erronées.
Pour palier à cela, il faut éditer et importer en local le WSDL :
Sur votre disque, créez un fichier et appelez-le HelloWorld.wsdl. Copiez-collez le contenu du WSDL, supprimez les caractères indésirables lors de la copie (« - ») et remplacez toutes les références du type NomDeMonPC:5100 par 127.0.0.1
<?xml version="1.0" encoding="utf-8" ?>
<wsdl:definitions name="HelloWorld" targetNamespace="http://tempuri.org/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:tns="http://tempuri.org/" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:wsa10="http://www.w3.org/2005/08/addressing" xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex">
<wsdl:types>
<xsd:schema targetNamespace="http://tempuri.org/Imports">
<xsd:import schemaLocation="http://127.0.0.1/HelloWorld.svc?xsd=xsd0" namespace="http://tempuri.org/" />
<xsd:import schemaLocation="http://127.0.0.1/HelloWorld.svc?xsd=xsd1" namespace="http://schemas.microsoft.com/2003/10/Serialization/" />
</xsd:schema>
</wsdl:types>
<wsdl:message name="IHelloWorld_SayHello_InputMessage">
<wsdl:part name="parameters" element="tns:SayHello" />
</wsdl:message>
<wsdl:message name="IHelloWorld_SayHello_OutputMessage">
<wsdl:part name="parameters" element="tns:SayHelloResponse" />
</wsdl:message>
<wsdl:portType name="IHelloWorld">
<wsdl:operation name="SayHello">
<wsdl:input wsaw:Action="http://tempuri.org/IHelloWorld/SayHello" message="tns:IHelloWorld_SayHello_InputMessage" />
<wsdl:output wsaw:Action="http://tempuri.org/IHelloWorld/SayHelloResponse" message="tns:IHelloWorld_SayHello_OutputMessage" />
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="BasicHttpBinding_IHelloWorld" type="tns:IHelloWorld">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="SayHello">
<soap:operation soapAction="http://tempuri.org/IHelloWorld/SayHello" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="HelloWorld">
<wsdl:port name="BasicHttpBinding_IHelloWorld" binding="tns:BasicHttpBinding_IHelloWorld">
<soap:address location="http://127.0.0.1/HelloWorld.svc" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
Notre WSDL est prêt, on va générer le proxy client dans une application Java.
4.2 Génération du proxy client
Dans une nouvelle application Java, nous allons faire appel à notre web service.
- Lancez Eclipse
- Créez un nouveau projet Java
- File > New > Project et choisissez Java/Java Project
- Nommez-le « Client WCF Hello World »
- Copiez le fichier HelloWorld.wsdl
- Collez-le dans la racine de votre projet Client WCF Hello World :
Le WSDL sera alors ajouté au projet
Il nous faut maintenant générer le proxy client à partir du WSDL.
- Clic droit sur le projet et New > Other (CTRL+N) et choisissez Web Service Client et cliquez sur Next
- Dans la fenêtre suivante, entrez l’adresse du WSDL HelloWorld.wsdl : /Client WCF Hello World/HelloWorld.wsdl et validez (Finish)
Notez qu’Eclipse vous a généré du code pour pouvoir communiquer avec le service WCF :
La prochaine étape : consommer le service HelloWorld
4.3 Consommer le service WCF
Ajoutez au projet une nouvelle classe Java de type Main
Clic droit sur le projet > New > Class. Nommez-la Main et cochez la case public static void main(String [] args)
Dans le fichier Main.java rajoutez ce code :
import java.rmi.RemoteException;
import org.tempuri.IHelloWorldProxy;
public class Main {
/**
* @param args
* @throws RemoteException
*/
public static void main(String[] args) throws RemoteException {
IHelloWorldProxy proxy = new IHelloWorldProxy();
System.out.println(proxy.sayHello("Bill"));
}
}
On a instancié un proxy client du service WCF et on fait appel à l’opération exposée sayHello.
Lancez l’application, observez le résultat :
5. Consommer le service avec une application PHP
Toujours dans une optique d’interopérabilité, nous allons voir comment consommer un service WCF hébergé sur Azure depuis une application PHP.
5.1 Le projet PHP
- Ouvrez Eclipse PDT et créez un nouveau projet de type PHP : File > New > PHP Project
- Nommez-le Client WCF Azure.
- Copiez-collez le WSDL modifié HelloWorld.wsdl (voir 4.1 Modification du WSDL)
- Ajoutez un nouveau fichier php au projet : clic droit sur la racine du projet > New > PHP File
- Nommez-le clientwcf.php
Nous allons créer notre proxy client en y spécifiant le WSDL :
<?php
try{
$client = new SoapClient("HelloWorld.wsdl");
} catch (Exception $e) {
print 'Caught exception: '. $e->getMessage(). "\n";
}
?>
Puis nous allons appeler la fonction SayHello avec les paramètres attendus. Les paramètres sont à spécifier dans un tableau :
$param = array('name' => "Bill PHP");
$result = $client->SayHello($param);
Ensuite on récupère le résultat et on l’affiche :
$webresult = $result->SayHelloResult;
print($webresult);
Le code complet :
<?php
try{
$client = new SoapClient("HelloWorld.wsdl");
$param = array('name' => "Bill");
$result = $client->SayHello($param);
$webresult = $result->SayHelloResult;
print($webresult);
} catch (Exception $e) {
print 'Caught exception: '. $e->getMessage(). "\n";
}
?>
Il reste à exécuter le script : faites un clic droit > Run As > PHP Script
Notre application PHP vient de communiquer avec notre service WCF sur Azure
6. Héberger un service WCF sur Windows Azure et consommer
Si vous possédez un token pour la CTP de la plateforme de services Azure, vous serez tenté d’héberger le service dans les nuages. Voici la démarche à suivre.
Sur le Azure Services Developer Portal créez un nouveau projet de type Hosted Services et remplissez les informations correspondantes :
Après la création du projet vous verrez la fenêtre suivante :
Vous disposez d’un environnement de tests (Staging) et un environnement de Production (Production). Votre projet possède une Application ID, reportez le dans les propriétés du projet Cloud Service sous l’onglet Portal dans Visual Studio :
Vous pouvez désormais accéder directement à votre espace sur Windows Azure. Sous Visual Studio, faites un clic droit sur la racine du projet SimpleWCFHosting et Publish.
Un dossier Publish s’ouvre et votre navigateur se dirige sur la page de déploiement. Sélectionner dans les champs correspondants le package (*.cspkg) et le fichier de configuration (*.cscfg) :
Déployez la solution et cliquez sur Run. Une fois la solution lancée, vous pourrez la faire migrer en production en appuyant sur le bouton Promote.
Le service est alors accessible via http://<domaine>.cloudapp.net/HelloWorld.svc (dans ce cas : http://demowcf.cloudapp.net/HelloWorld.svc)
Pour le consommer en Java et PHP, il faut reprendre le WSDL et repositionner toutes les références du type http://rd00155d30263f:20000/ par http://[MonDomaine].cloudapp.net/ (Voir 4.1 Modification du WSDL)
Une fois que vous aurez modifié le WSDL et régénéré le proxy client, relancez l’application :
Vous venez de consommer un service WCF depuis une application Java et PHP et tout cela dans les nuages !