occi 2.2.2 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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