Mokabyte

Dal 1996, architetture, metodologie, sviluppo software

  • Argomenti
    • Programmazione & Linguaggi
      • Java
      • DataBase & elaborazione dei dati
      • Frameworks & Tools
      • Processi di sviluppo
    • Architetture dei sistemi
      • Sicurezza informatica
      • DevOps
    • Project Management
      • Organizzazione aziendale
      • HR
      • Soft skills
    • Lean/Agile
      • Scrum
      • Teoria della complessità
      • Apprendimento & Serious Gaming
    • Internet & Digital
      • Cultura & Società
      • Conferenze & Reportage
      • Marketing & eCommerce
    • Hardware & Tecnologia
      • Intelligenza artificiale
      • UX design & Grafica
  • Ultimo numero
  • Archivio
    • Archivio dal 2006 ad oggi
    • Il primo sito web – 1996-2005
  • Chi siamo
  • Ventennale
  • Libri
  • Contatti
  • Argomenti
    • Programmazione & Linguaggi
      • Java
      • DataBase & elaborazione dei dati
      • Frameworks & Tools
      • Processi di sviluppo
    • Architetture dei sistemi
      • Sicurezza informatica
      • DevOps
    • Project Management
      • Organizzazione aziendale
      • HR
      • Soft skills
    • Lean/Agile
      • Scrum
      • Teoria della complessità
      • Apprendimento & Serious Gaming
    • Internet & Digital
      • Cultura & Società
      • Conferenze & Reportage
      • Marketing & eCommerce
    • Hardware & Tecnologia
      • Intelligenza artificiale
      • UX design & Grafica
  • Ultimo numero
  • Archivio
    • Archivio dal 2006 ad oggi
    • Il primo sito web – 1996-2005
  • Chi siamo
  • Ventennale
  • Libri
  • Contatti

Nel numero:

102 dicembre
, anno 2005

Introduzione al workflow

Sistemi di gestione del flusso di lavoro

Stefano Rossini
Stefano Rossini

Stefano Rossini è nato a Giussano (MI) il 29/10/1970 e ha conseguito il diploma universitario in Ingegneria Informatica presso il Politecnico di Torino. Ha maturato più di venti anni di esperienza in diversi progetti Enterprise mission-critical ricoprendo i ruoli di IT Program Manager, Project Manager & Software Architect presso importanti gruppi bancari, pubblica sanità, pubblica amministrazione e software house.

Attualmente ricopre il ruolo di Sofware Factory Manager, Lean Change Agent ed Enterprise Architect presso Capgemini.

Esperto in ambito di sanità pubblica come Project/Program Manager per la governance dei progetti IT strategici di Cartella Clinica Elettronica (CCE) e Fascicolo Sanitario Elettronico (FSE).

Esperto in ambito bancario dove ha ricoperto per una decina d'anni il ruolo di Project Manager e Leader Software Architect (BPM, IWBank e BPS) occupandosi della pianificazione e gestione del progetto, del coordinamento del gruppo di sviluppo software sia InHouse che Nearshore/Offshore. Esperto nella conduzione di progetti secondo metodologia di Project Management PMBok e metodologia agile Scrum.

Si occupa di Java dal 1999 arrivando da precedenti esperienze in C e C++ in ambito Telco (Alcatel & Siemens). Ha pubblicato più di un centinaio di articoli su argomenti di IT Governance, Project Management, architetture enterprise e problematiche di Integrazione e SOA. È coautore dei libri "Manuale pratico di Java" (2001) e "La programmazione della piattaforma J2EE" (2005) editi da Hops/Tecniche Nuove. Certificazioni IT Governance: COBIT V.4.1 Foundation Certificate; certificazioni IT Service Management: ITIL V.3 Foundation Examination; certificazioni Project Management: CSM - Scrum Master, CSPO - Scrum Product Owner, PMI: 35 contact hours.

Profilo linkedin: http://www.linkedin.com/pub/stefano-rossini/30/977/242

MokaByte

Introduzione al workflow

Sistemi di gestione del flusso di lavoro

Picture of Stefano Rossini

Stefano Rossini

  • Questo articolo parla di: Processi di sviluppo, Project Management

