Introduction aux SharePoint Service Applications

 

Les service applications constituent l'une des nouvelles fonctionnalités les plus puissantes de Microsoft SharePoint 2010. Cette fonctionnalité est en effet l'évolution de Shared Service Provider (SSP) introduite avec SharePoint  2007.

Un service application est un service "middle-tier" qui peut être partagé entre plusieurs instances d'une application web de la même ferme ou même à travers plusieurs fermes. Un service application fournit ses capacités à l'infrastructure SharePoint , en profitant des facilités de montée en charge, de maintanbilité et d'estensibilité de cette infrastructure. Par exemple, un service application pourrait être un service pour partager des données d'entreprise, fournir des calculs complexes, ou bien exécuter de longs traitements...

 

Tous les services natifs de SharePoint 2010 sont implémentés comme des service applications. Par exemple, le service de recherche est un service application qui peut être partagé entre plusieurs applications web et des fermes multiples. Les Business Connectivity Services, avec lesquels vous pouvez consommer et gérer les données externes au sein de l'interface utilisateur de SharePoint, est un autre exemple de service application. Toute l'architecture de SharePoint 2010 repose sur des service applications.

 

Quand créer un service application?

En général, un service application devrait être mis en œuvre dans les situations suivantes:

  • Si vous avez besoin de partager une logique métier ou des données entre de multiples applications web ou des fermes SharePoint.

  • Si vous avez besoin de mettre en œuvre des activités de longue durée et les tâches qui peuvent être exécutées sur le back-end, impliquant éventuellement des processus distants.

  • Si vous avez besoin d'une infrastructure évolutive et gérable qui tire parti de l'architecture SharePoint existante.

  • Si vous avez besoin d'utiliser l'authentification basée sur les revendications (Claims based authentication) pour la délégation de l'authentification et de l'autorisation.

En revanche, il n'est pas nécessaire de créer un service application dans les cas suivants:

  • Lorsque vous avez besoin de partager des données entre les sites ou des collections de sites au sein de la même application Web.

  • Lorsque vous n'avez pas besoin d'interagir avec les sources de données ou des composants externes à une seule application web.

Architecture

L'architecture des service application repose sur cinq composants de manière à satisfaire les besoins de montée en charge, d'extensibilité et de mantenabilité. Les éléments qui composent un service application sont les suivants:

 

Le service (SPService): C'est le service proprement dit, avec ses fonctionnalités, sa logique de trairtement et sa propre infrastructure. Il peut être hébergé sur un serveur spécifique de la ferme, ou sur un serveur externe. Par exemple, cela pourrait être un service externe de compression de documents, ou composant logiciel installé dans la ferme.

 

l'instance de service (SPServiceInstance): Représente une seule instance du service, fonctionnant sur un serveur de la ferme. Il peut y avoir plusieurs instances d'un service s'exécutant sur plusieurs serveurs d'applications de la ferme. L'architecture des service applications sait gérer automatiquement le balancement de charge des requête envoyées aux différentes instances du service.

 

l'Application service (SPServiceApplication): Il s'agit d'une couche logique qui rend l'infrastructure des service applications disponibles à la ferme. C'est une abstraction qui libère les consommateurs des service applications des soucis de connaître l'emplacement physiques des instances de service.

 

Le proxy du service (SPServiceProxy): Représente un consommateur de service (client) qui s'est abonné à service de la ferme SharePoint.

 

Le proxy d'application service (SPServiceApplicationProxy): Il s'agit du proxy qui virtualise l'accès à l'application de service. En général, il est utilisé sur les serveurs frontaux de la ferme et permet d'accéder au service application de manière transparente et indépendante de son emplacement actuel.

 

Modèle Objet des Service Applications

 

Cette architecture permet d'avoir un environnement entièrement évolutif et extensible, où les consommateurs des service applications ne savent pas où les services réels sont et comment ils fonctionnent. Au lieu de cela, ils interagissent via un proxy qui communique de façon transparente avec l'une des instances de service configurés.

