Packager un projet SQL pour Octopus

Publié par Fabrice Michellonet sous le(s) label(s) , , le 1 septembre 2016

Que ce soit manuellement ou de manière automatique, lorsque l'on parle de déploiement il va nous falloir définir un package de déploiement.

Dans l'univers Octopus, les packages de déploiement sont des fichiers avec une extension .nupkg. Voyons comment en créer un pour un projet de Base de données.

Ajouter une dépendance vers Octopack


Octopack est l’utilitaire que nous allons utiliser pour générer ce package de déploiement. Démystifions le terme, octopack produit un fichier qui n’est autre qu’un zip, contenant les fichiers à déployer ainsi qu’un ensemble de métadonnées et potentiellement des scripts powershell.
Bref, rien de bien extraordinaire.

Pour l’installer dans notre projet de base de données, nous allons utiliser Nuget, qui est un gestionnaire de dépendances très performant et bien connu des développeurs. Cependant il n’est pas facilement accessible lorsqu’on travailler sur un projet SQL/SSIS/SSRS/SSAS.

Pour tromper Visual Studio nous allons commencer par ajouter un projet C# de type console pour faire simple



Ajoutons sur ce projet C# une dépendance vers Octopack.



Dans la nouvelle fenêtre on cherche le package Octopack, et on l’installe.



Après avoir acquitté la fenêtre de preview d’install, la fenêtre «Output» de visual Studio devrait vous confirmer que l’installation s’est bien passée.



Il aurait été formidable de pouvoir l’installer directement dans notre projet de base, mais nous allons devoir transpirer un peu plus pour arriver à nos fins.
Ready ?? Ouvrons le fichier csproj de l’application console et copions la portion de msbuild qui correspond à Octopack



Puis, copions la discrètement dans notre fichier sqlproj, de la même manière à la fin de celui-ci.
Un petit rebuild pour vérifier que tout fonctionne toujours bien… et TADAM y’a toujours pas de package de déploiement généré.

Créer le package


Bon si vous avez été un peu curieux, vous aurez remarqué que la portion de msbuild que l’on a copiée a pour but d’importer un autre fichier msbuild (qui se trouve dans le répertoire packages\OctoPack.3.4.1\tools\OctoPack.targets)

En baragouinant un peu le msbuild, on comprend assez vite que la variable RunOctoPack est initialisée à false et c’est elle qui déclenche ou non la génération du package.

Alors évidemment, une solution possible est de modifier cette variable à true. Néanmoins cela induit qu’un package de déploiement sera créé a chaque build du projet. Ce n’est vraisemblablement pas ce que vous souhaitez.

Je vous propose plutôt d’ouvrir une console DOS et une fois dans le répertoire du projet, tapez la commande suivante :

msbuild ContinuousBI.Sql.sqlproj /t:Build /p:RunOctoPack=true

Si tout s’est bien passé vous devriez avoir une sortie similaire a celle-ci :



Cette fois ci, si vous jetez un œil dans le sous-dossier obj/octopacked de votre projet vous y découvrirez un fichier .nupkg qui est le package de déploiement

A quoi ressemble mon package ?


Pour aller un peu plus loin nous pouvons jeter un œil à ce qui a été produit pour nous par Octopack.
Je vous propose d’utiliser nuget package explorer
Ouvrez le et glissez déposez le fichier .nupkg, vous devriez obtenir un résultat semblable à celui-ci.



C’est confirmé, le dacpac issu de la compilation à bien été reconnu ; il est embarqué dans package de déploiement.

Nous verrons dans le prochain post comment le déployer avec Octopus.

Prolific usb to ttl et windows 10

Publié par Fabrice Michellonet sous le(s) label(s) , le 11 mai 2016



Dernièrement j'ai ressorti ma BeableBone Black histoire de faire une peu de veille techno. J'vous raconterai un de ces quatre en quoi monter une boite peut vite cramer tout votre temps libre, mais c'est pour la bonne cause.



