lib/floe/workflow.rb in floe-0.11.3 vs lib/floe/workflow.rb in floe-0.12.0
- old
+ new
@@ -4,10 +4,11 @@
require "json"
module Floe
class Workflow
include Logging
+ include ValidationMixin
class << self
def load(path_or_io, context = nil, credentials = {}, name = nil)
payload = path_or_io.respond_to?(:read) ? path_or_io.read : File.read(path_or_io)
# default the name if it is a filename and none was passed in
@@ -94,23 +95,25 @@
# backwards compatibility
# caller should really put credentials into context and not pass that variable
context.credentials = credentials if credentials
- raise Floe::InvalidWorkflowError, "Missing field \"States\"" if payload["States"].nil?
- raise Floe::InvalidWorkflowError, "Missing field \"StartAt\"" if payload["StartAt"].nil?
- raise Floe::InvalidWorkflowError, "\"StartAt\" not in the \"States\" field" unless payload["States"].key?(payload["StartAt"])
-
- @name = name
+ # NOTE: this is a string, and states use an array
+ @name = name || "State Machine"
@payload = payload
@context = context
@comment = payload["Comment"]
@start_at = payload["StartAt"]
- @states = payload["States"].to_a.map { |state_name, state| State.build!(self, state_name, state) }
- @states_by_name = @states.each_with_object({}) { |state, result| result[state.name] = state }
- rescue Floe::InvalidWorkflowError
+ # NOTE: Everywhere else we include our name (i.e.: parent name) when building the child name.
+ # When creating the states, we are dropping our name (i.e.: the workflow name)
+ @states = payload["States"].to_a.map { |state_name, state| State.build!(self, ["States", state_name], state) }
+
+ validate_workflow
+
+ @states_by_name = @states.each_with_object({}) { |state, result| result[state.short_name] = state }
+ rescue Floe::Error
raise
rescue => err
raise Floe::InvalidWorkflowError, err.message
end
@@ -155,11 +158,11 @@
def status
context.status
end
def output
- context.output if end?
+ context.json_output if end?
end
def end?
context.ended?
end
@@ -185,10 +188,17 @@
# backwards compatibility. Caller should access directly from context
def credentials
@context.credentials
end
+
private
+
+ def validate_workflow
+ missing_field_error!("States") if @states.empty?
+ missing_field_error!("StartAt") if @start_at.nil?
+ invalid_field_error!("StartAt", @start_at, "is not found in \"States\"") unless workflow_state?(@start_at, self)
+ end
def step!
next_state = {"Name" => context.next_state, "Guid" => SecureRandom.uuid, "PreviousStateGuid" => context.state["Guid"]}
# if rerunning due to an error (and we are using Retry)