it:ad:stateless:howto:example_reading_json

IT:AD:Stateless:HowTo:Examples/Reading JSON

Summary

The following is about where I stopped investigating…when I realized I would need to find a solution to providing Orthagonal States.

Your mileage may vary…

Reading

{
    "name": "SomeWorkflow",
    "states": [
        {
            "name": "OffHook",
            "transitions": [
                { "name": "CallDialed", "target": "Ringing" }
            ]
        },
        {
            "name": "Ringing",
            "transitions": [
                { "name": "HungUp", "target": "OffHook" },
                { "name": "CallConnected", "target": "Connected" }
            ]
        },
        {
            "name": "Connected",
            "transitions": [
                { "name": "LeftMessage", "target": "OffHook" },
                { "name": "HungUp", "target": "OffHook" },
                { "name": "PlacedOnHold", "target": "OnHold" }
            ],
            "command": "TelephoneCallExample.XYZ.BeHappy",
            "states": [
                {
                    "name": "OnHold",
                    "transitions": [
                        { "name": "TakenOffHold", "target": "Connected" },
                        { "name": "HungUp", "target": "OffHook" },
                        { "name": "PhoneHurledAgainstWall", "target": "PhoneDestroyed" }
                    ]
                }
            ]
        },
        {
            "name": "PhoneDetroyed",
            "transitions": [
            ]
        }
    ]
}

using the following:

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Text;
using Newtonsoft.Json;
using Stateless;

namespace TelephoneCallExample
{

    //public class WorkflowRepositoryService
    //{
    //    public WorkflowStatus Get(int id)
    //    {
            
    //    } 
    //}

    public class Workflow
    {
        public string Name { get; private set; }
        public StateMachine<WorkflowState, string> Engine { get; private set; }
        
        public ICollection<WorkflowState> States { get { return _states ??(_states = new Collection<WorkflowState>());} }
        ICollection<WorkflowState> _states = new Collection<WorkflowState>();

        public WorkflowStatus WorkflowStatus { get; private set; }

        public Workflow(WorkflowDefinition workflowDefinition)
        {
            WorkflowStatus = new WorkflowStatus();

            Engine = new StateMachine<WorkflowState, string>(
                () => this.Instance,
                (x) =>
                {
                    this.Instance = x;
                    WorkflowStatus.StateName = this.Instance.Name;
                }
                );

            this.Name = workflowDefinition.Name;
            ParseWorkflowStates(workflowDefinition.States);

            this.Initialize(this.States.First());

        }

        public void Initialize(WorkflowState x)
        {
            _instance = x;
        }
        private WorkflowState _instance;

        public WorkflowState Instance 
        {
            get { return _instance; }
            set { _instance = value; }
        }


        public void Trigger(string trigger)
        {
            Engine.Fire(trigger);
        }

        public override string ToString()
        {
            return string.Format("{0} [State:{1}]", this.Name, this.Engine.State.Name);
        }



        private void ParseWorkflowStates(ICollection<WorkflowStateDefinition> workflowStateDefinitions)
        {
            foreach (WorkflowStateDefinition workflowStateDefinition in workflowStateDefinitions)
            {
                Console.WriteLine(string.Format("Registering {0}", workflowStateDefinition.Name));

                WorkflowState workflowState = this.States.SingleOrDefault(x => x.Name == workflowStateDefinition.Name);
                if (workflowState == null)
                {
                    workflowState = new WorkflowState { Name = workflowStateDefinition.Name };
                    this.States.Add(workflowState);
                }

                foreach (WorkflowTargetDefinition workflowTargetDefinition in workflowStateDefinition.Transitions)
                {
                    Console.WriteLine(string.Format("- {0}:{1}", workflowTargetDefinition.Name,
                        workflowTargetDefinition.Target));

                    //Get the name, and try to find the State:
                    var targetState = this.States.SingleOrDefault(x => x.Name == workflowTargetDefinition.Target);
                    if (targetState == null)
                    {
                        targetState = new WorkflowState { Name = workflowTargetDefinition.Target };
                        this.States.Add(targetState);
                    }

                    this.Engine.Configure(workflowState)
                        .Permit(
                            workflowTargetDefinition.Name,
                            targetState);
                }
                //Are there any subStates?
                ParseWorkflowStates(workflowStateDefinition.States);

                if (workflowStateDefinition.Command != null)
                {
                    string tmp = workflowStateDefinition.Command;
                    int pos = tmp.LastIndexOf(".");
                    string tmpName = tmp.Substring(0, pos);
                    string tmpName2 = tmp.Substring(pos + 1);

                    var t = this.GetType().Assembly.GetType(tmpName);
                    var m = t.GetMethod(tmpName2);


                }

            }
        }

    }


