Blog ENI : Toute la veille numérique !
-25€ dès 75€ sur les livres en ligne, vidéos... avec le code FUSEE25. J'en profite !
Accès illimité 24h/24 à tous nos livres & vidéos ! 
Découvrez la Bibliothèque Numérique ENI. Cliquez ici

Bases de la programmation de composants

Introduction

Ce chapitre présente les bases pour concevoir son propre composant de flux de données, une tâche de flux de contrôle ou encore un gestionnaire de connexions, totalement intégré au produit, packageable et réutilisable, tout cela en utilisant l’API de création de composants SSIS.

1. Pourquoi développer un nouveau composant ?

Il est en effet intéressant de se poser la question. Dans les chapitres précédents, il a été expliqué que l’utilisation des scripts pouvait combler l’essentiel des lacunes existantes dans les composants intégrés au produit.

Mais que se passe-t-il lorsqu’une mise à jour du code d’une tâche de script devient nécessaire et que celle-ci est utilisée dans des dizaines de packages ? Il n’y a aucun moyen de factoriser des scripts, le risque est donc, lors du long processus de copier/coller de code, d’oublier certains packages. Sans compter le paramétrage et la documentation : il est nécessaire, comme pour une procédure stockée SQL, d’extrêmement documenter tous les lots qui font usage du code en question pour en permettre une exploitation sereine.

Un composant SSIS répond à ces problématiques : il offre la possibilité de réutiliser ce code, de le distribuer avec une boîte...

Pour bien démarrer

1. Quelques notions avant de commencer

Avant d’entrer dans le vif du sujet, il est important d’éclaircir un point. Une bonne partie des briques de SSIS - le flux de données en est un bon exemple déjà abordé - ont été développées par Microsoft en code natif, autrement dit en C++. Les composants que vous allez développer seront eux tous écrits en .NET.

Vous voilà rassuré, j’imagine...

Techniquement, ils pourront s’exécuter dans un contexte natif grâce à des wrappers prévus à cet effet. C’est le sens des mots « native » et « managed » dans le schéma d’architecture global du produit.

Avec les versions supérieures à SQL Server 2012, les composants, qui se présentent sous forme d’une librairie ou assembly .NET, doivent être développés a minima avec la version 4.0 du framework .NET, et déployés dans le GAC ou Global Assembly Cache de la machine. Les librairies peuvent alors être référencées par SSIS et utilisées par le moteur d’exécution.

Pour pouvoir utiliser les tâches customisées dans SQL Server Data Tools, il en faut un petit peu plus. En effet, ce dernier va parcourir les dossiers physiques contenant des DLL identiques à celles du GAC pour peupler les éléments utilisables dans les concepteurs. Ces dossiers se trouvent traditionnellement dans le sous-dossier \140\DTS\ de l’installation de SQL Server.

Ce dossier est dépendant de votre version de SQL Server, ainsi, sur SQL Server 2017 il s’agit de \140, \130 sur SQL Server 2016, \120 sur SQL 2014... Il est aussi possible d’obtenir leur emplacement en recherchant la valeur de la clé de registre :


HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL  
Server\140\SSIS\Setup\DTSPath
 

Attention, sur un système...

Exemple d’une tâche de flux de contrôle

1. Tâche personnalisée d’envoi d’e-mail

SQL Server Integration Services ne contient pas de tâche par défaut, permettant de faire des envois d’e-mails par une authentification autre qu’intégrée ou anonyme. Or, beaucoup de serveurs SMTP supportent uniquement une authentification basique et ne peuvent donc pas être utilisés dans SSIS. Il est possible de faire cet envoi à travers une méthode en C# très simple qui fait usage du SmtpClient de .NET. Celui-ci permet en effet d’envoyer des e-mails sans restriction sur les modes d’authentification. Ce morceau de code peut ensuite être intégré à une tâche de script SSIS.


private void EnvoieEmail(string host  
    , int port  
    , bool defaultCredentials  
    , string userName  
    , string password  
    , string from  
    , string to  
    , string subject  
    , string body  
    )  
{  
    using (SmtpClient c = new SmtpClient(host, port))  
    {  
        c.UseDefaultCredentials = defaultCredentials;  
        if(!defaultCredentials)   
            c.Credentials = new NetworkCredential(userName, password); 
        using (MailMessage m = new MailMessage(from, to, subject, body)) 
        {  
            c.Send(m);  
        }  
    }  
}
 

Comme évoqué en introduction, cette approche à base de tâche de script souffre de plusieurs lacunes, telles que la nécessité de copier/coller le code pour chaque utilisation. Il semble donc intéressant de créer une tâche personnalisée.

Tel que présenté dans les chapitres précédents, lorsqu’il s’agit de se connecter à une ressource extérieure, la philosophie du produit est de séparer la connexion de la tâche, il faudrait donc créer un gestionnaire de connexions personnalisé en plus de la tâche l’utilisant.

2. Rappels...

Log Provider, ouverture, logging et fermeture du log

1. Création d’un Log Provider

Un Log Provider a une tâche relativement simple : envoyer dans une destination déterminée une ligne de log, composée d’un certain nombre de champs que vous avez découverts dans les précédents chapitres.

Pour rappel, par défaut dans SSIS il est possible d’enregistrer cette ligne :

  • dans une base SQL Server

  • dans divers types de fichiers (CSV, TRC, XML)

  • dans le gestionnaire d’évènements de Windows