L'infrastructure de communication à la base de l'architecture des service applications est fournie par Windows Communication Foundation (WCF) de Microsoft. NET Framework 3 .5.

Création d'un service application

A titre d'exemple, nous allons implémenter un service application très simple nommé HelloService contenant une seule méthode nommée SayHello.

Noter que le code présenté n'est pas complet pour des raison de lisibilité.

Implementation de la classe SPService

Commençons par l'implémentation de la classe service HelloService, cette classe héritera de la classe SPIisWebService qui représente un service web hosté par IIS 7.0, SPIisWebService hérite de la classe SPService déja citée.

La classe service implémente aussi l'interface IServiceAdministration qui contient les méthodes nécessaires au service application pour s'intégrer avec les pages d'administration de SharePoint.


Voici le détail d'implémentation de l'interface IServiceAdministration :

 

Méthode CreateApplication responsable de la création d'une nouvelle instance de l'application
public SPServiceApplication CreateApplication(string name, Type serviceApplicationType, SPServiceProvisioningContext provisioningContext)
{
    if (!ValidateType(serviceApplicationType))
    {
        return null;
    }
    HelloServiceApplication webApplicationByName = this.GetWebApplicationByName(name);
    if (((webApplicationByName == null) && (provisioningContext != null)) && (provisioningContext.IisWebServiceApplicationPool != null))
    {
        webApplicationByName = this.CreateApplication(name, provisioningContext.IisWebServiceApplicationPool);
    }
    return webApplicationByName;
}

internal HelloServiceApplication CreateApplication(string name, SPIisWebServiceApplicationPool applicationPool)
{
    HelloServiceApplication application = new HelloServiceApplication(name, this, applicationPool);
    application.Update();
    application.AddServiceEndpoint("", SPIisWebServiceBindingType.Http);
    application.AddServiceEndpoint("secure", SPIisWebServiceBindingType.Https, "secure");
    return application;
}
Méthode CreateProxy responsable de la création du proxy du service
public SPServiceApplicationProxy CreateProxy(string name, SPServiceApplication serviceApplication, SPServiceProvisioningContext provisioningContext)
{
    if (null == serviceApplication)
    {
        throw new ArgumentNullException("serviceApplication");
    }
    if (serviceApplication.GetType() != typeof(HelloServiceApplication))
    {
        throw new NotSupportedException();
    }
    HelloServiceProxy serviceProxy = (HelloServiceProxy)base.Farm.GetObject(string.Empty, base.Farm.Id, typeof(HelloServiceProxy));
    if (serviceProxy == null)
    {
        serviceProxy = new HelloServiceProxy(base.Farm);
        serviceProxy.Update();
    }
    HelloServiceApplicationProxy applicationProxy = HelloServiceProxy.Local.GetApplicationProxy(name);
    if (applicationProxy != null)
    {
        return applicationProxy;
    }
    return new HelloServiceApplicationProxy(name, serviceProxy, (HelloServiceApplication)serviceApplication);
}
Méthode GetApplicationTypeDescription retourne une descption du service Application pour affichage
public SPPersistedTypeDescription GetApplicationTypeDescription(Type serviceApplicationType)
{
    if (!ValidateType(serviceApplicationType))
    {
        return null;
    }
    return new SPPersistedTypeDescription("Hello Service Application", "Hello Service Application");
}
Méthode GetApplicationTypes retourne un tableau des types de Service Application supportés
public Type[] GetApplicationTypes()
{
    return new Type[] { typeof(HelloServiceApplication) };
}
Méthode GetCreateApplicationLink retourne l'url vers la page d'administration au moment de création d'une nouvelle instance à partir de la Central Administration
public override SPAdministrationLink GetCreateApplicationLink(Type serviceApplicationType)
{
    if (!ValidateType(serviceApplicationType))
    {
        return null;
    }
    return new SPAdministrationLink("/_admin/HelloServiceApplication/CreateApplication.aspx");
}

Implementation de la classe SPServiceInstance

