Class: OMF::SFA::Util::GraphJSON
- Inherits:
-
Base::LObject
- Object
- Base::LObject
- OMF::SFA::Util::GraphJSON
- Defined in:
- lib/omf-sfa/util/graph_json.rb
Overview
This class handles the conversion between GraphJson and a set of resources.
Usage:
GraphJson.parse_file(file_name) => Array of OResources
Class Method Summary collapse
-
.parse(descr_hash, opts = {}) ⇒ Object
Parse a hash following the GraphJSON format and return a list od resources.
- .parse_file(file_name, opts = {}) ⇒ Object
Instance Method Summary collapse
-
#initialize ⇒ GraphJSON
constructor
A new instance of GraphJSON.
-
#parse(descr_hash, opts = {}) ⇒ Object
Parse a hash following the GraphJSON format and return a list od resources.
- #parse_defaults(graph, opts) ⇒ Object
- #parse_edges(graph, gopts) ⇒ Object
- #parse_network(network, opts) ⇒ Object
- #parse_node(node, gopts) ⇒ Object
- #parse_nodes(nodes, opts) ⇒ Object
- #parse_sliver_type(node, el_defaults) ⇒ Object
- #parse_value(el, name, defaults, opts, is_mandatory = false, opts_name = nil) ⇒ Object
Constructor Details
#initialize ⇒ GraphJSON
Returns a new instance of GraphJSON.
72 73 74 75 76 |
# File 'lib/omf-sfa/util/graph_json.rb', line 72 def initialize() @id2descr = {} @resources = {} @sliver_types = {} end |
Class Method Details
.parse(descr_hash, opts = {}) ⇒ Object
Parse a hash following the GraphJSON format and return a list od resources.
-
opts
-
:node_services Services to add to each node (default: [])
-
:create_new_uuids Don’t use ‘_id’ for UUID, create new ones
-
35 36 37 |
# File 'lib/omf-sfa/util/graph_json.rb', line 35 def self.parse(descr_hash, opts = {}) self.new.parse(descr_hash, opts) end |
.parse_file(file_name, opts = {}) ⇒ Object
23 24 25 26 |
# File 'lib/omf-sfa/util/graph_json.rb', line 23 def self.parse_file(file_name, opts = {}) content = File.open(file_name).read() self.new.parse(JSON.parse(content, symbolize_names: true), opts) end |
Instance Method Details
#parse(descr_hash, opts = {}) ⇒ Object
Parse a hash following the GraphJSON format and return a list od resources.
-
opts
-
:node_services Services to add to each node (default: [])
-
:create_new_uuids Don’t use ‘_id’ for UUID, create new ones
-
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/omf-sfa/util/graph_json.rb', line 46 def parse(descr_hash, opts = {}) @create_new_uuids = (opts[:create_new_uuids] == true) unless graph = descr_hash[:graph] raise GraphJSONException.new "Expected description 'graph' element at root - #{descr_hash}" end [:nodes, :edges].each do |type| unless graph[type] raise GraphJSONException.new "Missing '#{type}' declaration" end graph[type].each do |e| unless id = e[:_id] raise GraphJSONException.new "Missing '_id' for #{type} - #{e}" end if @id2descr.key? id raise GraphJSONException.new "Duplicated id '#{id}' detected - #{e}" end @id2descr[id] = e end end parse_defaults(graph, opts) parse_nodes(graph[:nodes], opts) parse_edges(graph, opts) #puts ">>>>> #{@resources}" @resources end |
#parse_defaults(graph, opts) ⇒ Object
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/omf-sfa/util/graph_json.rb', line 78 def parse_defaults(graph, opts) @defaults = {node: {}, interface: {}, network: {}} (graph[:defaults] || {}).each do |type, h| type_def = @defaults[type.to_sym] ||= {} h.each do |name, vh| puts "DEFAULTS>>> #{type} - #{name} => #{vh}" if ref_id = vh[:ref] unless ref = @id2descr[ref_id] raise GraphJSONException.new "Defaults refer to unknown id '#{id}' - #{@id2descr.keys}" end unless val = ref[name] raise GraphJSONException.new "Defaults refer to unspecified property '#{name}' in '#{ref_id}' - #{ref}" end elsif (val = vh[:value]).nil? raise GraphJSONException.new "Default '#{name}' for '#{type}' has no value defined - #{vh}" end type_def[name] = val #puts "#{type}::#{name} ===> #{val}" end end end |
#parse_edges(graph, gopts) ⇒ Object
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 |
# File 'lib/omf-sfa/util/graph_json.rb', line 142 def parse_edges(graph, gopts) # First collect interfaces into node declaration graph[:edges].each do |e| [[:_source, :tail, :_target], [:_target, :head, :_source]].each do |n_id, if_id, opp_id| n_descr = @id2descr[e[n_id]] next unless n_descr[:_type] == "node" if_a = (n_descr[:__ifs] ||= []) if_a << (if_descr = e[if_id] || {}) opp_descr = @id2descr[e[opp_id]] if opp_descr[:_type] == "network" if_descr[:__nw] = opp_descr (opp_descr[:__ifs] ||= []) << if_descr end (e[:__ifs] ||= []) << if_descr end end # graph[:nodes].each do |n_descr| next unless n_descr[:_type] == "node" node_id = n_descr[:_id] if_a = n_descr[:__ifs] next unless if_a # Add names to all interfaces names = if_a.map {|ifd| ifd[:name] }.compact i = 0 if_a.each do |ifs| next if ifs[:name] # ok, has one already begin name = "if#{i}" i += 1 end while names.include?(name) ifs[:name] = name end # Create interface resource node_r = @resources[node_id] if_a.each do |ifs| opts = { name: (ifs[:__client_id] = "#{node_r.name}:#{ifs[:name]}") } if ip_decl = ifs[:ip] if ip_decl.key? :type ip_decl[:ip_type] = ip_decl.delete(:type) end #puts "IP>>> #{ip_decl}" opts[:ip] = Ip.create(ip_decl) else # TODO: Maybe create IP address if the other end is a network if nw = ifs[:__nw] idx = nw[:__ifs].index do |oifs| ifs[:__client_id] == oifs[:__client_id] end #puts "\n#{idx}\n" end end if_r = ifs[:__if_r] = Interface.create(opts) node_r.interfaces << if_r end end # Create Link resources graph[:edges].each do |e| source = @id2descr[e[:_source]] target = @id2descr[e[:_target]] unless source && target raise GraphJSONException.new "Can't find source or target node - #{e}" end if source[:_type] == 'node' && target[:_type] == 'node' # direct link opts = {} unless id = e[:_id] raise GraphJSONException.new "Missing edge ID '_id' - #{e}" end opts[:uuid] = id unless @create_new_uuids opts[:name] = e[:name] #|| id link_r = Link.create(opts) @resources[id] = link_r elsif source[:_type] == 'network' && target[:_type] == 'network' raise GraphJSONException.new "Can't connect two networks directly - #{e}" else # one side is a network network = source[:_type] == 'network' ? source : target unless link_r = @resources[nw_id = network[:_id]] opts = {name: network[:name]} opts[:uuid] = nw_id unless @create_new_uuids link_r = Link.create(opts) @resources[nw_id] = link_r end end if link_r link_r.link_type = e[:link_type] || "lan" e[:__ifs].each do |ifs| link_r.interfaces << ifs[:__if_r] end end end end |
#parse_network(network, opts) ⇒ Object
135 136 137 138 139 140 |
# File 'lib/omf-sfa/util/graph_json.rb', line 135 def parse_network(network, opts) el_defaults = @defaults[:network] # add defaults parse_value(network, :netmask, el_defaults, network, false) parse_value(network, :type, el_defaults, network, false) end |
#parse_node(node, gopts) ⇒ Object
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
# File 'lib/omf-sfa/util/graph_json.rb', line 116 def parse_node(node, gopts) el_defaults = @defaults[:node] opts = {} unless id = node[:_id] raise GraphJSONException.new "Missing node ID '_id' - #{node}" end opts[:uuid] = id unless @create_new_uuids opts[:name] = node[:name] parse_value(node, :am_urn, el_defaults, opts, true, :component_manager) parse_value(node, :urn, el_defaults, opts, false) opts[:sliver_type] = parse_sliver_type(node, el_defaults) @resources[id] = node_r = Node.create(opts) (gopts[:node_services] || []).each do |s| node_r.services << s end node_r end |
#parse_nodes(nodes, opts) ⇒ Object
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/omf-sfa/util/graph_json.rb', line 100 def parse_nodes(nodes, opts) nodes.each do |n| unless type = n[:_type] raise GraphJSONException.new "Missing '_type' declaration - #{n}" end case type when 'node' parse_node(n, opts) when 'network' parse_network(n, opts) else raise GraphJSONException.new "Unknown node type '#{type}' - #{n}" end end end |
#parse_sliver_type(node, el_defaults) ⇒ Object
244 245 246 247 248 249 250 251 252 253 254 255 256 |
# File 'lib/omf-sfa/util/graph_json.rb', line 244 def parse_sliver_type(node, el_defaults) sliver_type = parse_value(node, :sliver_type, el_defaults, nil, true) disk_image_url = parse_value(node, :disk_image, el_defaults, nil, false) id = "#{sliver_type}-#{disk_image_url || '__none'}" unless st_res = @sliver_types[id] opts = {name: sliver_type} if disk_image_url opts[:disk_image] = DiskImage.create(url: disk_image_url) end st_res = @sliver_types[id] = SliverType.create(opts) end st_res end |
#parse_value(el, name, defaults, opts, is_mandatory = false, opts_name = nil) ⇒ Object
259 260 261 262 263 264 265 266 267 268 |
# File 'lib/omf-sfa/util/graph_json.rb', line 259 def parse_value(el, name, defaults, opts, is_mandatory = false, opts_name = nil) val = el[name] || defaults[name] if is_mandatory && val.nil? raise GraphJSONException.new "Can't find value for mandatory property '#{name}' in '#{el}'" end if opts && !val.nil? opts[(opts_name || name).to_sym] = val end val end |