On peut souhaiter étendre ces fournisseurs pour envoyer les lignes vers toute autre destination. Pour continuer avec les e-mails, pourquoi ne pas imaginer, par exemple, envoyer toutes les lignes de log d’un package dans un e-mail unique ?

Après avoir étendu la classe LogProviderBase, renseigné un DtsLogProviderAttribute et déployé un Log Provider dans le système de fichiers et le GAC comme expliqué au début du chapitre, ce Log Provider apparaît dans le menu SSIS - Enregistrement.

images/capt7-03.png

Le seul paramètre permettant de configurer un Log Provider est la chaîne de caractères présente dans la colonne Configuration. Au sein du composant, il s’agit de la propriété ConfigString, dont on peut bien sûr surcharger les méthodes get et set.

Ensuite, seules trois méthodes sont essentielles.

OpenLog est appelée lorsque le log est ouvert pour...

Énumérer sur toute collection avec un ForEachEnumerator

1. Création d’un ForEachEnumerator

Un ForEachEnumerator est très simple : hormis les codes de validation et d’initialisation, la seule méthode intéressante est la méthode GetEnumerator, qui doit renvoyer la collection d’objets sur laquelle itérer. Dans le cas d’un énumérateur sur des utilisateurs de domaine via WMI, cette méthode peut prendre la forme suivante : elle interroge WMI et renvoie une ArrayList de noms d’utilisateurs.


[DtsForEachEnumerator(DisplayName = "Enumerateur WMI",  
      Description = "A managed enumerator",  
      UITypeName = "ForeachWMI.ForeachWMIUI, ForeachWMI,  
Version=1.0.0.0, Culture=neutral, PublicKeyToken=1d3d0d61bfe2e94b",  
      ForEachEnumeratorContact = "Charles-Henri Sauget -  
chsauget@scop-it.com")]  
    public class ForeachWMI : ForEachEnumerator  
    {  
        private string _domain = string.Empty;  
  
        public string Domain { get => _domain; set =>  
_domain = value; }  
  
        public override object GetEnumerator(Connections connections, 
VariableDispenser variableDispenser, IDTSInfoEvents events,  ...

Sources, destinations et transformations personnalisées

À l’inverse des précédents, un PipelineComponent est très complexe et il est totalement inenvisageable d’en couvrir toutes les subtilités dans un seul chapitre d’un livre. Tout d’abord, contrairement aux autres composants, ce n’est pas ManagedDTS qui va être la bibliothèque de base, mais Microsoft.SqlServer.PipelineHost, DtsRuntimeWrap et DtsPipelineWrap.

Ensuite, il existe divers types de composants, des sources, des transformations et des destinations. Fort heureusement, la manière de les coder se ressemble beaucoup. Il est nécessaire d’être familier des scripts de Data Flow et des notions de synchronicité, afin d’aborder sereinement le développement de composants de flux de données personnalisés. Dans le cas contraire, il est conseillé de revoir ce chapitre.

L’exemple que nous allons utiliser est basé sur un cas d’utilisation concret, cela en fait une solution complète, mais aussi complexe, s’il s’agit de votre première expérience sur le sujet. Il serait préférable de démarrer avec la section sur la création d’une tâche personnalisée.

1. Cas d’usage

L’objectif du composant source personnalisé présenté ici est de récupérer des données depuis une table contenue dans un compte de stockage Azure (Azure Blob Storage).

images/7-RI-15.PNG

Afin de charger des données de test dans un stockage Azure Table, il est possible d’utiliser Microsoft Azure Storage Explorer, un fichier d’exemple prêt à charger est disponible dans les éléments à télécharger.

Les données à récupérer sont donc présentes dans un stockage Azure Table https://bloblivre.table.core.windows.net. Elles contiennent le code des employés ainsi que leurs salaires. Ces informations doivent être intégrées à l’entrepôt de données de l’entreprise afin de préparer le prochain plan social. Toutefois, aucun des composants natifs à SSIS ne permet de récupérer celles-ci, et sachant que ce type de source va devenir commun au sein de l’entreprise à la vue de son coût...

Débogage

1. Débogage des composants personnalisés

Afin de pouvoir tester vos composants personnalisés, il est nécessaire de les utiliser au sein d’un package SSIS. Or, il n’est malheureusement pas possible de déboguer le code de ces composants depuis SQL Server Data Tools. En effet, celui-ci lance le package dans un processus séparé, appelé DtsDebugHost. S’attacher à ce processus est difficile, voire impossible, car son exécution ne dure que très peu de temps. Fort heureusement, une solution autre que Debug.Writeline(« toto ») ou MessageBox.Show(« toto ») existe.

Il est possible de configurer votre bibliothèque afin de lancer, lorsqu’elle est exécutée en mode debug, un package de test via DtExec au sein de votre environnement de développement C# ou VB.net. Cela se configure dans les propriétés du projet, dans la partie Déboguer. Paramétrez l’action de démarrage à DtExec.exe, qui se situe dans une installation par défaut à l’emplacement suivant :


C:\Program Files (x86)\Microsoft SQL Server\<Sql 
Version>\DTS\Binn\DTExec.exe
 

Dans la partie paramètres, ajoutez les paramètres nécessaires pour lancer le lot de test : /FILE ou /F permettant de lancer un lot en mode fichier.


/F "C:\Users\scharly3\source\repos\Livre...