Bref pour en revenir à la Beagle, je ressors mon câble série que j'utilise pour me connecter à la console. Je fais les branchements et go sur le site de Prolific pour récupérer le dernier driver pour Windows 10.

Tiens! bizarre, même après un reboot je n'ai toujours rien qui s'affiche dans mon terminal.
En creusant, je m'aperçois que le driver du câble n'est pas reconnu.



S'en suit plusieurs tentatives de réinstallation et de reboot infructueuses.

Je cherche un peu sur Internet, pas mal de personnes ont des soucis avec des versions contrefaites acheté sur des sites asiatiques. Le mien vient de chez Adafruit, et il fonctionnait parfaitement il y a quelques mois, sur Windows 8.

Ho... tiens réessayons sur cet ancien PC. Ca fonctionne parfaitement!
Énorme je récupère l'installer du driver qui se trouve sur ce dernier;
Je repasse sur mon PC équipé de Windows 10, désinstalle le driver en place, reboot, installe l'ancien driver (fonctionnant sur Windows 8) et surprise, ca fonctionne.

Si ça c'est pas de l'obsolescence programmée! Honteux!
Rien que pour ça, je vous recommande plutôt d'investir dans un câble concurrent comme ce FTDI. J'en possède un également et fonctionne tout aussi bien.

Du coup, je vous dépose le driver fonctionnel, ici. J'espères que cela pourra aider quelqu'un.

Tiens, en prime je poste ici le schéma de branchement du câble Prolific avec la beagle.
  • Le fil noir va sur le pin 1 (GND)
  • le fil vert sur le pin 4 (RECEIVE)
  • le fil blanc sur le pin 5 (TRANSMIT)
Ne branchez surtout pas le fil rouge, c'est du 5V, vous grilleriez la beagle!!

Comment invoquer une méthode dont on connait le nom à l’exécution sur un dynamic?

Publié par Fabrice Michellonet sous le(s) label(s) , le 24 juillet 2015
Comment invoquer une méthode dont on connait le nom à l'exécution sur un dynamic?

Le mot clé dynamic en C# n'est pas nouveau, il a vu le jour avec C# 4 et pourtant il n’apparaît pas si souvent que ça dans les bouts de code que je fréquente.

Dernièrement je l'ai recroisé en utilisant SignalR; les hubs qui sont générés sont des objets dynamic.

Quoi qu'il en soit, dernièrement j'ai eu besoin d'invoquer une méthode dont le nom ne m'était connu qu'à l'exécution.
Croyez-moi, j'y ai passé un petit moment avant d'y arriver... Cela révèle vraisemblablement ma grande ignorance :)

Ce blog post prendra donc la forme d'un post-it qui me fera gagner du temps la prochaine fois que je me frotterai a cette bête-là. Si pour vous les classes Binder et CallSite n'ont plus de secret ce blog post vous semblera vraisemblablement bien terne.

Posons le problème, on me donne un objet dynamic auquel une méthode est ajoutée à l'exécution

private string sentence = "Hello world";

        public dynamic BuildObj()
        {
            dynamic myDynObj = new ExpandoObject();
            myDynObj.SayHello = new Func<string>(() => sentence);
            return myDynObj;
        }

Si j'avais connaissance de la méthode lors de la compilation je pourrais l'appeler ainsi :

[Test]
        public void CallDirectlyMethod()
        {
            dynamic myObj = BuildObj();

            var ret = myObj.SayHello();
            Assert.That(ret, Is.EqualTo(sentence));
        }

Malheureusement la signature de la méthode ne m'est connue qu'à l'exécution.
Ok, premier réflexe je sors l'attirail de la reflection.... mais les résultats restent catastrophiques :