    public interface IHasName
    {
        string Name { get; set; }
    }

    public class WorkflowStatus
    {
        public Guid Id {get; set; }
        public string Name { get; set; }
        public string StateName { get; set; }
    }

    public class WorkflowState :IHasName
    {
        public string Name { get; set; }

        public ICollection<WorkflowTransition> Transitions { get { return _transitions ?? (_transitions = new Collection<WorkflowTransition>()); } }
        ICollection<WorkflowTransition> _transitions;

        public override string ToString()
        {
            return string.Format("{0} [Triggers: {1}]", Name,string.Join(",",Transitions.Select(x=>x.Name).ToArray()));
        }
    }

    public class WorkflowTransition : IHasName
    {
        public string Name { get; set; }
        public WorkflowState Target { get; set; }

        public override string ToString()
        {
            return string.Format("{0} [Target: {1}]",Name,Target);
        }

    }

    public class WorkflowDefinition:IHasName
    {
        public string Name { get; set; }
        public WorkflowStateDefinition[] States { get; set; }
    }

    public class WorkflowStateDefinition : IHasName
    {
        public string Name { get; set; }

        public List<WorkflowTargetDefinition> Transitions { get { return _targets ?? (_targets = new List<WorkflowTargetDefinition>()); } }
        private List<WorkflowTargetDefinition> _targets;

        public ICollection<WorkflowStateDefinition> States { get { return _states??(_states = new Collection<WorkflowStateDefinition>());} }
        private ICollection<WorkflowStateDefinition> _states;

        public string Command { get; set; }
    }

    public class WorkflowTargetDefinition :IHasName
    {
        public string Name { get; set; }
        public string Target { get; set; }
    }



    class Program
    {
        static void Main(string[] args)
        {

            var workflowDefinition = Parse(File.ReadAllText(@"json1.json"));

            Workflow workflow = BuildWorkflowEngine( workflowDefinition, Guid.NewGuid());


            Fire(workflow, "CallDialed");
            Print(workflow);
            Fire(workflow, "CallConnected");
            Print(workflow);
            Fire(workflow, "PlacedOnHold");
            Print(workflow);
            Fire(workflow, "TakenOffHold");
            Print(workflow);
            Fire(workflow, "HungUp");
            Print(workflow);

            Console.WriteLine("Press any key...");
            Console.ReadKey(true);
        }

        private static WorkflowDefinition Parse(string workflowDescriptionJson)
        {
            WorkflowDefinition workflowDefinition =
             JsonConvert.DeserializeObject<WorkflowDefinition>(workflowDescriptionJson);

            return workflowDefinition;
        }

        

        private static Workflow BuildWorkflowEngine(WorkflowDefinition workflowDefinition, Guid workflowInstance)
        {
            //Deserialize json into workflow definition:
         
            int workflowId;
            Guid workflowInstanceId;

            Workflow workflow = new Workflow(workflowDefinition);
            
            return workflow;
        }



        static void Fire(Workflow workflow, string trigger)
        {
            Console.WriteLine("[Firing:] {0}", trigger);
            workflow.Trigger(trigger);
        }

        static void Print(Workflow workflow)
        {
            Console.WriteLine("[Status:] {0}", workflow.Engine.State.Name);
        }
    }

    public class XYZ
    {
        public void BeHappy()
        {
            Console.WriteLine("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
        }
        public void StartCallTimer()
        {
            Console.WriteLine("[Timer:] Call started at {0}", DateTime.Now);
        }

        public void StopCallTimer()
        {
            Console.WriteLine("[Timer:] Call ended at {0}", DateTime.Now);
        }
        
    }
}

  • /home/skysigal/public_html/data/pages/it/ad/stateless/howto/example_reading_json.txt
  • Last modified: 2023/11/04 01:58
  • by 127.0.0.1