Descriveremo che cosa è un workflow, introdurremo i concetti fondamentali legati ai workflow, ne forniremo una possibile classificazione e mostreremo in quali ambiti può essere utilizzato un motore di workflow.
Cercheremo infine di mostrare alcune analogie/differenze principali tra i concetti di wor-kflow, Business Process Management (BPM) e Orchestration.

In questo articolo introdurremo i concetti di Workflow e Workflow Management System.
In particolare descriveremo che cosa è un workflow, introdurremo i concetti fondamentali legati ai workflow, ne forniremo una possibile classificazione e mostreremo in quali ambiti può essere utilizzato un motore di workflow.
Cercheremo infine di mostrare alcune analogie/differenze principali tra i concetti di wor-kflow, Business Process Management (BPM) e Orchestration.

Cos‘è un Workflow?

Cercare di dare una definizione formale di Workflow non è propriamente banale visto che il concetto di workflow può essere associato a significati anche molto differenti.
Nella figura che segue si compara il grado di maturità  dell‘hype tecnologico di un Workflow rispetto al ben più consolidato e “stagionato” Relational Database Management Systems (vedere [1]).

Si può definire un Workflow come l‘automazione di un processo di business, in tutto o solo in parte, durante il quale i documenti, le informazioni o i compiti sono passati da un partecipante a un altro per compiere una determinata azione secondo quanto specificato da un insieme di regole procedurali ben definite.
Un workflow costituisce quindi un flusso di lavoro composto da un insieme di attività  correlate tra loro attraverso diverse tipologie di relazioni.

Gli attori di un Workflow

Un workflow è la definizione formale di un processo, utilizzata per la gestione di particolari attività  (gestione di ordini, pubblicazione di articoli, etc.).

Tutti i workflow sono sistemi orientati al processo.
La definizione di un processo rappresenta ciò che deve accadere all‘interno del sistema durante un processo di business o una procedura e può essere composta da un insieme di sotto-processi. Ciascun processo e sotto-processo è composto, a sua volta, da un insieme di attività . Ogni attività  è un singolo step logico all‘interno del processo.

Un workflow esegue attività  automatiche; la definizione di un processo, invece, descrive tutte le attività  sia automatiche sia manuali.

La definizione di un processo (cosa debba essere fatto, in che ordine e da chi) viene formalizzata in termini di:

  • Stato (nodo): Uno stato all‘interno di un processo specifica una dipendenza rispetto ad un attore esterno. A runtime questo comporta che il motore di workflow deve attendere fino a quando un attore esterno notifica che l‘esecuzione è stata portata a termine.
  • Azione: Un‘azione è la logica applicativa che deve essere eseguita dal motore di workflow in seguito al presentarsi di un evento specifico. I flussi di esecuzione concorrenti sono modellati con fork e join, mentre i flussi di esecuzione esclusivi sono modellati con merge e punti di decisione.
  • Transizioni: rappresentano lo spostamento del processo da uno stato ad un altro attraverso l‘applicazione di una predeterminata azione.
  • Process Context: è il contesto del processo gestito dal workflow.

La figura che segue (vedere [10]) riassume l‘anatomia di un processo:

Il Workflow Management System

Definito il concetto di workflow, vediamo di definire che cosa è un sistema di Workflow Management (WFMS) .
Un Workflow Management System è un sistema che permette di definire, creare e gestire l‘esecuzione di workflow attraverso l‘utilizzo di software in esecuzione all‘interno di uno o più motori di workflow. Un workflow manager si occupa di interpretare la definizione formale (ricevuta come input) di un processo, scritta con un linguaggio standard (es: XML, BPEL) o proprietario (es: jPdl), al fine di interagire con i vari attori partecipanti gestendone lo stato ed il coordinamento delle attività .

Da un punto di vista pratico, un WFMS è un componente software che prende in input la descrizione formale del processo di business e mantiene lo stato di esecuzione delegando le attività  alle applicazioni e/o persone necessarie al completamento dello stesso.

Mentre la definizione di processo (process definition) è la descrizione formale del processo (stati, transizioni, variabili di contesto, attività  associate, …) un‘istanza di processo è l‘istanza concreta di un processo attualmente in esecuzione.
Paragonando quanto detto all‘OOP, il process definition è analogo alla classe mentre un‘istanza di processo è il corrispettivo di un oggetto istanza della classe stessa.