[Test]
        public void CallMethodWithReflectionFails()
        {
            dynamic myObj = BuildObj();
            Type t = myObj.GetType();
            var method = t.GetMethod("SayHello", BindingFlags.Default | BindingFlags.Instance | BindingFlags.InvokeMethod  | BindingFlags.NonPublic);
            Assert.That(method, Is.Null);
        }

Quels que soient les bindings flags, impossible de trouver la méthode... FAIL!!

Voici, donc la combinaison magique, un savant mélange de Runtime.Binder et CallSite...

[Test]
        public void CallMethodWithCallSite()
        {
            dynamic myObj = BuildObj();

            var callSiteBinder = Binder.InvokeMember(CSharpBinderFlags.None, "SayHello",
                Enumerable.Empty<Type>(), myObj.GetType(),
                new []
                {
                    CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)
                });

            var callSite = CallSite<Func<CallSite, object, object>>.Create(callSiteBinder);
            string ret = callSite.Target(callSite, myObj);

            Assert.That(ret, Is.EqualTo(sentence));
        }

Ok, essayons de décrypter un peu ce code qui semble un peu alambiqué.
Binder.InvokeMember va nous permettre à l'exécution de pointer la bonne méthode un peu comme le ferait typeof(myObj).GetMethod()
Le premier paramètre permet de spécifier la manière dont est traité le type de retour. Dans le cas d'une Action nous aurions pu utiliser CSharpBinderFlags.ResultDiscarded. Dans notre cas, une Func, CSharpBinderFlags.None fonctionne bien.

puis viens en seconde position, évidement le nom de la méthode a appelé, passée sous forme de chaine.

En troisième position, il conviendra de fournir la liste des arguments de types à nécessaire dans le cas d'une méthode générique.

Viens ensuite le type sur lequel effectuer l'invocation, ce qui permet de pointer une surcharge.

Et finalement les informations sur les paramètres attendus et le type de retour (le premier élément du tableau);

La création du CallSite<Func<CallSite, object, object>> permet d'arrêter la signature du delegate que l'on cherche à appeler. Notez, que le dernier argument générique "object" devrait etre "string", car il représente le type de retour de la func... mais pour une raison qui m'échappe l'utilisation de string comme type de retour entraîne une erreur au runtime, alors que le retour de la func est bien affecté à une variable string à la ligne du dessous... il faut bien garder un peu de magie :)

Ok, évidemment il ne nous reste plus qu'à effectuer l'invocation, ce qui est réalisé via le code callSite.Target(callSite, myObj);

J'espère que ce post évitera quelques cheveux blancs a ceux qui se trouveront confronté au problème.

BeagleBone Black du carton à Mono

Publié par Fabrice Michellonet sous le(s) label(s) , , , le 1 juin 2015

L’IOT, on en parle partout, de plus en plus ; évidemment l’univers Microsoft n’est pas en retrait sur ce domaine avec la mise à disposition de Windows 10 sur le Raspberry ou encore le MinnowBoard MAX

Vous trouverez pas mal de blog post autour du raspberry… je vais donc plutôt vous présenter comment vous lancer dans le développement .NET embarqu& sur cette magnifique plateforme qu’est le BeagleBone Black (BBB). Au travers de cet article je vous propose d’étudier les différentes étapes à réaliser pour pouvoir lancer votre premier « Hello World » embarqué.



Tout d’abord il n’y a pas de Windows 10 sur le BBB, en tout cas pour l’instant, mais très honnêtement l’installation d’Ubuntu que je vous propose est à la portée de tous.

Matériel nécessaire


Je commence par un petit coup de pub pour le site AdaFruit ou vous trouverez tout le matos que vous pouvez imaginer pour nos petits joujoux.

Aller Go ! Pour faciliter la visualisation de ce qui se passe sur votre BBB je vous conseille d’investir dans un câble Serial TTL-232 en usb. Sans celui-ci vous devrez attendre que le BeagleBone ai récupéré une IP et vous y connecter (en ssh par exemple) et interagir avec.

