sabato 17 marzo 2018

Building an HMI with electron.js (Episode 2)

Building an HMI with electron.js (Part 2)

Let’s tak a step ahead in our journey toward the target of this notes that is, how to build an HMI runnable on different platforms using some Web Technologies.

Let’ add some TypeScript

The first step is to rearrange our project in order to introduce TypeScript.

  • First thing first, we’ll create a new folder named src wich will contain our TypeScript source files;
  • Then let’s rename our JavaScript files changing their extensions from js to ts, and move them from the root folder to the src folder. The content of the files will not change much, after all TypeScript is a superset of JavaScript. Infact the only thing that we’ll change are the const and let declarators that, in the spirit of the new idioma will become var;
  • Another change in the main.ts file is the relative path of the index.html file that will change into
  • A major change is the introduction of the tsconfig.json file in the root of our project which specifies the root files and the compiler options required to build the project.
    "compilerOptions": {
      "target": "es5",
      "module": "commonjs",
      "moduleResolution": "node",
      "noImplicitAny": false,
      "sourceMap": true,
      "outDir": "dist",
      "baseUrl": ".",
      "paths": {
        "*": [
    "include": [
  • Finally, we have to add some changes to our packag.json file, and in particular, we’ll add a build script that will invoke our TypeScript compiler tsc
"build": "tsc",

and then we need to modify a little our start script as follows:

"start": "npm run build && electron ./dist/main.js"

so that, in a few words, it will initially compile our TypeScript project, and then launch the application passing to the electron command the resulting main.js file.

Figure 2 - Running the TypeScript version

The code written for this note is available for consulting and comments on my GitHub Repository at the following link.

For now that’s all folks.

Enjoy, ūüėČ

giovedì 1 marzo 2018

Building an HMI with electron.js

Building an HMI with electron.js

As an engineer involved in the last two decades in design and development of complex systems in different fields such as Industrial Automation, Internet Of Things, and lately in Virtual/Augmented Reality aided Training Systems, one of the tasks to face with is the development of different HMI clients to allow the interaction between the end user and the above mentioned systems.

This note, and the attached project, freely available on my github repository, is aimed to identify a set of technologies that will allow the realization of those interfaces independently, as far as possible, from the hardware and operating system platform on which they are intended to run. Independency, in my humble opinion, is, and will be, a key concept, that will allow system engineers to scale all the components to the real needs and to the budget available to accomplish the requirements of a project.

Among all the different techonologies available on the market nowadays, the only ecosystem that is really cross platform is the one centered on the javascript programming language. Neither Java or .NET are capable of such a capillary diffusion natively. The language once used only for client applications running in a browser, thanks technologies like Node.js make its use allowed server side also. There’s a lot of tools and libraries borrowed from the Web Applications field that make the implementation of appealing user interfaces really simple. Boxing all this stuff in a desktop application runnable on Windows, Linux or even macOS, is really straightforward with frameworks such as electronjs.

The only caveat toward the use of plain javascript for large applications is in the nature of javascript itself or in the fact of being a loosely typed programming language. This fact made me, and many other old style programmers I suspect, suspicious respect the use of this idoma, but when I first read about TypeScript, a superset of Javascritpt introduced by Microsoft, that introduces types in JS, I felt very curious, and, a I always do with those kind of things, I began to study, and to search for some tools that hopefully will allow me to achieve the target that is to implement an HMI capable to connect and communicate over some channels and to run on my macbook, on a Windows pc/laptop and also on a tiny Raspbery Pi.

Development workstation setup

Let’s begin preparing to necessary to build do our application. To prove that the final product is really cross platform I will use a Macbook Pro with macOS High Sierra ver. 10.3.3 as my main development machine and a Windows 10 Pro laptop and an Ubuntu Server 16.04 LTS machine to repackage and test the resulting application.

To install all the necessary packages and frameworks I’ll make use of package managers, and, in detail:



First of all we need to have node.js, the javascript runtime, installed on development machines. I prefer using an LTS version, that, at the time of writing is 8.9.4 LTS. We can download the installer for the desired os from the node.js site, or we can use the above mentioned package managers.

On macOS, on a terminal we’ll issue the command

MacBook-Pro-di-Maurizio:/ maurizioattanasi$  brew install node@8

which will download and install the latest release of version 8. After the installation process terminates, on the same command line we’ll state the following command:

On a Windows system, with Chocolatey installed, on a command prompt, we’ll use the command:

C:\> choco install nodejs-lts

On Debian/Ubuntu machines, we’ll use:

m***@m***-server:~$ apt-get install -y nodejs

Node installation check

After the installation process, on a command promp (or Terminal), we’ll issue the command node -v to check the current version of node, and npm -v, to check the current version of npm.

MacBook-Pro-di-Maurizio:/ maurizioattanasi$ node -v

that tells us that we have installed the desired version. As a side effect of installing node.js, we have also at our disposal the *Node Package Manager a.k.a. npm. To check the npm version, on the terminal, we’ll issue:

MacBook-Pro-di-Maurizio:/ maurizioattanasi$ npm -v



By installing TypeScript we mean the TypeScript compiler, named tsc that is the main component needed to compile TypeScript code into plain JavaScritpt. Having npm installed on our development machines, this step is quite straightforward. On a command prompt, or a terminal, simply type:

MacBook-Pro-di-Maurizio:/ maurizioattanasi$ npm install -g typescript

then hit enter. After completion we’ll have tsc, the TypeScript compiler, installed globally (-g switch applyed to the npm command). To check the version installed, as usal, type:

MacBook-Pro-di-Maurizio:~ maurizioattanasi$ tsc -v
Version 2.6.2

Perfect! We have node.js version 8.9.4, npm version 5.6.0 and TypeScript version 2.6.2 installed on our machine. From now on we only need a text editor, one with which we feel at ease, and we can start writing down some code.

Project setup

To start a node project we’ll use npm again:

maurizioattanasi$ npm init -y

that will result in a package.json file which content will be similar to:

  "name": "electron-hmi",
  "version": "1.0.0",
  "description": "Demonstration project to explore the possibilities offered by multiplatform technologies such as node.js, typescript and electron, in **H**uman **M**achine **I**nterfaces (HMI) development.",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  "repository": {
    "type": "git",
    "url": "git+"
  "keywords": [],
  "author": "",
  "license": "MIT",
  "bugs": {
    "url": ""
  "homepage": ""

electronjs setup


Following the instructions on the npm page for electron, on the terminal:

maurizioattanasi$ npm install electron --save-dev --save-exact


maurizioattanasi$ npm i electron -D -E

at the end we’ll have the package.json file

  "devDependencies": {
    "electron": "1.8.2"

First electron app… The JavaScritp way


Following the electron tutorial Writing Your First Electron App
, we’ll create a main.js file and a index.html file and we’ll modify the package.json as follow:

  "main": "main.js",
  "scripts": {
    "start": "electron ."

Now we can try our application running…

maurizioattanasi$ npm start

…and, here we have our first web based desktop application.

Figure 1: My First Electron HMI

The next step is to replace the JavaScript code with TypeScript.


giovedì 4 maggio 2017

Docker…Buzzword o nuovo strumento nella nostra cassetta degli utensili?

Tutti quelli che come me sono sempre incuriositi alle novit√† si sono sicuramente imbattuti in un articolo che, a dir poco, osanna le virt√Ļ derivanti dall’utilizzo dei container per lo sviluppo e la distribuzione del software. La tecnologia dei container non √® nuova. Disponibile in ambiente linux dalla versione 2.6.4 (intorno al 2004) la tecnologia nota con l’acronimo LXC, sta venendo alla ribalta negli ultimi anni grazie soprattutto alla piattaforma Docker.
Volendo semplificare all’estremo il concetto si pu√≤ pensare che la containerizzazione avr√† un’impatto in ambito ITC pari almeno a quello avuto dall’introduzione delle macchine virtuali.

In origine erano le Virtual Machines…

Nella mia esperienza l’introduzione tra i miei strumenti del VMWare Player ha portato una piccola rivoluzione nel mio modo di lavorare. All’epoca ero impegnato nello sviluppo di un sistema di visione artificiale integrato nel sistema di controllo di un robot. Il sistema di controllo era implementato su una piattaforma Linux Debian, il che mi obbligava ad avere lo stesso sistema operativo sulla macchina di sviluppo e quindi o avere due computer o, pi√Ļ realisticamente, installare un secondo sistema operativo ed avviare il computer a seconda del progetto al quale stavo lavorando. La possibilit√† di avere una macchina virtuale che mi consentiva di avere contemporanemante sotto mano sia KDevelop e Debian che Visual Studio e Windows Xp era il massimo in termini di comodit√† ed efficienza.
Un altro vantaggio derivante dall’utilizzo delle macchine virtuali, √® stato quello di poter creare delle macchine di sviluppo molto simili, se non identiche, alle macchine in produzione in termini di pacchetti software installati, versioni particolari di driver di periferica, ecc.. Macchine di sviluppo che, in quanto virtualizzate ho la possibilit√† mettere da parte al termine della fase di sviluppo e tirar fuori al bisogno nel caso di un aggiornamento, di un bug fix, o di una semplice assistenza.
Last but not Least ora sono in grado di lavorare con qualunque sistema operativo a prescindere da quello installato sull’host (negli ultimi anni macOS su un Macbook Pro).
Il problema di fondo legato all’utilizzo delle macchine virtuali √® dato dal peso che ognuna di esse ha in termini di risorse hardware cosa molto evidente se poi parliamo di un laptop. Avere a disposizione pi√Ļ macchine virtuale, o, peggio ancora, mandarne in esecuzione pi√Ļ di una allo stesso momento √® un impresa ardua se si dispone di ‘soli’ 16GB di RAM ed un disco SSD da 256GB. E se poi volessimo creare un sistema di sviluppo per SharePoint? IMPOSSIBILE!…o No…?

… E poi arriv√≤ Docker™

A rendere ancora pi√Ļ interessante la faccenda c’√® la comunit√† di utenti pronti a condividere le proprie esperienze su piattaforme come Docker Hub.
Ok, di documentazione e di tutorial on line ce ne sono un’infinit√† ed in continuo aggironamento, quindi mi asterr√≤ dal ripetere ci che √® egregiamente illustrato da persone pi√Ļ esperte di me nel settore. Un buon punto di partenza √® la documentazione ufficiale (DOCKER 101: GETTING TO KNOW DOCKER).

Un caso pratico

Un esempio per dare un’idea della semplicit√† e dell’efficacia dello strumento per√≤ √® il caso di farlo se non altro per invogliare qualcun altro ad approfondire l’argomento. A tal fine utilizzer√≤ proprio un’esperienza che ho fatto poco tempo f√†, per risolvere un problema ad un cliente il cui sito web, a seguito di un attacco informatico, era stato accidentalmente cancellato, e l’ultimo backup disponibile era molto differente nei contenuti dalla versione persa. Il CMS utilizzato per creare il sito era Joomla! nella versione 2.5, ed il database era MySql. La procedura standard per predisporre un ambiente di sviluppo (LAMP, MAMP o WAMP a seconda del sistema operativo) sarebbe, in linea di principio:
- predisporre un server Apache o nginx;
- installare la versione corretta di php;
- installare la versione corretta di MySql;
In alternativa possiamo installare la versione di WAMPServer o MAMP.


Qualunque strada si decida di intraprendere, al termine, il nostro pc sar√† configurato per far girare un server Apache, avremo un database MySql ed una versione di php compatibile con la versione del cms del nostro sito web. Non ci resta che copiare il backup nella directory htdocs (o qualunque sia la cartella servita da Apache), modificare il file di configurazione in modo che possa puntare all’istanza di MySql ed al database, aprire il browser, navigare all’indirizzo http://localhost:8080 ed il gioco √® fatto, abbiamo una copia del sito web che gira sulla macchina di sviluppo sulla quale fare considerazioni e/o modifiche. Fin qui la procedura classica, e per il mio caso, un intervento su un sito web in particolare pu√≤ andare pi√Ļ che bene. In fondo, non essendo il mio mestiere, quanti siti web dovr√≤ mai far girare sul mio laptop? Ma se cos√¨ non fosse? Se arrivasse una richiesta d’intervento su un sito implementato con un cms diverso, con una diversa versione di php, o con un database diverso database? E questo sempre rimanendo nell’area dei cms che girano su server Apache, Php e MySql. Cosa dire poi se al posto di Apache fosse richiesto nginx, se al posto di MySql avessimo bisogno di PostgreSQL o SQL Server, ed al posto di php volessimo Ruby on Rails, o .NET o Java, o python o nodejs. E via dicendo verso l’infinito ed oltre…. Ok possiamo installare tutto (o almeno provarci) sulla nostra macchina e tentare di creare un ambiente di sviluppo simile, per quanto possibile, all’ambiente di produzione…. SIMILE ma certamente NON UGUALE. E anche se ci accontentiamo di SIMILE dobbiamo sempre sperare che nessuno dei pacchetti installati vada in conflitto con qualcos’altro…. Ok, proviamo un’altra strada.
Torniamo al caso di partenza, ovvero Joomla! in una particolare versione.
Una possibilità è quella di creare il nostro container a partire da una versione vanilla di una distribuzione di Linux, e, seguendo il manuale per la creazione di un container custom, installare tutti i componenti di cui abbiamo bisogno. Oppure possiamo ricorrere alle risorse messe a disposizione da altri sviluppatori su repositories come il già citato Docker Hub. Facendo una ricerca con la parola chiave Joomla troviamo ben 158 risultati, cercando, invece mysql, di risultati ne abbiamo 6418!

docker-hub-joomla docker-hub-mysql

Per far girare docker sul nostro sistema di sviluppo, √® sufficiente raggiungere la pagina Download Docker Community Edition, selezionare il sistema operativo e scaricare la versione adatta al nostro sistema operativo. Ora, Docker √® un sistema che gira in ambiente Linux, ma, con un piccolo accorgimento (in pratica l’installazione di una macchina virtuale) √® possibile far girare Docker anche su sistemi Windows o macOS (o OsX).
Portata a termine l’installazione di docker torniamo su Docker Hub, o un altro Registry Docker, e scarichiamo in locale le immagini di nostro interesse lanciando da un prompt dei comandi

$ docker pull joomla

per scaricare l’immagine del container ufficiale di Joomla!, e

$ docker pull mysql

per l’immagine di mysql.

A questo punto abbiamo due possibilità per mandare in esecuzione i due container:
Il primo è quello di mandare in esecuzione i due container lanciando da un prompt dei comandi le due istruzioni opportunamente modificate (per il significato dei parametri si rimanda alle pagine di Docker Hub dedicate ai due container):
$ docker run -it --link some-mysql:mysql --rm mysql sh -c 'exec mysql -h"$MYSQL_PORT_3306_TCP_ADDR" -P"$MYSQL_PORT_3306_TCP_PORT" -uroot -p"$MYSQL_ENV_MYSQL_ROOT_PASSWORD"'

$ docker run --name some-joomla --link some-mysql:mysql -p 8080:80 -d joomla
La seconda possibilità è quella di utilizzare Docker Compose e quindi:
- creare una cartella dedicata al nostro progetto, all’interno della quale creeremo un file YAML denominato docker-compose.yml (il nome deve essere questo), che conterr√† le seguenti istruzioni:

# Joomla! CMS Container 
# nome univoco del container 
container_name: my_web_site

# Definisce se il container deve essere riavviato 
#   (i pssibili valori sono no, always e on-failure)
restart: always

# Definisce l'immagine da cui avviare il container
image: joomla

# Collega il container ad un altro servizio
# (in questo caso a quello nel quale gira l'immagine di mysql)
- joomladb:mysql

# Espone la porta, interna al container, all'esterno sulla porta 8080
- 8080:80

# Esegue il mount di una cartella del container (/var/www/html)
# su una dell'host (./html)        
- ./html/:/var/www/html        
# Joomla! CMS Container

# MySql Container
container_name: my_web_site_db
restart: always
image: mysql
# Aggiunge alle variabili d'ambiente del container
# la password assegnata all'istanza di mysql (top of security XD)
- 3306:3306
- ~/usr/local/var/mysql/:/var/lib/mysql
# MySql Container

- dalla linea di comando lanciare l’istruzione nella directory contenente il file di sopra:

$ docker-compose up -d 

- Apriamo un browser all’indirizzo e otterremo


ed abbiamo il nostro CMS funzionante e pronto ad essere configurato per una nuova installazione. Se invece abbiamo necessit√† di operare localmente con il backup di un sito esistente, non ci resta che copiare il backup stesso nella cartella html, sovrascrivendo i files e le cartelle copiate dal container Joomla!, caricare sul server mysql l’ultimo backup del database, ed il gioco √® fatto.
- quando finiamo di operare, per terminare i due container, lanciamo il comando:
$ docker-compose down


Quello illustrato è solo uno dei tanti esempi che dimostrano la semplicità con cui è possibile approntare una workstation di sviluppo per un numero enorme di tecnologie.
Ad oggi ho gi√† sperimento le configurazioni ottimali per valutare diversi CMS (Wordpress, prestashop, …), con vari database (MySql, mariadb, mongodb, postgres, …), diversi server (apache, nginx, …), e via dicendo senza aver bisogno di installare niente sulla mia macchina di sviluppo e senza dover creare nuove macchine virtuali.
Forse la tecnologia non è ancora pronta per un utilizzo massivo in ambienti di produzione, anche se tutte le maggiori piattaforme cloud si sono attrezzate per supportare la tecnologia, ma le premesse sono ottime.


mercoledì 4 gennaio 2017

Angular 2 & Reactive Programming

Rx Angular 2
Il mio primo approccio con la Programmazione Reattiva (o meglio FRP - Functional Reactive Programming) risale ormai a met√† del 2013 quando, dopo aver letto una serie di articoli che descrivevano il paradigma di programmazione, ho deciso di introdurre un'implementazione di tale tecnica per .NET in una nuova release di un sistema MES (Manufacturing Execution System) che ho progettato ed implementato per l’azienda per cui lavoravo all’epoca. La libreria in questione era denominata Rx - Reactive Extensions.

In parole povere, le diverse implementazioni di Rx, consentono di manipolare flussi di dati e/o eventi (Observable) al fine di semplificare notevolmente lo sviluppo di codice asincrono mediante una sottoscrizione, Subscription, alle variazioni di tali flussi.

Tra i vari benefici che si possono avere con l’adozione di tali tecniche, quella che, a mio parere, √® quella di maggior pregio, √® data dal fatto che una volta creato uno stream di dati, diversi client possono effettuare una sottoscrizione alle variazioni dello stesso ottenendo, a costo zero, un sistema in grado di comunicare in modo broadcast con diversi client.

Le diverse implementazioni del paradigma, comprendono anche una libreria JavaScript denominata RxJS, e viene installata tra i diversi pacchetti a corredo di Angular 2.
Una delle applicazioni che meglio si prestano all’utilizzo della programmazione reattiva in un’applicazione Angular 2 √® data dalla fruizione di un servizio REST.
Nei post precedenti abbiamo creato sia un’applicazione client basata su Angular 2 che una Web API sviluppata con ASP.NET Core, ed entrambe hanno trovato posto su Azure.
Riprendendo il post precedente RESTful API con Swagger, e concentrandoci sul dettaglio della lista dei metodi esposti dal servizio, abbiamo:
Con questi metodi, possiamo pensare alla realizzazione di un’applicazione CRUD finalizzata alla gestione di una piccola biblioteca personale.
I sorgenti dell’intero progetto sono disponibili per la consultazione su github, ed il risultato finale, √® una Web Application di azure raggiungibile all’indirizzo
Il modulo principale è dato dal componente library che si presenta come segue:
ed la cui implementazione è data da:

import { Component, OnInit, ViewChild } from '@angular/core';
import { Subscription } from 'rxjs/Rx';
import { Router } from '@angular/router';
import { environment } from '../../environments/environment';
import { BookStoreService } from '../bookstore.service';
import { Book } from '../models/book';
import { ModalComponent } from '../modal/modal.component';

  selector: 'app-library',
  templateUrl: './library.component.html',
  styleUrls: ['./library.component.css'],
  providers: [BookStoreService]
export class LibraryComponent implements OnInit {

  title = 'Book Store';

  books: Book[] = [];

  errorMessage: string = '';
  isLoading: boolean = true;

  @ViewChild(ModalComponent) modal: ModalComponent;

  private subscription: Subscription;
  constructor(private _router: Router, private _bookStoreService: BookStoreService) { }

  ngOnInit() {

  reloadData() {
      b => this.books = b,
      e => this.errorMessage = e,
      () => this.isLoading = false);

  onNew() {
    this._router.navigate(['/edit', 'new']);

  onEdit(book: Book) {
    console.log('edit ' +;

  onDelete(book) {

    var message: string = 'Delete \'' + book.title + '\'?: ';
    this.modal.Title = 'Warning';;
    this.subscription = this.modal.observable.subscribe(x => {

      if (x) {
          book => {
            let b = this.books.find(item => ===;
            let id = this.books.indexOf(b);
            this.books.splice(id, 1);
            if (!environment.production)
          error => {


e dal servizio BookStoreService, cuore del vero interfacciamento con il servizio REST:

import { Injectable } from '@angular/core';
import { Http, Response, Headers } from '@angular/http';
import { Observable } from 'rxjs/Rx';

import { Book } from './models/book';

import { environment } from '../environments/environment';

export class BookStoreService {
    private baseUrl: string;

    constructor(private _http: Http) {
        this.baseUrl = environment.bookStoreApi.server + environment.bookStoreApi.apiUrl + '/books/';

    GetAll(): Observable<Book[]> {

        if (!environment.production)

        let books$ = this._http.get(this.baseUrl, { headers: this.GetHeaders() })

        return books$;

    public GetById = (id: string): Observable<Book> => {
        let books$ = this._http.get(this.baseUrl + id, { headers: this.GetHeaders() })
            .map(response => response.json())
        return books$;

    public Create = (book: Book): Observable<any> => {
        let book$ =, book, { headers: this.GetHeaders() })            

        return book$;

    public Update = (id: string, book: Book): Observable<any> => {
        let book$ = this._http.put(this.baseUrl + id, book, { headers: this.GetHeaders() })

        return book$;

    public Delete = (id: string): Observable<Book> => {
        let book$ = this._http.delete(this.baseUrl + id)

        return book$;

    private GetHeaders() {
        let headers = new Headers();

        headers.append('Accept', 'application/json');

        return headers;

function mapBooks(response: Response): Book[] {
    return response.json().map(toBook);

function toBook(r: any): Book {
    if (!environment.production)
        console.log('toBook: ' + JSON.stringify(r));

    let book = <Book>({
        title: r.title,
        authors: r.authors,
        publicationYear: r.publicationYear,
        isAvailable: r.isAvailable

    if (!environment.production)
        console.log('Parsed book: ', book);

    return book;

function handleError(error: Response) {
    return Observable.throw(error || 'Server error');

Per avere un’idea di come l’utilizzo della FRP abbia reso pi√Ļ agevole la gestione della programmazione asincrona focalizziamo la nostra attenzione sul metodo GetAll() che ritorna uno stream Observable

    GetAll(): Observable<Book[]> {

        if (!environment.production)

        let books$ = this._http.get(this.baseUrl, { headers: this.GetHeaders() })

        return books$;

ed al quale il componente library effettua una sottoscrizione mediante il metodo subscribe:
      b => this.books = b,
      e => this.errorMessage = e,
      () => this.isLoading = false);

In modo analogo vengono implementate le interfacce verso gli altri metodi esposti dal servizio REST.
Facile e pulito…


mercoledì 28 dicembre 2016

RESTful API con Swagger

Oggetto di questa nota sar√† swagger, un set di strumenti e di specifiche Open Source che stanno diventando lo Standard de facto per quel che riguarda l’implementazione e la documentazione di un’API RESTful.


Per comprendere cosa swagger sia e quale utilit√† abbia nel processo di sviluppo di una API, esistono in rete molti articoli, tra i quali API con Swagger in 5 minutiSwagger specification, e via dicendo.

Seguendo lo spirito del blog, invece, utilizzer√≤ questo post per memorizzare una possibile serie di passi per introdurre l’utilizzo dello strumento in una Web API sviluppata con il framework ASP.NET Core.

A tal fine partiremo da uno dei progetti sviluppati a titolo di esempio nei post precedenti, e pubblicati su Azure.

Tra i possibili strumenti per l’integrazione di swagger nel nostro processo, ci serviremo di Swashbuckle.
In primo luogo, aggiungiamo al file project.json del nostro progetto, la dipendenza alla versione attuale di Swashbuckle.
"Swashbuckle": "6.0.0-beta901",
Quindi, configuriamo la nostra App affinché faccia uso dello strumento in questione, aggiungendo nel metodo ConfigureServices, le seguenti righe:

            // Inject an implementation of ISwaggerProvider with defaulted settings applied

            services.ConfigureSwaggerGen(options =>
                options.SingleApiVersion(new Info
                    Version = "v1",
                    Title = "BookStore API",
                    Description = "A sample API  for swagger usage demonstration",
                    TermsOfService = "None",
                    Contact = new Contact() { Name = "Maurizio Attanasi", Email = "", Url = "" },
                    License = new License() { Name = "Creative Commons Attribution 4.0", Url = "" }

                //Determine base path for the application.
                var basePath = PlatformServices.Default.Application.ApplicationBasePath;

                //Set the comments path for the swagger json and ui.
                var xmlPath = Path.Combine(basePath, "BookApi.xml");
                // options.IncludeXmlComments(xmlPath);

Infine, nel metodo Configure, subito dopo aver avviato il pattern MVC, configuriamo l’uso sia di Swagger che della sua interfaccia utente:


            // Enable middleware to serve generated Swagger as a JSON endpoint

            // Enable middleware to serve swagger-ui assets (HTML, JS, CSS etc.)

Avviata la web application, e navigando all’indirizzo your-root-url/swagger/ui, nel nostro caso, visualizzeremo la pagina di documentazione autogenerata

 Degno di nota √® anche il fatto che la pagina fornisce anche un client che consente di testare il servizio senza ricorrere a tool esterni quali Postman o Fiddler. Espandendo infatti uno dei verbi visualizzati nella pagina, ed agendo sul pulsante Try it out, abbiamo


mercoledì 7 dicembre 2016

Integrazione Continua su Azure con git e azure-cli (parte II)

Node.jsMicorsoft AzureAngular 2

Continuiamo la precedente nota su Integrazione Continua su Azure con git e azure-cli, nella quale ho illustrato una possibile procedura per l’implementazione di un ambiente di sviluppo per l’integrazione continua su Microsoft Azure. In quell’occasione il progetto pubblicato implementava sia la gestione del front-end (sviluppato in quell’occasione con un’applicazione Angular 2), che il back-end (implementato con ASP.NET Core) implementata su host IIS.

In questo post concentreremo la nostra attenzione solo sulla pubblicazione di una Web App Angular 2 implementata con Node.js. A tal fine ci avvarremo di angular-cli, un set di strumenti in linea di comando per lo sviluppo di un'app Angular 2.


Creazione della Web App

Seguendo le istruzioni riportate dal sito creiamo una Web App Angular 2 con angular-cli.
  1. In primo luogo installiamo sul nostro sistema angular-cli:
  2. $ npm install -g angular-cli
  3. Quindi creiamo la nostra Web App:
  4. $ ng new my-a2-app
  5. Personalizziamone il contenuto, modificando:
    • il file app.component.ts
  6. import { Component } from '@angular/core';
      selector: 'app-root',
      templateUrl: './app.component.html',
      styleUrls: ['./app.component.css']
    export class AppComponent {
      title = 'my angular 2 app!';
      sign = 'Maurizio Attanasi';
      year = '2016';
    • il file app.component.html
  7. Avviamo il server in locale con il comando
  8. $ ng serve
  9. Aggiungiamo nella directory root del progetto il file .deployment che configurerà la directory di avvio del progetto, e contenente le righ che seguono:
project = dist

Preparazione e pubblicazione della Web App su azure

  1. Utilizzando le funzionalità di azure-cli viste nel post precedente, creiamo la Web App
  2. $ azure site create my-a2-app --git --gitusername ***
  3. Aggiorniamo le modifiche del repository locale, eseguiamo il commit ed infine eseguiamo il push verso il repository remoto di azure
$ git add .
$ git commit -m "Initial commit"
$ git push azure master
Se la è andata a buon fine, la nostra shell di comando sarà simile a quella seguente
Ulteriore conferma dell’avvenuta pubblicazione possiamo averla navigando il portale di azure al percoso my-a2-app > Deployment options
Ed infine, raggiungendo l’indirizzo

lunedì 28 novembre 2016

Integrazione Continua su Azure con git e azure-cli

In un precedente post (Integrazione Continua con Visual Studio Team Service) avevo condiviso il link ad un tutorial che illustrava il servizio di Continuous Integration offerto da Visual Studio Team Services. In questa nota riporterò gli step necessari ad ottenere un risultato analogo
per la pubblicazione su una Web Application su Azure sfruttando git come sistema di versioning, e azure-cli, un’interfaccia della riga di comando di Azure.
Gli strumenti necessari per raggiungere il nostro fine sono:
  • node.js (del quale utilizzeremo il gestore dei pacchetti, npm, per l’installazione, tra l’altro, di angular-cli);
  • git;
  • azure-cli;
  • un account Azure valido (anche un free trial);
Data la natura degli strumenti sopra elencati, la procedura che andremo a descrivere vale per tutti i sistemi operativi per i quali tali strumenti sono disponibili, e quindi Windows, Linux e osX/macOS.
In primo luogo verifichiamo che sul sistema sia installato Node.js eseguendo su una shell di comando
bash-3.2$ node --version
Nel caso in cui Node.js non sia presente sul sistema procederemo alla sua installazione seguendo le istruzioni presenti sul sito.
Allo stesso modo verifichiamo la presenza sul nostro sistema di git
bash-3.2$ git --version
git version 2.9.3 (Apple Git-75)
e azure-cli
bash-3.2$ azure --version
0.10.7 (node: 7.2.0)
Nel caso in cui questo pacchetto non sia presente sul sistema, utilizzeremo npm per la sua installazione
npm install -g azure-cli
Preparati gli strumenti necessari, procediamo alla realizzazione di una Web Application ed alla sua pubblicazione su Azure.
  1. Login
    Per eseguire il login dalla linea di comando di azure, eseguiamo:
$ azure login
e seguiamo le istruzioni riportate nella risposta
azure login
2. Impostazione Gestione servizi di Azure (asm)
Per abilitare i comandi della modalit√† Service Management dell’interfaccia della riga di comando di Azure, eseguire il comando.
bash-3.2$ azure config mode asm
  1. Impostazione dell’utente per la pubblicazione
    Per impostare nome utente e password per la pubblicazione della Web Application, eseguire il comando:
azure site deployment user set --username <username> --pass <password>

Creazione della Web Application

Tra le varie possibilit√† disponibili, (html,, Node.js, …), realizzeremo una Web Application faremo con l’ultima nata delle tecnologie ASP.NET:
Verifichiamo la presenza dell’sdk sul nostro sistema con il comando
bash-3.2$ dotnet --version
Nel caso in cui .net non sia presente, seguiamo le istruzioni
relative al sistema operativo di nostro interesse.


Per semplificare l’implementazione della web app utilizzeremo Yeoman, il set di strumenti per la creazione di progetti web gi√† visto in un precedente post.
In primo luogo procederemo all’installazione del generator necessario alla realizzazione di un progetto .net Core con il comando
$ sudo npm install -g generator-aspnet
Procediamo quindi alla creazione del nostro progetto creando la seguente gerarchia di directories:
$ mkdir CloudWorkbenchWebApplication
$ mkdir CloudWorkbenchWebApplication/src
$ mkdir CloudWorkbenchWebApplication/test
$ cd CloudWorkbenchWebApplication/
Nella cartella root del nostro progetto, creiamo il file global.json
che conterrà il seguente oggetto json
  "projects": [ "src", "test" ],
  "sdk": {
    "version": "1.0.0-preview2-1-003177"
Spostandoci nella cartella src, eseguiamo il comando
$ yo aspnet
in risposta al quale verrà avviata una procedura guidata per la creazione del nostro progetto
yo aspnet
Selezionando la voce Empty Web Application, e, in seguito assegnando il nome CloudWorkbenchWebApplication,
verr√† creata l’infrastruttura di una semplice Web Application ASP.NET Core.
Spostandoci nella cartella appena creata (CloudWorkbenchWebApplication), eseguiamo in sequenza i comandi
dotnet restore
dotnet run
dotnet run
In questo modo abbiamo avviato, sulla nostra macchina un Web Server che risponder√† all’indirizzo riportato (nel nostro caso http://localhost:5000/).
Avviando un browser e puntando all’indirizzo di cui sopra avremo:
Local Run
Et voilà, abbiamo la nostra Web Application!

Creazione del repository git

Tornando nella directory root del nostro progetto (quella contenente la cartelle src e test ed il file global.json),
1. creiamo il repository git
$ git init
  1. aggiungiamo tutti i files e le cartelle create
$ git add .
  1. eseguiamo il primo commit
$ git commit -m "Initial commit"

Creazione della Web Application su Azure

Mediante la linea di comando di azure, creiamo la nostra web application
 azure site create <app_name> --git --gitusername <username>
dove app_name è il nome che assegneremo alla web application, e username è il nome utente impostato nel passaggio precedente.
site creation
Selezioniamo il server sul quale pubblicheremo la nostra applicazione (nel nostro caso 3. West Europe).
Al termine dell’operazione, accedendo al portale di Azure, avremo, tra le risorse disponibili, quella appena creata
azure portal
Visualizzando i dettagli della nostra App, abbiamo
azure site detail
e, selezionando il pulsante Browse siamo in grado di visualizzare la web app appena creata (anche se vuota).

Pubblicazione della web application

Siamo pronti per eseguire il primo push verso il repository azure creato in precedenza.
A tal fine eseguiamo il comando
$ git push azure master
Oltre che copiare i file dal nostro repository locale al site di azure, il processo avvier√† le operazioni di restore e build dell’applicazione, ed infine alla pubblicazione dell’app.
Se l’operazione √® andata a buon fine, ricaricando il browser all’indirizzo precedente, abbiamo:
Et voil√† ancora!!! Abbiamo ottenuto il risultato voluto, ovvero siamo riusciti a pubblicare la nostra web application raggiungibile all'indirizzo utilizzando git e la linea di comando di azure.

Configurazione versione di Node.js

Poich√© la web application che abbiamo appena creato sar√† il punto di partenza per una serie prove per verificare le potenzialit√† di Azure per le applicazioni IoT, per provare Angular 2 in combinazione con .net core, ed altro ancora, facciamo un ulteriore passaggio per aggiornare la versione di Node.js di della nostra app azure con quella installata sul nostro sistema di sviluppo (la 7.2.0, come abbiamo visto all’inizio del post).
Tra gli Application Settings della nostra Web App individuiamo la chiave WEBSITE_NODE_DEFAULT_VERSION e modifichiamone il valore a 7.2.0, come illustrato nell’immagine seguente.
Salvando le modifiche effettuate il sito verrà riavviato e, se non ci sono problemi, ricaricando la pagina otterremo ancora il nostro Hello World.