Il processo, a sua volta, è composto da step che il processo “attraversa”. Di fatto, durante l‘esecuzione di un processo, il sistema di gestione del motore di workflow utilizza un token per tenere traccia dello stato corrente. Questo token è corrispondente al concetto di “program counter” all‘interno delle macchine di Von Neumann. Quando il token arriva in uno stato particolare viene assegnato ad un attore esterno che può essere un utente, un gruppo o un sistema.
Compito del WFMS è di mantenere correlato all‘istanza del processo le informazioni specifiche del suo contesto (context information). Ogni istanza di processo, quindi, avrà  un proprio contesto. Al Process Context possono essere associate una o più variabili (process context variable).
Generalmente le variabili del contesto del processo sono dichiarate nella definizione del processo stesso e sono inizializzate all‘atto della creazione del processo da parte del WFMS.
Il processo può transitare attraverso più stati che possono essere di diversi tipi. Durante l‘esecuzione del processo possono essere associate una o piu‘ azioni. Le azioni sono porzioni di logica applicativa che devono essere eseguite dal WFMS in seguito a un ben preciso evento.
Da un punto di vista terminologico è bene evitare di usare un generico termine di attività  (activity) ma differenziare in modo preciso tra stato (state) e azione(action) (vedere [1]).

Un semplice esempio di Workflow

Vediamo ora di esemplificare quanto è stato precedentemente spiegato.

Nel nostro esempio ci focalizzeremo su due semplici pattern (per approfondire i pattern legati ai workflow è possibile consultare [2]):

  • Sequence: un‘attività  all‘interno del workflow è eseguita solo in seguito alla terminazione dell‘attività  precedente.
  • Exclusive choiche: all‘interno del workflow esiste un punto in cui si decide di seguire un percorso piuttosto che un altro basandosi su quanto presente nel contesto di esecuzione.

L‘esempio considerato mostra un sistema di gestione degli ordini. In particolare, alla ricezione di un ordine viene verificato il credito di un cliente, se il credito è sufficiente l‘ordine viene evaso altrimenti viene scartato.

Per implementare tale esempio utilizzeremo tre differenti motori di workflow: OSWorkflow di Open Symphony, JBPM di JBoss e Oracle BPEL Process Manager. I tre motori si riferiscono rispettivamente ai seguenti ambiti di workflow: workflow (in senso “stretto” del termine), Business Process Management(BPM) e orchestration.

Anche se non è possibile dare definizioni di workflow, BPM e orchestration ampiamente accettate, è comunque possibile fare alcune considerazioni al riguardo (vedere [7]).
Caratteristiche comuni a queste tre tipologie di sistemi è il prevedere la definizione formale di un processo e la possibilità  di avere stati di attesa durante l‘esecuzione dei processi nonostante i diversi ambiti applicativi. Infatti, mentre i workflow sono solitamente correllati alla gestione di attività  svolte dalle persone, il Business Process Management (BPM) combina l‘utilizzo di workflow con l‘integrazione di applicazioni Enterprise (EAI) mentre l‘Orchestration è prettamente orientato alla “orchestrazione” dei Web Services.

Open Symphony – OSWorkflow

OSWorkflow (vedere [11]) è un motore di workflow open source e può essere considerato come un‘implementazione di “basso livello”. Situazioni come cicli di loop o condizioni che, in altri motori di workflow, possono essere espressi attraverso un‘opportuna rappresentazione grafica devono essere codificati in OSWorkflow utilizzando un linguaggio di scripting. OSWorkflow si basa ampiamente sul concetto di macchina a stati finiti. Ciascuno stato rappresenta la combinazione di un identificatore e di uno stato. Una transizione tra uno stato e un altro può avvenire anche senza alcuna azione esterna.
Al cuore di OSWorkflow vi è il descrittore di definizione del workflow. Questo descrittore è un file XML. Il descrittore contiene tutti gli step, gli stati, le transizioni e le funzionalità  per un dato workflow.
Il file XML può essere creato manualmente oppure utilizzando l‘editor grafico di OSWorkflow.

L‘utilizzo del designer di OSWorkflow facilita la creazione del descrittore XML che, altrimenti, deve essere effettuata manualmente.
Ad esempio, il file XML corrispondente al workflow indicato è:

                                          it.mokabyte.mokaworkflow.ReceiveOrderPreFunction          ${orderNumber}                                                                                                                                                                                                                                              it.mokabyte.mokaworkflow.CheckOrderCondition                  ${creditCardNumber}                                                                                                                                                        com.opensymphony.workflow.util.StatusCondition                OrderChecked                                                                                      ......  