Pour brancher le câble prenez comme repère le fil noir qui doit venir se placer sur le pin J1 de votre BBB.

Installez les drivers FTDI pour prendre en compte l’adaptateur usb. Ils se trouvent ici

Finalement en utilisant Putty, configuré comme ci-dessous la console s’affiche enfin sur votre pc.



Si l’idée de brancher un câble Ethernet sur votre BeagleBone vous donne de l’urticaire, je vous conseille ce dongle usb. Il est directement reconnu sous Ubuntu.


Installation d’Ubuntu




Nous allons installer dans la mémoire eMMC la version 14.04 d’Ubuntu spécialement conçue pour la BBC. Après avoir téléchargé le fichier img.xz, il vous faudra le décompresser avec un outil comme 7zip.

L’image ainsi extraite pourra être copiée sur une micro sd avec Win 32 Disk Imager

Lorsque la copie se termine, insérer la micro sd dans le port prévu à cet effet sur la BBB. Tout en appuyant avec votre index sur le bouton « boot » (le plus proche du port Ethernet), alimentez la BeagleBone. Laissez le doigt appuyé jusqu’à ce que les diodes clignotent.

Il faut 5 bonnes minutes pour que l’installation se termine ; mais grâce au câble TTL vous serez aux premières loges pour suivre l’installation.

Mise à jour du Système et installation de mono


Ok, si vous en êtes arrivé là, c’est du tout cuit.

Nous allons commencer par mettre à jour le système grâce package manager APT. A partir de la console tapez les commandes suivantes :

sudo apt-get update
sudo apt-get upgrade

Après quelques minutes le système est prêt, on peut passer à Mono. Le runtime devrait être suffisant étant donné que l’on va se contenter d’exécuter des binaires créer sur votre machine de dev. Pour l’installation on tape donc :

sudo apt-get install mono-runtime

Création de l’exécutable et déploiement sur le BBB


Je vous laisse écrire votre premier Hello Beagle World dans Visual Studio ; en créant un projet de type console et en targettant le Framework 4.5;

Une fois compilé, j’ai opté pour un déploiement type « bin-deploy » en utilisant un transfert via PSCP

Une fois PSCP copié, vous pourriez copier le fichier avec une ligne de commande comme celle-ci :

pscp.exe "C:\ BBB\ HelloWorld\bin\Debug\HelloWorld.exe" ubuntu@192.168.10.2:/home/ubuntu

Le premier paramètre étant le ficher à transmettre le second l’url de destination au format :

user@hote:/chemin_de_destination

En dessert, après tous ces efforts, nous pouvons enfin exécuter sur le Beagle notre Hello World en tapant :

Mono HelloWorld.exe

Kibana : Explorez vos données.

Publié par Fabrice Michellonet sous le(s) label(s) , , , le 23 décembre 2014

Cet article fait partie d’une sérié dédiée à Elasticsearch, reportez vous à l’article sommaire pour accéder facilement aux autres posts.


Kibana est la brique de visualisation qui gravite autour d’Elasticsearch. Voici, quelques exemple de représentations faites avec Kibana :





Kibana 2


Kibana 3


L’exploration de données et la réalisation de dashboard ne nécessitent aucun code, ce qui permet de donner la main aux fonctionnels ; De plus Kibana et Elastocsearch permettent d’avoir des rapports real time, se mettant à jour à mesure que les données sont stockées.

Pour les lecteurs qui connaissent bien la stack SQL Serveur, on pourrait le comparer à un Report Builder sous stéroïdes et surtout qui tiendrait (mieux) ses promesses de simplicités et d’accessibilité pour les non-techniciens

Je me propose dans ce billet de découvrir ensemble les fonctionnalités de « data discovering » sur un dataset public recensant les accidents corporels de la circulation

Si ces données vous intéressent, je vous invite d’ailleurs à jeter un œil à la très bonne session (video, slides) de Patrice Harel sur le mining avec SSAS et qui s’appui sur le même jeu de données.


