occi 2.2.2 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- require 'json'
1
+ require 'active_support/json'
2
2
  require 'occi/core/category'
3
3
  require 'occi/core/action'
4
4
  require 'occi/core/attribute_properties'
@@ -7,13 +7,22 @@ module OCCI
7
7
  module Core
8
8
  class Kind < OCCI::Core::Category
9
9
 
10
- attr_accessor :entities
10
+ attr_accessor :entities, :related, :actions
11
11
 
12
- def initialize(kind, default = nil)
12
+ # @param [String ] scheme
13
+ # @param [String] term
14
+ # @param [String] title
15
+ # @param [OCCI::Core::AttributeProperties] attributes
16
+ # @param [Array] related
17
+ # @param [Array] actions
18
+ def initialize(scheme, term, title=nil, attributes=nil, related=nil, actions=nil)
13
19
  @entities = []
14
- super(kind, default)
20
+ @related = related.to_a
21
+ @actions = actions.to_a
22
+ super(scheme, term, title, attributes)
15
23
  end
16
24
 
25
+ # @return [String] name of the OCCI core class the entity is related to
17
26
  def entity_type
18
27
  case type_identifier
19
28
  when "http://schemas.ogf.org/occi/core#resource"
@@ -25,8 +34,26 @@ module OCCI
25
34
  end
26
35
  end
27
36
 
37
+ # @return [String] string containing location URI of kind
28
38
  def location
29
- '/' + self[:term] + '/'
39
+ '/' + @term + '/'
40
+ end
41
+
42
+ def as_json(options={ })
43
+ kind = Hashie::Mash.new
44
+ kind.related = @related if @related.any?
45
+ kind.actions = @actions if @actions.any?
46
+ kind.merge! super
47
+ kind
48
+ end
49
+
50
+ def to_text
51
+ text = super
52
+ text << ';rel=' + @related.join(' ').inspect if @related.any?
53
+ text << ';location=' + self.location.inspect
54
+ text << ';attributes=' + @attributes.combine.join(' ').inspect if @attributes.any?
55
+ text << ';actions=' + @actions.join(' ').inspect if @actions.any?
56
+ text
30
57
  end
31
58
 
32
59
  end
@@ -1,5 +1,4 @@
1
1
  require 'hashie/mash'
2
- require 'occi/model'
3
2
  require 'occi/core/entity'
4
3
  require 'occi/core/kind'
5
4
 
@@ -7,60 +6,24 @@ module OCCI
7
6
  module Core
8
7
  class Link < Entity
9
8
 
