Nelle specifiche del OMG (4) del 17 gennaio 2008 del BPMN (2) viene illustrata una possibile mappatura della notazione nel BPEL. Come riportato in nota, nell’ annesso A di tale documento, tale mappatura non è definitiva in quanto presenta ancora qualche problema di allineamento, ma verrà sistemata nella prossima pubblicazione. In attesa di uno standard completo, è comunque possibile nella maggioranza dei casi effettuare tale traduzione. Nello stesso standard viene riportato un esempio utile alla comprensione di questo procedimento, e in questo capitolo ne verrà effettuata una breve analisi.
L’esempio si basa sul processo presentato nel Capitolo 5 di questa sezione. Fase iniziale del processo
Il primo problema da affrontare è lo start event del processo. In BPEL (5) i processi si attivano con una receive, di conseguenza bisogna modellare un altro processo di servizio che ogni venerdì invii un messaggio al processo principale per poter farlo partire.
I‐37. Processo starter di servizio
Il task “receive issue list” verrà quindi sostituito da una receive che creerà un’istanza del processo (attributo createInstance), mentre l’intero processo viene descritto all’interno di un sequence, in quanto vogliamo che le seguenti attività vengano svolte in cascata. Le proprietà utilizzate dal modellatore del processo per gestire le decisioni vengono mappate in BPEL in elementi variables chiamati “processData” .
Il task “review issue list” che come abbiamo visto viene svolta dall’issue list manager, viene mappata in un’istruzione sincrona invoke, con inclusa una outputVariable.
L’exclusive gateway “Any issues ready” viene mappato in uno switch, e l’alternativa “no” (essendo progettata come default) viene mappata con l’otherwise case dello stesso. In questo caso si vuole terminare il processo, quindi viene inserito solo il tag empty.
Come possiamo notare in figura I‐32, il processo presenta dei loop che coinvolgono alcuni sottoprocessi. Questi loop in BPEL verranno mappati con delle invoke a dei servizi chiamati “ [(target of loop) activityName]_Derived_Process” (e.g. “Discussion_Cycle_Derived_Process”), che verranno chiamati dalle attività che in tali loop li precedono. Questa gestione dei sottoprocessi genera una serie di process e invoke che devono essere indirizzati. A questo scopo vengono definiti in WSDL (17) tali processi con la notazione “call_<process name>”. Al momento dell’invocazione vengono passate le variabili necessarie all’esecuzione del sottoprocesso, al termine del quale restituirà il controllo al processo principale grazie a dei tag reply.
Il sottoprocesso “Discussion cycle” è di tipo loop. In questo caso il loop è di facile realizzazione (non essendoci altri loop interlacciati ad esso da altri sottoprocessi) quindi la condizione è facilmente implementabile con un while.
SubProcess Discussion Cycle
Il sottoprocesso contiene tre percorsi paralleli che vengono mappati da un flow. Andiamo ad analizzare come vengono mappati i tre percorsi alternativi:
• Nel cammino superiore il timer intermediate event viene gestito come un
faultHandler con un suo scope. Viene aggiunto a questo scope un eventHandler che
contiene un for che serve da delay, alla fine del quale viene generato un fault attraverso l’uso di throw. La gestione del fault contiene solo un elemento empty perché alla fine del percorso non ci sono altre attività.
• Il cammino centrale può essere mappato in due modi. Nella soluzione presentata viene usato un tag sequence, ma una possibile alternativa è quella di usare dei link. Questa bivalenza rappresenta un’incognita nella generazione di documenti BPEL (5) da BPMN (1). Il timer intermediate event viene mappato come una wait, mentre il task viene mappato come un invoke asincrono (non è prevista risposta).
• Nel terzo cammino possiamo notare che il primo task viene mappato con un invoke sincrono con due source, le due condizioni del controllo decisionale (notare che la condizione di default viene messa come negazione della precedente in quanto si attiva su true). In questo caso quindi il controllo viene implementato con dei link, uno dei quali effettua il wait e la invoke (ramo “yes”) e l’altro solo una empty (ramo “no”).
SubProcess Collect Votes
Il sottoprocesso “collect votes”, così come il task “announce issues”, fa parte dei loop che abbiamo analizzato nella fase iniziale del processo, quindi anche per esso verrà generato un processo derivato.
I percorsi paralleli interni al sottoprocesso sono simili a quelli discussi nel paragrafo precedente, fatta eccezione per l’ultimo che presenta un ciclo infinto. Questi si realizza con un while la cui condizione è 1=0 (qualsiasi condizione sempre falsa sarebbe adatta). L’uscita dal ciclo infinto (così come dal sottoprocesso) viene realizzata similmente per quanto visto
nel primo ramo parallelo del sottoprocesso “Discussion Cycle”. Viene quindi definito uno
scope per la gestione del fault generato dal onAlarm.
Conclusione del processo
Come illustrato precedentemente, il passaggio all’ultima parte del processo avviene tramite la generazione di un fault (timeout di “collect votes”), quindi andrà inserita nel faultHandler del relativo scope. All’interno dell’handler vengono implementati i controlli decisionali e i task (switch e invoke) e le invoke ai processi derivati per chiudere i cicli ai sottoprocessi. Un caso particolare però è introdotto dal gateway “issues w/o majority”, cui si può arrivare da due percorsi alternativi. Questo è dovuto alla sovrapposizione di due controlli condizionali, possibilità comune in una notazione a diagramma ma impossibile in un linguaggio strutturato a blocchi come il BPEL (5). Le alternative sono due:
• Duplicare il codice di controllo e prevedere le varie possibilità dei cammini. • Separare gli elementi in un processo derivato richiamabile da una invoke.
La seconda opzione è quella scelta dall’OMG (4) in questo esempio, che conclude l’analisi della mappatura del processo in BPEL (5).