Installation

Commençons par l’installation qui comme pour les autres composants de la stack est triviale :
Tout commence évidement par le téléchargement du binaire ici, suivi de la décompression de l’archive.
Si votre instance elasticsearh ne tourne pas sur le même serveur qui hébergera Kibana ou si elle écoute sur un port non standard, il vous faudra modifier le fichier de configuration config/kibana.yml.
Dans mon cas, je ne touche à rien!
Puis à l’aide d’une fenêtre commande, il nous faudra exécuter /bin/kibana après s’être placé dans le répertoire ou a été décompressé l’archive.
Finalement pointons notre navigateur sur l’url http://localhost:5601

Exploration

S’il s’agit de la première fois que vous lancez Kibana, cet écran vous sera présenté, dans lequel il vous faudra choisir un index (équivalent de base de données) ainsi qu’une colonne typée date.
Ce dernier point est extrêmement important, car Kibana part du principe qu’il est naturel pour l’esprit humain et plus facile de découvrir des données lorsqu’elles sont représentées sur une frise.



Dans notre dataset, nous ne disposons malheureusement pas de la date de l’accident, qui aurait été le candidat idéal en tant que « time field ».
Pour l’exemple, nous nous rabattrons sur le champ @timestamp représentant l’instant ou a été inséré l’événement dans notre index.

On se retrouve propulsé dans nos données via l’écran suivant :



On reconnait très vite plusieurs sections dans cette interface :

  • La colonne de gauche qui contient les champs à disposition (1).
  • Tout en haut (2), une zone de filtre ; n’oublions pas qu’elasticsearch est un moteur de recherche…
  • L’indicateur du nombre d’enregistrements après filtrage (3).
  • La frise temporelle sur laquelle on regarde les événements (4).
  • Finalement la vue tableau de données au centre. Notons que pour l’instant elle nous représente la version brute des données, car nous n’avons pas encore choisit de colonnes à afficher.

Commençons par cliquer sur les barres du graph afin d’effectuer un drilldown au niveau temps.



Instantanément cela nous permet de découvrir la répartition des data dans le temps. Notez, que les clics que nous avons fait sur le graph sont interprétés comme une clause de filtrage, diminuant les événements auxquels on s’intéresse.

Pour avoir un aperçu du contenu des champs, je vous conseille de cliquer sur le nom d'un champ dans la colonne de gauche ; comme ceci :



Les informations et actions présentées ici sont une vraie mine d’or.
En plus d'un premier comptage des données sous-jacentes, on peut par exemple se concentrer sur les événements qui ont eu lieu sur l’A31 en cliquant sur l'icone loupe+. Evidemment, la frise temporelle et les données sont mis à jour.



Maintenant, intéressons nous au champ tbl qui représente le nombre de blessés légers dans un accident.



En cliquant sur « Visualize », on obtient la répartition top 20, sous forme d’histogramme, du nombre de blessés légers sur l’ensemble des événements de la base.



Ici aussi cette visualisation, nous permet d’appréhender rapidement la teneur de nos données.

Finalement jetons un œil, au filtre qui se trouve tout en haut de l’interface de Kibana. Par défaut, vous y trouverez une *. Attention, il n’y a pas ici d’analogie avec SQL, ici l’étoile signifie sans filtre.
Nous pourrions par exemple nous intéresser à une commune en particulier, celle de Cergy par exemple (95002). Il nous suffira pour ce faire de saisir le filtre suivant :

codeinsee:=95002



Ou bien les accidents impliquant plus de 2 morts
ttué:>2



Ou encore les accidents impliquant plus de 2 morts dans l’Oise :
ttué:>2 AND codeinsee [60000 TO 69999]



Voila qui clos ce premier article sur Kibana, en espérant vous avoir donné envie d’essayer ce superbe outil.