Class: Collins::State::Specification

Inherits:
Object
  • Object
show all
Includes:
Util
Defined in:
lib/collins/state/specification.rb

Overview

Represents a managed state

Modeling a state machine like process in collins is useful for multi-step processes such as decommissioning hardware (where you want the process to span several days, with several discrete steps), or monitoring some process and taking action. A Specification provides a common format for storing state information as a value of an asset.

This will rarely be used directly, but rather is a byproduct of using Mixin

Constant Summary collapse

EMPTY_NAME =

Used as name placeholder when unspecified

:None
EMPTY_DESCRIPTION =

Used as description placeholder when unspecified

"Unspecified"

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*args) ⇒ Specification

Note:

If the specified timestamp is not a ‘Fixnum` (unixtime), the value is converted to a fixnum

Instantiate a new Specification

Examples:

Specification.new :start, 'I am a state', Time.now
Specification.new :start, :description => 'Hello World', :timestamp => 0

Parameters:

  • args (Hash, (Symbol,String,Fixnum))

    Arguments for instantiation

Options Hash (*args):

  • :name (String, Symbol)

    The name of the specification

  • :description (String)

    A description of the specification

  • :timestamp (Fixnum, Time, String) — default: Time.at(0).utcto_i

    The time the event occurred

Raises:

  • (ArgumentError)

    when ‘timestamp` is not a `Time`, `String` or `Fixnum`

  • (ArgumentError)

    when ‘name` or `description` not specified



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/collins/state/specification.rb', line 67

def initialize *args
  opts = {}
  while arg = args.shift do
    if arg.is_a?(Hash) then
      opts.update(arg)
    else
      key = [:name, :description, :timestamp].select{|k| !opts.key?(k)}.first
      opts.update(key => arg) unless key.nil?
    end
  end
  opts = symbolize_hash(opts)

  if opts.fetch(:none, false) then
    @name = EMPTY_NAME
    @description = EMPTY_DESCRIPTION
  else
    @name = ::Collins::Option(opts.delete(:name)).map{|s| s.to_sym}.get_or_else {
      raise ArgumentError.new("Name not specified")
    }
    @description = ::Collins::Option(opts.delete(:description)).get_or_else {
      raise ArgumentError.new("Description not specified")
    }
  end
  ts = ::Collins::Option(opts.delete(:timestamp)).get_or_else(Time.at(0))
  @timestamp = parse_timestamp(ts)
  # Flatten if needed
  if opts.key?(:extras) then
    @extras = opts[:extras]
  else
    @extras = opts
  end
end

Instance Attribute Details

#descriptionString (readonly)

Returns State description, for humans.

Returns:

  • (String)

    State description, for humans

See Also:



45
46
47
# File 'lib/collins/state/specification.rb', line 45

def description
  @description
end

#extrasHash (readonly)

Returns Additional meta-data.

Returns:

  • (Hash)

    Additional meta-data



51
52
53
# File 'lib/collins/state/specification.rb', line 51

def extras
  @extras
end

#nameSymbol (readonly)

Note:

This is a unique key and should not change.

Returns Name of the specification.

Returns:

  • (Symbol)

    Name of the specification.

See Also:



41
42
43
# File 'lib/collins/state/specification.rb', line 41

def name
  @name
end

#timestampFixnum

Returns Unixtime, UTC, when this state was entered.

Returns:

  • (Fixnum)

    Unixtime, UTC, when this state was entered



48
49
50
# File 'lib/collins/state/specification.rb', line 48

def timestamp
  @timestamp
end

Class Method Details

.emptyCollins::State::Specification

Create an empty specification

Returns:



25
26
27
# File 'lib/collins/state/specification.rb', line 25

def self.empty
  ::Collins::State::Specification.new :none => true
end

.json_create(json) ⇒ Collins::State::Specification

Note:

This method is required by the JSON module for deserialization

Create an instance from JSON data

Parameters:

  • json (Hash)

    JSON data

Returns:



34
35
36
# File 'lib/collins/state/specification.rb', line 34

def self.json_create json
  ::Collins::State::Specification.new json['data']
end

Instance Method Details

#<<(key, value) ⇒ Object



141
142
143
144
145
# File 'lib/collins/state/specification.rb', line 141

def <<(key, value)
  @extras[key.to_sym] = [] unless @extras.key?(key.to_sym)
  @extras[key.to_sym] << value
  @extras[key.to_sym]
end

#==(other) ⇒ Object

Mostly used for testing



171
172
173
174
175
# File 'lib/collins/state/specification.rb', line 171

def ==(other)
  (other.class == self.class) &&
    other.name == self.name &&
    other.timestamp == self.timestamp
end

#[](key) ⇒ Object



128
129
130
# File 'lib/collins/state/specification.rb', line 128

def [](key)
  @extras[key.to_sym]
end

#[]=(key, value) ⇒ Object



137
138
139
# File 'lib/collins/state/specification.rb', line 137

def []=(key, value)
  @extras[key.to_sym] = value
end

#defined?Boolean

Returns Indicate whether Specification is defined or not.

Returns:

  • (Boolean)

    Indicate whether Specification is defined or not



115
116
117
# File 'lib/collins/state/specification.rb', line 115

def defined?
  @name != EMPTY_NAME || @description != EMPTY_DESCRIPTION
end

#empty?Boolean

Returns Indicate whether Specification is empty or not.

Returns:

  • (Boolean)

    Indicate whether Specification is empty or not



110
111
112
# File 'lib/collins/state/specification.rb', line 110

def empty?
  !self.defined?
end

#fetch(key, default) ⇒ Object



134
135
136
# File 'lib/collins/state/specification.rb', line 134

def fetch(key, default)
  @extras.fetch(key.to_sym, default)
end

#key?(key) ⇒ Boolean

Returns:

  • (Boolean)


131
132
133
# File 'lib/collins/state/specification.rb', line 131

def key?(key)
  @extras.key?(key.to_sym)
end

#merge(other) ⇒ Object

merges appropriate extras from the other spec into this one

Parameters:



102
103
104
105
106
107
# File 'lib/collins/state/specification.rb', line 102

def merge other
  ext = other.extras.merge(@extras)
  ext.delete(:none)
  @extras = ext
  self
end

#to_hashHash

Returns Hash representation of data.

Returns:

  • (Hash)

    Hash representation of data



159
160
161
162
163
# File 'lib/collins/state/specification.rb', line 159

def to_hash
  h = Hash[:name => name, :description => description, :timestamp => timestamp]
  h[:extras] = extras unless extras.empty?
  h
end

#to_json(*a) ⇒ String

Note:

this is required by the JSON module

Convert this instance to JSON

Returns:

  • (String)

    JSON string representation of object



151
152
153
154
155
156
# File 'lib/collins/state/specification.rb', line 151

def to_json(*a)
  {
    'json_class' => self.class.name,
    'data' => to_hash
  }.to_json(*a)
end

#to_optionCollins::Option

Returns None if undefined/empty.

Returns:

  • (Collins::Option)

    None if undefined/empty



120
121
122
123
124
125
126
# File 'lib/collins/state/specification.rb', line 120

def to_option
  if self.defined? then
    ::Collins::Some(self)
  else
    ::Collins::None()
  end
end

#to_sString

Returns human readable.

Returns:

  • (String)

    human readable



166
167
168
# File 'lib/collins/state/specification.rb', line 166

def to_s
  "Specification(name = #{name}, description = #{description}, timestamp = #{timestamp}, extras = #{extras})"
end