Bladeren bron

Merged in actions-workflows (pull request #5)

Actions workflows + Falta validate YAML

Approved-by: Guillermo Espinoza <guillermo@interlink.com.ar>
Maximiliano Schvindt 8 jaren geleden
bovenliggende
commit
729972b3c7

+ 2 - 1
composer.json

@@ -73,7 +73,8 @@
         "workflows-commands": [
             "chown -Rf www-data:www-data app/Resources/workflows",
             "cp -n app/Resources/workflows/workflow_list.yml.dist app/Resources/workflows/workflow_list.yml",
-            "chown -Rf www-data:www-data app/Resources/workflows/workflow_list.yml"
+            "chown -Rf www-data:www-data app/Resources/workflows/workflow_list.yml",
+            "chown -Rf www-data:www-data web/workflows_png"
         ],
         "symfony-scripts": [
             "Incenteev\\ParameterHandler\\ScriptHandler::buildParameters",

+ 8 - 4
src/FTTHBundle/Admin/ONUAdmin.php

@@ -35,7 +35,7 @@ class ONUAdmin extends BaseAdmin
     protected function configureListFields(ListMapper $listMapper)
     {
         $listMapper
-            ->add('id')
+            // ->add('id')
             ->add('ip')
             ->add('mac')
             ->add('serialNumber')
@@ -43,10 +43,11 @@ class ONUAdmin extends BaseAdmin
             ->add('clientId')
             ->add('olt')
             ->add('model')
-            ->add('node')
-            ->add('profile')
+            ->add('workflow')
+            // ->add('node')
+            // ->add('profile')
             ->add('currentState','string', array('template' => 'FTTHBundle:ONU:base_list_field_onu_state.html.twig'))
-            ->add('transitionState')
+            // ->add('transitionState')
             ->add('_action', null, array(
                 'actions' => array(
                     'show' => array(),
@@ -90,8 +91,11 @@ class ONUAdmin extends BaseAdmin
             ->add('clientId')
             ->add('olt')
             ->add('model')
+            ->add('model.workflow')
             ->add('node')
             ->add('profile')
+            ->add('currentState')
+            ->add('log','string', array('template' => 'FTTHBundle:ONU:show_log.html.twig'))
         ;
     }
 

+ 24 - 0
src/FTTHBundle/Entity/OLT.php

@@ -359,4 +359,28 @@ class OLT
         return $this;
     }
 
+    public function getWorkflow() 
+    {
+        if($this->model) {
+            $model = $this->model;
+            if($model->getWorkflow() && $model->getWorkflow()->getEnable()) {
+                return $model->getWorkflow()->getName();
+            }
+        }
+        
+        return "onu_state";
+    }
+    
+    public function getWorkflowType() 
+    {
+        if($this->model) {
+            $model = $this->model;
+            if($model->getWorkflow() && $model->getWorkflow()->getEnable()) {
+                return $model->getWorkflow()->getType();
+            }
+        }
+        
+        return "state_machine";
+    }
+
 }

+ 7 - 0
src/FTTHBundle/Entity/ONU.php

@@ -437,4 +437,11 @@ class ONU
         return "state_machine";
     }
 
+    public function getLog() 
+    {
+        $out = array();
+        exec("tail -400 /var/flowdat/ftth/var/logs/dev.log | grep 'ONU_id_{$this->id}'", $out);
+        return implode("\n",$out);
+    }
+
 }

+ 9 - 1
src/FTTHBundle/Resources/translations/FTTHBundle.es.yml

@@ -32,6 +32,8 @@ filter:
     label_upload: Upload
     label_download: Download
     label_workflow: Workflow
+    label_log: Log
+    label_model_workflow: Workflow
 breadcrumb:
     link_o_n_u_list: Listado ONU
     link_o_n_u_create: Crear ONU
@@ -78,6 +80,8 @@ form:
     label_upload: Upload
     label_download: Download
     label_workflow: Workflow
+    label_log: Log
+    label_model_workflow: Workflow
 list:
     label_id: Id
     label_ip: Ip
@@ -105,6 +109,8 @@ list:
     label_upload: Upload
     label_download: Download
     label_workflow: Workflow
+    label_log: Log
+    label_model_workflow: Workflow
 show:
     label_id: Id
     label_ip: Ip
@@ -131,4 +137,6 @@ show:
     label_profile: Perfil
     label_upload: Upload
     label_download: Download
-    label_workflow: Workflow
+    label_workflow: Workflow
+    label_log: Log
+    label_model_workflow: Workflow

+ 5 - 0
src/FTTHBundle/Resources/views/ONU/show_log.html.twig

@@ -0,0 +1,5 @@
+{% extends 'SonataAdminBundle:CRUD:base_show_field.html.twig' %}
+
+{% block field %}
+    <pre style="font-size: 10px;">{{object.getLog()}}</pre>
+{% endblock %}

+ 3 - 3
src/FTTHBundle/Resources/views/ONU/show_workflow.html.twig

@@ -4,7 +4,7 @@
     <h1>ONU "{{ onu.ponSerialNumber}}"</h1>
     <div class="row">
         <div class="col-md-5">
-            <h2>Current State</h2>
+            <h2>Workflow: {{onu.getWorkflow()}}</h2>
             <p>
                 <code>
                     FTTHBundle\Entity\ONU::current_state = {{ onu.getCurrentState() }}
@@ -63,9 +63,9 @@
     </div>
     <div>
         <br />
-        <img src="http://200.50.175.17/ftth/onu_state.png" />
+        <img src="http://200.50.175.17/ftth/workflows_png/{{onu.getWorkflow()}}.png" />
         <br />
-        <img src="http://200.50.175.17/ftth/transition_state.png" />
+        <img src="http://200.50.175.17/ftth/workflows_png/transition_state.png" />
     </div>
     <br />
     <div>

+ 29 - 21
src/WorkflowBundle/Admin/ActionAdmin.php

@@ -14,7 +14,15 @@ class ActionAdmin extends BaseAdmin
 
     public function getTemplate($name)
     {
-        return parent::getTemplate($name);
+        switch ($name) {
+            case 'edit':
+                return 'WorkflowBundle:Action:action_edit.html.twig';
+                break;
+
+            default:
+                return parent::getTemplate($name);
+                break;
+        }
     }
 
     /**
@@ -24,6 +32,7 @@ class ActionAdmin extends BaseAdmin
     {
         $datagridMapper
             ->add('name')
+            ->add('workflowType')
             ->add('workflowName')
             ->add('objectClass')
             ->add('event')
@@ -38,10 +47,11 @@ class ActionAdmin extends BaseAdmin
     {
         $listMapper
             ->add('name')
+            ->add('workflowType')
             ->add('workflowName')
             ->add('objectClass')
             ->add('event')
-            ->add('eventName')
+            ->add('eventReference')
             ->add('_action', null, array(
                 'actions' => array(
                     'show' => array(),
@@ -60,24 +70,21 @@ class ActionAdmin extends BaseAdmin
 
         $formMapper
             ->add('name')
+            ->add('workflowType', 'choice', array('choices' => array('state_machine' => 'state_machine', 'workflow' => 'workflow')))
             ->add('workflowName')
-            ->add('objectClass')
-            ->add('event')
-            ->add('eventName')
-            ->add('template')
-            // ->add('type', 'choice', array('choices' => array('state_machine' => 'state_machine', 'workflow' => 'workflow')))
-            // ->add('markingType', 'choice', array('choices' => array('single_state' => 'single_state', 'multiple_state' => 'multiple_state')))
-            // ->add('markingName', 'choice', array('choices' => array('currentState' => 'currentState')))
-            // ->add('template', null, array('attr' => array('style' => 'height:500px;')))
+            ->add('objectClass', 'choice', array('choices' => array('FTTHBundle\Entity\ONU' => 'FTTHBundle\Entity\ONU', 'FTTHBundle\Entity\OLT' => 'FTTHBundle\Entity\OLT')))
+            ->add('event', 'choice', array('choices' => array('transition' => 'transition', 'leave' => 'leave', 'enter' => 'enter', 'guard' => 'guard')))
+            ->add('eventReference')
+            ->add('template', null, array('attr' => array('style' => 'height:500px;')))
 
             ->setHelps(array(
+               'workflowType' => $this->trans("helps.action_label_workflow_type"),
+               'workflowName' => $this->trans("helps.action_label_workflow_name"),
                'name' => $this->trans("helps.action_label_name"),
-               'actionName' => $this->trans("helps.action_label_type"),
-               'objectClass' => $this->trans("helps.action_label_marking_type"),
-               'event' => $this->trans("helps.action_label_marking_name"),
-               'eventName' => $this->trans("helps.action_label_marking_name"),
-               'template' => $this->trans("helps.action_label_marking_name"),
-
+               'objectClass' => $this->trans("helps.action_label_object_class"),
+               'event' => $this->trans("helps.action_label_event"),
+               'eventReference' => $this->trans("helps.action_label_event_reference"),
+               'template' => $this->trans("helps.action_label_template")
             ))
             ;
     }
@@ -90,11 +97,12 @@ class ActionAdmin extends BaseAdmin
         $showMapper
             ->add('id')
             ->add('name')
-            // ->add('description')
-            // ->add('enable')
-            // ->add('created')
-            // ->add('updated')
-            // ->add('template','string', array('template' => 'WorkflowBundle:Workflow:show_template.html.twig'))
+            ->add('workflowType')
+            ->add('workflowName')
+            ->add('objectClass')
+            ->add('event')
+            ->add('eventReference')
+            ->add('template','string', array('template' => 'WorkflowBundle:Action:show_template.html.twig'))
         ;
     }
 

+ 39 - 8
src/WorkflowBundle/Entity/Action.php

@@ -27,6 +27,13 @@ class Action
      */
     protected $name;
 
+    /**
+     * @var string
+     *
+     * @ORM\Column(type="string", length=255, nullable=false)
+     */
+    protected $workflowType;
+    
     /**
      * @var string
      *
@@ -53,7 +60,7 @@ class Action
      *
      * @ORM\Column(type="string", length=255, nullable=false)
      */
-    protected $eventName;
+    protected $eventReference;
 
     /**
      * @var text
@@ -153,6 +160,30 @@ class Action
         return $this->template;
     }
 
+    /**
+     * Set workflowType
+     *
+     * @param string $workflowType
+     *
+     * @return Action
+     */
+    public function setWorkflowType($workflowType)
+    {
+        $this->workflowType = $workflowType;
+
+        return $this;
+    }
+
+    /**
+     * Get workflowType
+     *
+     * @return string
+     */
+    public function getWorkflowType()
+    {
+        return $this->workflowType;
+    }
+
     /**
      * Set workflowName
      *
@@ -202,27 +233,27 @@ class Action
     }
 
     /**
-     * Set eventName
+     * Set eventReference
      *
-     * @param string $eventName
+     * @param string $eventReference
      *
      * @return Action
      */
-    public function setEventName($eventName)
+    public function setEventReference($eventReference)
     {
-        $this->eventName = $eventName;
+        $this->eventReference = $eventReference;
 
         return $this;
     }
 
     /**
-     * Get eventName
+     * Get eventReference
      *
      * @return string
      */
-    public function getEventName()
+    public function getEventReference()
     {
-        return $this->eventName;
+        return $this->eventReference;
     }
 
     /**

+ 8 - 0
src/WorkflowBundle/Entity/Workflow.php

@@ -459,6 +459,14 @@ class Workflow
         $console = $rootDir."/../bin/console";
         exec("php {$console} cache:clear --env=prod");
 
+        $web_workflows = $rootDir."/../web/workflows_png/";
+        foreach($workflows as $k => $workflow) {
+            $file_locate = "{$web_workflows}/{$workflow->getName()}";
+            exec("php {$console} workflow:dump {$workflow->getName()} > {$file_locate}.dot");
+            if(file_exists("{$file_locate}.dot")) {
+                exec("dot -Tpng {$file_locate}.dot -o {$file_locate}.png");
+            }
+        }
     }
 
 }

+ 77 - 5
src/WorkflowBundle/Event/EventSubscriber.php

@@ -29,27 +29,54 @@ class EventSubscriber implements EventSubscriberInterface
     public static function getSubscribedEvents()
     {
         return array(
+                'workflow.leave' => array('leave'),
                 'workflow.transition' => array('transition'),
                 'workflow.enter' => array('enter'),
-                'workflow.leave' => array('leave'),
                 'workflow.guard' => array('guard')
         );
     }
 
-    public function transition(Event $event)
+    public function leave(Event $event)
     {
-        
+        foreach ($event->getTransition()->getFroms() as $place) {
+            $actions = $this->getActions($event, 'leave', $place);
+
+            foreach($actions as $k => $action) {
+                $params = array('object'=>$event->getSubject());
+                $this->completeAction($action, $params);
+
+            }
+            
+        }
 
     }
-    
-    public function leave(Event $event)
+
+    public function transition(Event $event)
     {
+        $transitionName = $event->getTransition()->getName();
+
+        $actions = $this->getActions($event, 'transition', $transitionName);
 
+        foreach($actions as $k => $action) {
+            $params = array('object'=>$event->getSubject());
+            $this->completeAction($action, $params);
+
+        }
 
     }
 
     public function enter(Event $event)
     {
+        foreach ($event->getTransition()->getTos() as $place) {
+            $actions = $this->getActions($event, 'enter', $place);
+
+            foreach($actions as $k => $action) {
+                $params = array('object'=>$event->getSubject());
+                $this->completeAction($action, $params);
+
+            }
+            
+        }
 
         
     }
@@ -58,5 +85,50 @@ class EventSubscriber implements EventSubscriberInterface
     {
        //$event->setBlocked(true);
     }
+
+    public function getActions($event, $eventType, $eventReference) {
+        $logger = $this->container->get('logger');
+
+        $em = $this->container->get("doctrine.orm.entity_manager");
+        $object = $event->getSubject();
+        $class = (string) get_class($object);
+    
+        $filter = array();
+        $filter['event'] = $eventType;
+        $filter['objectClass'] = $class;
+        $filter['workflowType'] = $object->getWorkflowType();
+        $filter['workflowName'] = $object->getWorkflow();
+        $filter['eventReference'] = $eventReference;
+
+        $logger->info("WORKFLOW-ACTION {$object->getWorkflowType()}.{$object->getWorkflow()} => EVENT {$eventType}:{$eventReference} => CLASS {$class}_id_{$object->getId()}");
+
+        $actions = $em->getRepository("WorkflowBundle:Action")->findBy($filter);
+
+        return $actions;
+
+    }
+
+    public function completeAction($action, $params) {
+        
+        $logger = $this->container->get('logger');
+        $template = $action->getTemplate();
+
+        $twig = new \Twig_Environment(new \Twig_Loader_String());
+        $rendered = $twig->render($template, $params);
+
+        $object = $params['object'];
+        $class = get_class($object);
+        
+        $logger->info("WORKFLOW-ACTION {$class}_id_{$object->getId()} | action_id_{$action->getId()} => Render: {$rendered}");
+        
+        $string = file_get_contents("/var/flowdat/ftth/out.log");
+            
+        $string .= "### Action id :".$action->getId().PHP_EOL;
+        $string .= "----------------------".PHP_EOL.$template.PHP_EOL;
+        $string .= "----------------------".PHP_EOL.$rendered.PHP_EOL.PHP_EOL;
+        
+        file_put_contents("/var/flowdat/ftth/out.log", $string);
+
+    }
     
 }

+ 32 - 10
src/WorkflowBundle/Resources/translations/WorkflowBundle.es.yml

@@ -7,14 +7,20 @@ filter:
     label_created: Creado
     label_updated: Actualizado
     label_enable : Habilitado
-    label_event: Evento
-    label_event_name: Evento
+    label_workflow_type : Tipo de Workflow
+    label_workflow_name : Workflow
+    label_object_class  : Clase
+    label_event : Evento
+    label_event_reference : Referencia
     label_actions: Actions
     label_entity_class: Entidad
 breadcrumb:
     link_workflow_list: Listado Workflows
     link_workflow_create: Crear Workflow
     link_workflow_delete: Eliminar Workflow
+    link_action_list: Listado Acciones
+    link_action_create: Crear Acción
+    link_action_delete: Eliminar Acción
     link_doctrine2_work_flow_action_list: Listado Doctrine2WorkFlowAction
     link_doctrine2_work_flow_action_create: Crear Doctrine2WorkFlowAction
     link_doctrine2_work_flow_action_delete: Eliminar Doctrine2WorkFlowAction
@@ -30,8 +36,11 @@ form:
     label_type : Tipo de Workflow
     label_marking_type : Tipo de marcador
     label_marking_name : Nombre de marcador
-    label_event: Evento
-    label_event_name: Evento
+    label_workflow_type : Tipo de Workflow
+    label_workflow_name : Workflow
+    label_object_class  : Clase
+    label_event : Evento
+    label_event_reference : Referencia
     label_actions: Actions
     label_entity_class: Entidad
 list:
@@ -46,8 +55,11 @@ list:
     label_type : Tipo de Workflow
     label_marking_type : Tipo de marcador
     label_marking_name : Nombre de marcador
-    label_event: Evento
-    label_event_name: Evento
+    label_workflow_type : Tipo de Workflow
+    label_workflow_name : Workflow
+    label_object_class  : Clase
+    label_event : Evento
+    label_event_reference : Referencia
     label_actions: Actions
     label_entity_class: Entidad
 show:
@@ -62,12 +74,22 @@ show:
     label_type : Tipo de Workflow
     label_marking_type : Tipo de marcador
     label_marking_name : Nombre de marcador
-    label_event: Evento
-    label_event_name: Evento
+    label_workflow_type : Tipo de Workflow
+    label_workflow_name : Workflow
+    label_object_class  : Clase
+    label_event : Evento
+    label_event_reference : Referencia
     label_actions: Actions
     label_entity_class: Entidad
 helps:
-    workflow_label_name: Nombre con el que se identificará el workflow. Se convertirá a minúscula y los espacios se reemplazarán por "_"
+    workflow_label_name: Nombre con el que se identificará el wWrkflow. Se convertirá a minúscula y los espacios se reemplazarán por "_"
     workflow_label_type: "Tipo de Workflow: state_machine o workflow"
     workflow_label_marking_type: "Tipo de Marcador: single_state o multiple_state"
-    workflow_label_marking_name: "Nombre del Marcador, atributo de la entidad que tendrá el estado, por defecto: currentState"
+    workflow_label_marking_name: "Nombre del Marcador, atributo de la entidad que tendrá el estado, por defecto: currentState"
+    action_label_name: Nombre con el que se identificará a una Acción
+    action_label_workflow_type: Tipo de Workflow.
+    action_label_workflow_name: Nombre del Workflow al cual hace referencia.
+    action_label_object_class: Clase a la que se vinculará la Acción
+    action_label_event: Tipo de evento[leave|transition|enter|guard] al cual responderá la Acción
+    action_label_event_reference: Nombre del estado o transición que realiza el Evento
+    action_label_template: Template en twig con las acciones a realizar en dicha Acción

+ 35 - 0
src/WorkflowBundle/Resources/views/Action/action_edit.html.twig

@@ -0,0 +1,35 @@
+{% extends 'SonataAdminBundle:CRUD:base_edit.html.twig' %}
+
+{% block form %}
+    {{ parent() }}
+     
+    {#https://github.com/ryanburnette/textarea-as-ace-editor#}
+    {#https://ace.c9.io/#}
+    {#https://ace.c9.io/build/kitchen-sink.html#}
+    <script src="{{ asset('bundles/baseadmin') }}/ace_editor/src-noconflict/ace.js" type="text/javascript" charset="utf-8"></script>
+    <script src="{{ asset('bundles/baseadmin') }}/ace_editor/textarea-as-ace-editor.js" type="text/javascript" charset="utf-8"></script>
+     
+    <style type="text/css" media="screen">
+        .ace_editor {
+            height: 250px!important;
+        }
+    </style>
+
+    <script type="text/javascript">
+        $( document ).ready(function() {
+            $("textarea").asAceEditor();
+            editor = $('textarea').data('ace-editor');
+            
+            editor.setTheme("ace/theme/github");
+            editor.getSession().setMode("ace/mode/twig");
+            //editor.setReadOnly(true);
+            editor.setFontSize(14);
+            editor.setShowInvisibles(true);
+            editor.getSession().setTabSize(2);
+            editor.getSession().setUseSoftTabs(true);
+            editor.getSession().setUseWrapMode(true);
+        });
+    </script>
+
+
+{% endblock %}

+ 30 - 0
src/WorkflowBundle/Resources/views/Action/show_template.html.twig

@@ -0,0 +1,30 @@
+{% extends 'SonataAdminBundle:CRUD:base_show_field.html.twig' %}
+
+{% block field %}
+    <textarea id="textarea_ace_editor">{{object.getTemplate()}}</textarea>
+
+    <script src="{{ asset('bundles/baseadmin') }}/ace_editor/src-noconflict/ace.js" type="text/javascript" charset="utf-8"></script>
+    <script src="{{ asset('bundles/baseadmin') }}/ace_editor/textarea-as-ace-editor.js" type="text/javascript" charset="utf-8"></script>
+     
+    <style type="text/css" media="screen">
+        .ace_editor {
+            height: 250px!important;
+        }
+    </style>
+
+    <script type="text/javascript">
+        $( document ).ready(function() {
+            $("#textarea_ace_editor").asAceEditor();
+            editor = $('#textarea_ace_editor').data('ace-editor');
+            
+            editor.setTheme("ace/theme/github");
+            editor.getSession().setMode("ace/mode/twig");
+            editor.setReadOnly(true);
+            editor.setFontSize(14);
+            editor.setShowInvisibles(true);
+            editor.getSession().setTabSize(2);
+            editor.getSession().setUseSoftTabs(true);
+            editor.getSession().setUseWrapMode(true);
+        });
+    </script>
+{% endblock %}

+ 27 - 1
src/WorkflowBundle/Resources/views/Workflow/show_template.html.twig

@@ -1,5 +1,31 @@
 {% extends 'SonataAdminBundle:CRUD:base_show_field.html.twig' %}
 
 {% block field %}
-    <pre>{{object.getTemplate()}}</pre>
+    <textarea id="textarea_ace_editor">{{object.getTemplate()}}</textarea>
+
+    <script src="{{ asset('bundles/baseadmin') }}/ace_editor/src-noconflict/ace.js" type="text/javascript" charset="utf-8"></script>
+    <script src="{{ asset('bundles/baseadmin') }}/ace_editor/textarea-as-ace-editor.js" type="text/javascript" charset="utf-8"></script>
+     
+    <style type="text/css" media="screen">
+        .ace_editor {
+            height: 250px!important;
+        }
+    </style>
+
+    <script type="text/javascript">
+        $( document ).ready(function() {
+            $("#textarea_ace_editor").asAceEditor();
+            editor = $('#textarea_ace_editor').data('ace-editor');
+            
+            editor.setTheme("ace/theme/github");
+            editor.getSession().setMode("ace/mode/twig");
+            editor.setReadOnly(true);
+            editor.setFontSize(14);
+            editor.setShowInvisibles(true);
+            editor.getSession().setTabSize(2);
+            editor.getSession().setUseSoftTabs(true);
+            editor.getSession().setUseWrapMode(true);
+        });
+    </script>
+    <img src="http://200.50.175.17/ftth/workflows_png/{{object.getName()}}.png" />
 {% endblock %}

+ 6 - 0
src/WorkflowBundle/Resources/views/Workflow/workflow_edit.html.twig

@@ -9,6 +9,12 @@
      <script src="{{ asset('bundles/baseadmin') }}/ace_editor/src-noconflict/ace.js" type="text/javascript" charset="utf-8"></script>
      <script src="{{ asset('bundles/baseadmin') }}/ace_editor/textarea-as-ace-editor.js" type="text/javascript" charset="utf-8"></script>
      
+     <style type="text/css" media="screen">
+        .ace_editor {
+            height: 250px!important;
+        }
+    </style>
+    
      <script type="text/javascript">
         $( document ).ready(function() {
             $("textarea").asAceEditor();

+ 12 - 0
src/WorkflowBundle/Validator/Constraints/ContainsYaml.php

@@ -0,0 +1,12 @@
+<?php
+namespace WorkflowBundle\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * @Annotation
+ */
+class ContainsYaml extends Constraint
+{
+    public $message = 'workflow_error_yaml_format';
+}

+ 24 - 0
src/WorkflowBundle/Validator/Constraints/ContainsYamlValidator.php

@@ -0,0 +1,24 @@
+<?php
+namespace WorkflowBundle\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+use Symfony\Component\Yaml\Yaml;
+
+class ContainsYamlValidator extends ConstraintValidator
+{
+    public function validate($value, Constraint $constraint)
+    {
+        $yaml = Yaml::dump($value,100,2);
+
+        
+        
+        
+        
+        // if (!preg_match('/^[a-zA-Z0-9]+$/', $value, $matches)) {
+        //     $this->context->buildViolation($constraint->message)
+        //         ->setParameter('%string%', $value)
+        //         ->addViolation();
+        // }
+    }
+}

BIN
web/workflows_png/onu_state.png


+ 10 - 0
web/workflows_png/onu_state_v2.dot

@@ -0,0 +1,10 @@
+digraph workflow {
+  ratio="compress" rankdir="LR"
+  node [fontsize="9" fontname="Arial" color="#333333" fillcolor="lightblue" fixedsize="1" width="1"];
+  edge [fontsize="9" fontname="Arial" color="#333333" arrowhead="normal" arrowsize="0.5"];
+
+  place_active [label="active", shape=circle, style="filled"];
+  place_suspend [label="suspend", shape=circle];
+  place_active -> place_suspend [label="active_to_suspends" style="solid"];
+}
+

BIN
web/workflows_png/onu_state_v2.png


+ 18 - 0
web/workflows_png/onu_state_v5.dot

@@ -0,0 +1,18 @@
+digraph workflow {
+  ratio="compress" rankdir="LR"
+  node [fontsize="9" fontname="Arial" color="#333333" fillcolor="lightblue" fixedsize="1" width="1"];
+  edge [fontsize="9" fontname="Arial" color="#333333" arrowhead="normal" arrowsize="0.5"];
+
+  place_active [label="active", shape=circle, style="filled"];
+  place_suspend [label="suspend", shape=circle];
+  place_pendiente [label="pendiente", shape=circle];
+  place_holamundo [label="holamundo", shape=circle];
+  place_holapepe [label="holapepe", shape=circle];
+  place_active -> place_suspend [label="active_to_suspend" style="solid"];
+  place_active -> place_pendiente [label="active_to_pendiente" style="solid"];
+  place_active -> place_holamundo [label="active_to_holamundo" style="solid"];
+  place_suspend -> place_active [label="suspend_to_active" style="solid"];
+  place_pendiente -> place_active [label="pendiente_to_active" style="solid"];
+  place_holamundo -> place_holapepe [label="holamundo_to_holapepe" style="solid"];
+}
+

BIN
web/workflows_png/onu_state_v5.png


BIN
web/workflows_png/transition_state.png