La classe instance de service HelloServiceInstance hérite de la classe SPIisWebServiceInstance qui représente une instance du service web hosté par IIS 7.0, SPIisWebServiceInstance hérite de la classe SPServiceInstance déja citée.

Voici le détail d'implémentation de HelloServiceInstance :

[System.Runtime.InteropServices.Guid("03FF2EC1-9C55-4B14-BECF-F87BC13E991F")]
public class HelloServiceInstance : SPIisWebServiceInstance
{
    private const string HelloServiceInstanceName = "HelloServiceInstance";
        
    public HelloServiceInstance()
    {
    }

    internal HelloServiceInstance(SPServer server, HelloService service)
        : base(server, service)
    {
    }

    internal HelloServiceInstance(string name, SPServer server, HelloService service)
        : base(server, service)
    {
    }
       
    public override string DisplayName
    {
        get
        {
            return HelloServiceInstanceName;
        }
    }

    public override string TypeName
    {
        get
        {
            return HelloServiceInstanceName;
        }
    }
}

Implementation de la classe SPServiceApplication

L'étape suivante concerne la création de la classe instance de service HelloServiceApplication qui hérite de la classe SPIisWebServiceApplication qui représente une application service hostée par IIS 7.0, SPIisWebServiceApplication hérite de la classe SPServiceApplication déja citée.

la classe HelloServiceApplication implémente aussi l'interface IHelloService qui décrit les méthodes utiles à la logique métier de notre application service.


Voici le détail d'implémentation de HelloServiceApplication :
 

[System.Runtime.InteropServices.Guid("C559CC57-543A-4FFA-815B-4B88A603A1FA")]
public sealed class HelloServiceApplication : SPIisWebServiceApplication, IHelloService
{
    private HelloServiceInstance m_serviceInstance;

    protected override string VirtualPath
    {
        get
        {
            return "Service.svc";
        }
    }

    protected override string InstallPath
    {
        get
        {
            return Path.GetFullPath(SPUtility.GetGenericSetupPath(@"WebServices\HelloServiceApplication"));
        }
    }

    public override SPAdministrationLink ManageLink
    {
        get
        {
            return new SPAdministrationLink(string.Format("/_admin/HelloServiceApplication/HelloServiceAdmin.aspx?id={0}", Id.ToString()));
        }
    }

    #region IHelloService
    public string SayHello(string name)
    {
        return string.Format("Hello {0} !!!", name);
    }   
    #endregion
}

Implementation de la classe SPServiceApplicationProxy

La dernière étape est la création de la classe proxy de service HelloServiceApplicationProxy qui hérite de la classe SPIisWebServiceApplicationProxy.
Voici le détail d'implémentation de HelloServiceApplication :

[System.Runtime.InteropServices.Guid("C559CC57-543A-4FFA-815B-4B88A603A1FA")]
public sealed class HelloServiceApplicationProxy : SPIisWebServiceApplicationProxy
{
    private HelloServiceApplication m_application;

    public HelloServiceApplicationProxy()
    {
    }

    internal HelloServiceApplicationProxy(string name, SPIisWebServiceProxy serviceProxy, HelloServiceApplication serviceApplication)
        : base(name, serviceProxy, serviceApplication.Uri)
    {
        this.m_application = serviceApplication;
    }

    internal HelloServiceApplicationProxy(string name, SPIisWebServiceProxy serviceProxy, Uri serviceApplicationAddress)
        : base(name, serviceProxy, serviceApplicationAddress)
    {
    }
  
    public HelloServiceApplication Application
    {
        get
        {
            if (this.m_application == null)
            {
                return null;
            }
            return HelloService.Local.GetWebApplicationByName(this.m_application.Name);
        }
    }

    public override string TypeName
    {
        get
        {
            return "Hello Service Application Proxy";
        }
    }
}

CONCLUSION

Après avoir exposé l'architecture d'un "Service Application" et revu sommairement le code nécessaire à sa création, nous pouvons conclure que la mise en oeuvre d'un "Service Application" sous SharePoint n'est pas une tâche triviale, et qu'il est important de valider que cette technique est l'unique solution au besoin avant de l'adopter.