In corrispondenza di ciascuno stato viene eseguita una determinata azione (primo o dopo la transizione di stato può essere eseguita quella che OSWorkflow definisce con il nome di function). L‘azione che deve essere eseguita è determinata da una condition. OSWorkflow esegue la prima action per cui la condition è verificata. Se non è verificata alcuna condizione, viene eseguita un‘ azione di default che deve essere sempre specificata.
Le condition sono implementate da classi Java che implementano l‘interfaccia com.opensymphony.workflow.Condition mentre le function, invece, sono implementate da classi Java che implementano l‘interfaccia com.opensymphony.workflow.FunctionProvider.

A secondo della tipologia di elemento da inserire nel workflow è necessario implementare l‘opportuna interfaccia.

Un esempio di condition è riportato nel seguito:

public class CheckOrderCondition implements Condition {public boolean passesCondition(Map transientVars, Map args, PropertySet ps)throws WorkflowException {Logica della condition: il valore di ritorno deve essere true o false}}

Per quanto riguarda, invece, una function:

public class CheckOrderPreFunction implements FunctionProvider {public void execute(Map transientVars, Map args, PropertySet ps) {logica applicativa dell‘action}}

JBoss JBPM

JBoss JBPM è il motore di workflow open source proposto da JBoss (vedere[6]).
I processi di jBPM sono creati utilizzando un linguaggio proprietario di definizione dei processi di nome jPdl. La gestione dello stato con jBpm si basa su un grafico con nodi e transizioni che costituiscono la definizione di un processo. Le interazioni principali con jBpm sono due: avviare l‘esecuzione di un processo e segnalare la terminazione di uno stato. In entrambi i casi jBpm si occupa di calcolare lo stato successivo.
Il grafico degli stati fornisce la struttura del processo. Le azioni sono costituite da logica applicativa (classi che implementano l‘interfaccia org.jbpm.graph.def.ActionHandler) che può essere eseguita in seguito a eventi particolari come l‘ingresso in un nodo, l‘uscita da un nodo e la transizione di stato. Le definizioni dei processi sono contenute all‘interno di file XML che possono essere costruiti “a mano” o mediante il tool grafico JBoss jBPM Graphical Process Designer distribuito come plugin di eclipse. In modalità  grafica “drag and drop” è quindi possibile disegnare facilmente il nostro processo di esempio.

Il design del processo corrisponde alla creazione automatica del file XML dei definizone del processo da parte del tool.

La creazione degli Handler (action) da associare agli eventi di interesse è costituita da una classe Java che deve implementare l‘interfaccia org.jbpm.graph.def.ActionHandler:

import org.jbpm.graph.def.ActionHandler;public class MokaActionHandler implements ActionHandler {public void execute(ExecutionContext executionContext) throws Exception {/ Logica applicativa dell‘Action. . . .context.getContextInstance().setVariable("message", "Hello World!");. . . . context.leaveNode("tr2");. . . .}}

Oracle BPEL

L‘Oracle BPEL Designer (vedere [ORA_BPD] ) permette di definire in modo grafico i processi ed ottenere la generazione automatica del codice secondo lo standard BPEL.
Con il tool è quindi possibile, in modalità  grafica “drag-and-drop” (Design View), disegnare facilmente il processo di esempio ed ottenere la generazione automatica del corrisponde codice BPEL (Source View)

Conclusioni

In questo articolo abbiamo introdotto i concetti fondamentali legati ai Workflow ed un semplice esempio pratico.
Per ulteriori approfondimenti sull‘argomento si rimanda alla bibliografia.