10
- # Define appropriate kind
11
- def self.register
12
- data = Hashie::Mash.new
13
- data[:actions] = []
14
- data[:related] = %w{http://schemas.ogf.org/occi/core#entity}
15
- data[:term] = "link"
16
- data[:scheme] = "http://schemas.ogf.org/occi/core#"
17
- data[:title] = "Link"
9
+ # @return [OCCI::Core::Kind] kind definition of Link type
10
+ def self.kind_definition
11
+ kind = OCCI::Core::Kind.new('http://schemas.ogf.org/occi/core#','link')
18
12
 
19
- data.attributes!.occi!.core!.target!.type = "string"
20
- data.attributes!.occi!.core!.target!.pattern = ".*"
21
- data.attributes!.occi!.core!.target!.required = false
22
- data.attributes!.occi!.core!.target!.mutable = true
13
+ kind.related = %w{http://schemas.ogf.org/occi/core#entity}
14
+ kind.title = "Link"
23
15
 
24
- data.attributes!.occi!.core!.source!.type = "string"
25
- data.attributes!.occi!.core!.source!.pattern = ".*"
26
- data.attributes!.occi!.core!.source!.required = false
27
- data.attributes!.occi!.core!.source!.mutable = true
16
+ kind.attributes.occi!.core!.target!.type = "string"
17
+ kind.attributes.occi!.core!.target!.pattern = ".*"
18
+ kind.attributes.occi!.core!.target!.required = false
19
+ kind.attributes.occi!.core!.target!.mutable = true
28
20
 
29
- kind = OCCI::Core::Kind.new(data)
30
- OCCI::Model.register(kind)
31
- end
32
-
33
- def target
34
- return self[:target]
35
- end
36
-
37
- def target=(target)
38
- self[:target] = target
39
- self.attributes!.occi!.core!.target = target
40
- end
41
-
42
- def source
43
- return self[:source]
44
- end
45
-
46
- def source=(source)
47
- self[:source] = source
48
- self.attributes!.occi!.core!.source = source
49
- end
21
+ kind.attributes.occi!.core!.source!.type = "string"
22
+ kind.attributes.occi!.core!.source!.pattern = ".*"
23
+ kind.attributes.occi!.core!.source!.required = false
24
+ kind.attributes.occi!.core!.source!.mutable = true
50
25
 
51
- def convert_value(val, duping=false) #:nodoc:
52
- case val
53
- when self.class
54
- val.dup
55
- when ::Hash
56
- val = val.dup if duping
57
- self.class.subkey_class.new.merge(val) unless val.kind_of?(Hashie::Mash)
58
- val
59
- when Array
60
- val.collect { |e| convert_value(e) }
61
- else
62
- val
63
- end
26
+ kind
64
27
  end
65
28
 
66
29
  end
@@ -1,19 +1,45 @@
1
- require 'json'
1
+ require 'active_support/json'
2
2
  require 'occi/core/category'
3
3
 
4
4
  module OCCI
5
5
  module Core
6
6
  class Mixin < OCCI::Core::Category
7
7
 
8
- attr_accessor :entities
8
+ attr_accessor :entities, :related, :actions
9
9
 
10
- def initialize(mixin, default = nil)
10
+ # @param [String ] scheme
11
+ # @param [String] term
12
+ # @param [String] title
13
+ # @param [OCCI::Core::AttributeProperties] attributes
14
+ # @param [Array] related
15
+ # @param [Array] actions
16
+ def initialize(scheme, term, title=nil, attributes=nil, related=nil, actions=nil)
11
17
  @entities = []
12
- super(mixin, default)
18
+ @related = related.to_a
19
+ @actions = actions.to_a
20
+ super(scheme, term, title, attributes)
13
21
  end
14
22
 
23
+ # @return [String] string containing location URI of mixin
15
24
  def location
16
- '/mixin/' + self[:term] + '/'
25
+ '/mixins/' + @term + '/'
26
+ end
27
+
28
+ def as_json(options={ })
29
+ mixin = Hashie::Mash.new
30
+ mixin.related = @related if @related.any?
31
+ mixin.actions = @actions if @actions.any?
32
+ mixin.merge! super
33
+ mixin
34
+ end
35
+
36
+ def to_text
37
+ text = super
38
+ text << ';rel=' + @related.join(' ').inspect if @related.any?
39
+ text << ';location=' + self.location.inspect
40
+ text << ';attributes=' + @attributes.combine.join(' ').inspect if @attributes.any?
41
+ text << ';actions=' + @actions.join(' ').inspect if @actions.any?
42
+ text
17
43
  end
18
44
 
19
45
  end
@@ -1,5 +1,5 @@
1
1
  require 'hashie/mash'
2
- require 'occi/model'
2
+ require 'active_support/json'
3
3
  require 'occi/core/entity'
4
4
  require 'occi/core/kind'
5
5
 
@@ -7,46 +7,47 @@ module OCCI
7
7
  module Core
8
8
  class Resource < Entity
9
9
 
10
- def self.register
11
- data = Hashie::Mash.new
12
- data[:related] = %w{http://schemas.ogf.org/occi/core#entity}
13
- data[:term] = "resource"
14
- data[:scheme] = "http://schemas.ogf.org/occi/core#"
15
- data[:title] = "Resource"
10
+ attr_accessor :links
16
11
 
17
- data.attributes!.occi!.core!.summary!.type = "string"
18
- data.attributes!.occi!.core!.summary!.pattern = ".*"
19
- data.attributes!.occi!.core!.summary!.required = false
20
- data.attributes!.occi!.core!.summary!.mutable = true
12
+ def initialize(kind, mixins=nil, attributes=nil, links=nil)
13
+ @href = nil
14
+ @links = links.to_a
15
+ super(kind, mixins, attributes)
16
+ end
17
+
18
+ def self.kind_definition
19
+ kind = OCCI::Core::Kind.new('http://schemas.ogf.org/occi/core#', 'resource')
20
+
21
+ kind.related = %w{http://schemas.ogf.org/occi/core#entity}
22
+ kind.title = 'Resource'
23
+
24
+ kind.attributes.occi!.core!.summary!.type = 'string'
25
+ kind.attributes.occi!.core!.summary!.pattern = '.*'
26
+ kind.attributes.occi!.core!.summary!.required = false
27
+ kind.attributes.occi!.core!.summary!.mutable = true
21
28
 
22
- kind = OCCI::Core::Kind.new(data)
23
- OCCI::Model.register(kind)
29
+ kind
24
30
  end
25
31
 
26
- def summary
27
- self[:summary] ||= self.attributes!.occi!.core!.summary if self.attributes!.occi!.core
28
- return self[:summary]
32
+ # set id for resource and update the the source of all links
33
+ # @param [UUIDTools::UUID] id
34
+ def id=(id)
35
+ super(id)
36
+ @links.each { |link| link.attributes.occi!.core!.source = self.location }
29
37
  end
30
38
 
31
- def summary=(summary)
32
- self[:summary] = summary
33
- self.attributes ||= OCCI::Core::Attributes.new
34
- self.attributes!.occi!.core!.summary = summary
39
+ # update the source of all links before returning them
40
+ # @return [Array] links of resource
41
+ def links
42
+ @links.each { |link| link.attributes.occi!.core!.source = self.location }
43
+ @links
35
44
  end
36
45
 
37
- def convert_value(val, duping=false) #:nodoc:
38
- case val
39
- when self.class
40
- val.dup
41
- when ::Hash
42
- val = val.dup if duping
43
- self.class.subkey_class.new.merge(val) unless val.kind_of?(Hashie::Mash)
44
- val
45
- when Array
46
- val.collect { |e| convert_value(e) }
47
- else
48
- val
49
- end
46
+ def as_json(options={ })
47
+ resource = Hashie::Mash.new
48
+ resource.links = @links if @links.any?
49
+ resource.merge! super
50
+ resource
50
51
  end
51
52
 
52
53
  end
@@ -6,13 +6,17 @@ module OCCI
6
6
 
7
7
  include Logger::Severity
8
8
 
9
+ attr_reader :logger
10
+
9
11
  # creates a new OCCI logger
10
12
  # @param [IO,String] logdev The log device. This is a filename (String) or IO object (typically +STDOUT+,
11
13
  # +STDERR+, or an open file).
12
- # @param [Constant] level Logging severity threshold (e.g. <tt>OCCI::Log::INFO</tt>).
13
- def initialize(logdev, level)
14
- @logger = Logger.new(logdev)
15
- @logger.level = level
14
+ def initialize(logdev)
15
+ if logdev.kind_of? Logger
16
+ @logger = logdev
17
+ else
18
+ @logger = Logger.new(logdev)
19
+ end
16
20
 
17
21
  # subscribe to log messages and send to logger
18
22
  @log_subscriber = ActiveSupport::Notifications.subscribe("log") do |name, start, finish, id, payload|
@@ -20,6 +24,14 @@ module OCCI
20
24
  end
21
25
  end
22
26
 
27
+ def level=(severity)
28
+ @logger.level = severity
29
+ end
30
+
31
+ def level
32
+ @logger.level
33
+ end
34
+
23
35
  # @see info
24
36
  def self.debug(message)
25
37
  ActiveSupport::Notifications.instrument("log", :level => Logger::DEBUG, :message => message)
@@ -3,21 +3,28 @@ require 'occi/log'
3
3
 
4
4
  module OCCI
5
5
  class Model
6
- @@categories = { }
7
- @@locations = { }
6
+ attr_accessor :categories
7
+ attr_accessor :locations
8
+
9
+ def initialize(collection=nil)
10
+ @categories = { }
11
+ @locations = { }
12
+ register_core
13
+ register_collection collection if collection
14
+ end
8
15
 
9
16
  # register OCCI Core categories enitity, resource and link
10
- def self.register_core
11
- OCCI::Log.info("### Registering OCCI Core categories enitity, resource and link ###")
12
- OCCI::Core::Entity.register
13
- OCCI::Core::Resource.register
14
- OCCI::Core::Link.register
17
+ def register_core
18
+ OCCI::Log.info "### Registering OCCI Core categories enitity, resource and link ###"
19
+ register OCCI::Core::Entity.kind_definition
20
+ register OCCI::Core::Resource.kind_definition
21
+ register OCCI::Core::Link.kind_definition
15
22
  end
16
23
 
17
24
  # register OCCI Infrastructure categories
18
- def self.register_infrastructure
19
- OCCI::Log.info("### Registering OCCI Infrastructure categories ###")
20
- self.register_files('etc/model/infrastructure')
25
+ def register_infrastructure
26
+ OCCI::Log.info "### Registering OCCI Infrastructure categories ###"
27
+ register_files 'etc/model/infrastructure'
21
28
  end
22
29
 
23
30
  # register OCCI categories from files
@@ -25,81 +32,80 @@ module OCCI
25
32
  # @param [String] path to a folder containing files which include OCCI collections in JSON format. The path is
26
33
  # recursively searched for files with the extension .json .
27
34
  # @param [Sting] scheme_base_url base location for provider specific extensions of the OCCI model
28
- def self.register_files(path, scheme_base_url='http://localhost')
29
- OCCI::Log.info("### Initializing OCCI Model from #{path} ###")
35
+ def register_files(path, scheme_base_url='http://localhost')
36
+ OCCI::Log.info "### Initializing OCCI Model from #{path} ###"
30
37
  Dir.glob(path + '/**/*.json').each do |file|
31
38
  collection = OCCI::Collection.new(JSON.parse(File.read(file)))
32
39
  # add location of service provider to scheme if it has a relative location
33
40
  collection.kinds.collect { |kind| kind.scheme = scheme_base_url + kind.scheme if kind.scheme.start_with? '/' } if collection.kinds
34
41
  collection.mixins.collect { |mixin| mixin.scheme = scheme_base_url + mixin.scheme if mixin.scheme.start_with? '/' } if collection.mixins
35
42
  collection.actions.collect { |action| action.scheme = scheme_base_url + action.scheme if action.scheme.start_with? '/' } if collection.actions
36
- self.register_collection(collection)
43
+ register_collection collection
37
44
  end
38
45
  end
39
46
 
40
47
  # register OCCI categories from OCCI collection
41
- def self.register_collection(collection)
42
- collection.kinds.each { |kind| self.register(OCCI::Core::Kind.new(kind)) } if collection.kinds
43
- collection.mixins.each { |mixin| self.register(OCCI::Core::Mixin.new(mixin)) } if collection.mixins
44
- collection.actions.each { |action| self.register(OCCI::Core::Action.new(action)) } if collection.actions
48
+ def register_collection(collection)
49
+ collection.categories.each { |category| register category }
45
50
  end
46
51
 
47
- def self.reset()
48
- @@categories.each_value.each { |category| category.entities = [] if category.entities }
52
+ def reset()
53
+ @categories.each_value.each { |category| category.entities = [] if category.entities }
49
54
  end
50
55
 
51
56
  # ---------------------------------------------------------------------------------------------------------------------
52
- def self.register(category)
53
- OCCI::Log.debug("### Registering category #{category.type_identifier}")
54
- @@categories[category.type_identifier] = category
55
- @@locations[category.location] = category.type_identifier unless category.kind_of?(OCCI::Core::Action)
57
+ def register(category)
58
+ OCCI::Log.debug "### Registering category #{category.type_identifier}"
59
+ @categories[category.type_identifier] = category
60
+ @locations[category.location] = category.type_identifier unless category.kind_of? OCCI::Core::Action
56
61
  end
57
62
 
58
63
  # ---------------------------------------------------------------------------------------------------------------------
59
- def self.unregister(category)
60
- OCCI::Log.debug("### Unregistering category #{category.type_identifier}")
61
- @@categories.delete(category.type_identifier)
62
- @@locations.delete(category.location) unless category.kind_of?(OCCI :Core::Action)
64
+ def unregister(category)
65
+ OCCI::Log.debug "### Unregistering category #{category.type_identifier}"
66
+ @categories.delete category.type_identifier
67
+ @locations.delete category.location unless category.kind_of? OCCI :Core::Action
63
68
  end
64
69
 
65
70
  # Returns the category corresponding to a given type identifier
66
71
  #
67
72
  # @param [URI] type identifier of a category
68
- def self.get_by_id(id)
69
- @@categories.fetch(id) { OCCI::Log.debug("Category with id #{id} not found"); nil }
73
+ def get_by_id(id)
74
+ @categories.fetch(id) { OCCI::Log.debug("Category with id #{id} not found"); nil }
70
75
  end
71
76
 
72
77
  # Returns the category corresponding to a given location
73
78
  #
74
79
  # @param [URI] Location of a category
75
- def self.get_by_location(location)
76
- id = @@locations.fetch(location) { OCCI::Log.debug("Category with location #{location} not found"); nil }
77
- self.get_by_id(id)
80
+ def get_by_location(location)
81
+ id = @locations.fetch(location) { OCCI::Log.debug("Category with location #{location} not found"); nil }
82
+ get_by_id id
78
83
  end
79
84
 
80
85
  # Return all categories from model. If filter is present, return only the categories specified by filter
81
86
  #
82
- # @param [Hashie:Hash] filter
83
- # @return [Hashie::Mash] collection
84
- def self.get(filter = [])
85
- collection = Hashie::Mash.new({ :kinds => [], :mixins => [], :actions => [] })
87
+ # @param [OCCI::Collection] filter
88
+ # @return [OCCI::Collection] collection
89
+ def get(filter = [])
90
+ collection = OCCI::Collection.new
86
91
  if filter.empty?
87
- @@categories.each_value do |category|
92
+ @categories.each_value do |category|
88
93
  collection.kinds << category if category.kind_of? OCCI::Core::Kind
89
94
  collection.mixins << category if category.kind_of? OCCI::Core::Mixin
90
95
  collection.actions << category if category.kind_of? OCCI::Core::Action
91
96
  end
97
+ else
98
+ categories = filter.categories
99
+ OCCI::Log.debug("### Filtering categories #{categories.collect { |c| c.type_identifier }.inspect}")
100
+ while categories.any? do
101
+ category = categories.pop
102
+ categories.concat @categories.each_value.select { |cat| cat.related_to?(category.type_identifier, self) }
103
+ collection.kinds << get_by_id(category.type_identifier) if category.kind_of? OCCI::Core::Kind
104
+ collection.mixins << get_by_id(category.type_identifier) if category.kind_of? OCCI::Core::Mixin
105
+ collection.actions << get_by_id(category.type_identifier) if category.kind_of? OCCI::Core::Action
106
+ end
92
107
  end
93
- OCCI::Log.debug("### Filtering categories #{filter.collect{|c| c.type_identifier}.inspect}")
94
- while filter.any? do
95
- cat = filter.pop
96
- filter.concat @@categories.each_value.select { |category| category.related_to?(cat.type_identifier) }
97
- category = get_by_id(cat.type_identifier)
98
- collection.kinds << category if category.kind_of?(OCCI::Core::Kind)
99
- collection.mixins << category if category.kind_of?(OCCI::Core::Mixin)
100
- collection.actions << category if category.kind_of?(OCCI::Core::Action)
101
- end
102
- return collection
108
+ collection
103
109
  end
104
110
 
105
111
  end