Skip to content

Commit

Permalink
Merge pull request #8 from Around25/feature/#1-basic-process
Browse files Browse the repository at this point in the history
Partially added nodejs script task execution
  • Loading branch information
cosmin-harangus authored Oct 24, 2017
2 parents 8b41bf9 + 7c092a7 commit 56271b7
Show file tree
Hide file tree
Showing 10 changed files with 167 additions and 41 deletions.
13 changes: 11 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
language: elixir
elixir: '1.5'
otp_release: '20.0'

elixir:
- '1.5'
otp_release:
- '19.0'
- '20.0'

env:
- MIX_ENV=test

script: mix coveralls.travis
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

[![Build Status](https://travis-ci.org/Around25/hashiru-bpmn.svg?branch=master)](https://travis-ci.org/Around25/hashiru-bpmn)
[![Hex Version](https://img.shields.io/hexpm/v/bpmn.svg)](https://hex.pm/packages/bpmn)
[![Join the chat at https://gitter.im/hashiru-bpmn/Lobby](https://badges.gitter.im/hashiru-bpmn/Lobby.svg)](https://gitter.im/hashiru-bpmn/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Coverage Status](https://coveralls.io/repos/github/Around25/hashiru-bpmn/badge.svg?branch=develop)](https://coveralls.io/github/Around25/hashiru-bpmn?branch=develop)
[![Join the chat at https://gitter.im/hashiru-bpmn/Lobby](https://badges.gitter.im/hashiru-bpmn/Lobby.svg)](https://gitter.im/hashiru-bpmn/Lobby)

The scope of this project is to create a bpmn2 execution engine that can scale on multiple node in an elixir cluster.

Expand Down
19 changes: 12 additions & 7 deletions lib/bpmn/activity/task/script.ex
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
defmodule Bpmn.Activity.Task.Script do
@moduledoc """
Handle passing the token through an event element.
iex> Bpmn.Port.Nodejs.eval_string("1+1", %{cosmin: "soss"})
%{"context" => %{"cosmin" => "soss"}, "script" => "1+1", "type" => "string"}
"""

@doc """
Expand All @@ -13,13 +17,14 @@ defmodule Bpmn.Activity.Task.Script do
@doc """
Execute the start event business logic
"""
def execute({:bpmn_activity_task_script, {source, target, condition}}, context) do
case Bpmn.Expression.execute(condition, context) do
{:ok, true} -> execute({:bpmn_sequence_flow, {source, target}}, context)
{:ok, false} -> {:false}
_ -> {:error}
end
end
def execute({:bpmn_activity_task_script, %{outputs: outputs, type: type, script: script}}, context) do
IO.inspect Bpmn.Port.Nodejs.eval_string("1+3", %{testing: "something"})
# case Bpmn.Expression.execute(condition, context) do
# {:ok, true} -> execute({:bpmn_sequence_flow, {source, target}}, context)
# {:ok, false} -> {:false}
# _ -> {:error}
# end
end
def execute(elem, context), do: tokenOut(elem, context)

end
23 changes: 23 additions & 0 deletions lib/bpmn/application.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
defmodule Bpmn.Application do
# See http://elixir-lang.org/docs/stable/elixir/Application.html
# for more information on OTP Applications
@moduledoc false

use Application

def start(_type, _args) do
import Supervisor.Spec, warn: false

# Define workers and child supervisors to be supervised
children = [
# Starts a worker by calling: Bpmn.Worker.start_link(arg1, arg2, arg3)
# worker(Bpmn.Worker, [arg1, arg2, arg3]),
supervisor(Bpmn.Port.Supervisor, [])
]

# See http://elixir-lang.org/docs/stable/elixir/Supervisor.html
# for other strategies and supported options
opts = [strategy: :one_for_one, name: Bpmn.Supervisor]
Supervisor.start_link(children, opts)
end
end
52 changes: 24 additions & 28 deletions lib/bpmn/event/start.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,34 +6,34 @@ defmodule Bpmn.Event.Start do
A BPMN start event can have the following BPMN contents:
<bpmn:startEvent id="StartEvent_1" name="START" camunda:initiator="HTTP">
<bpmn:outgoing>SequenceFlow_0u2ggjm</bpmn:outgoing>
<bpmn:extensionElements>
<camunda:formData>
<camunda:formField id="username" label="Username" type="string">
<camunda:validation>
<camunda:constraint name="username" config="required" />
<camunda:constraint name="password" config="required" />
</camunda:validation>
</camunda:formField>
<camunda:formField id="password" label="Password" type="string" />
</camunda:formData>
<camunda:executionListener class="bpmn.event.start.listener" event="start" />
</bpmn:extensionElements>
</bpmn:startEvent>
<bpmn:startEvent id="StartEvent_1" name="START" camunda:initiator="HTTP">
<bpmn:outgoing>SequenceFlow_0u2ggjm</bpmn:outgoing>
<bpmn:extensionElements>
<camunda:formData>
<camunda:formField id="username" label="Username" type="string">
<camunda:validation>
<camunda:constraint name="username" config="required" />
<camunda:constraint name="password" config="required" />
</camunda:validation>
</camunda:formField>
<camunda:formField id="password" label="Password" type="string" />
</camunda:formData>
<camunda:executionListener class="bpmn.event.start.listener" event="start" />
</bpmn:extensionElements>
</bpmn:startEvent>
This node can be represented as the following Elixir token:
{:bpmn_event_start,
%{
id: "StartEvent_1",
name: "START",
outgoing: ["SequenceFlow_0u2ggjm"],
inputs: [%{"username"=>"user", "password"=>"password"}],
definitions: [{:error_event_definition, %{}}]
}
{:bpmn_event_start,
%{
id: "StartEvent_1",
name: "START",
outgoing: ["SequenceFlow_0u2ggjm"],
inputs: [%{"username"=>"user", "password"=>"password"}],
definitions: [{:error_event_definition, %{}}]
}
}
## Examples
Expand All @@ -47,10 +47,6 @@ defmodule Bpmn.Event.Start do
iex> true
true
# iex> {:ok, context} = Bpmn.Context.start_link(%{"to" => {:bpmn_activity_task_script, {}}}, %{"username" => "test", "password" => "secret"})
# iex> {:ok, pid} = Bpmn.Event.Start.tokenIn({:bpmn_event_start, %{outgoing: ["to"]}}, context)
# iex> context == pid
# true
"""

@doc """
Expand Down
65 changes: 65 additions & 0 deletions lib/bpmn/port/nodejs.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
defmodule Bpmn.Port.Nodejs do
use GenServer

def start_link cmd \\ nil do
cmd = case cmd do
nil-> ["node /Users/cosmin/Incubator/github/hashiru/bpmn/priv/scripts/node.js"]
_-> cmd
end
GenServer.start_link __MODULE__, cmd, name: __MODULE__
end

def eval_script script, context do
GenServer.call __MODULE__, {:script, script, context}
end

def eval_string script, context do
GenServer.call __MODULE__, {:string, script, context}
end

def close do
GenServer.call __MODULE__, {:close}
end

## callbacks

def init cmd do
port = Port.open {:spawn, hd(cmd)}, [:binary]
{:ok, port}
end

def handle_call({:string, script, context}, from, port), do: send_request({"string", script, context}, from, port)
def handle_call({:script, script, context}, from, port), do: send_request({"file", script, context}, from, port)

def handle_call {:close}, _, port do
Port.close port
{:reply, :ok, nil}
end

def handle_call _, _from, nil do
{:stop, :port_closed, nil}
end

defp send_request {type, script, context}, _, port do
msg = Poison.encode!(%{
type: type,
script: script,
context: context,
})
result = case Port.command port, msg do
true -> receive do
{^port, {:data, result}} ->
{:ok, result}

after 5_000 -> {:error, :timed_out}
end

false -> {:error, :process_dead}
end

case result do
{:error, reason} -> {:stop, reason, nil}
{:ok, x} -> {:reply, Poison.decode!(x), port}
end
end
end
15 changes: 15 additions & 0 deletions lib/bpmn/port/supervisor.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
defmodule Bpmn.Port.Supervisor do
use Supervisor

def start_link() do
Supervisor.start_link(__MODULE__, :ok)
end

def init(:ok) do
children = [
{Bpmn.Port.Nodejs, ["node ./priv/scripts/node.js"]}
]

Supervisor.init(children, strategy: :one_for_one)
end
end
11 changes: 8 additions & 3 deletions mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ defmodule Bpmn.Mixfile do
[
app: :bpmn,
version: @version,
elixir: "~> 1.4",
elixir: "~> 1.5",
build_embedded: Mix.env == :prod,
start_permanent: Mix.env == :prod,
package: package(),
Expand All @@ -18,6 +18,8 @@ defmodule Bpmn.Mixfile do
name: "Hashiru BPMN",
source_url: "https://github.com/around25/hashiru-bpmn",
homepage_url: "https://github.com/around25/hashiru-bpmn",
test_coverage: [tool: ExCoveralls],
preferred_cli_env: [coveralls: :test],
docs: docs()
]
end
Expand All @@ -37,7 +39,8 @@ defmodule Bpmn.Mixfile do
# Type "mix help compile.app" for more information
def application do
# Specify extra applications you'll use from Erlang/Elixir
[extra_applications: [:logger]]
[extra_applications: [:logger],
mod: {Bpmn.Application, []}]
end

# Dependencies can be Hex packages:
Expand All @@ -52,7 +55,9 @@ defmodule Bpmn.Mixfile do
defp deps do
[
{:credo, "~> 0.8.8", only: [:dev, :test], runtime: false},
{:ex_doc, "~> 0.16", only: [:dev, :test], runtime: false}
{:ex_doc, "~> 0.16", only: [:dev, :test], runtime: false},
{:excoveralls, "~> 0.7.4", only: [:dev, :test], runtime: false},
{:poison, "~> 3.1"}
]
end

Expand Down
3 changes: 3 additions & 0 deletions priv/scripts/node.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
process.stdin.on('data', d => {
process.stdout.write(d + "\n");
});
4 changes: 4 additions & 0 deletions test/bpmn/activity/task/script_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
defmodule Bpmn.Activity.Task.ScriptTest do
use ExUnit.Case, async: true
doctest Bpmn.Activity.Task.Script
end

0 comments on commit 56271b7

Please sign in to comment.