1The state of workflowhttp://www.jbpm.org/state.of.workflow.html2W.M.P. van der Aalstl, A.H.M. ter Hofstede, B. Kiepuszewski, A.P. Barros “Workflow Patterns” http://is.tm.tue.nl/research/patterns/download/wfs-pat-2002.pdf3Workflow Patternshttp://www.openwfe.org/docbook/build/ch07.html 4http://is.tm.tue.nl/research/patterns/ 5Open Source Workflow Engines Written in Javahttp://www.manageability.org/blog/stuff/workflow_in_java/view6JBoss Process Managerhttp://www.jbpm.org/7http://jbpm.org/3/introduction.html8JBoss jBPM GPD”Getting Started: How to create your first process definition”http://jbpm.org/gpd/index.html9J. Koenig”Integrating Business Process Management with Open Source JBoss jBPM”http://www.jboss.com/pdf/jbpm_whitepaper.pdf10T. BaeyensjBpm: Open Source Solution for BPMhttp://erp.ittoolbox.com/documents/document.asp?i=188811Open Simphonyhttp://www.opensymphony.com/12Oracle BPEL Process Managerhttp://www.oracle.com/technology/products/ias/bpel/index.html 13Oracle BPEL Process Manager (download)http://www.oracle.com/technology/software/index.html14Workflow Reference Model Diagram

Stefano Rossini
Stefano Rossini

Stefano Rossini è nato a Giussano (MI) il 29/10/1970 e ha conseguito il diploma universitario in Ingegneria Informatica presso il Politecnico di Torino. Ha maturato più di venti anni di esperienza in diversi progetti Enterprise mission-critical ricoprendo i ruoli di IT Program Manager, Project Manager & Software Architect presso importanti gruppi bancari, pubblica sanità, pubblica amministrazione e software house.

Attualmente ricopre il ruolo di Sofware Factory Manager, Lean Change Agent ed Enterprise Architect presso Capgemini.

Esperto in ambito di sanità pubblica come Project/Program Manager per la governance dei progetti IT strategici di Cartella Clinica Elettronica (CCE) e Fascicolo Sanitario Elettronico (FSE).

Esperto in ambito bancario dove ha ricoperto per una decina d'anni il ruolo di Project Manager e Leader Software Architect (BPM, IWBank e BPS) occupandosi della pianificazione e gestione del progetto, del coordinamento del gruppo di sviluppo software sia InHouse che Nearshore/Offshore. Esperto nella conduzione di progetti secondo metodologia di Project Management PMBok e metodologia agile Scrum.

Si occupa di Java dal 1999 arrivando da precedenti esperienze in C e C++ in ambito Telco (Alcatel & Siemens). Ha pubblicato più di un centinaio di articoli su argomenti di IT Governance, Project Management, architetture enterprise e problematiche di Integrazione e SOA. È coautore dei libri "Manuale pratico di Java" (2001) e "La programmazione della piattaforma J2EE" (2005) editi da Hops/Tecniche Nuove. Certificazioni IT Governance: COBIT V.4.1 Foundation Certificate; certificazioni IT Service Management: ITIL V.3 Foundation Examination; certificazioni Project Management: CSM - Scrum Master, CSPO - Scrum Product Owner, PMI: 35 contact hours.

Profilo linkedin: http://www.linkedin.com/pub/stefano-rossini/30/977/242

Facebook
Twitter
LinkedIn
Picture of Stefano Rossini

Stefano Rossini

Stefano Rossini è nato a Giussano (MI) il 29/10/1970 e ha conseguito il diploma universitario in Ingegneria Informatica presso il Politecnico di Torino. Ha maturato più di venti anni di esperienza in diversi progetti Enterprise mission-critical ricoprendo i ruoli di IT Program Manager, Project Manager & Software Architect presso importanti gruppi bancari, pubblica sanità, pubblica amministrazione e software house. Attualmente ricopre il ruolo di Sofware Factory Manager, Lean Change Agent ed Enterprise Architect presso Capgemini. Esperto in ambito di sanità pubblica come Project/Program Manager per la governance dei progetti IT strategici di Cartella Clinica Elettronica (CCE) e Fascicolo Sanitario Elettronico (FSE). Esperto in ambito bancario dove ha ricoperto per una decina d'anni il ruolo di Project Manager e Leader Software Architect (BPM, IWBank e BPS) occupandosi della pianificazione e gestione del progetto, del coordinamento del gruppo di sviluppo software sia InHouse che Nearshore/Offshore. Esperto nella conduzione di progetti secondo metodologia di Project Management PMBok e metodologia agile Scrum. Si occupa di Java dal 1999 arrivando da precedenti esperienze in C e C++ in ambito Telco (Alcatel & Siemens). Ha pubblicato più di un centinaio di articoli su argomenti di IT Governance, Project Management, architetture enterprise e problematiche di Integrazione e SOA. È coautore dei libri "Manuale pratico di Java" (2001) e "La programmazione della piattaforma J2EE" (2005) editi da Hops/Tecniche Nuove. Certificazioni IT Governance: COBIT V.4.1 Foundation Certificate; certificazioni IT Service Management: ITIL V.3 Foundation Examination; certificazioni Project Management: CSM - Scrum Master, CSPO - Scrum Product Owner, PMI: 35 contact hours. Profilo linkedin: http://www.linkedin.com/pub/stefano-rossini/30/977/242
Tutti gli articoli
Nello stesso numero
Loading...

Architetture e tecniche di progettazione EJB

III parte: trasmissione dati tra strati con DTO

Java Business Integration

Parte III: Service Unit & Service Assembly

Applicazioni Desktop

Persistenza delle preferenze

La Reflection in Java

Parte II

Integration Patterns

Parte III: la pratica

Service Oriented Architecture

Parte III: Maturity Model

Skill differenti per applicazioni J2EE di successo

La sfida del teamworking

Firma digitale con dispositivo crittografico sicuro

I parte: le smart card

J2ME vs Symbian

Evoluzione e confronto

Nella stessa serie
Loading...

Accessibilità in team di prodotto: sfide, normative e best practice

I parte: Cosa è l’accessibilità e perché implementarla

Il web al tempo della GEO (Generative Engine Optimization)

II parte: Strategie per strutturare i contenuti

Un backlog non tanto buono

II parte: Caratteristiche e ruolo del backlog.

FIWARE: Open APIs for Open Minds

V parte: Implementazione del sistema di ricarica

Il web al tempo della GEO (Generative Engine Optimization)

I parte: Struttura e ricerca delle informazioni

Un backlog non tanto buono

I parte: Un progetto con qualche difficoltà

DDD, microservizi e architetture evolutive: uno sguardo d’insieme

X parte: Il ruolo del Software Architect

FIWARE: Open APIs for Open Minds

IV parte: Sistema di ricarica intelligente per veicoli elettrici

Tra Play14 e serious gaming

Un ponte tra gioco e apprendimento

DDD, microservizi e architetture evolutive: uno sguardo d’insieme

IX parte: Event Sourcing is not Event Streaming

FIWARE: Open APIs for Open Minds

III parte: Tecnologie e implementazione

Agilità organizzativa

II parte: Qualche caso d’esempio

Agilità organizzativa

I parte: Individui e interazioni nelle aziende moderne

FIWARE: Open APIs for Open Minds

II parte: Generic Enablers per costruire ecosistemi smart

Intelligenza artificiale e industria

Riflessioni sull’uomo e sulla macchina

Effetto Forrester e dinamiche dei sistemi di produzione

La storiella di una birra per comprendere il Lean

DDD, microservizi e architetture evolutive: uno sguardo d’insieme

VIII parte: La filosofia dell’architettura del software

Digital revolution: trasformare le aziende in ecosistemi digitali

XVIII parte: Una piattaforma comune a tutti gli eventi

Scene dalla “neolingua”

Panoramica semiseria dell’incomunicabilità aziendale

Autenticazione schede elettorali… lean!

Simulazione lean nella gestione di un seggio

FIWARE: Open APIs for Open Minds

I parte: Fondamenti e architettura

Italian Agile Days: una conferenza matura

Resoconto da IAD24 di Firenze

“Sì, ma quanto mi costi?”. Considerazioni sull’Agile in azienda

III parte: Earned Value Analisys e Scrum

La lezione da apprendere? Le organizzazioni che apprendono

IV parte: Gli archetipi sistemici

Mokabyte

MokaByte è una rivista online nata nel 1996, dedicata alla comunità degli sviluppatori java.
La rivista tratta di vari argomenti, tra cui architetture enterprise e integrazione, metodologie di sviluppo lean/agile e aspetti sociali e culturali del web.

Imola Informatica

MokaByte è un marchio registrato da:
Imola Informatica S.P.A.
Via Selice 66/a 40026 Imola (BO)
C.F. e Iscriz. Registro imprese BO 03351570373
P.I. 00614381200
Cap. Soc. euro 100.000,00 i.v.

Privacy | Cookie Policy

Contatti

Contattaci tramite la nostra pagina contatti, oppure scrivendo a redazione@mokabyte.it

Seguici sui social

Facebook Linkedin Rss
Imola Informatica
Mokabyte