From c979a76789830869ddca9b06e2f14cffa041b6b5 Mon Sep 17 00:00:00 2001 From: Florian Feldhaus Date: Sat, 19 May 2012 11:10:06 +0200 Subject: [PATCH] refactoring of the code base. Improved rendering. Overall usage of ruby and sinatra best practises. Code cleanup. Dummy backend now persistent. Improved rSpec scenarios. --- AUTHORS | 8 + Gemfile | 4 +- Gemfile.lock | 3 + LICENSE | 13 + config.ru | 4 +- etc/model/extensions/console_link.json | 13 + etc/model/infrastructure/compute.json | 115 + etc/model/infrastructure/ipnetwork.json | 52 + .../infrastructure/ipnetworkinterface.json | 43 + etc/model/infrastructure/network.json | 56 + .../infrastructure/networkinterface.json | 40 + etc/model/infrastructure/os_template.json | 9 + .../infrastructure/resource_template.json | 9 + etc/model/infrastructure/storage.json | 75 + etc/model/infrastructure/storagelink.json | 38 + etc/occi-server.conf | 2 + lib/occi/CategoryRegistry.rb | 70 - lib/occi/Exceptions.rb | 50 +- lib/occi/Registry.rb | 88 + lib/occi/Request.rb | 204 ++ lib/occi/antlr/OCCI.g | 69 +- lib/occi/antlr/OCCILexer.rb | 1040 +++++---- lib/occi/antlr/OCCIParser.rb | 1924 +++++++++-------- lib/occi/backend/Dummy.rb | 124 +- lib/occi/backend/Manager.rb | 48 +- lib/occi/backend/ec2/Compute.rb | 96 +- lib/occi/backend/ec2/EC2.rb | 164 +- lib/occi/backend/opennebula/Compute.rb | 290 +-- lib/occi/backend/opennebula/Network.rb | 54 +- lib/occi/backend/opennebula/OpenNebula.rb | 157 +- lib/occi/backend/opennebula/Storage.rb | 94 +- lib/occi/core/Action.rb | 12 +- lib/occi/core/Attribute.rb | 48 - lib/occi/core/Category.rb | 56 +- lib/occi/core/Entity.rb | 217 +- lib/occi/core/Kind.rb | 42 +- lib/occi/core/Link.rb | 69 +- lib/occi/core/Mixin.rb | 19 +- lib/occi/core/Resource.rb | 44 +- lib/occi/extensions/ConsoleLink.rb | 56 - lib/occi/extensions/NFSStorage.rb | 98 - lib/occi/extensions/Reservation.rb | 58 - .../{VirtualMachine.rb => virtual_machine.rb} | 16 +- lib/occi/helpers/OCCIRequestHelper.rb | 32 - lib/occi/infrastructure/Compute.rb | 115 - lib/occi/infrastructure/IPNetworkInterface.rb | 52 - lib/occi/infrastructure/Ipnetworking.rb | 52 - lib/occi/infrastructure/Network.rb | 82 - lib/occi/infrastructure/Networkinterface.rb | 72 - lib/occi/infrastructure/OSTemplate.rb | 47 - lib/occi/infrastructure/ResourceTemplate.rb | 46 - lib/occi/infrastructure/Storage.rb | 103 - lib/occi/infrastructure/StorageLink.rb | 71 - lib/occi/occi-server.rb | 688 ------ lib/occi/rendering/AbstractRenderer.rb | 78 - lib/occi/rendering/Renderer.rb | 81 - lib/occi/rendering/http/JSONRenderer.rb | 214 -- lib/occi/rendering/http/LocationRegistry.rb | 135 -- lib/occi/rendering/http/Request.rb | 220 -- lib/occi/rendering/http/Response.rb | 99 - lib/occi/rendering/http/TextRenderer.rb | 299 --- lib/occi/server.rb | 571 +++++ .../{StateMachine.rb => state_machine.rb} | 34 +- spec/occi/antlr/parser_spec.rb | 7 +- spec/occi/occi_server_spec.rb | 31 - .../rendering/http/location_registry_spec.rb | 27 - spec/occi/rendering/http/request_spec.rb | 40 - spec/occi/server_spec.rb | 101 + views/text.erb | 30 + 69 files changed, 3830 insertions(+), 5188 deletions(-) create mode 100644 AUTHORS create mode 100644 LICENSE create mode 100644 etc/model/extensions/console_link.json create mode 100644 etc/model/infrastructure/compute.json create mode 100644 etc/model/infrastructure/ipnetwork.json create mode 100644 etc/model/infrastructure/ipnetworkinterface.json create mode 100644 etc/model/infrastructure/network.json create mode 100644 etc/model/infrastructure/networkinterface.json create mode 100644 etc/model/infrastructure/os_template.json create mode 100644 etc/model/infrastructure/resource_template.json create mode 100644 etc/model/infrastructure/storage.json create mode 100644 etc/model/infrastructure/storagelink.json delete mode 100644 lib/occi/CategoryRegistry.rb create mode 100644 lib/occi/Registry.rb create mode 100644 lib/occi/Request.rb delete mode 100644 lib/occi/core/Attribute.rb delete mode 100644 lib/occi/extensions/ConsoleLink.rb delete mode 100644 lib/occi/extensions/NFSStorage.rb delete mode 100644 lib/occi/extensions/Reservation.rb rename lib/occi/extensions/one/{VirtualMachine.rb => virtual_machine.rb} (80%) delete mode 100644 lib/occi/helpers/OCCIRequestHelper.rb delete mode 100644 lib/occi/infrastructure/Compute.rb delete mode 100644 lib/occi/infrastructure/IPNetworkInterface.rb delete mode 100644 lib/occi/infrastructure/Ipnetworking.rb delete mode 100644 lib/occi/infrastructure/Network.rb delete mode 100644 lib/occi/infrastructure/Networkinterface.rb delete mode 100644 lib/occi/infrastructure/OSTemplate.rb delete mode 100644 lib/occi/infrastructure/ResourceTemplate.rb delete mode 100644 lib/occi/infrastructure/Storage.rb delete mode 100644 lib/occi/infrastructure/StorageLink.rb delete mode 100644 lib/occi/occi-server.rb delete mode 100644 lib/occi/rendering/AbstractRenderer.rb delete mode 100644 lib/occi/rendering/Renderer.rb delete mode 100644 lib/occi/rendering/http/JSONRenderer.rb delete mode 100644 lib/occi/rendering/http/LocationRegistry.rb delete mode 100644 lib/occi/rendering/http/Request.rb delete mode 100644 lib/occi/rendering/http/Response.rb delete mode 100644 lib/occi/rendering/http/TextRenderer.rb create mode 100644 lib/occi/server.rb rename lib/occi/{StateMachine.rb => state_machine.rb} (92%) delete mode 100644 spec/occi/occi_server_spec.rb delete mode 100644 spec/occi/rendering/http/location_registry_spec.rb delete mode 100644 spec/occi/rendering/http/request_spec.rb create mode 100644 spec/occi/server_spec.rb create mode 100644 views/text.erb diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..3fd5b62 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,8 @@ +rOCCI was designed and is mainly developed by Florian Feldhaus (GWDG) and Piotr Kasprzak (GWDG) in Germany. + +Special thanks to the following extraordinary individuals, who-out which rOCCI would not be possible: + +* Hayati Bice - who wrote the initial version of an OCCI server rOCCI is based on +* Max Günther - who wrote the EC2 backend +* Andre Thevapalan - for his input regarding the JSON rendering +* the OCCI Working Group - for developing OCCI \ No newline at end of file diff --git a/Gemfile b/Gemfile index 91e5b95..1592a3b 100644 --- a/Gemfile +++ b/Gemfile @@ -4,8 +4,9 @@ source :rubygems gem "uuidtools" gem "json" gem "antlr3" +#gem "hashie", :git => 'git://github.com/ffeldhaus/hashie.git', :branch => "hash_deep_merge_with_array_concatenation" gem "hashie" -gem "nokogiri", "<=1.5.0" +gem "nokogiri", "<=1.5.0" # sinatra and related gem "sinatra" @@ -28,4 +29,5 @@ group :development do gem "simplecov" gem "yard" gem "yard-sinatra" + gem "rspec-http" end \ No newline at end of file diff --git a/Gemfile.lock b/Gemfile.lock index 641a3d7..be4b380 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -42,6 +42,8 @@ GEM rspec-core (2.9.0) rspec-expectations (2.9.0) diff-lcs (~> 1.1.3) + rspec-http (0.10.0) + rspec (~> 2.0) rspec-mocks (2.9.0) simplecov (0.6.1) multi_json (~> 1.0) @@ -78,6 +80,7 @@ DEPENDENCIES nokogiri (<= 1.5.0) passenger rspec + rspec-http simplecov sinatra sinatra-contrib diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d1b52ba --- /dev/null +++ b/LICENSE @@ -0,0 +1,13 @@ +Copyright (c) 2012 GWDG + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. \ No newline at end of file diff --git a/config.ru b/config.ru index 4a989dd..bf86909 100644 --- a/config.ru +++ b/config.ru @@ -2,8 +2,8 @@ $: << 'lib' require 'rubygems' require 'sinatra' -require 'occi/occi-server.rb' +require 'occi/server' VERSION_NUMBER=0.5 -run OCCIServer.new +run OCCI::Server.new diff --git a/etc/model/extensions/console_link.json b/etc/model/extensions/console_link.json new file mode 100644 index 0000000..0d349ac --- /dev/null +++ b/etc/model/extensions/console_link.json @@ -0,0 +1,13 @@ +{ + "kinds":[ + { + "term":"console", + "scheme":"http://schemas.ogf.org/occi/infrastructure/compute#", + "title":"Link to the VM's console", + "related":[ + "http://schemas.ogf.org/occi/core#link" + ], + "location":"/consolelink/" + } + ] +} \ No newline at end of file diff --git a/etc/model/infrastructure/compute.json b/etc/model/infrastructure/compute.json new file mode 100644 index 0000000..28bf23b --- /dev/null +++ b/etc/model/infrastructure/compute.json @@ -0,0 +1,115 @@ +{ + "kinds":[ + { + "term":"compute", + "scheme":"http://schemas.ogf.org/occi/infrastructure#", + "title":"Compute Resource", + "related":[ + "http://schemas.ogf.org/occi/core#resource" + ], + "attributes":{ + "occi":{ + "compute":{ + "architecture":{ + "mutable":true, + "required":false, + "type":"string", + "pattern":"x86|x64", + "default":"x86" + }, + "cores":{ + "mutable":true, + "required":false, + "type":"number", + "minimum":1, + "maximum":32767 + }, + "hostname":{ + "mutable":true, + "required":false, + "type":"string", + "pattern":"(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]*[a-zA-Z0-9])\\.)*" + }, + "speed":{ + "mutable":true, + "required":false, + "type":"number", + "minimum":0, + "maximum":32767 + }, + "memory":{ + "mutable":true, + "required":false, + "type":"number", + "minimum":0, + "maximum":32767 + }, + "state":{ + "mutable":false, + "required":false, + "type":"string", + "pattern":"inactive|active|suspended|failed", + "default":"inactive" + } + } + } + }, + "actions":[ + "http://schemas.ogf.org/occi/infrastructure/compute/action#start", + "http://schemas.ogf.org/occi/infrastructure/compute/action#stop", + "http://schemas.ogf.org/occi/infrastructure/compute/action#restart", + "http://schemas.ogf.org/occi/infrastructure/compute/action#suspend" + ], + "location":"/compute/" + } + ], + "actions":[ + { + "term":"start", + "scheme":"http://schemas.ogf.org/occi/infrastructure/compute/action#", + "title":"Start Compute instance" + }, + { + "term":"stop", + "scheme":"http://schemas.ogf.org/occi/infrastructure/compute/action#", + "title":"Stop Compute instance", + "attributes":{ + "method":{ + "mutable":true, + "required":false, + "type":"string", + "pattern":"graceful|acpioff|poweroff", + "default":"poweroff" + } + } + }, + { + "term":"restart", + "scheme":"http://schemas.ogf.org/occi/infrastructure/compute/action#", + "title":"Restart Compute instance", + "attributes":{ + "method":{ + "mutable":true, + "required":false, + "type":"string", + "pattern":"graceful|warm|cold", + "default":"cold" + } + } + }, + { + "term":"suspend", + "scheme":"http://schemas.ogf.org/occi/infrastructure/compute/action#", + "title":"Suspend Compute instance", + "attributes":{ + "method":{ + "mutable":true, + "required":false, + "type":"string", + "pattern":"hibernate|suspend", + "default":"suspend" + } + } + } + ] +} \ No newline at end of file diff --git a/etc/model/infrastructure/ipnetwork.json b/etc/model/infrastructure/ipnetwork.json new file mode 100644 index 0000000..54809a8 --- /dev/null +++ b/etc/model/infrastructure/ipnetwork.json @@ -0,0 +1,52 @@ +{ + "mixins":[ + { + "term":"ipnetwork", + "scheme":"http://schemas.ogf.org/occi/infrastructure/network#", + "title":"IP Network Mixin", + "attributes":{ + "occi":{ + "network":{ + "address":{ + "mutable":true, + "required":false, + "type":"string", + "pattern":"(^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:)))(%.+)?\\s*(\\/(\\d|\\d\\d|1[0-1]\\d|12[0-8]))$)|(^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\\/(\\d|[1-2]\\d|3[0-2]))$)", + "default":"10.0.0.0/8" + }, + "gateway":{ + "mutable":true, + "required":false, + "type":{ + "string":{ + "pattern":"(^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$)|(^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:)))(%.+)?\\s*)" + } + }, + "default":"10.0.0.1" + }, + "allocation":{ + "mutable":true, + "required":false, + "type":{ + "string":{ + "pattern":"dynamic|static" + } + }, + "default":"dynamic" + }, + "state":{ + "mutable":false, + "required":false, + "type":{ + "string":{ + "pattern":"active|inactive" + } + }, + "default":"inactive" + } + } + } + } + } + ] +} \ No newline at end of file diff --git a/etc/model/infrastructure/ipnetworkinterface.json b/etc/model/infrastructure/ipnetworkinterface.json new file mode 100644 index 0000000..ce3bf9b --- /dev/null +++ b/etc/model/infrastructure/ipnetworkinterface.json @@ -0,0 +1,43 @@ +{ + "mixins":[ + { + "term":"ipnetworkinterface", + "scheme":"http://schemas.ogf.org/occi/infrastructure/networkinterface#", + "title":"IP Networkinterface Mixin", + "attributes":{ + "occi":{ + "networkinterface":{ + "address":{ + "mutable":true, + "required":false, + "type":"string", + "pattern":"(^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$)|(^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:)))(%.+)?\\s*)", + "default":"10.0.0.0/8" + }, + "gateway":{ + "mutable":true, + "required":false, + "type":"string", + "pattern":"(^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$)|(^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:)))(%.+)?\\s*)", + "default":"10.0.0.1" + }, + "allocation":{ + "mutable":true, + "required":false, + "type":"string", + "pattern":"dynamic|static", + "default":"dynamic" + }, + "state":{ + "mutable":false, + "required":false, + "type":"string", + "pattern":"active|inactive", + "default":"inactive" + } + } + } + } + } + ] +} \ No newline at end of file diff --git a/etc/model/infrastructure/network.json b/etc/model/infrastructure/network.json new file mode 100644 index 0000000..1586feb --- /dev/null +++ b/etc/model/infrastructure/network.json @@ -0,0 +1,56 @@ +{ + "kinds":[ + { + "term":"network", + "scheme":"http://schemas.ogf.org/occi/infrastructure#", + "title":"Network Resource", + "related":[ + "http://schemas.ogf.org/occi/core#resource" + ], + "attributes":{ + "occi":{ + "storage":{ + "vlan":{ + "mutable":true, + "required":false, + "type":"number", + "minimum":0, + "maximum":4095, + "default":0 + }, + "label":{ + "mutable":true, + "required":false, + "type":"string", + "pattern":".*" + }, + "state":{ + "mutable":false, + "required":false, + "type":"string", + "pattern":"active|inactive", + "default":"inactive" + } + } + } + }, + "actions":[ + "http://schemas.ogf.org/occi/infrastructure/network/action#up" , + "http://schemas.ogf.org/occi/infrastructure/network/action#down" + ], + "location":"/network/" + } + ], + "actions":[ + { + "term":"up", + "scheme":"http://schemas.ogf.org/occi/infrastructure/network/action#", + "title":"Activate network" + }, + { + "term":"down", + "scheme":"http://schemas.ogf.org/occi/infrastructure/network/action#up", + "title":"Activate network" + } + ] +} diff --git a/etc/model/infrastructure/networkinterface.json b/etc/model/infrastructure/networkinterface.json new file mode 100644 index 0000000..95211df --- /dev/null +++ b/etc/model/infrastructure/networkinterface.json @@ -0,0 +1,40 @@ +{ + "kinds":[ + { + "term":"networkinterface", + "scheme":"http://schemas.ogf.org/occi/infrastructure#", + "title":"Networkinterface", + "related":[ + "http://schemas.ogf.org/occi/core#link" + ], + "attributes":{ + "occi":{ + "networkinterface":{ + "interface":{ + "mutable":true, + "required":false, + "type":"string", + "pattern":".*", + "default":"eth0" + }, + "mac":{ + "mutable":true, + "required":false, + "type":"string", + "pattern":"^([0-9A-F]{2}[:-]){5}([0-9A-F]{2})$", + "default":"00:16:3e:00:00:00" + }, + "state":{ + "mutable":false, + "required":false, + "type":"string", + "pattern":"active|inactive", + "default":"inactive" + } + } + } + }, + "location":"/networkinterface/" + } + ] +} \ No newline at end of file diff --git a/etc/model/infrastructure/os_template.json b/etc/model/infrastructure/os_template.json new file mode 100644 index 0000000..605f8ae --- /dev/null +++ b/etc/model/infrastructure/os_template.json @@ -0,0 +1,9 @@ +{ + "mixins":[ + { + "term":"os_tpl", + "scheme":"http://schemas.ogf.org/occi/infrastructure#", + "title":"Operating System Template" + } + ] +} \ No newline at end of file diff --git a/etc/model/infrastructure/resource_template.json b/etc/model/infrastructure/resource_template.json new file mode 100644 index 0000000..4d83cf9 --- /dev/null +++ b/etc/model/infrastructure/resource_template.json @@ -0,0 +1,9 @@ +{ + "mixins":[ + { + "term":"resource_tpl", + "scheme":"http://schemas.ogf.org/occi/infrastructure#", + "title":"Resource Template" + } + ] +} \ No newline at end of file diff --git a/etc/model/infrastructure/storage.json b/etc/model/infrastructure/storage.json new file mode 100644 index 0000000..f10775b --- /dev/null +++ b/etc/model/infrastructure/storage.json @@ -0,0 +1,75 @@ +{ + "kinds":[ + { + "term":"storage", + "scheme":"http://schemas.ogf.org/occi/infrastructure#", + "title":"Storage Resource", + "related":[ + "http://schemas.ogf.org/occi/core#resource" + ], + "attributes":{ + "occi":{ + "storage":{ + "size":{ + "mutable":true, + "required":false, + "type":"number", + "minimum":0, + "maximum":32767 + }, + "state":{ + "mutable":false, + "required":false, + "type":"string", + "pattern":"online|offline|backup|snapshot|resize|degraded", + "default":"offline" + } + } + } + }, + "actions":[ + "http://schemas.ogf.org/occi/infrastructure/storage/action#online", + "http://schemas.ogf.org/occi/infrastructure/storage/action#offline", + "http://schemas.ogf.org/occi/infrastructure/storage/action#backup", + "http://schemas.ogf.org/occi/infrastructure/storage/action#snapshot", + "http://schemas.ogf.org/occi/infrastructure/storage/action#resize" + ], + "location":"/storage/" + } + ], + "actions":[ + { + "term":"online", + "scheme":"http://schemas.ogf.org/occi/infrastructure/storage/action#", + "title":"Activate Storage" + }, + { + "term":"offline", + "scheme":"http://schemas.ogf.org/occi/infrastructure/storage/action#", + "title":"Deactivate Storage" + }, + { + "term":"backup", + "scheme":"http://schemas.ogf.org/occi/infrastructure/storage/action#", + "title":"Backup Storage" + }, + { + "term":"snapshot", + "scheme":"http://schemas.ogf.org/occi/infrastructure/storage/action#", + "title":"Snapshot Storage" + }, + { + "term":"resize", + "scheme":"http://schemas.ogf.org/occi/infrastructure/storage/action#", + "title":"Resize Storage", + "attributes":{ + "size":{ + "mutable":true, + "required":false, + "type":"number", + "default":"suspend" + } + } + } + ] +} \ No newline at end of file diff --git a/etc/model/infrastructure/storagelink.json b/etc/model/infrastructure/storagelink.json new file mode 100644 index 0000000..4486be1 --- /dev/null +++ b/etc/model/infrastructure/storagelink.json @@ -0,0 +1,38 @@ +{ + "kinds":[ + { + "term":"storagelink", + "scheme":"http://schemas.ogf.org/occi/infrastructure#", + "title":"Storage Link", + "related":[ + "http://schemas.ogf.org/occi/core#link" + ], + "attributes":{ + "occi":{ + "storagelink":{ + "deviceid":{ + "mutable":true, + "required":false, + "type":"string", + "pattern":".*" + }, + "mountpoint":{ + "mutable":true, + "required":false, + "type":"string", + "pattern":".*" + }, + "state":{ + "mutable":false, + "required":false, + "type":"string", + "pattern":"active|inactive", + "default":"inactive" + } + } + } + }, + "location":"/storagelink/" + } + ] +} \ No newline at end of file diff --git a/etc/occi-server.conf b/etc/occi-server.conf index 336e1f9..2c251c5 100644 --- a/etc/occi-server.conf +++ b/etc/occi-server.conf @@ -11,6 +11,8 @@ ONE_XMLRPC=http://134.76.9.66:2633/RPC2 TEMPLATE_LOCATION=etc/one_templates/ +OCCI_MODEL_PATH=etc/model/ + ONE_USER=oneadmin ONE_PASSWORD=oneadmin diff --git a/lib/occi/CategoryRegistry.rb b/lib/occi/CategoryRegistry.rb deleted file mode 100644 index 1bf033d..0000000 --- a/lib/occi/CategoryRegistry.rb +++ /dev/null @@ -1,70 +0,0 @@ -############################################################################## -# Copyright 2011 Service Computing group, TU Dortmund -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -############################################################################## - -############################################################################## -# Description: registry for all Category/Kind/Mixin instances currently -# known to the OCCI server -# Author(s): Hayati Bice, Florian Feldhaus, Piotr Kasprzak -############################################################################## - -require 'occi/Log' - -module OCCI - # --------------------------------------------------------------------------------------------------------------------- - module CategoryRegistry - - @@categories_by_id = {} - @@categories_by_location = {} - - # --------------------------------------------------------------------------------------------------------------------- - def self.register(category) - @@categories_by_id[category.type_identifier] = category - @@categories_by_location[category.location] = category if category.respond_to?('location') - end - - # --------------------------------------------------------------------------------------------------------------------- - def self.unregister(category) - @@categories_by_id.delete(category.type_identifier) - @@categories_by_location.delete(category.location) - end - - # --------------------------------------------------------------------------------------------------------------------- - def self.get_by_id(id) - @@categories_by_id.fetch(id) { raise OCCI::CategoryNotFoundException, "Category with key " + id + " not found" } - end - - def self.get_by_location(location) - @@categories_by_location.fetch(location) { raise "Category with location " + location + " not found" } - end - - # Return all categories from category registry. If filter is present, return only the categories specified by filter - # - # @param [Hashie:Mash] filter - # @return [Array] categories - def self.get(filter) - categories = Array.new - filter.values.flatten(1).each do |category| - begin - occi_categories << self.get_by_id(category.type_identifier) - rescue OCCI::CategoryNotFoundException => e - OCCI::Log.warn(e.message) - end - end - return categories unless categories.empty? - return @@categories_by_id.values - end - end -end \ No newline at end of file diff --git a/lib/occi/Exceptions.rb b/lib/occi/Exceptions.rb index a0a2633..a71655b 100644 --- a/lib/occi/Exceptions.rb +++ b/lib/occi/Exceptions.rb @@ -21,25 +21,39 @@ ############################################################################## module OCCI - + # Tried to create an already existing mixin - class MixinAlreadyExistsError < RuntimeError; end - - class CategoryNotFoundException < RuntimeError; end - - class CategoryMissingException < RuntimeError; end - - class MixinNotFoundException < RuntimeError; end - - class MixinCreationException < RuntimeError; end - - class LocationAlreadyRegisteredException < RuntimeError; end - - class LocationNotRegisteredException < RuntimeError; end - + class MixinAlreadyExistsError < RuntimeError; + end + + class CategoryNotFoundException < RuntimeError; + end + + class CategoryMissingException < RuntimeError; + end + + class MixinNotFoundException < RuntimeError; + end + + class MixinCreationException < RuntimeError; + end + + class LocationAlreadyRegisteredException < RuntimeError; + end + + class LocationNotRegisteredException < RuntimeError; + end + # Tried to create an already existing mixin - class BackendError < RuntimeError; end + class BackendError < RuntimeError; + end + + class ParserException < RuntimeError; + end + + class ContentTypeNotSupported < RuntimeError; + end - class ParserException < RuntimeError; end - + class CategoryNotFound < RuntimeError; + end end \ No newline at end of file diff --git a/lib/occi/Registry.rb b/lib/occi/Registry.rb new file mode 100644 index 0000000..c6078b8 --- /dev/null +++ b/lib/occi/Registry.rb @@ -0,0 +1,88 @@ +############################################################################## +# Copyright 2011 Service Computing group, TU Dortmund +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +############################################################################## + +############################################################################## +# Description: registry for all Category/Kind/Mixin instances currently +# known to the OCCI server +# Author(s): Hayati Bice, Florian Feldhaus, Piotr Kasprzak +############################################################################## + +require 'occi/log' + +module OCCI + # --------------------------------------------------------------------------------------------------------------------- + module Registry + + @@categories = {} + @@categories_initial = {} + @@locations = {} + + def self.reset() + @@categories = @@categories_initial + end + + # --------------------------------------------------------------------------------------------------------------------- + def self.register(category) + @@categories[category.type_identifier] = category + @@categories_initial[category.type_identifier] = category + @@locations[category.term] = category.type_identifier unless category.kind_of?(OCCI::Core::Action) + end + + # --------------------------------------------------------------------------------------------------------------------- + def self.unregister(category) + @@categories.delete(category.type_identifier) + @@categories_initial.delete(category.type_identifier) + @@locations.delete(category.term) unless category.kind_of?(OCCI :Core::Action) + end + + # Returns the category corresponding to a given type identifier + # + # @param [URI] type identifier of a category + def self.get_by_id(id) + @@categories.fetch(id) { OCCI::Log.debug("Category with id #{id} not found"); nil } + end + + # Returns the category corresponding to a given location + # + # @param [URI] Location of a category + def self.get_by_location(location) + id = @@locations.fetch(location.delete('/')) { OCCI::Log.debug("Category with location #{location} not found"); nil } + self.get_by_id(id) + end + + # Return all categories from category registry. If filter is present, return only the categories specified by filter + # + # @param [Hashie:Hash] filter + # @return [Hashie::Mash] collection + def self.get(filter = []) + collection = Hashie::Mash.new({:kinds => [], :mixins => [], :actions => []}) + filter.each do |cat| + category = get_by_id(cat.type_identifier) + collection.kinds << category if category.kind_of?(OCCI::Core::Kind) + collection.mixins << category if category.kind_of?(OCCI::Core::Mixin) + collection.actions << category if category.kind_of?(OCCI::Core::Action) + end + if filter.empty? + @@categories.each_value do |category| + collection.kinds << category if category.kind_of? OCCI::Core::Kind + collection.mixins << category if category.kind_of? OCCI::Core::Mixin + collection.actions << category if category.kind_of? OCCI::Core::Action + end + end + return collection + end + end +end \ No newline at end of file diff --git a/lib/occi/Request.rb b/lib/occi/Request.rb new file mode 100644 index 0000000..4454701 --- /dev/null +++ b/lib/occi/Request.rb @@ -0,0 +1,204 @@ +############################################################################## +# Copyright 2011 Service Computing group, TU Dortmund +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +############################################################################## + +############################################################################## +# @note OCCI RESTful Web Service +# @author Florian Feldhaus, Piotr Kasprzak +############################################################################## + +require 'json' +require 'occi/Log' +require 'occi/antlr/OCCIParser' + +module OCCI + class Request + + attr_reader :kinds + attr_reader :mixins + attr_reader :actions + attr_reader :resources + attr_reader :links + attr_reader :locations + + # Parses a Rack/Sinatra Request and extract OCCI relevant information + # + # @param [Rack::Request] request from Sinatra/Rack + def initialize(request) + @kinds = [] + @mixins = [] + @actions = [] + @resources = [] + @links = [] + @locations = [] + +=begin + if content_type.includes?('multipart') + # TODO: implement multipart handling + # handle file upload + if params['file'] != nil + OCCI::Log.debug("Location of Image #{params['file'][:tempfile].path}") + $image_path = $config[:one_image_tmp_dir] + '/' + params['file'][:filename] + FileUtils.cp(params['file'][:tempfile].path, $image_path) + end + + # handle file upload in multipart requests + request.POST.values.each do |body| + if body.kind_of?(String) + parse_text(body) + elsif body.kind_of?(Hash) + if body['type'].include?('application/json') + # try to parse body as JSON object + parse_json(body.read) + elsif body['type'].include?('text/plain') # text/plain + parse_text(body.read) + end unless body['type'].nil? + end + end + end +=end + + body = request.body.read.to_s + + # always check headers + parse_header_locations(request.env) + if @locations.empty? + if request.path_info.include?('/-/') + parse_header_categories(request.env) + else + parse_header_entity(request.env) + end + end + + case request.media_type + when 'text/uri-list' + body.each_line do |line| + @locations << URI.parse(line) + end + when 'text/plain', nil + parse_text_locations(body) + if @locations.empty? + if request.path_info.include?('/-/') + parse_text_categories(body) + else + parse_text_entity(body) + end + end + when 'application/occi+json' || 'application/json' + parse_json(body) + else + raise OCCI::ContentTypeNotSupported + end + + end + + def categories + @kinds + @mixins + @actions + end + + # --------------------------------------------------------------------------------------------------------------------- + private + # --------------------------------------------------------------------------------------------------------------------- + + def parse_header_locations(header) + x_occi_location_strings = header['HTTP_X_OCCI_LOCATION'].to_s.split(',') + x_occi_location_strings.each { |loc| @locations << OCCI::Parser.new('X-OCCI-Location: ' + loc).x_occi_location } + end + + def parse_header_categories(header) + category_strings = header['HTTP_CATEGORY'].to_s.split(',') + category_strings.each do |cat| + category = OCCI::Parser.new('Category: ' + cat).category + @kinds.concat category.kinds.collect { |kind| OCCI::Core::Kind.new(kind) } + @mixins.concat category.mixins.collect { |mixin| OCCI::Core::Mixin.new(mixin) } + @actions.concat category.actions.collect { |action| OCCI::Core::Action.new(action) } + end + end + + def parse_header_entity(header) + entity = Hashie::Mash.new + category_strings = header['HTTP_CATEGORY'].to_s.split(',') + return if category_strings.empty? + attribute_strings = header['HTTP_X_OCCI_ATTRIBUTE'].to_s.split(',') + categories = Hashie::Mash.new({:kinds => [], :mixins => [], :actions => []}) + category_strings.each { |cat| categories.merge!(OCCI::Parser.new('Category: ' + cat).category) } + return if categories.kinds.empty? + entity.kind = categories.kinds.first.scheme + categories.kinds.first.term + entity.mixins = categories.mixins.collect { |mixin| mixin.scheme + mixin.term } if categories.mixins.any? + attribute_strings.each { |attr| entity.attributes!.merge!(OCCI::Parser.new('X-OCCI-Attribute: ' + attr).x_occi_attribute) } + kind = OCCI::Registry.get_by_id(entity.kind) + # TODO: error handling + return if kind.nil? + if kind.entity_type == OCCI::Core::Link.name + entity.target = link.attributes.occi!.core!.target + entity.source = link.attributes.occi!.core!.source + @links << OCCI::Core::Link.new(entity) + elsif kind.entity_type == OCCI::Core::Resource.name + link_strings = header['HTTP_LINK'].to_s.split(',') + link_strings.each { |link| entity.links << OCCI::Parser.new('Link: ' + link).link } + @resources << OCCI::Core::Resource.new(entity) + end + end + + def parse_text_locations(body) + body.each_line do |line| + @locations << OCCI::Parser.new(line).x_occi_location if line.include? 'X-OCCI-Location' + end + end + + def parse_text_categories(body) + body.each_line do |line| + category = OCCI::Parser.new(line).category + @kinds.concat category.kinds.collect { |kind| OCCI::Core::Kind.new(kind) } + @mixins.concat category.mixins.collect { |mixin| OCCI::Core::Mixin.new(mixin) } + @actions.concat category.actions.collect { |action| OCCI::Core::Action.new(action) } + end + end + + def parse_text_entity(body) + entity = Hashie::Mash.new + links = [] + categories = Hashie::Mash.new({:kinds => [], :mixins => [], :actions => []}) + body.each_line do |line| + categories.merge!(OCCI::Parser.new(line).category) if line.include? 'Category' + entity.attributes!.merge!(OCCI::Parser.new(line).x_occi_attribute) if line.include? 'X-OCCI-Attribute' + links << OCCI::Parser.new(line).link if line.include? 'Link' + end + entity.kind = categories.kinds.first.scheme + categories.kinds.first.term if categories.kinds.first + entity.mixins = categories.mixins.collect { |mixin| mixin.scheme + mixin.term } if entity.mixins + kind = OCCI::Registry.get_by_id(entity.kind) + # TODO: error handling + return if kind.nil? + if OCCI::Registry.get_by_id(entity.kind).entity_type == OCCI::Core::Link.name + entity.target = links.first.attributes.occi!.core!.target + entity.source = links.first.attributes.occi!.core!.source + @links << OCCI::Core::Link.new(entity) + elsif OCCI::Registry.get_by_id(entity.kind).entity_type == OCCI::Core::Resource.name + entity.links = links + @resources << OCCI::Core::Resource.new(entity) + end unless entity.kind.nil? + end + + def parse_json(body) + collection = Hashie::Mash.new(JSON.parse(body)) + @kinds.concat collection.kinds.collect { |kind| OCCI::Core::Kind.new(kind) } if collection.kinds + @mixins.concat collection.mixins.collect { |mixin| OCCI::Core::Mixin.new(mixin) } if collection.mixins + @resources.concat collection.resources.collect { |resource| OCCI::Core::Resource.new(resource) } if collection.resources + @links.concat collection.links.collect { |link| OCCI::Core::Link.new(link) } if collection.links + @locations.concat collection.locations.collect { |location| URI.parse(location) } if collection.locations + end + + end +end diff --git a/lib/occi/antlr/OCCI.g b/lib/occi/antlr/OCCI.g index 825b64b..1c73849 100644 --- a/lib/occi/antlr/OCCI.g +++ b/lib/occi/antlr/OCCI.g @@ -49,22 +49,21 @@ Category: storage; actions="http://schemas.ogf.org/occi/infrastructure/storage/action#resize http://schemas.ogf.org/occi/infrastructure/storage/action#online" */ -category returns [mash] - : 'Category' ':' category_value { mash = $category_value.mash }; - category_value returns [mash] - @init{ mash = Hashie::Mash.new( {:kinds=>[],:mixins=>[],:actions=>[] } ) } +category returns [hash] + : 'Category' ':' category_value { hash = $category_value.hash }; + category_value returns [hash] + @init{ hash = Hashie::Mash.new( {:kinds=>[],:mixins=>[],:actions=>[] } ) } : category_term category_scheme category_class category_title? category_rel? category_location? category_attributes? category_actions? ';'? { type = $category_class.value cat = Hashie::Mash.new cat.term = $category_term.value cat.scheme = $category_scheme.value - cat.type_identifier = cat.scheme + cat.term cat.title = $category_title.value cat.related = $category_rel.value cat.location = $category_location.value - cat.attributes = $category_attributes.mash + cat.attributes = $category_attributes.hash cat.actions = $category_actions.array - mash[(type+'s').to_sym] << cat + hash[(type+'s').to_sym] << cat }; category_term returns [value] : WS? term { value = $term.text }; @@ -78,9 +77,9 @@ category returns [mash] { value = $rel.text }; category_location returns [value] : ';' WS? 'location' '=' '"' location '"' { value = $location.text }; - category_attributes returns [mash] @init{mash = Hashie::Mash.new} - : ';' WS? 'attributes' '=' '"' attr=attribute_name { mash.merge!($attr.mash) } - ( WS? next_attr=attribute_name { mash.merge!($next_attr.mash) } )* '"'; + category_attributes returns [hash] @init{hash = Hashie::Mash.new} + : ';' WS? 'attributes' '=' '"' attr=attribute_name { hash.merge!($attr.hash) } + ( WS? next_attr=attribute_name { hash.merge!($next_attr.hash) } )* '"'; category_actions returns [array] @init{array = Array.new} : ';' WS? 'actions' '=' '"' act=action_location { array << $act.text } ( WS? next_act=action_location { array << $next_act.text } )* '"'; @@ -94,24 +93,23 @@ category="http://example.com/occi/link#disk_drive"; com.example.drive0.interface="ide0"; com.example.drive1.interface="ide1" */ -link returns [mash] - @init{mash = Hashie::Mash.new} - : 'Link' ':' link_value { mash = $link_value.mash }; - link_value returns [mash] - @init{ mash = Hashie::Mash.new } - : link_target { mash[:target] = $link_target.value } - link_rel { mash[:rel] = $link_rel.value } - link_self? { mash[:self] = $link_self.value } - link_category? { mash[:category] = $link_category.value } - link_attributes { mash[:attributes] = $link_attributes.mash } +link returns [hash] + : 'Link' ':' link_value { hash = $link_value.hash }; + link_value returns [hash] + @init{ hash = Hashie::Mash.new } + : link_target { hash[:target] = $link_target.value } + link_rel { hash[:rel] = $link_rel.value } + link_self? { hash[:self] = $link_self.value } + link_category? { hash[:category] = $link_category.value } + link_attributes { hash[:attributes] = $link_attributes.hash } ';'? ; link_target returns [value] : WS? '<' target '>' { value = $target.text }; link_rel returns [value] : ';' WS? 'rel' '=' '"' rel '"' { value = $rel.text }; link_self returns [value] : ';' WS? 'self' '=' '"' self_location '"' { value = $self_location.text }; link_category returns [value] : ';' WS? 'category' '=' '"' category_name '"' { value = $category_name.text }; - link_attributes returns [mash] @init { mash = Hashie::Mash.new } - : (';' WS? attribute { mash.merge!($attribute.mash) } )*; + link_attributes returns [hash] @init { hash = Hashie::Mash.new } + : (';' WS? attribute { hash.merge!($attribute.hash) } )*; /* e.g. @@ -123,9 +121,8 @@ X-OCCI-Attribute: occi.compute.memory=3.0 X-OCCI-Attribute: occi.compute.state="active" */ -x_occi_attribute returns [mash] - @init { mash = Hashie::Mash.new } - : 'X-OCCI-Attribute' ':' WS? attribute ';'? { mash = $attribute.mash } ; +x_occi_attribute returns [hash] + : 'X-OCCI-Attribute' ':' WS? attribute ';'? { hash = $attribute.hash } ; /* e.g. @@ -143,16 +140,18 @@ class_type : ( 'kind' | 'mixin' | 'action' ); title : ( ESC | ~( '\\' | '"' | '\'' ) | '\'' )*; rel : uri; location : uri; -attribute returns [mash] @init { mash = Hashie::Mash.new } - : comp_first=attribute_component { cur_mash = mash; comp = $comp_first.text } - ( '.' comp_next=attribute_component { cur_mash[comp.to_sym] = Hashie::Mash.new; cur_mash = cur_mash[comp.to_sym]; comp = $comp_next.text })* - '=' attribute_value { cur_mash[comp.to_sym] = $attribute_value.text }; -attribute_name returns [mash] @init { mash = Hashie::Mash.new } - : comp_first=attribute_component { cur_mash = mash; comp = $comp_first.text } - ( '.' comp_next=attribute_component { cur_mash[comp.to_sym] = Hashie::Mash.new; cur_mash = cur_mash[comp.to_sym]; comp = $comp_next.text })* - { cur_mash[comp.to_sym] = ATTRIBUTE }; +attribute returns [hash] @init { hash = Hashie::Mash.new } + : comp_first=attribute_component { cur_hash = hash; comp = $comp_first.text } + ( '.' comp_next=attribute_component { cur_hash[comp.to_sym] = Hashie::Mash.new; cur_hash = cur_hash[comp.to_sym]; comp = $comp_next.text })* + '=' attribute_value { cur_hash[comp.to_sym] = $attribute_value.value }; +attribute_name returns [hash] @init { hash = Hashie::Mash.new } + : comp_first=attribute_component { cur_hash = hash; comp = $comp_first.text } + ( '.' comp_next=attribute_component { cur_hash[comp.to_sym] = Hashie::Mash.new; cur_hash = cur_hash[comp.to_sym]; comp = $comp_next.text })* + { cur_hash[comp.to_sym] = ATTRIBUTE }; attribute_component : LOALPHA ( LOALPHA | DIGIT | '-' | '_' )*; -attribute_value : ( ( '"' ( ESC | ~( '\\' | '"' | '\'' ) | '\'' )* '"') | ( DIGIT ( '.' DIGIT )* ) ); +attribute_value returns [value] : ( string { value = $string.text } | number { value = $number.text.to_i } ); +string : ( '"' ( ESC | ~( '\\' | '"' | '\'' ) | '\'' )* '"'); +number : ( DIGIT* ( '.' DIGIT+ )? ); action_location : uri; target : uri; self_location : uri; @@ -160,6 +159,6 @@ category_name : uri; LOALPHA : ('a'..'z')+; UPALPHA : ('A'..'Z')+; -DIGIT : ('0'..'9')+; +DIGIT : ('0'..'9'); WS : ( '\t' | ' ' | '\r' | '\n'| '\u000C' )+; ESC : '\\' ( '"' | '\'' ); \ No newline at end of file diff --git a/lib/occi/antlr/OCCILexer.rb b/lib/occi/antlr/OCCILexer.rb index c4524f3..994d15e 100644 --- a/lib/occi/antlr/OCCILexer.rb +++ b/lib/occi/antlr/OCCILexer.rb @@ -5,15 +5,15 @@ # Generated using ANTLR version: 3.2.1-SNAPSHOT Jul 31, 2010 19:34:52 # Ruby runtime library version: 1.8.11 # Input grammar file: OCCI.g -# Generated at: 2012-03-28 22:43:36 +# Generated at: 2012-05-18 21:42:45 # # ~~~> start load path setup -this_directory = File.expand_path( File.dirname( __FILE__ ) ) -$LOAD_PATH.unshift( this_directory ) unless $LOAD_PATH.include?( this_directory ) +this_directory = File.expand_path(File.dirname(__FILE__)) +$LOAD_PATH.unshift(this_directory) unless $LOAD_PATH.include?(this_directory) antlr_load_failed = proc do - load_path = $LOAD_PATH.map { |dir| ' - ' << dir }.join( $/ ) + load_path = $LOAD_PATH.map { |dir| ' - ' << dir }.join($/) raise LoadError, <<-END.strip! Failed to load the ANTLR3 runtime library (version 1.8.11): @@ -30,29 +30,29 @@ END end -defined?( ANTLR3 ) or begin - - # 1: try to load the ruby antlr3 runtime library from the system path +defined?(ANTLR3) or begin + + # 1: try to load the ruby antlr3 runtime library from the system path require 'antlr3' - + rescue LoadError - + # 2: try to load rubygems if it isn't already loaded - defined?( Gem ) or begin + defined?(Gem) or begin require 'rubygems' rescue LoadError antlr_load_failed.call end - + # 3: try to activate the antlr3 gem begin - Gem.activate( 'antlr3', '~> 1.8.11' ) + Gem.activate('antlr3', '~> 1.8.11') rescue Gem::LoadError antlr_load_failed.call end - + require 'antlr3' - + end # <~~~ end load path setup @@ -61,22 +61,22 @@ module OCCI # TokenData defines all of the token type integer values # as constants, which will be included in all # ANTLR-generated recognizers. - const_defined?( :TokenData ) or TokenData = ANTLR3::TokenScheme.new + const_defined?(:TokenData) or TokenData = ANTLR3::TokenScheme.new module TokenData # define the token constants - define_tokens( :T__29 => 29, :T__28 => 28, :T__27 => 27, :T__26 => 26, - :T__25 => 25, :T__24 => 24, :T__23 => 23, :ESC => 8, - :T__22 => 22, :T__21 => 21, :T__20 => 20, :EOF => -1, - :T__9 => 9, :T__19 => 19, :T__16 => 16, :T__15 => 15, - :T__18 => 18, :T__17 => 17, :T__12 => 12, :T__11 => 11, - :T__14 => 14, :T__13 => 13, :T__10 => 10, :DIGIT => 7, - :LOALPHA => 5, :T__42 => 42, :T__43 => 43, :T__40 => 40, - :T__41 => 41, :T__30 => 30, :T__31 => 31, :T__32 => 32, - :T__33 => 33, :WS => 4, :T__34 => 34, :T__35 => 35, :T__36 => 36, - :T__37 => 37, :UPALPHA => 6, :T__38 => 38, :T__39 => 39 ) - + define_tokens(:T__29 => 29, :T__28 => 28, :T__27 => 27, :T__26 => 26, + :T__25 => 25, :T__24 => 24, :T__23 => 23, :ESC => 8, + :T__22 => 22, :T__21 => 21, :T__20 => 20, :EOF => -1, + :T__9 => 9, :T__19 => 19, :T__16 => 16, :T__15 => 15, + :T__18 => 18, :T__17 => 17, :T__12 => 12, :T__11 => 11, + :T__14 => 14, :T__13 => 13, :T__10 => 10, :DIGIT => 7, + :LOALPHA => 5, :T__42 => 42, :T__43 => 43, :T__40 => 40, + :T__41 => 41, :T__30 => 30, :T__31 => 31, :T__32 => 32, + :T__33 => 33, :WS => 4, :T__34 => 34, :T__35 => 35, :T__36 => 36, + :T__37 => 37, :UPALPHA => 6, :T__38 => 38, :T__39 => 39) + end @@ -84,35 +84,35 @@ class Lexer < ANTLR3::Lexer @grammar_home = OCCI include TokenData - + begin - generated_using( "OCCI.g", "3.2.1-SNAPSHOT Jul 31, 2010 19:34:52", "1.8.11" ) + generated_using("OCCI.g", "3.2.1-SNAPSHOT Jul 31, 2010 19:34:52", "1.8.11") rescue NoMethodError => error # ignore end - - RULE_NAMES = [ "T__9", "T__10", "T__11", "T__12", "T__13", "T__14", - "T__15", "T__16", "T__17", "T__18", "T__19", "T__20", - "T__21", "T__22", "T__23", "T__24", "T__25", "T__26", - "T__27", "T__28", "T__29", "T__30", "T__31", "T__32", - "T__33", "T__34", "T__35", "T__36", "T__37", "T__38", - "T__39", "T__40", "T__41", "T__42", "T__43", "LOALPHA", - "UPALPHA", "DIGIT", "WS", "ESC" ].freeze - RULE_METHODS = [ :t__9!, :t__10!, :t__11!, :t__12!, :t__13!, :t__14!, - :t__15!, :t__16!, :t__17!, :t__18!, :t__19!, :t__20!, - :t__21!, :t__22!, :t__23!, :t__24!, :t__25!, :t__26!, - :t__27!, :t__28!, :t__29!, :t__30!, :t__31!, :t__32!, - :t__33!, :t__34!, :t__35!, :t__36!, :t__37!, :t__38!, - :t__39!, :t__40!, :t__41!, :t__42!, :t__43!, :loalpha!, - :upalpha!, :digit!, :ws!, :esc! ].freeze - - - def initialize( input=nil, options = {} ) - super( input, options ) + + RULE_NAMES = ["T__9", "T__10", "T__11", "T__12", "T__13", "T__14", + "T__15", "T__16", "T__17", "T__18", "T__19", "T__20", + "T__21", "T__22", "T__23", "T__24", "T__25", "T__26", + "T__27", "T__28", "T__29", "T__30", "T__31", "T__32", + "T__33", "T__34", "T__35", "T__36", "T__37", "T__38", + "T__39", "T__40", "T__41", "T__42", "T__43", "LOALPHA", + "UPALPHA", "DIGIT", "WS", "ESC"].freeze + RULE_METHODS = [:t__9!, :t__10!, :t__11!, :t__12!, :t__13!, :t__14!, + :t__15!, :t__16!, :t__17!, :t__18!, :t__19!, :t__20!, + :t__21!, :t__22!, :t__23!, :t__24!, :t__25!, :t__26!, + :t__27!, :t__28!, :t__29!, :t__30!, :t__31!, :t__32!, + :t__33!, :t__34!, :t__35!, :t__36!, :t__37!, :t__38!, + :t__39!, :t__40!, :t__41!, :t__42!, :t__43!, :loalpha!, + :upalpha!, :digit!, :ws!, :esc!].freeze + + + def initialize(input=nil, options = {}) + super(input, options) end - - + + # - - - - - - - - - - - lexer rules - - - - - - - - - - - - # lexer rule t__9! (T__9) # (in OCCI.g) @@ -123,12 +123,12 @@ def t__9! type = T__9 channel = ANTLR3::DEFAULT_CHANNEL - + # - - - - main rule block - - - - # at line 7:8: 'Category' - match( "Category" ) + match("Category") + - @state.type = type @state.channel = channel @@ -147,12 +147,12 @@ def t__10! type = T__10 channel = ANTLR3::DEFAULT_CHANNEL - + # - - - - main rule block - - - - # at line 8:9: ':' - match( 0x3a ) + match(0x3a) + - @state.type = type @state.channel = channel @@ -171,12 +171,12 @@ def t__11! type = T__11 channel = ANTLR3::DEFAULT_CHANNEL - + # - - - - main rule block - - - - # at line 9:9: ';' - match( 0x3b ) + match(0x3b) + - @state.type = type @state.channel = channel @@ -195,12 +195,12 @@ def t__12! type = T__12 channel = ANTLR3::DEFAULT_CHANNEL - + # - - - - main rule block - - - - # at line 10:9: 'scheme' - match( "scheme" ) + match("scheme") + - @state.type = type @state.channel = channel @@ -219,12 +219,12 @@ def t__13! type = T__13 channel = ANTLR3::DEFAULT_CHANNEL - + # - - - - main rule block - - - - # at line 11:9: '=' - match( 0x3d ) + match(0x3d) + - @state.type = type @state.channel = channel @@ -243,12 +243,12 @@ def t__14! type = T__14 channel = ANTLR3::DEFAULT_CHANNEL - + # - - - - main rule block - - - - # at line 12:9: '\"' - match( 0x22 ) + match(0x22) + - @state.type = type @state.channel = channel @@ -267,12 +267,12 @@ def t__15! type = T__15 channel = ANTLR3::DEFAULT_CHANNEL - + # - - - - main rule block - - - - # at line 13:9: 'class' - match( "class" ) + match("class") + - @state.type = type @state.channel = channel @@ -291,12 +291,12 @@ def t__16! type = T__16 channel = ANTLR3::DEFAULT_CHANNEL - + # - - - - main rule block - - - - # at line 14:9: 'title' - match( "title" ) + match("title") + - @state.type = type @state.channel = channel @@ -315,12 +315,12 @@ def t__17! type = T__17 channel = ANTLR3::DEFAULT_CHANNEL - + # - - - - main rule block - - - - # at line 15:9: 'rel' - match( "rel" ) + match("rel") + - @state.type = type @state.channel = channel @@ -339,12 +339,12 @@ def t__18! type = T__18 channel = ANTLR3::DEFAULT_CHANNEL - + # - - - - main rule block - - - - # at line 16:9: 'location' - match( "location" ) + match("location") + - @state.type = type @state.channel = channel @@ -363,12 +363,12 @@ def t__19! type = T__19 channel = ANTLR3::DEFAULT_CHANNEL - + # - - - - main rule block - - - - # at line 17:9: 'attributes' - match( "attributes" ) + match("attributes") + - @state.type = type @state.channel = channel @@ -387,12 +387,12 @@ def t__20! type = T__20 channel = ANTLR3::DEFAULT_CHANNEL - + # - - - - main rule block - - - - # at line 18:9: 'actions' - match( "actions" ) + match("actions") + - @state.type = type @state.channel = channel @@ -411,12 +411,12 @@ def t__21! type = T__21 channel = ANTLR3::DEFAULT_CHANNEL - + # - - - - main rule block - - - - # at line 19:9: 'Link' - match( "Link" ) + match("Link") + - @state.type = type @state.channel = channel @@ -435,12 +435,12 @@ def t__22! type = T__22 channel = ANTLR3::DEFAULT_CHANNEL - + # - - - - main rule block - - - - # at line 20:9: '<' - match( 0x3c ) + match(0x3c) + - @state.type = type @state.channel = channel @@ -459,12 +459,12 @@ def t__23! type = T__23 channel = ANTLR3::DEFAULT_CHANNEL - + # - - - - main rule block - - - - # at line 21:9: '>' - match( 0x3e ) + match(0x3e) + - @state.type = type @state.channel = channel @@ -483,12 +483,12 @@ def t__24! type = T__24 channel = ANTLR3::DEFAULT_CHANNEL - + # - - - - main rule block - - - - # at line 22:9: 'self' - match( "self" ) + match("self") + - @state.type = type @state.channel = channel @@ -507,12 +507,12 @@ def t__25! type = T__25 channel = ANTLR3::DEFAULT_CHANNEL - + # - - - - main rule block - - - - # at line 23:9: 'category' - match( "category" ) + match("category") + - @state.type = type @state.channel = channel @@ -531,12 +531,12 @@ def t__26! type = T__26 channel = ANTLR3::DEFAULT_CHANNEL - + # - - - - main rule block - - - - # at line 24:9: 'X-OCCI-Attribute' - match( "X-OCCI-Attribute" ) + match("X-OCCI-Attribute") + - @state.type = type @state.channel = channel @@ -555,12 +555,12 @@ def t__27! type = T__27 channel = ANTLR3::DEFAULT_CHANNEL - + # - - - - main rule block - - - - # at line 25:9: 'X-OCCI-Location' - match( "X-OCCI-Location" ) + match("X-OCCI-Location") + - @state.type = type @state.channel = channel @@ -579,12 +579,12 @@ def t__28! type = T__28 channel = ANTLR3::DEFAULT_CHANNEL - + # - - - - main rule block - - - - # at line 26:9: '@' - match( 0x40 ) + match(0x40) + - @state.type = type @state.channel = channel @@ -603,12 +603,12 @@ def t__29! type = T__29 channel = ANTLR3::DEFAULT_CHANNEL - + # - - - - main rule block - - - - # at line 27:9: '%' - match( 0x25 ) + match(0x25) + - @state.type = type @state.channel = channel @@ -627,12 +627,12 @@ def t__30! type = T__30 channel = ANTLR3::DEFAULT_CHANNEL - + # - - - - main rule block - - - - # at line 28:9: '_' - match( 0x5f ) + match(0x5f) + - @state.type = type @state.channel = channel @@ -651,12 +651,12 @@ def t__31! type = T__31 channel = ANTLR3::DEFAULT_CHANNEL - + # - - - - main rule block - - - - # at line 29:9: '\\\\' - match( 0x5c ) + match(0x5c) + - @state.type = type @state.channel = channel @@ -675,12 +675,12 @@ def t__32! type = T__32 channel = ANTLR3::DEFAULT_CHANNEL - + # - - - - main rule block - - - - # at line 30:9: '+' - match( 0x2b ) + match(0x2b) + - @state.type = type @state.channel = channel @@ -699,12 +699,12 @@ def t__33! type = T__33 channel = ANTLR3::DEFAULT_CHANNEL - + # - - - - main rule block - - - - # at line 31:9: '.' - match( 0x2e ) + match(0x2e) + - @state.type = type @state.channel = channel @@ -723,12 +723,12 @@ def t__34! type = T__34 channel = ANTLR3::DEFAULT_CHANNEL - + # - - - - main rule block - - - - # at line 32:9: '~' - match( 0x7e ) + match(0x7e) + - @state.type = type @state.channel = channel @@ -747,12 +747,12 @@ def t__35! type = T__35 channel = ANTLR3::DEFAULT_CHANNEL - + # - - - - main rule block - - - - # at line 33:9: '#' - match( 0x23 ) + match(0x23) + - @state.type = type @state.channel = channel @@ -771,12 +771,12 @@ def t__36! type = T__36 channel = ANTLR3::DEFAULT_CHANNEL - + # - - - - main rule block - - - - # at line 34:9: '?' - match( 0x3f ) + match(0x3f) + - @state.type = type @state.channel = channel @@ -795,12 +795,12 @@ def t__37! type = T__37 channel = ANTLR3::DEFAULT_CHANNEL - + # - - - - main rule block - - - - # at line 35:9: '&' - match( 0x26 ) + match(0x26) + - @state.type = type @state.channel = channel @@ -819,12 +819,12 @@ def t__38! type = T__38 channel = ANTLR3::DEFAULT_CHANNEL - + # - - - - main rule block - - - - # at line 36:9: '/' - match( 0x2f ) + match(0x2f) + - @state.type = type @state.channel = channel @@ -843,12 +843,12 @@ def t__39! type = T__39 channel = ANTLR3::DEFAULT_CHANNEL - + # - - - - main rule block - - - - # at line 37:9: '-' - match( 0x2d ) + match(0x2d) + - @state.type = type @state.channel = channel @@ -867,12 +867,12 @@ def t__40! type = T__40 channel = ANTLR3::DEFAULT_CHANNEL - + # - - - - main rule block - - - - # at line 38:9: 'action' - match( "action" ) + match("action") + - @state.type = type @state.channel = channel @@ -891,12 +891,12 @@ def t__41! type = T__41 channel = ANTLR3::DEFAULT_CHANNEL - + # - - - - main rule block - - - - # at line 39:9: 'kind' - match( "kind" ) + match("kind") + - @state.type = type @state.channel = channel @@ -915,12 +915,12 @@ def t__42! type = T__42 channel = ANTLR3::DEFAULT_CHANNEL - + # - - - - main rule block - - - - # at line 40:9: 'mixin' - match( "mixin" ) + match("mixin") + - @state.type = type @state.channel = channel @@ -939,12 +939,12 @@ def t__43! type = T__43 channel = ANTLR3::DEFAULT_CHANNEL - + # - - - - main rule block - - - - # at line 41:9: '\\'' - match( 0x27 ) + match(0x27) + - @state.type = type @state.channel = channel @@ -963,36 +963,35 @@ def loalpha! type = LOALPHA channel = ANTLR3::DEFAULT_CHANNEL - + # - - - - main rule block - - - - - # at line 161:11: ( 'a' .. 'z' )+ - # at file 161:11: ( 'a' .. 'z' )+ + # at line 160:11: ( 'a' .. 'z' )+ + # at file 160:11: ( 'a' .. 'z' )+ match_count_1 = 0 while true alt_1 = 2 - look_1_0 = @input.peek( 1 ) + look_1_0 = @input.peek(1) - if ( look_1_0.between?( 0x61, 0x7a ) ) + if (look_1_0.between?(0x61, 0x7a)) alt_1 = 1 end case alt_1 - when 1 - # at line 161:12: 'a' .. 'z' - match_range( 0x61, 0x7a ) + when 1 + # at line 160:12: 'a' .. 'z' + match_range(0x61, 0x7a) - else - match_count_1 > 0 and break - eee = EarlyExit(1) + else + match_count_1 > 0 and break + eee = EarlyExit(1) - raise eee + raise eee end match_count_1 += 1 end - @state.type = type @state.channel = channel @@ -1011,36 +1010,35 @@ def upalpha! type = UPALPHA channel = ANTLR3::DEFAULT_CHANNEL - + # - - - - main rule block - - - - - # at line 162:11: ( 'A' .. 'Z' )+ - # at file 162:11: ( 'A' .. 'Z' )+ + # at line 161:11: ( 'A' .. 'Z' )+ + # at file 161:11: ( 'A' .. 'Z' )+ match_count_2 = 0 while true alt_2 = 2 - look_2_0 = @input.peek( 1 ) + look_2_0 = @input.peek(1) - if ( look_2_0.between?( 0x41, 0x5a ) ) + if (look_2_0.between?(0x41, 0x5a)) alt_2 = 1 end case alt_2 - when 1 - # at line 162:12: 'A' .. 'Z' - match_range( 0x41, 0x5a ) + when 1 + # at line 161:12: 'A' .. 'Z' + match_range(0x41, 0x5a) - else - match_count_2 > 0 and break - eee = EarlyExit(2) + else + match_count_2 > 0 and break + eee = EarlyExit(2) - raise eee + raise eee end match_count_2 += 1 end - @state.type = type @state.channel = channel @@ -1059,36 +1057,14 @@ def digit! type = DIGIT channel = ANTLR3::DEFAULT_CHANNEL - - # - - - - main rule block - - - - - # at line 163:11: ( '0' .. '9' )+ - # at file 163:11: ( '0' .. '9' )+ - match_count_3 = 0 - while true - alt_3 = 2 - look_3_0 = @input.peek( 1 ) - - if ( look_3_0.between?( 0x30, 0x39 ) ) - alt_3 = 1 - - end - case alt_3 - when 1 - # at line 163:12: '0' .. '9' - match_range( 0x30, 0x39 ) - - else - match_count_3 > 0 and break - eee = EarlyExit(3) - - raise eee - end - match_count_3 += 1 - end + # - - - - main rule block - - - - + # at line 162:11: ( '0' .. '9' ) + # at line 162:11: ( '0' .. '9' ) + # at line 162:12: '0' .. '9' + match_range(0x30, 0x39) - @state.type = type @state.channel = channel @@ -1107,44 +1083,42 @@ def ws! type = WS channel = ANTLR3::DEFAULT_CHANNEL - + # - - - - main rule block - - - - - # at line 164:11: ( '\\t' | ' ' | '\\r' | '\\n' | '\\u000C' )+ - # at file 164:11: ( '\\t' | ' ' | '\\r' | '\\n' | '\\u000C' )+ - match_count_4 = 0 + # at line 163:11: ( '\\t' | ' ' | '\\r' | '\\n' | '\\u000C' )+ + # at file 163:11: ( '\\t' | ' ' | '\\r' | '\\n' | '\\u000C' )+ + match_count_3 = 0 while true - alt_4 = 2 - look_4_0 = @input.peek( 1 ) + alt_3 = 2 + look_3_0 = @input.peek(1) - if ( look_4_0.between?( 0x9, 0xa ) || look_4_0.between?( 0xc, 0xd ) || look_4_0 == 0x20 ) - alt_4 = 1 + if (look_3_0.between?(0x9, 0xa) || look_3_0.between?(0xc, 0xd) || look_3_0 == 0x20) + alt_3 = 1 end - case alt_4 - when 1 - # at line - if @input.peek( 1 ).between?( 0x9, 0xa ) || @input.peek( 1 ).between?( 0xc, 0xd ) || @input.peek(1) == 0x20 - @input.consume - else - mse = MismatchedSet( nil ) - recover mse - raise mse - end - + case alt_3 + when 1 + # at line + if @input.peek(1).between?(0x9, 0xa) || @input.peek(1).between?(0xc, 0xd) || @input.peek(1) == 0x20 + @input.consume + else + mse = MismatchedSet(nil) + recover mse + raise mse + end - else - match_count_4 > 0 and break - eee = EarlyExit(4) + else + match_count_3 > 0 and break + eee = EarlyExit(3) - raise eee + raise eee end - match_count_4 += 1 + match_count_3 += 1 end - @state.type = type @state.channel = channel @@ -1163,21 +1137,19 @@ def esc! type = ESC channel = ANTLR3::DEFAULT_CHANNEL - + # - - - - main rule block - - - - - # at line 165:11: '\\\\' ( '\"' | '\\'' ) - match( 0x5c ) + # at line 164:11: '\\\\' ( '\"' | '\\'' ) + match(0x5c) if @input.peek(1) == 0x22 || @input.peek(1) == 0x27 @input.consume else - mse = MismatchedSet( nil ) + mse = MismatchedSet(nil) recover mse raise mse end - - @state.type = type @state.channel = channel @@ -1196,347 +1168,347 @@ def esc! # build and emit the actual next token def token! # at line 1:8: ( T__9 | T__10 | T__11 | T__12 | T__13 | T__14 | T__15 | T__16 | T__17 | T__18 | T__19 | T__20 | T__21 | T__22 | T__23 | T__24 | T__25 | T__26 | T__27 | T__28 | T__29 | T__30 | T__31 | T__32 | T__33 | T__34 | T__35 | T__36 | T__37 | T__38 | T__39 | T__40 | T__41 | T__42 | T__43 | LOALPHA | UPALPHA | DIGIT | WS | ESC ) - alt_5 = 40 - alt_5 = @dfa5.predict( @input ) - case alt_5 - when 1 - # at line 1:10: T__9 - t__9! + alt_4 = 40 + alt_4 = @dfa4.predict(@input) + case alt_4 + when 1 + # at line 1:10: T__9 + t__9! - when 2 - # at line 1:15: T__10 - t__10! + when 2 + # at line 1:15: T__10 + t__10! - when 3 - # at line 1:21: T__11 - t__11! + when 3 + # at line 1:21: T__11 + t__11! - when 4 - # at line 1:27: T__12 - t__12! + when 4 + # at line 1:27: T__12 + t__12! - when 5 - # at line 1:33: T__13 - t__13! + when 5 + # at line 1:33: T__13 + t__13! - when 6 - # at line 1:39: T__14 - t__14! + when 6 + # at line 1:39: T__14 + t__14! - when 7 - # at line 1:45: T__15 - t__15! + when 7 + # at line 1:45: T__15 + t__15! - when 8 - # at line 1:51: T__16 - t__16! + when 8 + # at line 1:51: T__16 + t__16! - when 9 - # at line 1:57: T__17 - t__17! + when 9 + # at line 1:57: T__17 + t__17! - when 10 - # at line 1:63: T__18 - t__18! + when 10 + # at line 1:63: T__18 + t__18! - when 11 - # at line 1:69: T__19 - t__19! + when 11 + # at line 1:69: T__19 + t__19! - when 12 - # at line 1:75: T__20 - t__20! + when 12 + # at line 1:75: T__20 + t__20! - when 13 - # at line 1:81: T__21 - t__21! + when 13 + # at line 1:81: T__21 + t__21! - when 14 - # at line 1:87: T__22 - t__22! + when 14 + # at line 1:87: T__22 + t__22! - when 15 - # at line 1:93: T__23 - t__23! + when 15 + # at line 1:93: T__23 + t__23! - when 16 - # at line 1:99: T__24 - t__24! + when 16 + # at line 1:99: T__24 + t__24! - when 17 - # at line 1:105: T__25 - t__25! + when 17 + # at line 1:105: T__25 + t__25! - when 18 - # at line 1:111: T__26 - t__26! + when 18 + # at line 1:111: T__26 + t__26! - when 19 - # at line 1:117: T__27 - t__27! + when 19 + # at line 1:117: T__27 + t__27! - when 20 - # at line 1:123: T__28 - t__28! + when 20 + # at line 1:123: T__28 + t__28! - when 21 - # at line 1:129: T__29 - t__29! + when 21 + # at line 1:129: T__29 + t__29! - when 22 - # at line 1:135: T__30 - t__30! + when 22 + # at line 1:135: T__30 + t__30! - when 23 - # at line 1:141: T__31 - t__31! + when 23 + # at line 1:141: T__31 + t__31! - when 24 - # at line 1:147: T__32 - t__32! + when 24 + # at line 1:147: T__32 + t__32! - when 25 - # at line 1:153: T__33 - t__33! + when 25 + # at line 1:153: T__33 + t__33! - when 26 - # at line 1:159: T__34 - t__34! + when 26 + # at line 1:159: T__34 + t__34! - when 27 - # at line 1:165: T__35 - t__35! + when 27 + # at line 1:165: T__35 + t__35! - when 28 - # at line 1:171: T__36 - t__36! + when 28 + # at line 1:171: T__36 + t__36! - when 29 - # at line 1:177: T__37 - t__37! + when 29 + # at line 1:177: T__37 + t__37! - when 30 - # at line 1:183: T__38 - t__38! + when 30 + # at line 1:183: T__38 + t__38! - when 31 - # at line 1:189: T__39 - t__39! + when 31 + # at line 1:189: T__39 + t__39! - when 32 - # at line 1:195: T__40 - t__40! + when 32 + # at line 1:195: T__40 + t__40! - when 33 - # at line 1:201: T__41 - t__41! + when 33 + # at line 1:201: T__41 + t__41! - when 34 - # at line 1:207: T__42 - t__42! + when 34 + # at line 1:207: T__42 + t__42! - when 35 - # at line 1:213: T__43 - t__43! + when 35 + # at line 1:213: T__43 + t__43! - when 36 - # at line 1:219: LOALPHA - loalpha! + when 36 + # at line 1:219: LOALPHA + loalpha! - when 37 - # at line 1:227: UPALPHA - upalpha! + when 37 + # at line 1:227: UPALPHA + upalpha! - when 38 - # at line 1:235: DIGIT - digit! + when 38 + # at line 1:235: DIGIT + digit! - when 39 - # at line 1:241: WS - ws! + when 39 + # at line 1:241: WS + ws! - when 40 - # at line 1:244: ESC - esc! + when 40 + # at line 1:244: ESC + esc! end end - + # - - - - - - - - - - DFA definitions - - - - - - - - - - - - class DFA5 < ANTLR3::DFA - EOT = unpack( 1, -1, 1, 32, 2, -1, 1, 31, 2, -1, 5, 31, 1, 32, 2, - -1, 1, 32, 3, -1, 1, 48, 8, -1, 2, 31, 6, -1, 9, 31, - 4, -1, 7, 31, 1, 68, 3, 31, 1, -1, 3, 31, 1, 76, 3, - 31, 1, -1, 3, 31, 1, -1, 1, 84, 2, 31, 1, -1, 1, 87, - 1, 31, 1, 89, 3, 31, 2, -1, 1, 94, 1, 95, 1, -1, 1, - 31, 1, -1, 2, 31, 1, 100, 3, -1, 3, 31, 1, 105, 2, -1, - 1, 108, 1, 109, 1, 31, 5, -1, 1, 31, 1, 112, 1, -1 ) - EOF = unpack( 113, -1 ) - MIN = unpack( 1, 9, 1, 97, 2, -1, 1, 99, 2, -1, 1, 97, 1, 105, 1, - 101, 1, 111, 1, 99, 1, 105, 2, -1, 1, 45, 3, -1, 1, - 34, 8, -1, 2, 105, 6, -1, 1, 104, 1, 108, 1, 97, 2, - 116, 1, 108, 1, 99, 2, 116, 1, -1, 1, 79, 2, -1, 1, - 110, 1, 120, 1, 101, 1, 102, 1, 115, 1, 101, 1, 108, - 2, 97, 1, 114, 1, 105, 1, 67, 1, 100, 1, 105, 1, 109, - 1, 97, 1, 115, 1, 103, 1, 101, 1, -1, 1, 116, 1, 105, - 1, 111, 1, 67, 1, 97, 1, 110, 1, 101, 1, -1, 1, 97, - 1, 111, 1, 97, 1, 105, 1, 98, 1, 110, 1, 73, 1, -1, - 2, 97, 1, -1, 1, 114, 1, -1, 1, 111, 1, 117, 1, 97, - 1, 45, 2, -1, 1, 121, 1, 110, 1, 116, 1, 97, 1, -1, - 1, 65, 2, 97, 1, 101, 5, -1, 1, 115, 1, 97, 1, -1 ) - MAX = unpack( 1, 126, 1, 97, 2, -1, 1, 101, 2, -1, 1, 108, 1, 105, - 1, 101, 1, 111, 1, 116, 1, 105, 2, -1, 1, 45, 3, -1, - 1, 39, 8, -1, 2, 105, 6, -1, 1, 104, 1, 108, 1, 97, - 2, 116, 1, 108, 1, 99, 2, 116, 1, -1, 1, 79, 2, -1, - 1, 110, 1, 120, 1, 101, 1, 102, 1, 115, 1, 101, 1, 108, - 1, 122, 1, 97, 1, 114, 1, 105, 1, 67, 1, 100, 1, 105, - 1, 109, 1, 122, 1, 115, 1, 103, 1, 101, 1, -1, 1, 116, - 1, 105, 1, 111, 1, 67, 1, 122, 1, 110, 1, 101, 1, -1, - 1, 122, 1, 111, 1, 122, 1, 105, 1, 98, 1, 110, 1, 73, - 1, -1, 2, 122, 1, -1, 1, 114, 1, -1, 1, 111, 1, 117, - 1, 122, 1, 45, 2, -1, 1, 121, 1, 110, 1, 116, 1, 122, - 1, -1, 1, 76, 2, 122, 1, 101, 5, -1, 1, 115, 1, 122, - 1, -1 ) - ACCEPT = unpack( 2, -1, 1, 2, 1, 3, 1, -1, 1, 5, 1, 6, 6, -1, 1, 14, - 1, 15, 1, -1, 1, 20, 1, 21, 1, 22, 1, -1, 1, 24, - 1, 25, 1, 26, 1, 27, 1, 28, 1, 29, 1, 30, 1, 31, - 2, -1, 1, 35, 1, 36, 1, 37, 1, 38, 1, 39, 1, 1, 9, - -1, 1, 13, 1, -1, 1, 40, 1, 23, 19, -1, 1, 9, 7, - -1, 1, 16, 7, -1, 1, 33, 2, -1, 1, 7, 1, -1, 1, 8, - 4, -1, 1, 34, 1, 4, 4, -1, 1, 32, 4, -1, 1, 12, 1, - 18, 1, 19, 1, 17, 1, 10, 2, -1, 1, 11 ) - SPECIAL = unpack( 113, -1 ) + class DFA4 < ANTLR3::DFA + EOT = unpack(1, -1, 1, 32, 2, -1, 1, 31, 2, -1, 5, 31, 1, 32, 2, + -1, 1, 32, 3, -1, 1, 48, 8, -1, 2, 31, 6, -1, 9, 31, + 4, -1, 7, 31, 1, 68, 3, 31, 1, -1, 3, 31, 1, 76, 3, + 31, 1, -1, 3, 31, 1, -1, 1, 84, 2, 31, 1, -1, 1, 87, + 1, 31, 1, 89, 3, 31, 2, -1, 1, 94, 1, 95, 1, -1, 1, + 31, 1, -1, 2, 31, 1, 100, 3, -1, 3, 31, 1, 105, 2, -1, + 1, 108, 1, 109, 1, 31, 5, -1, 1, 31, 1, 112, 1, -1) + EOF = unpack(113, -1) + MIN = unpack(1, 9, 1, 97, 2, -1, 1, 99, 2, -1, 1, 97, 1, 105, 1, + 101, 1, 111, 1, 99, 1, 105, 2, -1, 1, 45, 3, -1, 1, + 34, 8, -1, 2, 105, 6, -1, 1, 104, 1, 108, 1, 97, 2, + 116, 1, 108, 1, 99, 2, 116, 1, -1, 1, 79, 2, -1, 1, + 110, 1, 120, 1, 101, 1, 102, 1, 115, 1, 101, 1, 108, + 2, 97, 1, 114, 1, 105, 1, 67, 1, 100, 1, 105, 1, 109, + 1, 97, 1, 115, 1, 103, 1, 101, 1, -1, 1, 116, 1, 105, + 1, 111, 1, 67, 1, 97, 1, 110, 1, 101, 1, -1, 1, 97, + 1, 111, 1, 97, 1, 105, 1, 98, 1, 110, 1, 73, 1, -1, + 2, 97, 1, -1, 1, 114, 1, -1, 1, 111, 1, 117, 1, 97, + 1, 45, 2, -1, 1, 121, 1, 110, 1, 116, 1, 97, 1, -1, + 1, 65, 2, 97, 1, 101, 5, -1, 1, 115, 1, 97, 1, -1) + MAX = unpack(1, 126, 1, 97, 2, -1, 1, 101, 2, -1, 1, 108, 1, 105, + 1, 101, 1, 111, 1, 116, 1, 105, 2, -1, 1, 45, 3, -1, + 1, 39, 8, -1, 2, 105, 6, -1, 1, 104, 1, 108, 1, 97, + 2, 116, 1, 108, 1, 99, 2, 116, 1, -1, 1, 79, 2, -1, + 1, 110, 1, 120, 1, 101, 1, 102, 1, 115, 1, 101, 1, 108, + 1, 122, 1, 97, 1, 114, 1, 105, 1, 67, 1, 100, 1, 105, + 1, 109, 1, 122, 1, 115, 1, 103, 1, 101, 1, -1, 1, 116, + 1, 105, 1, 111, 1, 67, 1, 122, 1, 110, 1, 101, 1, -1, + 1, 122, 1, 111, 1, 122, 1, 105, 1, 98, 1, 110, 1, 73, + 1, -1, 2, 122, 1, -1, 1, 114, 1, -1, 1, 111, 1, 117, + 1, 122, 1, 45, 2, -1, 1, 121, 1, 110, 1, 116, 1, 122, + 1, -1, 1, 76, 2, 122, 1, 101, 5, -1, 1, 115, 1, 122, + 1, -1) + ACCEPT = unpack(2, -1, 1, 2, 1, 3, 1, -1, 1, 5, 1, 6, 6, -1, 1, 14, + 1, 15, 1, -1, 1, 20, 1, 21, 1, 22, 1, -1, 1, 24, + 1, 25, 1, 26, 1, 27, 1, 28, 1, 29, 1, 30, 1, 31, + 2, -1, 1, 35, 1, 36, 1, 37, 1, 38, 1, 39, 1, 1, 9, + -1, 1, 13, 1, -1, 1, 40, 1, 23, 19, -1, 1, 9, 7, + -1, 1, 16, 7, -1, 1, 33, 2, -1, 1, 7, 1, -1, 1, 8, + 4, -1, 1, 34, 1, 4, 4, -1, 1, 32, 4, -1, 1, 12, 1, + 18, 1, 19, 1, 17, 1, 10, 2, -1, 1, 11) + SPECIAL = unpack(113, -1) TRANSITION = [ - unpack( 2, 34, 1, -1, 2, 34, 18, -1, 1, 34, 1, -1, 1, 6, 1, 23, - 1, -1, 1, 17, 1, 25, 1, 30, 3, -1, 1, 20, 1, -1, 1, 27, - 1, 21, 1, 26, 10, 33, 1, 2, 1, 3, 1, 13, 1, 5, 1, 14, 1, - 24, 1, 16, 2, 32, 1, 1, 8, 32, 1, 12, 11, 32, 1, 15, 2, - 32, 1, -1, 1, 19, 2, -1, 1, 18, 1, -1, 1, 11, 1, 31, 1, - 7, 7, 31, 1, 28, 1, 10, 1, 29, 4, 31, 1, 9, 1, 4, 1, 8, - 6, 31, 3, -1, 1, 22 ), - unpack( 1, 35 ), - unpack( ), - unpack( ), - unpack( 1, 36, 1, -1, 1, 37 ), - unpack( ), - unpack( ), - unpack( 1, 39, 10, -1, 1, 38 ), - unpack( 1, 40 ), - unpack( 1, 41 ), - unpack( 1, 42 ), - unpack( 1, 44, 16, -1, 1, 43 ), - unpack( 1, 45 ), - unpack( ), - unpack( ), - unpack( 1, 46 ), - unpack( ), - unpack( ), - unpack( ), - unpack( 1, 47, 4, -1, 1, 47 ), - unpack( ), - unpack( ), - unpack( ), - unpack( ), - unpack( ), - unpack( ), - unpack( ), - unpack( ), - unpack( 1, 49 ), - unpack( 1, 50 ), - unpack( ), - unpack( ), - unpack( ), - unpack( ), - unpack( ), - unpack( ), - unpack( 1, 51 ), - unpack( 1, 52 ), - unpack( 1, 53 ), - unpack( 1, 54 ), - unpack( 1, 55 ), - unpack( 1, 56 ), - unpack( 1, 57 ), - unpack( 1, 58 ), - unpack( 1, 59 ), - unpack( ), - unpack( 1, 60 ), - unpack( ), - unpack( ), - unpack( 1, 61 ), - unpack( 1, 62 ), - unpack( 1, 63 ), - unpack( 1, 64 ), - unpack( 1, 65 ), - unpack( 1, 66 ), - unpack( 1, 67 ), - unpack( 26, 31 ), - unpack( 1, 69 ), - unpack( 1, 70 ), - unpack( 1, 71 ), - unpack( 1, 72 ), - unpack( 1, 73 ), - unpack( 1, 74 ), - unpack( 1, 75 ), - unpack( 26, 31 ), - unpack( 1, 77 ), - unpack( 1, 78 ), - unpack( 1, 79 ), - unpack( ), - unpack( 1, 80 ), - unpack( 1, 81 ), - unpack( 1, 82 ), - unpack( 1, 83 ), - unpack( 26, 31 ), - unpack( 1, 85 ), - unpack( 1, 86 ), - unpack( ), - unpack( 26, 31 ), - unpack( 1, 88 ), - unpack( 26, 31 ), - unpack( 1, 90 ), - unpack( 1, 91 ), - unpack( 1, 92 ), - unpack( 1, 93 ), - unpack( ), - unpack( 26, 31 ), - unpack( 26, 31 ), - unpack( ), - unpack( 1, 96 ), - unpack( ), - unpack( 1, 97 ), - unpack( 1, 98 ), - unpack( 18, 31, 1, 99, 7, 31 ), - unpack( 1, 101 ), - unpack( ), - unpack( ), - unpack( 1, 102 ), - unpack( 1, 103 ), - unpack( 1, 104 ), - unpack( 26, 31 ), - unpack( ), - unpack( 1, 106, 10, -1, 1, 107 ), - unpack( 26, 31 ), - unpack( 26, 31 ), - unpack( 1, 110 ), - unpack( ), - unpack( ), - unpack( ), - unpack( ), - unpack( ), - unpack( 1, 111 ), - unpack( 26, 31 ), - unpack( ) + unpack(2, 34, 1, -1, 2, 34, 18, -1, 1, 34, 1, -1, 1, 6, 1, 23, + 1, -1, 1, 17, 1, 25, 1, 30, 3, -1, 1, 20, 1, -1, 1, 27, + 1, 21, 1, 26, 10, 33, 1, 2, 1, 3, 1, 13, 1, 5, 1, 14, 1, + 24, 1, 16, 2, 32, 1, 1, 8, 32, 1, 12, 11, 32, 1, 15, 2, + 32, 1, -1, 1, 19, 2, -1, 1, 18, 1, -1, 1, 11, 1, 31, 1, + 7, 7, 31, 1, 28, 1, 10, 1, 29, 4, 31, 1, 9, 1, 4, 1, 8, + 6, 31, 3, -1, 1, 22), + unpack(1, 35), + unpack(), + unpack(), + unpack(1, 36, 1, -1, 1, 37), + unpack(), + unpack(), + unpack(1, 39, 10, -1, 1, 38), + unpack(1, 40), + unpack(1, 41), + unpack(1, 42), + unpack(1, 44, 16, -1, 1, 43), + unpack(1, 45), + unpack(), + unpack(), + unpack(1, 46), + unpack(), + unpack(), + unpack(), + unpack(1, 47, 4, -1, 1, 47), + unpack(), + unpack(), + unpack(), + unpack(), + unpack(), + unpack(), + unpack(), + unpack(), + unpack(1, 49), + unpack(1, 50), + unpack(), + unpack(), + unpack(), + unpack(), + unpack(), + unpack(), + unpack(1, 51), + unpack(1, 52), + unpack(1, 53), + unpack(1, 54), + unpack(1, 55), + unpack(1, 56), + unpack(1, 57), + unpack(1, 58), + unpack(1, 59), + unpack(), + unpack(1, 60), + unpack(), + unpack(), + unpack(1, 61), + unpack(1, 62), + unpack(1, 63), + unpack(1, 64), + unpack(1, 65), + unpack(1, 66), + unpack(1, 67), + unpack(26, 31), + unpack(1, 69), + unpack(1, 70), + unpack(1, 71), + unpack(1, 72), + unpack(1, 73), + unpack(1, 74), + unpack(1, 75), + unpack(26, 31), + unpack(1, 77), + unpack(1, 78), + unpack(1, 79), + unpack(), + unpack(1, 80), + unpack(1, 81), + unpack(1, 82), + unpack(1, 83), + unpack(26, 31), + unpack(1, 85), + unpack(1, 86), + unpack(), + unpack(26, 31), + unpack(1, 88), + unpack(26, 31), + unpack(1, 90), + unpack(1, 91), + unpack(1, 92), + unpack(1, 93), + unpack(), + unpack(26, 31), + unpack(26, 31), + unpack(), + unpack(1, 96), + unpack(), + unpack(1, 97), + unpack(1, 98), + unpack(18, 31, 1, 99, 7, 31), + unpack(1, 101), + unpack(), + unpack(), + unpack(1, 102), + unpack(1, 103), + unpack(1, 104), + unpack(26, 31), + unpack(), + unpack(1, 106, 10, -1, 1, 107), + unpack(26, 31), + unpack(26, 31), + unpack(1, 110), + unpack(), + unpack(), + unpack(), + unpack(), + unpack(), + unpack(1, 111), + unpack(26, 31), + unpack() ].freeze - - ( 0 ... MIN.length ).zip( MIN, MAX ) do | i, a, z | + + (0 ... MIN.length).zip(MIN, MAX) do |i, a, z| if a > 0 and z < 0 - MAX[ i ] %= 0x10000 + MAX[i] %= 0x10000 end end - - @decision = 5 - + + @decision = 4 + def description <<-'__dfa_description__'.strip! @@ -1545,16 +1517,16 @@ def description end end - + private - + def initialize_dfas super rescue nil - @dfa5 = DFA5.new( self, 5 ) + @dfa4 = DFA4.new(self, 4) end end # class Lexer < ANTLR3::Lexer - at_exit { Lexer.main( ARGV ) } if __FILE__ == $0 + at_exit { Lexer.main(ARGV) } if __FILE__ == $0 end diff --git a/lib/occi/antlr/OCCIParser.rb b/lib/occi/antlr/OCCIParser.rb index f4fd25a..aa26241 100644 --- a/lib/occi/antlr/OCCIParser.rb +++ b/lib/occi/antlr/OCCIParser.rb @@ -5,15 +5,15 @@ # Generated using ANTLR version: 3.2.1-SNAPSHOT Jul 31, 2010 19:34:52 # Ruby runtime library version: 1.8.11 # Input grammar file: OCCI.g -# Generated at: 2012-03-28 22:43:35 +# Generated at: 2012-05-18 21:42:45 # # ~~~> start load path setup -this_directory = File.expand_path( File.dirname( __FILE__ ) ) -$LOAD_PATH.unshift( this_directory ) unless $LOAD_PATH.include?( this_directory ) +this_directory = File.expand_path(File.dirname(__FILE__)) +$LOAD_PATH.unshift(this_directory) unless $LOAD_PATH.include?(this_directory) antlr_load_failed = proc do - load_path = $LOAD_PATH.map { |dir| ' - ' << dir }.join( $/ ) + load_path = $LOAD_PATH.map { |dir| ' - ' << dir }.join($/) raise LoadError, <<-END.strip! Failed to load the ANTLR3 runtime library (version 1.8.11): @@ -30,39 +30,39 @@ END end -defined?( ANTLR3 ) or begin - - # 1: try to load the ruby antlr3 runtime library from the system path +defined?(ANTLR3) or begin + + # 1: try to load the ruby antlr3 runtime library from the system path require 'antlr3' - + rescue LoadError - + # 2: try to load rubygems if it isn't already loaded - defined?( Gem ) or begin + defined?(Gem) or begin require 'rubygems' rescue LoadError antlr_load_failed.call end - + # 3: try to activate the antlr3 gem begin - Gem.activate( 'antlr3', '~> 1.8.11' ) + Gem.activate('antlr3', '~> 1.8.11') rescue Gem::LoadError antlr_load_failed.call end - + require 'antlr3' - + end # <~~~ end load path setup # - - - - - - begin action @parser::header - - - - - - # OCCI.g - - require 'uri' - require 'hashie' - ATTRIBUTE = { :mutable => true, :required => false, :type => { :string => {} }, :default => '' } + +require 'uri' +require 'hashie' +ATTRIBUTE = {:mutable => true, :required => false, :type => {:string => {}}, :default => ''} # - - - - - - end action @parser::header - - - - - - - @@ -71,21 +71,21 @@ module OCCI # TokenData defines all of the token type integer values # as constants, which will be included in all # ANTLR-generated recognizers. - const_defined?( :TokenData ) or TokenData = ANTLR3::TokenScheme.new + const_defined?(:TokenData) or TokenData = ANTLR3::TokenScheme.new module TokenData # define the token constants - define_tokens( :T__29 => 29, :T__28 => 28, :T__27 => 27, :T__26 => 26, - :T__25 => 25, :T__24 => 24, :T__23 => 23, :T__22 => 22, - :ESC => 8, :T__21 => 21, :T__20 => 20, :EOF => -1, :T__9 => 9, - :T__19 => 19, :T__16 => 16, :T__15 => 15, :T__18 => 18, - :T__17 => 17, :T__12 => 12, :T__11 => 11, :T__14 => 14, - :T__13 => 13, :T__10 => 10, :DIGIT => 7, :LOALPHA => 5, - :T__42 => 42, :T__43 => 43, :T__40 => 40, :T__41 => 41, - :T__30 => 30, :T__31 => 31, :T__32 => 32, :T__33 => 33, - :WS => 4, :T__34 => 34, :T__35 => 35, :T__36 => 36, :T__37 => 37, - :UPALPHA => 6, :T__38 => 38, :T__39 => 39 ) + define_tokens(:T__29 => 29, :T__28 => 28, :T__27 => 27, :T__26 => 26, + :T__25 => 25, :T__24 => 24, :T__23 => 23, :T__22 => 22, + :ESC => 8, :T__21 => 21, :T__20 => 20, :EOF => -1, :T__9 => 9, + :T__19 => 19, :T__16 => 16, :T__15 => 15, :T__18 => 18, + :T__17 => 17, :T__12 => 12, :T__11 => 11, :T__14 => 14, + :T__13 => 13, :T__10 => 10, :DIGIT => 7, :LOALPHA => 5, + :T__42 => 42, :T__43 => 43, :T__40 => 40, :T__41 => 41, + :T__30 => 30, :T__31 => 31, :T__32 => 32, :T__33 => 33, + :WS => 4, :T__34 => 34, :T__35 => 35, :T__36 => 36, :T__37 => 37, + :UPALPHA => 6, :T__38 => 38, :T__39 => 39) # register the proper human-readable name or literal value # for each token type @@ -93,68 +93,69 @@ module TokenData # this is necessary because anonymous tokens, which are # created from literal values in the grammar, do not # have descriptive names - register_names( "WS", "LOALPHA", "UPALPHA", "DIGIT", "ESC", "'Category'", - "':'", "';'", "'scheme'", "'='", "'\"'", "'class'", - "'title'", "'rel'", "'location'", "'attributes'", "'actions'", - "'Link'", "'<'", "'>'", "'self'", "'category'", "'X-OCCI-Attribute'", - "'X-OCCI-Location'", "'@'", "'%'", "'_'", "'\\\\'", - "'+'", "'.'", "'~'", "'#'", "'?'", "'&'", "'/'", "'-'", - "'action'", "'kind'", "'mixin'", "'\\''" ) - + register_names("WS", "LOALPHA", "UPALPHA", "DIGIT", "ESC", "'Category'", + "':'", "';'", "'scheme'", "'='", "'\"'", "'class'", + "'title'", "'rel'", "'location'", "'attributes'", "'actions'", + "'Link'", "'<'", "'>'", "'self'", "'category'", "'X-OCCI-Attribute'", + "'X-OCCI-Location'", "'@'", "'%'", "'_'", "'\\\\'", + "'+'", "'.'", "'~'", "'#'", "'?'", "'&'", "'/'", "'-'", + "'action'", "'kind'", "'mixin'", "'\\''") + end class Parser < ANTLR3::Parser @grammar_home = OCCI - RULE_METHODS = [ :category, :category_value, :category_term, :category_scheme, - :category_class, :category_title, :category_rel, :category_location, - :category_attributes, :category_actions, :link, :link_value, - :link_target, :link_rel, :link_self, :link_category, - :link_attributes, :x_occi_attribute, :x_occi_location, - :uri, :term, :scheme, :class_type, :title, :rel, :location, - :attribute, :attribute_name, :attribute_component, - :attribute_value, :action_location, :target, :self_location, - :category_name ].freeze + RULE_METHODS = [:category, :category_value, :category_term, :category_scheme, + :category_class, :category_title, :category_rel, :category_location, + :category_attributes, :category_actions, :link, :link_value, + :link_target, :link_rel, :link_self, :link_category, + :link_attributes, :x_occi_attribute, :x_occi_location, + :uri, :term, :scheme, :class_type, :title, :rel, :location, + :attribute, :attribute_name, :attribute_component, + :attribute_value, :string, :number, :action_location, + :target, :self_location, :category_name].freeze include TokenData begin - generated_using( "OCCI.g", "3.2.1-SNAPSHOT Jul 31, 2010 19:34:52", "1.8.11" ) + generated_using("OCCI.g", "3.2.1-SNAPSHOT Jul 31, 2010 19:34:52", "1.8.11") rescue NoMethodError => error # ignore end - def initialize( input, options = {} ) - super( input, options ) + def initialize(input, options = {}) + super(input, options) end + # - - - - - - - - - - - - Rules - - - - - - - - - - - - - # # parser rule category # # (in OCCI.g) - # 52:1: category returns [mash] : 'Category' ':' category_value ; + # 52:1: category returns [hash] : 'Category' ':' category_value ; # def category # -> uncomment the next line to manually enable rule tracing # trace_in( __method__, 1 ) - mash = nil + hash = nil category_value1 = nil begin # at line 53:4: 'Category' ':' category_value - match( T__9, TOKENS_FOLLOWING_T__9_IN_category_42 ) - match( T__10, TOKENS_FOLLOWING_T__10_IN_category_44 ) - @state.following.push( TOKENS_FOLLOWING_category_value_IN_category_46 ) + match(T__9, TOKENS_FOLLOWING_T__9_IN_category_42) + match(T__10, TOKENS_FOLLOWING_T__10_IN_category_44) + @state.following.push(TOKENS_FOLLOWING_category_value_IN_category_46) category_value1 = category_value @state.following.pop # --> action - mash = category_value1 - # <-- action + hash = category_value1 + # <-- action rescue ANTLR3::Error::RecognitionError => re report_error(re) @@ -165,8 +166,8 @@ def category # trace_out( __method__, 1 ) end - - return mash + + return hash end @@ -174,12 +175,12 @@ def category # parser rule category_value # # (in OCCI.g) - # 54:3: category_value returns [mash] : category_term category_scheme category_class ( category_title )? ( category_rel )? ( category_location )? ( category_attributes )? ( category_actions )? ( ';' )? ; + # 54:3: category_value returns [hash] : category_term category_scheme category_class ( category_title )? ( category_rel )? ( category_location )? ( category_attributes )? ( category_actions )? ( ';' )? ; # def category_value # -> uncomment the next line to manually enable rule tracing # trace_in( __method__, 2 ) - mash = nil + hash = nil category_class2 = nil category_term3 = nil category_scheme4 = nil @@ -189,165 +190,164 @@ def category_value category_attributes8 = nil category_actions9 = nil # - - - - @init action - - - - - mash = Hashie::Mash.new( {:kinds=>[],:mixins=>[],:actions=>[] } ) + hash = Hashie::Mash.new({:kinds => [], :mixins => [], :actions => []}) begin # at line 56:15: category_term category_scheme category_class ( category_title )? ( category_rel )? ( category_location )? ( category_attributes )? ( category_actions )? ( ';' )? - @state.following.push( TOKENS_FOLLOWING_category_term_IN_category_value_78 ) + @state.following.push(TOKENS_FOLLOWING_category_term_IN_category_value_78) category_term3 = category_term @state.following.pop - @state.following.push( TOKENS_FOLLOWING_category_scheme_IN_category_value_80 ) + @state.following.push(TOKENS_FOLLOWING_category_scheme_IN_category_value_80) category_scheme4 = category_scheme @state.following.pop - @state.following.push( TOKENS_FOLLOWING_category_class_IN_category_value_82 ) + @state.following.push(TOKENS_FOLLOWING_category_class_IN_category_value_82) category_class2 = category_class @state.following.pop # at line 56:60: ( category_title )? alt_1 = 2 - look_1_0 = @input.peek( 1 ) + look_1_0 = @input.peek(1) - if ( look_1_0 == T__11 ) - look_1_1 = @input.peek( 2 ) + if (look_1_0 == T__11) + look_1_1 = @input.peek(2) - if ( look_1_1 == WS ) - look_1_3 = @input.peek( 3 ) + if (look_1_1 == WS) + look_1_3 = @input.peek(3) - if ( look_1_3 == T__16 ) + if (look_1_3 == T__16) alt_1 = 1 end - elsif ( look_1_1 == T__16 ) + elsif (look_1_1 == T__16) alt_1 = 1 end end case alt_1 - when 1 - # at line 56:60: category_title - @state.following.push( TOKENS_FOLLOWING_category_title_IN_category_value_84 ) - category_title5 = category_title - @state.following.pop + when 1 + # at line 56:60: category_title + @state.following.push(TOKENS_FOLLOWING_category_title_IN_category_value_84) + category_title5 = category_title + @state.following.pop end # at line 56:76: ( category_rel )? alt_2 = 2 - look_2_0 = @input.peek( 1 ) + look_2_0 = @input.peek(1) - if ( look_2_0 == T__11 ) - look_2_1 = @input.peek( 2 ) + if (look_2_0 == T__11) + look_2_1 = @input.peek(2) - if ( look_2_1 == WS ) - look_2_3 = @input.peek( 3 ) + if (look_2_1 == WS) + look_2_3 = @input.peek(3) - if ( look_2_3 == T__17 ) + if (look_2_3 == T__17) alt_2 = 1 end - elsif ( look_2_1 == T__17 ) + elsif (look_2_1 == T__17) alt_2 = 1 end end case alt_2 - when 1 - # at line 56:76: category_rel - @state.following.push( TOKENS_FOLLOWING_category_rel_IN_category_value_87 ) - category_rel6 = category_rel - @state.following.pop + when 1 + # at line 56:76: category_rel + @state.following.push(TOKENS_FOLLOWING_category_rel_IN_category_value_87) + category_rel6 = category_rel + @state.following.pop end # at line 56:90: ( category_location )? alt_3 = 2 - look_3_0 = @input.peek( 1 ) + look_3_0 = @input.peek(1) - if ( look_3_0 == T__11 ) - look_3_1 = @input.peek( 2 ) + if (look_3_0 == T__11) + look_3_1 = @input.peek(2) - if ( look_3_1 == WS ) - look_3_3 = @input.peek( 3 ) + if (look_3_1 == WS) + look_3_3 = @input.peek(3) - if ( look_3_3 == T__18 ) + if (look_3_3 == T__18) alt_3 = 1 end - elsif ( look_3_1 == T__18 ) + elsif (look_3_1 == T__18) alt_3 = 1 end end case alt_3 - when 1 - # at line 56:90: category_location - @state.following.push( TOKENS_FOLLOWING_category_location_IN_category_value_90 ) - category_location7 = category_location - @state.following.pop + when 1 + # at line 56:90: category_location + @state.following.push(TOKENS_FOLLOWING_category_location_IN_category_value_90) + category_location7 = category_location + @state.following.pop end # at line 56:109: ( category_attributes )? alt_4 = 2 - look_4_0 = @input.peek( 1 ) + look_4_0 = @input.peek(1) - if ( look_4_0 == T__11 ) - look_4_1 = @input.peek( 2 ) + if (look_4_0 == T__11) + look_4_1 = @input.peek(2) - if ( look_4_1 == WS ) - look_4_3 = @input.peek( 3 ) + if (look_4_1 == WS) + look_4_3 = @input.peek(3) - if ( look_4_3 == T__19 ) + if (look_4_3 == T__19) alt_4 = 1 end - elsif ( look_4_1 == T__19 ) + elsif (look_4_1 == T__19) alt_4 = 1 end end case alt_4 - when 1 - # at line 56:109: category_attributes - @state.following.push( TOKENS_FOLLOWING_category_attributes_IN_category_value_93 ) - category_attributes8 = category_attributes - @state.following.pop + when 1 + # at line 56:109: category_attributes + @state.following.push(TOKENS_FOLLOWING_category_attributes_IN_category_value_93) + category_attributes8 = category_attributes + @state.following.pop end # at line 56:130: ( category_actions )? alt_5 = 2 - look_5_0 = @input.peek( 1 ) + look_5_0 = @input.peek(1) - if ( look_5_0 == T__11 ) - look_5_1 = @input.peek( 2 ) + if (look_5_0 == T__11) + look_5_1 = @input.peek(2) - if ( look_5_1 == WS || look_5_1 == T__20 ) + if (look_5_1 == WS || look_5_1 == T__20) alt_5 = 1 end end case alt_5 - when 1 - # at line 56:130: category_actions - @state.following.push( TOKENS_FOLLOWING_category_actions_IN_category_value_96 ) - category_actions9 = category_actions - @state.following.pop + when 1 + # at line 56:130: category_actions + @state.following.push(TOKENS_FOLLOWING_category_actions_IN_category_value_96) + category_actions9 = category_actions + @state.following.pop end # at line 56:148: ( ';' )? alt_6 = 2 - look_6_0 = @input.peek( 1 ) + look_6_0 = @input.peek(1) - if ( look_6_0 == T__11 ) + if (look_6_0 == T__11) alt_6 = 1 end case alt_6 - when 1 - # at line 56:148: ';' - match( T__11, TOKENS_FOLLOWING_T__11_IN_category_value_99 ) + when 1 + # at line 56:148: ';' + match(T__11, TOKENS_FOLLOWING_T__11_IN_category_value_99) end # --> action - type = category_class2 - cat = Hashie::Mash.new - cat.term = category_term3 - cat.scheme = category_scheme4 - cat.type_identifier = cat.scheme + cat.term - cat.title = category_title5 - cat.related = category_rel6 - cat.location = category_location7 - cat.attributes = category_attributes8 - cat.actions = category_actions9 - mash[(type+'s').to_sym] << cat - - # <-- action + type = category_class2 + cat = Hashie::Mash.new + cat.term = category_term3 + cat.scheme = category_scheme4 + cat.title = category_title5 + cat.related = category_rel6 + cat.location = category_location7 + cat.attributes = category_attributes8 + cat.actions = category_actions9 + hash[(type+'s').to_sym] << cat + + # <-- action rescue ANTLR3::Error::RecognitionError => re report_error(re) @@ -358,8 +358,8 @@ def category_value # trace_out( __method__, 2 ) end - - return mash + + return hash end @@ -367,7 +367,7 @@ def category_value # parser rule category_term # # (in OCCI.g) - # 69:3: category_term returns [value] : ( WS )? term ; + # 68:3: category_term returns [value] : ( WS )? term ; # def category_term # -> uncomment the next line to manually enable rule tracing @@ -376,26 +376,26 @@ def category_term term10 = nil begin - # at line 69:37: ( WS )? term - # at line 69:37: ( WS )? + # at line 68:37: ( WS )? term + # at line 68:37: ( WS )? alt_7 = 2 - look_7_0 = @input.peek( 1 ) + look_7_0 = @input.peek(1) - if ( look_7_0 == WS ) + if (look_7_0 == WS) alt_7 = 1 end case alt_7 - when 1 - # at line 69:37: WS - match( WS, TOKENS_FOLLOWING_WS_IN_category_term_131 ) + when 1 + # at line 68:37: WS + match(WS, TOKENS_FOLLOWING_WS_IN_category_term_131) end - @state.following.push( TOKENS_FOLLOWING_term_IN_category_term_134 ) + @state.following.push(TOKENS_FOLLOWING_term_IN_category_term_134) term10 = term @state.following.pop # --> action - value = ( term10 && @input.to_s( term10.start, term10.stop ) ) - # <-- action + value = (term10 && @input.to_s(term10.start, term10.stop)) + # <-- action rescue ANTLR3::Error::RecognitionError => re report_error(re) @@ -406,7 +406,7 @@ def category_term # trace_out( __method__, 3 ) end - + return value end @@ -415,7 +415,7 @@ def category_term # parser rule category_scheme # # (in OCCI.g) - # 71:3: category_scheme returns [value] : ';' ( WS )? 'scheme' '=' '\"' scheme '\"' ; + # 70:3: category_scheme returns [value] : ';' ( WS )? 'scheme' '=' '\"' scheme '\"' ; # def category_scheme # -> uncomment the next line to manually enable rule tracing @@ -424,31 +424,31 @@ def category_scheme scheme11 = nil begin - # at line 71:37: ';' ( WS )? 'scheme' '=' '\"' scheme '\"' - match( T__11, TOKENS_FOLLOWING_T__11_IN_category_scheme_160 ) - # at line 71:41: ( WS )? + # at line 70:37: ';' ( WS )? 'scheme' '=' '\"' scheme '\"' + match(T__11, TOKENS_FOLLOWING_T__11_IN_category_scheme_160) + # at line 70:41: ( WS )? alt_8 = 2 - look_8_0 = @input.peek( 1 ) + look_8_0 = @input.peek(1) - if ( look_8_0 == WS ) + if (look_8_0 == WS) alt_8 = 1 end case alt_8 - when 1 - # at line 71:41: WS - match( WS, TOKENS_FOLLOWING_WS_IN_category_scheme_162 ) + when 1 + # at line 70:41: WS + match(WS, TOKENS_FOLLOWING_WS_IN_category_scheme_162) end - match( T__12, TOKENS_FOLLOWING_T__12_IN_category_scheme_165 ) - match( T__13, TOKENS_FOLLOWING_T__13_IN_category_scheme_167 ) - match( T__14, TOKENS_FOLLOWING_T__14_IN_category_scheme_169 ) - @state.following.push( TOKENS_FOLLOWING_scheme_IN_category_scheme_171 ) + match(T__12, TOKENS_FOLLOWING_T__12_IN_category_scheme_165) + match(T__13, TOKENS_FOLLOWING_T__13_IN_category_scheme_167) + match(T__14, TOKENS_FOLLOWING_T__14_IN_category_scheme_169) + @state.following.push(TOKENS_FOLLOWING_scheme_IN_category_scheme_171) scheme11 = scheme @state.following.pop - match( T__14, TOKENS_FOLLOWING_T__14_IN_category_scheme_173 ) + match(T__14, TOKENS_FOLLOWING_T__14_IN_category_scheme_173) # --> action - value = ( scheme11 && @input.to_s( scheme11.start, scheme11.stop ) ) - # <-- action + value = (scheme11 && @input.to_s(scheme11.start, scheme11.stop)) + # <-- action rescue ANTLR3::Error::RecognitionError => re report_error(re) @@ -459,7 +459,7 @@ def category_scheme # trace_out( __method__, 4 ) end - + return value end @@ -468,7 +468,7 @@ def category_scheme # parser rule category_class # # (in OCCI.g) - # 73:3: category_class returns [value] : ';' ( WS )? 'class' '=' '\"' class_type '\"' ; + # 72:3: category_class returns [value] : ';' ( WS )? 'class' '=' '\"' class_type '\"' ; # def category_class # -> uncomment the next line to manually enable rule tracing @@ -477,31 +477,31 @@ def category_class class_type12 = nil begin - # at line 73:37: ';' ( WS )? 'class' '=' '\"' class_type '\"' - match( T__11, TOKENS_FOLLOWING_T__11_IN_category_class_202 ) - # at line 73:41: ( WS )? + # at line 72:37: ';' ( WS )? 'class' '=' '\"' class_type '\"' + match(T__11, TOKENS_FOLLOWING_T__11_IN_category_class_202) + # at line 72:41: ( WS )? alt_9 = 2 - look_9_0 = @input.peek( 1 ) + look_9_0 = @input.peek(1) - if ( look_9_0 == WS ) + if (look_9_0 == WS) alt_9 = 1 end case alt_9 - when 1 - # at line 73:41: WS - match( WS, TOKENS_FOLLOWING_WS_IN_category_class_204 ) + when 1 + # at line 72:41: WS + match(WS, TOKENS_FOLLOWING_WS_IN_category_class_204) end - match( T__15, TOKENS_FOLLOWING_T__15_IN_category_class_207 ) - match( T__13, TOKENS_FOLLOWING_T__13_IN_category_class_209 ) - match( T__14, TOKENS_FOLLOWING_T__14_IN_category_class_211 ) - @state.following.push( TOKENS_FOLLOWING_class_type_IN_category_class_213 ) + match(T__15, TOKENS_FOLLOWING_T__15_IN_category_class_207) + match(T__13, TOKENS_FOLLOWING_T__13_IN_category_class_209) + match(T__14, TOKENS_FOLLOWING_T__14_IN_category_class_211) + @state.following.push(TOKENS_FOLLOWING_class_type_IN_category_class_213) class_type12 = class_type @state.following.pop - match( T__14, TOKENS_FOLLOWING_T__14_IN_category_class_215 ) + match(T__14, TOKENS_FOLLOWING_T__14_IN_category_class_215) # --> action - value = ( class_type12 && @input.to_s( class_type12.start, class_type12.stop ) ) - # <-- action + value = (class_type12 && @input.to_s(class_type12.start, class_type12.stop)) + # <-- action rescue ANTLR3::Error::RecognitionError => re report_error(re) @@ -512,7 +512,7 @@ def category_class # trace_out( __method__, 5 ) end - + return value end @@ -521,7 +521,7 @@ def category_class # parser rule category_title # # (in OCCI.g) - # 75:3: category_title returns [value] : ';' ( WS )? 'title' '=' '\"' title '\"' ; + # 74:3: category_title returns [value] : ';' ( WS )? 'title' '=' '\"' title '\"' ; # def category_title # -> uncomment the next line to manually enable rule tracing @@ -530,31 +530,31 @@ def category_title title13 = nil begin - # at line 75:37: ';' ( WS )? 'title' '=' '\"' title '\"' - match( T__11, TOKENS_FOLLOWING_T__11_IN_category_title_240 ) - # at line 75:41: ( WS )? + # at line 74:37: ';' ( WS )? 'title' '=' '\"' title '\"' + match(T__11, TOKENS_FOLLOWING_T__11_IN_category_title_240) + # at line 74:41: ( WS )? alt_10 = 2 - look_10_0 = @input.peek( 1 ) + look_10_0 = @input.peek(1) - if ( look_10_0 == WS ) + if (look_10_0 == WS) alt_10 = 1 end case alt_10 - when 1 - # at line 75:41: WS - match( WS, TOKENS_FOLLOWING_WS_IN_category_title_242 ) + when 1 + # at line 74:41: WS + match(WS, TOKENS_FOLLOWING_WS_IN_category_title_242) end - match( T__16, TOKENS_FOLLOWING_T__16_IN_category_title_245 ) - match( T__13, TOKENS_FOLLOWING_T__13_IN_category_title_247 ) - match( T__14, TOKENS_FOLLOWING_T__14_IN_category_title_249 ) - @state.following.push( TOKENS_FOLLOWING_title_IN_category_title_251 ) + match(T__16, TOKENS_FOLLOWING_T__16_IN_category_title_245) + match(T__13, TOKENS_FOLLOWING_T__13_IN_category_title_247) + match(T__14, TOKENS_FOLLOWING_T__14_IN_category_title_249) + @state.following.push(TOKENS_FOLLOWING_title_IN_category_title_251) title13 = title @state.following.pop - match( T__14, TOKENS_FOLLOWING_T__14_IN_category_title_253 ) + match(T__14, TOKENS_FOLLOWING_T__14_IN_category_title_253) # --> action - value = ( title13 && @input.to_s( title13.start, title13.stop ) ) - # <-- action + value = (title13 && @input.to_s(title13.start, title13.stop)) + # <-- action rescue ANTLR3::Error::RecognitionError => re report_error(re) @@ -565,7 +565,7 @@ def category_title # trace_out( __method__, 6 ) end - + return value end @@ -574,7 +574,7 @@ def category_title # parser rule category_rel # # (in OCCI.g) - # 77:3: category_rel returns [value] : ';' ( WS )? 'rel' '=' '\"' rel '\"' ; + # 76:3: category_rel returns [value] : ';' ( WS )? 'rel' '=' '\"' rel '\"' ; # def category_rel # -> uncomment the next line to manually enable rule tracing @@ -583,31 +583,31 @@ def category_rel rel14 = nil begin - # at line 77:35: ';' ( WS )? 'rel' '=' '\"' rel '\"' - match( T__11, TOKENS_FOLLOWING_T__11_IN_category_rel_280 ) - # at line 77:39: ( WS )? + # at line 76:35: ';' ( WS )? 'rel' '=' '\"' rel '\"' + match(T__11, TOKENS_FOLLOWING_T__11_IN_category_rel_280) + # at line 76:39: ( WS )? alt_11 = 2 - look_11_0 = @input.peek( 1 ) + look_11_0 = @input.peek(1) - if ( look_11_0 == WS ) + if (look_11_0 == WS) alt_11 = 1 end case alt_11 - when 1 - # at line 77:39: WS - match( WS, TOKENS_FOLLOWING_WS_IN_category_rel_282 ) + when 1 + # at line 76:39: WS + match(WS, TOKENS_FOLLOWING_WS_IN_category_rel_282) end - match( T__17, TOKENS_FOLLOWING_T__17_IN_category_rel_285 ) - match( T__13, TOKENS_FOLLOWING_T__13_IN_category_rel_287 ) - match( T__14, TOKENS_FOLLOWING_T__14_IN_category_rel_289 ) - @state.following.push( TOKENS_FOLLOWING_rel_IN_category_rel_291 ) + match(T__17, TOKENS_FOLLOWING_T__17_IN_category_rel_285) + match(T__13, TOKENS_FOLLOWING_T__13_IN_category_rel_287) + match(T__14, TOKENS_FOLLOWING_T__14_IN_category_rel_289) + @state.following.push(TOKENS_FOLLOWING_rel_IN_category_rel_291) rel14 = rel @state.following.pop - match( T__14, TOKENS_FOLLOWING_T__14_IN_category_rel_293 ) + match(T__14, TOKENS_FOLLOWING_T__14_IN_category_rel_293) # --> action - value = ( rel14 && @input.to_s( rel14.start, rel14.stop ) ) - # <-- action + value = (rel14 && @input.to_s(rel14.start, rel14.stop)) + # <-- action rescue ANTLR3::Error::RecognitionError => re report_error(re) @@ -618,7 +618,7 @@ def category_rel # trace_out( __method__, 7 ) end - + return value end @@ -627,7 +627,7 @@ def category_rel # parser rule category_location # # (in OCCI.g) - # 79:3: category_location returns [value] : ';' ( WS )? 'location' '=' '\"' location '\"' ; + # 78:3: category_location returns [value] : ';' ( WS )? 'location' '=' '\"' location '\"' ; # def category_location # -> uncomment the next line to manually enable rule tracing @@ -636,31 +636,31 @@ def category_location location15 = nil begin - # at line 79:39: ';' ( WS )? 'location' '=' '\"' location '\"' - match( T__11, TOKENS_FOLLOWING_T__11_IN_category_location_318 ) - # at line 79:43: ( WS )? + # at line 78:39: ';' ( WS )? 'location' '=' '\"' location '\"' + match(T__11, TOKENS_FOLLOWING_T__11_IN_category_location_318) + # at line 78:43: ( WS )? alt_12 = 2 - look_12_0 = @input.peek( 1 ) + look_12_0 = @input.peek(1) - if ( look_12_0 == WS ) + if (look_12_0 == WS) alt_12 = 1 end case alt_12 - when 1 - # at line 79:43: WS - match( WS, TOKENS_FOLLOWING_WS_IN_category_location_320 ) + when 1 + # at line 78:43: WS + match(WS, TOKENS_FOLLOWING_WS_IN_category_location_320) end - match( T__18, TOKENS_FOLLOWING_T__18_IN_category_location_323 ) - match( T__13, TOKENS_FOLLOWING_T__13_IN_category_location_325 ) - match( T__14, TOKENS_FOLLOWING_T__14_IN_category_location_327 ) - @state.following.push( TOKENS_FOLLOWING_location_IN_category_location_329 ) + match(T__18, TOKENS_FOLLOWING_T__18_IN_category_location_323) + match(T__13, TOKENS_FOLLOWING_T__13_IN_category_location_325) + match(T__14, TOKENS_FOLLOWING_T__14_IN_category_location_327) + @state.following.push(TOKENS_FOLLOWING_location_IN_category_location_329) location15 = location @state.following.pop - match( T__14, TOKENS_FOLLOWING_T__14_IN_category_location_331 ) + match(T__14, TOKENS_FOLLOWING_T__14_IN_category_location_331) # --> action - value = ( location15 && @input.to_s( location15.start, location15.stop ) ) - # <-- action + value = (location15 && @input.to_s(location15.start, location15.stop)) + # <-- action rescue ANTLR3::Error::RecognitionError => re report_error(re) @@ -671,7 +671,7 @@ def category_location # trace_out( __method__, 8 ) end - + return value end @@ -680,79 +680,79 @@ def category_location # parser rule category_attributes # # (in OCCI.g) - # 81:3: category_attributes returns [mash] : ';' ( WS )? 'attributes' '=' '\"' attr= attribute_name ( ( WS )? next_attr= attribute_name )* '\"' ; + # 80:3: category_attributes returns [hash] : ';' ( WS )? 'attributes' '=' '\"' attr= attribute_name ( ( WS )? next_attr= attribute_name )* '\"' ; # def category_attributes # -> uncomment the next line to manually enable rule tracing # trace_in( __method__, 9 ) - mash = nil + hash = nil attr = nil next_attr = nil # - - - - @init action - - - - - mash = Hashie::Mash.new + hash = Hashie::Mash.new begin - # at line 82:10: ';' ( WS )? 'attributes' '=' '\"' attr= attribute_name ( ( WS )? next_attr= attribute_name )* '\"' - match( T__11, TOKENS_FOLLOWING_T__11_IN_category_attributes_370 ) - # at line 82:14: ( WS )? + # at line 81:10: ';' ( WS )? 'attributes' '=' '\"' attr= attribute_name ( ( WS )? next_attr= attribute_name )* '\"' + match(T__11, TOKENS_FOLLOWING_T__11_IN_category_attributes_370) + # at line 81:14: ( WS )? alt_13 = 2 - look_13_0 = @input.peek( 1 ) + look_13_0 = @input.peek(1) - if ( look_13_0 == WS ) + if (look_13_0 == WS) alt_13 = 1 end case alt_13 - when 1 - # at line 82:14: WS - match( WS, TOKENS_FOLLOWING_WS_IN_category_attributes_372 ) + when 1 + # at line 81:14: WS + match(WS, TOKENS_FOLLOWING_WS_IN_category_attributes_372) end - match( T__19, TOKENS_FOLLOWING_T__19_IN_category_attributes_375 ) - match( T__13, TOKENS_FOLLOWING_T__13_IN_category_attributes_377 ) - match( T__14, TOKENS_FOLLOWING_T__14_IN_category_attributes_379 ) - @state.following.push( TOKENS_FOLLOWING_attribute_name_IN_category_attributes_383 ) + match(T__19, TOKENS_FOLLOWING_T__19_IN_category_attributes_375) + match(T__13, TOKENS_FOLLOWING_T__13_IN_category_attributes_377) + match(T__14, TOKENS_FOLLOWING_T__14_IN_category_attributes_379) + @state.following.push(TOKENS_FOLLOWING_attribute_name_IN_category_attributes_383) attr = attribute_name @state.following.pop # --> action - mash.merge!(attr) + hash.merge!(attr) # <-- action - # at line 83:10: ( ( WS )? next_attr= attribute_name )* + # at line 82:10: ( ( WS )? next_attr= attribute_name )* while true # decision 15 alt_15 = 2 - look_15_0 = @input.peek( 1 ) + look_15_0 = @input.peek(1) - if ( look_15_0.between?( WS, LOALPHA ) ) + if (look_15_0.between?(WS, LOALPHA)) alt_15 = 1 end case alt_15 - when 1 - # at line 83:12: ( WS )? next_attr= attribute_name - # at line 83:12: ( WS )? - alt_14 = 2 - look_14_0 = @input.peek( 1 ) - - if ( look_14_0 == WS ) - alt_14 = 1 - end - case alt_14 when 1 - # at line 83:12: WS - match( WS, TOKENS_FOLLOWING_WS_IN_category_attributes_399 ) + # at line 82:12: ( WS )? next_attr= attribute_name + # at line 82:12: ( WS )? + alt_14 = 2 + look_14_0 = @input.peek(1) - end - @state.following.push( TOKENS_FOLLOWING_attribute_name_IN_category_attributes_404 ) - next_attr = attribute_name - @state.following.pop - # --> action - mash.merge!(next_attr) + if (look_14_0 == WS) + alt_14 = 1 + end + case alt_14 + when 1 + # at line 82:12: WS + match(WS, TOKENS_FOLLOWING_WS_IN_category_attributes_398) + + end + @state.following.push(TOKENS_FOLLOWING_attribute_name_IN_category_attributes_403) + next_attr = attribute_name + @state.following.pop + # --> action + hash.merge!(next_attr) # <-- action - else - break # out of loop for decision 15 + else + break # out of loop for decision 15 end end # loop for decision 15 - match( T__14, TOKENS_FOLLOWING_T__14_IN_category_attributes_412 ) + match(T__14, TOKENS_FOLLOWING_T__14_IN_category_attributes_411) rescue ANTLR3::Error::RecognitionError => re report_error(re) @@ -763,8 +763,8 @@ def category_attributes # trace_out( __method__, 9 ) end - - return mash + + return hash end @@ -772,7 +772,7 @@ def category_attributes # parser rule category_actions # # (in OCCI.g) - # 84:3: category_actions returns [array] : ';' ( WS )? 'actions' '=' '\"' act= action_location ( ( WS )? next_act= action_location )* '\"' ; + # 83:3: category_actions returns [array] : ';' ( WS )? 'actions' '=' '\"' act= action_location ( ( WS )? next_act= action_location )* '\"' ; # def category_actions # -> uncomment the next line to manually enable rule tracing @@ -784,67 +784,67 @@ def category_actions array = Array.new begin - # at line 85:10: ';' ( WS )? 'actions' '=' '\"' act= action_location ( ( WS )? next_act= action_location )* '\"' - match( T__11, TOKENS_FOLLOWING_T__11_IN_category_actions_442 ) - # at line 85:14: ( WS )? + # at line 84:10: ';' ( WS )? 'actions' '=' '\"' act= action_location ( ( WS )? next_act= action_location )* '\"' + match(T__11, TOKENS_FOLLOWING_T__11_IN_category_actions_441) + # at line 84:14: ( WS )? alt_16 = 2 - look_16_0 = @input.peek( 1 ) + look_16_0 = @input.peek(1) - if ( look_16_0 == WS ) + if (look_16_0 == WS) alt_16 = 1 end case alt_16 - when 1 - # at line 85:14: WS - match( WS, TOKENS_FOLLOWING_WS_IN_category_actions_444 ) + when 1 + # at line 84:14: WS + match(WS, TOKENS_FOLLOWING_WS_IN_category_actions_443) end - match( T__20, TOKENS_FOLLOWING_T__20_IN_category_actions_447 ) - match( T__13, TOKENS_FOLLOWING_T__13_IN_category_actions_449 ) - match( T__14, TOKENS_FOLLOWING_T__14_IN_category_actions_451 ) - @state.following.push( TOKENS_FOLLOWING_action_location_IN_category_actions_455 ) + match(T__20, TOKENS_FOLLOWING_T__20_IN_category_actions_446) + match(T__13, TOKENS_FOLLOWING_T__13_IN_category_actions_448) + match(T__14, TOKENS_FOLLOWING_T__14_IN_category_actions_450) + @state.following.push(TOKENS_FOLLOWING_action_location_IN_category_actions_454) act = action_location @state.following.pop # --> action - array << ( act && @input.to_s( act.start, act.stop ) ) + array << (act && @input.to_s(act.start, act.stop)) # <-- action - # at line 86:10: ( ( WS )? next_act= action_location )* + # at line 85:10: ( ( WS )? next_act= action_location )* while true # decision 18 alt_18 = 2 - look_18_0 = @input.peek( 1 ) + look_18_0 = @input.peek(1) - if ( look_18_0.between?( WS, DIGIT ) || look_18_0 == T__10 || look_18_0 == T__13 || look_18_0.between?( T__28, T__42 ) ) + if (look_18_0.between?(WS, DIGIT) || look_18_0 == T__10 || look_18_0 == T__13 || look_18_0.between?(T__28, T__42)) alt_18 = 1 end case alt_18 - when 1 - # at line 86:12: ( WS )? next_act= action_location - # at line 86:12: ( WS )? - alt_17 = 2 - look_17_0 = @input.peek( 1 ) - - if ( look_17_0 == WS ) - alt_17 = 1 - end - case alt_17 when 1 - # at line 86:12: WS - match( WS, TOKENS_FOLLOWING_WS_IN_category_actions_471 ) + # at line 85:12: ( WS )? next_act= action_location + # at line 85:12: ( WS )? + alt_17 = 2 + look_17_0 = @input.peek(1) - end - @state.following.push( TOKENS_FOLLOWING_action_location_IN_category_actions_476 ) - next_act = action_location - @state.following.pop - # --> action - array << ( next_act && @input.to_s( next_act.start, next_act.stop ) ) + if (look_17_0 == WS) + alt_17 = 1 + end + case alt_17 + when 1 + # at line 85:12: WS + match(WS, TOKENS_FOLLOWING_WS_IN_category_actions_470) + + end + @state.following.push(TOKENS_FOLLOWING_action_location_IN_category_actions_475) + next_act = action_location + @state.following.pop + # --> action + array << (next_act && @input.to_s(next_act.start, next_act.stop)) # <-- action - else - break # out of loop for decision 18 + else + break # out of loop for decision 18 end end # loop for decision 18 - match( T__14, TOKENS_FOLLOWING_T__14_IN_category_actions_483 ) + match(T__14, TOKENS_FOLLOWING_T__14_IN_category_actions_482) rescue ANTLR3::Error::RecognitionError => re report_error(re) @@ -855,7 +855,7 @@ def category_actions # trace_out( __method__, 10 ) end - + return array end @@ -864,26 +864,24 @@ def category_actions # parser rule link # # (in OCCI.g) - # 97:1: link returns [mash] : 'Link' ':' link_value ; + # 96:1: link returns [hash] : 'Link' ':' link_value ; # def link # -> uncomment the next line to manually enable rule tracing # trace_in( __method__, 11 ) - mash = nil + hash = nil link_value16 = nil - # - - - - @init action - - - - - mash = Hashie::Mash.new begin - # at line 99:4: 'Link' ':' link_value - match( T__21, TOKENS_FOLLOWING_T__21_IN_link_505 ) - match( T__10, TOKENS_FOLLOWING_T__10_IN_link_507 ) - @state.following.push( TOKENS_FOLLOWING_link_value_IN_link_509 ) + # at line 97:4: 'Link' ':' link_value + match(T__21, TOKENS_FOLLOWING_T__21_IN_link_499) + match(T__10, TOKENS_FOLLOWING_T__10_IN_link_501) + @state.following.push(TOKENS_FOLLOWING_link_value_IN_link_503) link_value16 = link_value @state.following.pop # --> action - mash = link_value16 - # <-- action + hash = link_value16 + # <-- action rescue ANTLR3::Error::RecognitionError => re report_error(re) @@ -894,8 +892,8 @@ def link # trace_out( __method__, 11 ) end - - return mash + + return hash end @@ -903,107 +901,107 @@ def link # parser rule link_value # # (in OCCI.g) - # 100:2: link_value returns [mash] : link_target link_rel ( link_self )? ( link_category )? link_attributes ( ';' )? ; + # 98:2: link_value returns [hash] : link_target link_rel ( link_self )? ( link_category )? link_attributes ( ';' )? ; # def link_value # -> uncomment the next line to manually enable rule tracing # trace_in( __method__, 12 ) - mash = nil + hash = nil link_target17 = nil link_rel18 = nil link_self19 = nil link_category20 = nil link_attributes21 = nil # - - - - @init action - - - - - mash = Hashie::Mash.new + hash = Hashie::Mash.new begin - # at line 102:6: link_target link_rel ( link_self )? ( link_category )? link_attributes ( ';' )? - @state.following.push( TOKENS_FOLLOWING_link_target_IN_link_value_531 ) + # at line 100:6: link_target link_rel ( link_self )? ( link_category )? link_attributes ( ';' )? + @state.following.push(TOKENS_FOLLOWING_link_target_IN_link_value_525) link_target17 = link_target @state.following.pop # --> action - mash[:target] = link_target17 + hash[:target] = link_target17 # <-- action - @state.following.push( TOKENS_FOLLOWING_link_rel_IN_link_value_540 ) + @state.following.push(TOKENS_FOLLOWING_link_rel_IN_link_value_534) link_rel18 = link_rel @state.following.pop # --> action - mash[:rel] = link_rel18 + hash[:rel] = link_rel18 # <-- action - # at line 104:6: ( link_self )? + # at line 102:6: ( link_self )? alt_19 = 2 - look_19_0 = @input.peek( 1 ) + look_19_0 = @input.peek(1) - if ( look_19_0 == T__11 ) - look_19_1 = @input.peek( 2 ) + if (look_19_0 == T__11) + look_19_1 = @input.peek(2) - if ( look_19_1 == WS ) - look_19_3 = @input.peek( 3 ) + if (look_19_1 == WS) + look_19_3 = @input.peek(3) - if ( look_19_3 == T__24 ) + if (look_19_3 == T__24) alt_19 = 1 end - elsif ( look_19_1 == T__24 ) + elsif (look_19_1 == T__24) alt_19 = 1 end end case alt_19 - when 1 - # at line 104:6: link_self - @state.following.push( TOKENS_FOLLOWING_link_self_IN_link_value_549 ) - link_self19 = link_self - @state.following.pop + when 1 + # at line 102:6: link_self + @state.following.push(TOKENS_FOLLOWING_link_self_IN_link_value_543) + link_self19 = link_self + @state.following.pop end # --> action - mash[:self] = link_self19 + hash[:self] = link_self19 # <-- action - # at line 105:6: ( link_category )? + # at line 103:6: ( link_category )? alt_20 = 2 - look_20_0 = @input.peek( 1 ) + look_20_0 = @input.peek(1) - if ( look_20_0 == T__11 ) - look_20_1 = @input.peek( 2 ) + if (look_20_0 == T__11) + look_20_1 = @input.peek(2) - if ( look_20_1 == WS ) - look_20_3 = @input.peek( 3 ) + if (look_20_1 == WS) + look_20_3 = @input.peek(3) - if ( look_20_3 == T__25 ) + if (look_20_3 == T__25) alt_20 = 1 end - elsif ( look_20_1 == T__25 ) + elsif (look_20_1 == T__25) alt_20 = 1 end end case alt_20 - when 1 - # at line 105:6: link_category - @state.following.push( TOKENS_FOLLOWING_link_category_IN_link_value_559 ) - link_category20 = link_category - @state.following.pop + when 1 + # at line 103:6: link_category + @state.following.push(TOKENS_FOLLOWING_link_category_IN_link_value_553) + link_category20 = link_category + @state.following.pop end # --> action - mash[:category] = link_category20 + hash[:category] = link_category20 # <-- action - @state.following.push( TOKENS_FOLLOWING_link_attributes_IN_link_value_569 ) + @state.following.push(TOKENS_FOLLOWING_link_attributes_IN_link_value_563) link_attributes21 = link_attributes @state.following.pop # --> action - mash[:attributes] = link_attributes21 + hash[:attributes] = link_attributes21 # <-- action - # at line 107:6: ( ';' )? + # at line 105:6: ( ';' )? alt_21 = 2 - look_21_0 = @input.peek( 1 ) + look_21_0 = @input.peek(1) - if ( look_21_0 == T__11 ) + if (look_21_0 == T__11) alt_21 = 1 end case alt_21 - when 1 - # at line 107:6: ';' - match( T__11, TOKENS_FOLLOWING_T__11_IN_link_value_578 ) + when 1 + # at line 105:6: ';' + match(T__11, TOKENS_FOLLOWING_T__11_IN_link_value_572) end @@ -1016,8 +1014,8 @@ def link_value # trace_out( __method__, 12 ) end - - return mash + + return hash end @@ -1025,7 +1023,7 @@ def link_value # parser rule link_target # # (in OCCI.g) - # 109:2: link_target returns [value] : ( WS )? '<' target '>' ; + # 107:2: link_target returns [value] : ( WS )? '<' target '>' ; # def link_target # -> uncomment the next line to manually enable rule tracing @@ -1034,28 +1032,28 @@ def link_target target22 = nil begin - # at line 109:32: ( WS )? '<' target '>' - # at line 109:32: ( WS )? + # at line 107:32: ( WS )? '<' target '>' + # at line 107:32: ( WS )? alt_22 = 2 - look_22_0 = @input.peek( 1 ) + look_22_0 = @input.peek(1) - if ( look_22_0 == WS ) + if (look_22_0 == WS) alt_22 = 1 end case alt_22 - when 1 - # at line 109:32: WS - match( WS, TOKENS_FOLLOWING_WS_IN_link_target_597 ) + when 1 + # at line 107:32: WS + match(WS, TOKENS_FOLLOWING_WS_IN_link_target_591) end - match( T__22, TOKENS_FOLLOWING_T__22_IN_link_target_600 ) - @state.following.push( TOKENS_FOLLOWING_target_IN_link_target_602 ) + match(T__22, TOKENS_FOLLOWING_T__22_IN_link_target_594) + @state.following.push(TOKENS_FOLLOWING_target_IN_link_target_596) target22 = target @state.following.pop - match( T__23, TOKENS_FOLLOWING_T__23_IN_link_target_604 ) + match(T__23, TOKENS_FOLLOWING_T__23_IN_link_target_598) # --> action - value = ( target22 && @input.to_s( target22.start, target22.stop ) ) - # <-- action + value = (target22 && @input.to_s(target22.start, target22.stop)) + # <-- action rescue ANTLR3::Error::RecognitionError => re report_error(re) @@ -1066,7 +1064,7 @@ def link_target # trace_out( __method__, 13 ) end - + return value end @@ -1075,7 +1073,7 @@ def link_target # parser rule link_rel # # (in OCCI.g) - # 110:2: link_rel returns [value] : ';' ( WS )? 'rel' '=' '\"' rel '\"' ; + # 108:2: link_rel returns [value] : ';' ( WS )? 'rel' '=' '\"' rel '\"' ; # def link_rel # -> uncomment the next line to manually enable rule tracing @@ -1084,31 +1082,31 @@ def link_rel rel23 = nil begin - # at line 110:30: ';' ( WS )? 'rel' '=' '\"' rel '\"' - match( T__11, TOKENS_FOLLOWING_T__11_IN_link_rel_619 ) - # at line 110:34: ( WS )? + # at line 108:30: ';' ( WS )? 'rel' '=' '\"' rel '\"' + match(T__11, TOKENS_FOLLOWING_T__11_IN_link_rel_613) + # at line 108:34: ( WS )? alt_23 = 2 - look_23_0 = @input.peek( 1 ) + look_23_0 = @input.peek(1) - if ( look_23_0 == WS ) + if (look_23_0 == WS) alt_23 = 1 end case alt_23 - when 1 - # at line 110:34: WS - match( WS, TOKENS_FOLLOWING_WS_IN_link_rel_621 ) + when 1 + # at line 108:34: WS + match(WS, TOKENS_FOLLOWING_WS_IN_link_rel_615) end - match( T__17, TOKENS_FOLLOWING_T__17_IN_link_rel_624 ) - match( T__13, TOKENS_FOLLOWING_T__13_IN_link_rel_626 ) - match( T__14, TOKENS_FOLLOWING_T__14_IN_link_rel_628 ) - @state.following.push( TOKENS_FOLLOWING_rel_IN_link_rel_630 ) + match(T__17, TOKENS_FOLLOWING_T__17_IN_link_rel_618) + match(T__13, TOKENS_FOLLOWING_T__13_IN_link_rel_620) + match(T__14, TOKENS_FOLLOWING_T__14_IN_link_rel_622) + @state.following.push(TOKENS_FOLLOWING_rel_IN_link_rel_624) rel23 = rel @state.following.pop - match( T__14, TOKENS_FOLLOWING_T__14_IN_link_rel_632 ) + match(T__14, TOKENS_FOLLOWING_T__14_IN_link_rel_626) # --> action - value = ( rel23 && @input.to_s( rel23.start, rel23.stop ) ) - # <-- action + value = (rel23 && @input.to_s(rel23.start, rel23.stop)) + # <-- action rescue ANTLR3::Error::RecognitionError => re report_error(re) @@ -1119,7 +1117,7 @@ def link_rel # trace_out( __method__, 14 ) end - + return value end @@ -1128,7 +1126,7 @@ def link_rel # parser rule link_self # # (in OCCI.g) - # 111:2: link_self returns [value] : ';' ( WS )? 'self' '=' '\"' self_location '\"' ; + # 109:2: link_self returns [value] : ';' ( WS )? 'self' '=' '\"' self_location '\"' ; # def link_self # -> uncomment the next line to manually enable rule tracing @@ -1137,31 +1135,31 @@ def link_self self_location24 = nil begin - # at line 111:31: ';' ( WS )? 'self' '=' '\"' self_location '\"' - match( T__11, TOKENS_FOLLOWING_T__11_IN_link_self_647 ) - # at line 111:35: ( WS )? + # at line 109:31: ';' ( WS )? 'self' '=' '\"' self_location '\"' + match(T__11, TOKENS_FOLLOWING_T__11_IN_link_self_641) + # at line 109:35: ( WS )? alt_24 = 2 - look_24_0 = @input.peek( 1 ) + look_24_0 = @input.peek(1) - if ( look_24_0 == WS ) + if (look_24_0 == WS) alt_24 = 1 end case alt_24 - when 1 - # at line 111:35: WS - match( WS, TOKENS_FOLLOWING_WS_IN_link_self_649 ) + when 1 + # at line 109:35: WS + match(WS, TOKENS_FOLLOWING_WS_IN_link_self_643) end - match( T__24, TOKENS_FOLLOWING_T__24_IN_link_self_652 ) - match( T__13, TOKENS_FOLLOWING_T__13_IN_link_self_654 ) - match( T__14, TOKENS_FOLLOWING_T__14_IN_link_self_656 ) - @state.following.push( TOKENS_FOLLOWING_self_location_IN_link_self_658 ) + match(T__24, TOKENS_FOLLOWING_T__24_IN_link_self_646) + match(T__13, TOKENS_FOLLOWING_T__13_IN_link_self_648) + match(T__14, TOKENS_FOLLOWING_T__14_IN_link_self_650) + @state.following.push(TOKENS_FOLLOWING_self_location_IN_link_self_652) self_location24 = self_location @state.following.pop - match( T__14, TOKENS_FOLLOWING_T__14_IN_link_self_660 ) + match(T__14, TOKENS_FOLLOWING_T__14_IN_link_self_654) # --> action - value = ( self_location24 && @input.to_s( self_location24.start, self_location24.stop ) ) - # <-- action + value = (self_location24 && @input.to_s(self_location24.start, self_location24.stop)) + # <-- action rescue ANTLR3::Error::RecognitionError => re report_error(re) @@ -1172,7 +1170,7 @@ def link_self # trace_out( __method__, 15 ) end - + return value end @@ -1181,7 +1179,7 @@ def link_self # parser rule link_category # # (in OCCI.g) - # 112:2: link_category returns [value] : ';' ( WS )? 'category' '=' '\"' category_name '\"' ; + # 110:2: link_category returns [value] : ';' ( WS )? 'category' '=' '\"' category_name '\"' ; # def link_category # -> uncomment the next line to manually enable rule tracing @@ -1190,31 +1188,31 @@ def link_category category_name25 = nil begin - # at line 112:35: ';' ( WS )? 'category' '=' '\"' category_name '\"' - match( T__11, TOKENS_FOLLOWING_T__11_IN_link_category_675 ) - # at line 112:39: ( WS )? + # at line 110:35: ';' ( WS )? 'category' '=' '\"' category_name '\"' + match(T__11, TOKENS_FOLLOWING_T__11_IN_link_category_669) + # at line 110:39: ( WS )? alt_25 = 2 - look_25_0 = @input.peek( 1 ) + look_25_0 = @input.peek(1) - if ( look_25_0 == WS ) + if (look_25_0 == WS) alt_25 = 1 end case alt_25 - when 1 - # at line 112:39: WS - match( WS, TOKENS_FOLLOWING_WS_IN_link_category_677 ) + when 1 + # at line 110:39: WS + match(WS, TOKENS_FOLLOWING_WS_IN_link_category_671) end - match( T__25, TOKENS_FOLLOWING_T__25_IN_link_category_680 ) - match( T__13, TOKENS_FOLLOWING_T__13_IN_link_category_682 ) - match( T__14, TOKENS_FOLLOWING_T__14_IN_link_category_684 ) - @state.following.push( TOKENS_FOLLOWING_category_name_IN_link_category_686 ) + match(T__25, TOKENS_FOLLOWING_T__25_IN_link_category_674) + match(T__13, TOKENS_FOLLOWING_T__13_IN_link_category_676) + match(T__14, TOKENS_FOLLOWING_T__14_IN_link_category_678) + @state.following.push(TOKENS_FOLLOWING_category_name_IN_link_category_680) category_name25 = category_name @state.following.pop - match( T__14, TOKENS_FOLLOWING_T__14_IN_link_category_688 ) + match(T__14, TOKENS_FOLLOWING_T__14_IN_link_category_682) # --> action - value = ( category_name25 && @input.to_s( category_name25.start, category_name25.stop ) ) - # <-- action + value = (category_name25 && @input.to_s(category_name25.start, category_name25.stop)) + # <-- action rescue ANTLR3::Error::RecognitionError => re report_error(re) @@ -1225,7 +1223,7 @@ def link_category # trace_out( __method__, 16 ) end - + return value end @@ -1234,58 +1232,58 @@ def link_category # parser rule link_attributes # # (in OCCI.g) - # 113:2: link_attributes returns [mash] : ( ';' ( WS )? attribute )* ; + # 111:2: link_attributes returns [hash] : ( ';' ( WS )? attribute )* ; # def link_attributes # -> uncomment the next line to manually enable rule tracing # trace_in( __method__, 17 ) - mash = nil + hash = nil attribute26 = nil # - - - - @init action - - - - - mash = Hashie::Mash.new + hash = Hashie::Mash.new begin - # at line 114:8: ( ';' ( WS )? attribute )* - # at line 114:8: ( ';' ( WS )? attribute )* + # at line 112:8: ( ';' ( WS )? attribute )* + # at line 112:8: ( ';' ( WS )? attribute )* while true # decision 27 alt_27 = 2 - look_27_0 = @input.peek( 1 ) + look_27_0 = @input.peek(1) - if ( look_27_0 == T__11 ) - look_27_1 = @input.peek( 2 ) + if (look_27_0 == T__11) + look_27_1 = @input.peek(2) - if ( look_27_1.between?( WS, LOALPHA ) ) + if (look_27_1.between?(WS, LOALPHA)) alt_27 = 1 end end case alt_27 - when 1 - # at line 114:9: ';' ( WS )? attribute - match( T__11, TOKENS_FOLLOWING_T__11_IN_link_attributes_714 ) - # at line 114:13: ( WS )? - alt_26 = 2 - look_26_0 = @input.peek( 1 ) - - if ( look_26_0 == WS ) - alt_26 = 1 - end - case alt_26 when 1 - # at line 114:13: WS - match( WS, TOKENS_FOLLOWING_WS_IN_link_attributes_716 ) + # at line 112:9: ';' ( WS )? attribute + match(T__11, TOKENS_FOLLOWING_T__11_IN_link_attributes_708) + # at line 112:13: ( WS )? + alt_26 = 2 + look_26_0 = @input.peek(1) + + if (look_26_0 == WS) + alt_26 = 1 + end + case alt_26 + when 1 + # at line 112:13: WS + match(WS, TOKENS_FOLLOWING_WS_IN_link_attributes_710) - end - @state.following.push( TOKENS_FOLLOWING_attribute_IN_link_attributes_719 ) - attribute26 = attribute - @state.following.pop - # --> action - mash.merge!(attribute26) + end + @state.following.push(TOKENS_FOLLOWING_attribute_IN_link_attributes_713) + attribute26 = attribute + @state.following.pop + # --> action + hash.merge!(attribute26) # <-- action - else - break # out of loop for decision 27 + else + break # out of loop for decision 27 end end # loop for decision 27 @@ -1298,8 +1296,8 @@ def link_attributes # trace_out( __method__, 17 ) end - - return mash + + return hash end @@ -1307,52 +1305,50 @@ def link_attributes # parser rule x_occi_attribute # # (in OCCI.g) - # 126:1: x_occi_attribute returns [mash] : 'X-OCCI-Attribute' ':' ( WS )? attribute ( ';' )? ; + # 124:1: x_occi_attribute returns [hash] : 'X-OCCI-Attribute' ':' ( WS )? attribute ( ';' )? ; # def x_occi_attribute # -> uncomment the next line to manually enable rule tracing # trace_in( __method__, 18 ) - mash = nil + hash = nil attribute27 = nil - # - - - - @init action - - - - - mash = Hashie::Mash.new begin - # at line 128:4: 'X-OCCI-Attribute' ':' ( WS )? attribute ( ';' )? - match( T__26, TOKENS_FOLLOWING_T__26_IN_x_occi_attribute_746 ) - match( T__10, TOKENS_FOLLOWING_T__10_IN_x_occi_attribute_748 ) - # at line 128:27: ( WS )? + # at line 125:4: 'X-OCCI-Attribute' ':' ( WS )? attribute ( ';' )? + match(T__26, TOKENS_FOLLOWING_T__26_IN_x_occi_attribute_734) + match(T__10, TOKENS_FOLLOWING_T__10_IN_x_occi_attribute_736) + # at line 125:27: ( WS )? alt_28 = 2 - look_28_0 = @input.peek( 1 ) + look_28_0 = @input.peek(1) - if ( look_28_0 == WS ) + if (look_28_0 == WS) alt_28 = 1 end case alt_28 - when 1 - # at line 128:27: WS - match( WS, TOKENS_FOLLOWING_WS_IN_x_occi_attribute_750 ) + when 1 + # at line 125:27: WS + match(WS, TOKENS_FOLLOWING_WS_IN_x_occi_attribute_738) end - @state.following.push( TOKENS_FOLLOWING_attribute_IN_x_occi_attribute_753 ) + @state.following.push(TOKENS_FOLLOWING_attribute_IN_x_occi_attribute_741) attribute27 = attribute @state.following.pop - # at line 128:41: ( ';' )? + # at line 125:41: ( ';' )? alt_29 = 2 - look_29_0 = @input.peek( 1 ) + look_29_0 = @input.peek(1) - if ( look_29_0 == T__11 ) + if (look_29_0 == T__11) alt_29 = 1 end case alt_29 - when 1 - # at line 128:41: ';' - match( T__11, TOKENS_FOLLOWING_T__11_IN_x_occi_attribute_755 ) + when 1 + # at line 125:41: ';' + match(T__11, TOKENS_FOLLOWING_T__11_IN_x_occi_attribute_743) end # --> action - mash = attribute27 - # <-- action + hash = attribute27 + # <-- action rescue ANTLR3::Error::RecognitionError => re report_error(re) @@ -1363,8 +1359,8 @@ def x_occi_attribute # trace_out( __method__, 18 ) end - - return mash + + return hash end @@ -1372,7 +1368,7 @@ def x_occi_attribute # parser rule x_occi_location # # (in OCCI.g) - # 136:1: x_occi_location returns [uri] : 'X-OCCI-Location' ':' ( WS )? location ( ';' )? ; + # 133:1: x_occi_location returns [uri] : 'X-OCCI-Location' ':' ( WS )? location ( ';' )? ; # def x_occi_location # -> uncomment the next line to manually enable rule tracing @@ -1381,41 +1377,41 @@ def x_occi_location location28 = nil begin - # at line 137:4: 'X-OCCI-Location' ':' ( WS )? location ( ';' )? - match( T__27, TOKENS_FOLLOWING_T__27_IN_x_occi_location_775 ) - match( T__10, TOKENS_FOLLOWING_T__10_IN_x_occi_location_777 ) - # at line 137:26: ( WS )? + # at line 134:4: 'X-OCCI-Location' ':' ( WS )? location ( ';' )? + match(T__27, TOKENS_FOLLOWING_T__27_IN_x_occi_location_763) + match(T__10, TOKENS_FOLLOWING_T__10_IN_x_occi_location_765) + # at line 134:26: ( WS )? alt_30 = 2 - look_30_0 = @input.peek( 1 ) + look_30_0 = @input.peek(1) - if ( look_30_0 == WS ) + if (look_30_0 == WS) alt_30 = 1 end case alt_30 - when 1 - # at line 137:26: WS - match( WS, TOKENS_FOLLOWING_WS_IN_x_occi_location_779 ) + when 1 + # at line 134:26: WS + match(WS, TOKENS_FOLLOWING_WS_IN_x_occi_location_767) end - @state.following.push( TOKENS_FOLLOWING_location_IN_x_occi_location_782 ) + @state.following.push(TOKENS_FOLLOWING_location_IN_x_occi_location_770) location28 = location @state.following.pop - # at line 137:39: ( ';' )? + # at line 134:39: ( ';' )? alt_31 = 2 - look_31_0 = @input.peek( 1 ) + look_31_0 = @input.peek(1) - if ( look_31_0 == T__11 ) + if (look_31_0 == T__11) alt_31 = 1 end case alt_31 - when 1 - # at line 137:39: ';' - match( T__11, TOKENS_FOLLOWING_T__11_IN_x_occi_location_784 ) + when 1 + # at line 134:39: ';' + match(T__11, TOKENS_FOLLOWING_T__11_IN_x_occi_location_772) end # --> action - uri = URI.parse(( location28 && @input.to_s( location28.start, location28.stop ) )) - # <-- action + uri = URI.parse((location28 && @input.to_s(location28.start, location28.stop))) + # <-- action rescue ANTLR3::Error::RecognitionError => re report_error(re) @@ -1426,7 +1422,7 @@ def x_occi_location # trace_out( __method__, 19 ) end - + return uri end @@ -1435,43 +1431,42 @@ def x_occi_location # parser rule uri # # (in OCCI.g) - # 139:1: uri : ( LOALPHA | UPALPHA | DIGIT | '@' | ':' | '%' | '_' | '\\\\' | '+' | '.' | '~' | '#' | '?' | '&' | '/' | '=' | '-' | 'action' | 'kind' | 'mixin' )+ ; + # 136:1: uri : ( LOALPHA | UPALPHA | DIGIT | '@' | ':' | '%' | '_' | '\\\\' | '+' | '.' | '~' | '#' | '?' | '&' | '/' | '=' | '-' | 'action' | 'kind' | 'mixin' )+ ; # def uri # -> uncomment the next line to manually enable rule tracing # trace_in( __method__, 20 ) begin - # at line 139:9: ( LOALPHA | UPALPHA | DIGIT | '@' | ':' | '%' | '_' | '\\\\' | '+' | '.' | '~' | '#' | '?' | '&' | '/' | '=' | '-' | 'action' | 'kind' | 'mixin' )+ - # at file 139:9: ( LOALPHA | UPALPHA | DIGIT | '@' | ':' | '%' | '_' | '\\\\' | '+' | '.' | '~' | '#' | '?' | '&' | '/' | '=' | '-' | 'action' | 'kind' | 'mixin' )+ + # at line 136:9: ( LOALPHA | UPALPHA | DIGIT | '@' | ':' | '%' | '_' | '\\\\' | '+' | '.' | '~' | '#' | '?' | '&' | '/' | '=' | '-' | 'action' | 'kind' | 'mixin' )+ + # at file 136:9: ( LOALPHA | UPALPHA | DIGIT | '@' | ':' | '%' | '_' | '\\\\' | '+' | '.' | '~' | '#' | '?' | '&' | '/' | '=' | '-' | 'action' | 'kind' | 'mixin' )+ match_count_32 = 0 while true alt_32 = 2 - look_32_0 = @input.peek( 1 ) + look_32_0 = @input.peek(1) - if ( look_32_0.between?( LOALPHA, DIGIT ) || look_32_0 == T__10 || look_32_0 == T__13 || look_32_0.between?( T__28, T__42 ) ) + if (look_32_0.between?(LOALPHA, DIGIT) || look_32_0 == T__10 || look_32_0 == T__13 || look_32_0.between?(T__28, T__42)) alt_32 = 1 end case alt_32 - when 1 - # at line - if @input.peek( 1 ).between?( LOALPHA, DIGIT ) || @input.peek(1) == T__10 || @input.peek(1) == T__13 || @input.peek( 1 ).between?( T__28, T__42 ) - @input.consume - @state.error_recovery = false - else - mse = MismatchedSet( nil ) - raise mse - end - + when 1 + # at line + if @input.peek(1).between?(LOALPHA, DIGIT) || @input.peek(1) == T__10 || @input.peek(1) == T__13 || @input.peek(1).between?(T__28, T__42) + @input.consume + @state.error_recovery = false + else + mse = MismatchedSet(nil) + raise mse + end - else - match_count_32 > 0 and break - eee = EarlyExit(32) + else + match_count_32 > 0 and break + eee = EarlyExit(32) - raise eee + raise eee end match_count_32 += 1 end @@ -1486,17 +1481,17 @@ def uri # trace_out( __method__, 20 ) end - - return + + return end - TermReturnValue = define_return_scope + TermReturnValue = define_return_scope # # parser rule term # # (in OCCI.g) - # 140:1: term : LOALPHA ( LOALPHA | DIGIT | '-' | '_' )* ; + # 137:1: term : LOALPHA ( LOALPHA | DIGIT | '-' | '_' )* ; # def term # -> uncomment the next line to manually enable rule tracing @@ -1507,36 +1502,35 @@ def term return_value.start = @input.look begin - # at line 140:10: LOALPHA ( LOALPHA | DIGIT | '-' | '_' )* - match( LOALPHA, TOKENS_FOLLOWING_LOALPHA_IN_term_888 ) - # at line 140:18: ( LOALPHA | DIGIT | '-' | '_' )* + # at line 137:10: LOALPHA ( LOALPHA | DIGIT | '-' | '_' )* + match(LOALPHA, TOKENS_FOLLOWING_LOALPHA_IN_term_876) + # at line 137:18: ( LOALPHA | DIGIT | '-' | '_' )* while true # decision 33 alt_33 = 2 - look_33_0 = @input.peek( 1 ) + look_33_0 = @input.peek(1) - if ( look_33_0 == LOALPHA || look_33_0 == DIGIT || look_33_0 == T__30 || look_33_0 == T__39 ) + if (look_33_0 == LOALPHA || look_33_0 == DIGIT || look_33_0 == T__30 || look_33_0 == T__39) alt_33 = 1 end case alt_33 - when 1 - # at line - if @input.peek(1) == LOALPHA || @input.peek(1) == DIGIT || @input.peek(1) == T__30 || @input.peek(1) == T__39 - @input.consume - @state.error_recovery = false - else - mse = MismatchedSet( nil ) - raise mse - end - + when 1 + # at line + if @input.peek(1) == LOALPHA || @input.peek(1) == DIGIT || @input.peek(1) == T__30 || @input.peek(1) == T__39 + @input.consume + @state.error_recovery = false + else + mse = MismatchedSet(nil) + raise mse + end - else - break # out of loop for decision 33 + else + break # out of loop for decision 33 end end # loop for decision 33 # - - - - - - - rule clean up - - - - - - - - - return_value.stop = @input.look( -1 ) + return_value.stop = @input.look(-1) rescue ANTLR3::Error::RecognitionError => re report_error(re) @@ -1547,17 +1541,17 @@ def term # trace_out( __method__, 21 ) end - + return return_value end - SchemeReturnValue = define_return_scope + SchemeReturnValue = define_return_scope # # parser rule scheme # # (in OCCI.g) - # 141:1: scheme : uri ; + # 138:1: scheme : uri ; # def scheme # -> uncomment the next line to manually enable rule tracing @@ -1568,12 +1562,12 @@ def scheme return_value.start = @input.look begin - # at line 141:20: uri - @state.following.push( TOKENS_FOLLOWING_uri_IN_scheme_923 ) + # at line 138:20: uri + @state.following.push(TOKENS_FOLLOWING_uri_IN_scheme_911) uri @state.following.pop # - - - - - - - rule clean up - - - - - - - - - return_value.stop = @input.look( -1 ) + return_value.stop = @input.look(-1) rescue ANTLR3::Error::RecognitionError => re report_error(re) @@ -1584,17 +1578,17 @@ def scheme # trace_out( __method__, 22 ) end - + return return_value end - ClassTypeReturnValue = define_return_scope + ClassTypeReturnValue = define_return_scope # # parser rule class_type # # (in OCCI.g) - # 142:1: class_type : ( 'kind' | 'mixin' | 'action' ) ; + # 139:1: class_type : ( 'kind' | 'mixin' | 'action' ) ; # def class_type # -> uncomment the next line to manually enable rule tracing @@ -1605,18 +1599,18 @@ def class_type return_value.start = @input.look begin - # at line 142:15: ( 'kind' | 'mixin' | 'action' ) - if @input.peek( 1 ).between?( T__40, T__42 ) + # at line 139:15: ( 'kind' | 'mixin' | 'action' ) + if @input.peek(1).between?(T__40, T__42) @input.consume @state.error_recovery = false else - mse = MismatchedSet( nil ) + mse = MismatchedSet(nil) raise mse end # - - - - - - - rule clean up - - - - - - - - - return_value.stop = @input.look( -1 ) + return_value.stop = @input.look(-1) rescue ANTLR3::Error::RecognitionError => re report_error(re) @@ -1627,17 +1621,17 @@ def class_type # trace_out( __method__, 23 ) end - + return return_value end - TitleReturnValue = define_return_scope + TitleReturnValue = define_return_scope # # parser rule title # # (in OCCI.g) - # 143:1: title : ( ESC | ~ ( '\\\\' | '\"' | '\\'' ) | '\\'' )* ; + # 140:1: title : ( ESC | ~ ( '\\\\' | '\"' | '\\'' ) | '\\'' )* ; # def title # -> uncomment the next line to manually enable rule tracing @@ -1648,35 +1642,34 @@ def title return_value.start = @input.look begin - # at line 143:11: ( ESC | ~ ( '\\\\' | '\"' | '\\'' ) | '\\'' )* - # at line 143:11: ( ESC | ~ ( '\\\\' | '\"' | '\\'' ) | '\\'' )* + # at line 140:11: ( ESC | ~ ( '\\\\' | '\"' | '\\'' ) | '\\'' )* + # at line 140:11: ( ESC | ~ ( '\\\\' | '\"' | '\\'' ) | '\\'' )* while true # decision 34 alt_34 = 2 - look_34_0 = @input.peek( 1 ) + look_34_0 = @input.peek(1) - if ( look_34_0.between?( WS, T__13 ) || look_34_0.between?( T__15, T__30 ) || look_34_0.between?( T__32, T__43 ) ) + if (look_34_0.between?(WS, T__13) || look_34_0.between?(T__15, T__30) || look_34_0.between?(T__32, T__43)) alt_34 = 1 end case alt_34 - when 1 - # at line - if @input.peek( 1 ).between?( WS, T__13 ) || @input.peek( 1 ).between?( T__15, T__30 ) || @input.peek( 1 ).between?( T__32, T__43 ) - @input.consume - @state.error_recovery = false - else - mse = MismatchedSet( nil ) - raise mse - end - + when 1 + # at line + if @input.peek(1).between?(WS, T__13) || @input.peek(1).between?(T__15, T__30) || @input.peek(1).between?(T__32, T__43) + @input.consume + @state.error_recovery = false + else + mse = MismatchedSet(nil) + raise mse + end - else - break # out of loop for decision 34 + else + break # out of loop for decision 34 end end # loop for decision 34 - # - - - - - - - rule clean up - - - - - - - - - return_value.stop = @input.look( -1 ) + # - - - - - - - rule clean up - - - - - - - - + return_value.stop = @input.look(-1) rescue ANTLR3::Error::RecognitionError => re report_error(re) @@ -1687,17 +1680,17 @@ def title # trace_out( __method__, 24 ) end - + return return_value end - RelReturnValue = define_return_scope + RelReturnValue = define_return_scope # # parser rule rel # # (in OCCI.g) - # 144:1: rel : uri ; + # 141:1: rel : uri ; # def rel # -> uncomment the next line to manually enable rule tracing @@ -1708,12 +1701,12 @@ def rel return_value.start = @input.look begin - # at line 144:9: uri - @state.following.push( TOKENS_FOLLOWING_uri_IN_rel_988 ) + # at line 141:9: uri + @state.following.push(TOKENS_FOLLOWING_uri_IN_rel_976) uri @state.following.pop # - - - - - - - rule clean up - - - - - - - - - return_value.stop = @input.look( -1 ) + return_value.stop = @input.look(-1) rescue ANTLR3::Error::RecognitionError => re report_error(re) @@ -1724,17 +1717,17 @@ def rel # trace_out( __method__, 25 ) end - + return return_value end - LocationReturnValue = define_return_scope + LocationReturnValue = define_return_scope # # parser rule location # # (in OCCI.g) - # 145:1: location : uri ; + # 142:1: location : uri ; # def location # -> uncomment the next line to manually enable rule tracing @@ -1745,12 +1738,12 @@ def location return_value.start = @input.look begin - # at line 145:13: uri - @state.following.push( TOKENS_FOLLOWING_uri_IN_location_996 ) + # at line 142:13: uri + @state.following.push(TOKENS_FOLLOWING_uri_IN_location_984) uri @state.following.pop # - - - - - - - rule clean up - - - - - - - - - return_value.stop = @input.look( -1 ) + return_value.stop = @input.look(-1) rescue ANTLR3::Error::RecognitionError => re report_error(re) @@ -1761,7 +1754,7 @@ def location # trace_out( __method__, 26 ) end - + return return_value end @@ -1770,57 +1763,57 @@ def location # parser rule attribute # # (in OCCI.g) - # 146:1: attribute returns [mash] : comp_first= attribute_component ( '.' comp_next= attribute_component )* '=' attribute_value ; + # 143:1: attribute returns [hash] : comp_first= attribute_component ( '.' comp_next= attribute_component )* '=' attribute_value ; # def attribute # -> uncomment the next line to manually enable rule tracing # trace_in( __method__, 27 ) - mash = nil + hash = nil comp_first = nil comp_next = nil attribute_value29 = nil # - - - - @init action - - - - - mash = Hashie::Mash.new + hash = Hashie::Mash.new begin - # at line 147:6: comp_first= attribute_component ( '.' comp_next= attribute_component )* '=' attribute_value - @state.following.push( TOKENS_FOLLOWING_attribute_component_IN_attribute_1018 ) + # at line 144:6: comp_first= attribute_component ( '.' comp_next= attribute_component )* '=' attribute_value + @state.following.push(TOKENS_FOLLOWING_attribute_component_IN_attribute_1005) comp_first = attribute_component @state.following.pop # --> action - cur_mash = mash; comp = ( comp_first && @input.to_s( comp_first.start, comp_first.stop ) ) + cur_hash = hash; comp = (comp_first && @input.to_s(comp_first.start, comp_first.stop)) # <-- action - # at line 148:6: ( '.' comp_next= attribute_component )* + # at line 145:6: ( '.' comp_next= attribute_component )* while true # decision 35 alt_35 = 2 - look_35_0 = @input.peek( 1 ) + look_35_0 = @input.peek(1) - if ( look_35_0 == T__33 ) + if (look_35_0 == T__33) alt_35 = 1 end case alt_35 - when 1 - # at line 148:8: '.' comp_next= attribute_component - match( T__33, TOKENS_FOLLOWING_T__33_IN_attribute_1030 ) - @state.following.push( TOKENS_FOLLOWING_attribute_component_IN_attribute_1034 ) - comp_next = attribute_component - @state.following.pop - # --> action - cur_mash[comp.to_sym] = Hashie::Mash.new; cur_mash = cur_mash[comp.to_sym]; comp = ( comp_next && @input.to_s( comp_next.start, comp_next.stop ) ) + when 1 + # at line 145:8: '.' comp_next= attribute_component + match(T__33, TOKENS_FOLLOWING_T__33_IN_attribute_1016) + @state.following.push(TOKENS_FOLLOWING_attribute_component_IN_attribute_1020) + comp_next = attribute_component + @state.following.pop + # --> action + cur_hash[comp.to_sym] = Hashie::Mash.new; cur_hash = cur_hash[comp.to_sym]; comp = (comp_next && @input.to_s(comp_next.start, comp_next.stop)) # <-- action - else - break # out of loop for decision 35 + else + break # out of loop for decision 35 end end # loop for decision 35 - match( T__13, TOKENS_FOLLOWING_T__13_IN_attribute_1046 ) - @state.following.push( TOKENS_FOLLOWING_attribute_value_IN_attribute_1048 ) + match(T__13, TOKENS_FOLLOWING_T__13_IN_attribute_1031) + @state.following.push(TOKENS_FOLLOWING_attribute_value_IN_attribute_1033) attribute_value29 = attribute_value @state.following.pop # --> action - cur_mash[comp.to_sym] = ( attribute_value29 && @input.to_s( attribute_value29.start, attribute_value29.stop ) ) - # <-- action + cur_hash[comp.to_sym] = attribute_value29 + # <-- action rescue ANTLR3::Error::RecognitionError => re report_error(re) @@ -1831,8 +1824,8 @@ def attribute # trace_out( __method__, 27 ) end - - return mash + + return hash end @@ -1840,52 +1833,52 @@ def attribute # parser rule attribute_name # # (in OCCI.g) - # 150:1: attribute_name returns [mash] : comp_first= attribute_component ( '.' comp_next= attribute_component )* ; + # 147:1: attribute_name returns [hash] : comp_first= attribute_component ( '.' comp_next= attribute_component )* ; # def attribute_name # -> uncomment the next line to manually enable rule tracing # trace_in( __method__, 28 ) - mash = nil + hash = nil comp_first = nil comp_next = nil # - - - - @init action - - - - - mash = Hashie::Mash.new + hash = Hashie::Mash.new begin - # at line 151:27: comp_first= attribute_component ( '.' comp_next= attribute_component )* - @state.following.push( TOKENS_FOLLOWING_attribute_component_IN_attribute_name_1092 ) + # at line 148:27: comp_first= attribute_component ( '.' comp_next= attribute_component )* + @state.following.push(TOKENS_FOLLOWING_attribute_component_IN_attribute_name_1077) comp_first = attribute_component @state.following.pop # --> action - cur_mash = mash; comp = ( comp_first && @input.to_s( comp_first.start, comp_first.stop ) ) + cur_hash = hash; comp = (comp_first && @input.to_s(comp_first.start, comp_first.stop)) # <-- action - # at line 152:6: ( '.' comp_next= attribute_component )* + # at line 149:6: ( '.' comp_next= attribute_component )* while true # decision 36 alt_36 = 2 - look_36_0 = @input.peek( 1 ) + look_36_0 = @input.peek(1) - if ( look_36_0 == T__33 ) + if (look_36_0 == T__33) alt_36 = 1 end case alt_36 - when 1 - # at line 152:8: '.' comp_next= attribute_component - match( T__33, TOKENS_FOLLOWING_T__33_IN_attribute_name_1104 ) - @state.following.push( TOKENS_FOLLOWING_attribute_component_IN_attribute_name_1108 ) - comp_next = attribute_component - @state.following.pop - # --> action - cur_mash[comp.to_sym] = Hashie::Mash.new; cur_mash = cur_mash[comp.to_sym]; comp = ( comp_next && @input.to_s( comp_next.start, comp_next.stop ) ) + when 1 + # at line 149:8: '.' comp_next= attribute_component + match(T__33, TOKENS_FOLLOWING_T__33_IN_attribute_name_1088) + @state.following.push(TOKENS_FOLLOWING_attribute_component_IN_attribute_name_1092) + comp_next = attribute_component + @state.following.pop + # --> action + cur_hash[comp.to_sym] = Hashie::Mash.new; cur_hash = cur_hash[comp.to_sym]; comp = (comp_next && @input.to_s(comp_next.start, comp_next.stop)) # <-- action - else - break # out of loop for decision 36 + else + break # out of loop for decision 36 end end # loop for decision 36 # --> action - cur_mash[comp.to_sym] = ATTRIBUTE - # <-- action + cur_hash[comp.to_sym] = ATTRIBUTE + # <-- action rescue ANTLR3::Error::RecognitionError => re report_error(re) @@ -1896,17 +1889,17 @@ def attribute_name # trace_out( __method__, 28 ) end - - return mash + + return hash end - AttributeComponentReturnValue = define_return_scope + AttributeComponentReturnValue = define_return_scope # # parser rule attribute_component # # (in OCCI.g) - # 154:1: attribute_component : LOALPHA ( LOALPHA | DIGIT | '-' | '_' )* ; + # 151:1: attribute_component : LOALPHA ( LOALPHA | DIGIT | '-' | '_' )* ; # def attribute_component # -> uncomment the next line to manually enable rule tracing @@ -1917,36 +1910,35 @@ def attribute_component return_value.start = @input.look begin - # at line 154:23: LOALPHA ( LOALPHA | DIGIT | '-' | '_' )* - match( LOALPHA, TOKENS_FOLLOWING_LOALPHA_IN_attribute_component_1128 ) - # at line 154:31: ( LOALPHA | DIGIT | '-' | '_' )* + # at line 151:23: LOALPHA ( LOALPHA | DIGIT | '-' | '_' )* + match(LOALPHA, TOKENS_FOLLOWING_LOALPHA_IN_attribute_component_1110) + # at line 151:31: ( LOALPHA | DIGIT | '-' | '_' )* while true # decision 37 alt_37 = 2 - look_37_0 = @input.peek( 1 ) + look_37_0 = @input.peek(1) - if ( look_37_0 == LOALPHA || look_37_0 == DIGIT || look_37_0 == T__30 || look_37_0 == T__39 ) + if (look_37_0 == LOALPHA || look_37_0 == DIGIT || look_37_0 == T__30 || look_37_0 == T__39) alt_37 = 1 end case alt_37 - when 1 - # at line - if @input.peek(1) == LOALPHA || @input.peek(1) == DIGIT || @input.peek(1) == T__30 || @input.peek(1) == T__39 - @input.consume - @state.error_recovery = false - else - mse = MismatchedSet( nil ) - raise mse - end - + when 1 + # at line + if @input.peek(1) == LOALPHA || @input.peek(1) == DIGIT || @input.peek(1) == T__30 || @input.peek(1) == T__39 + @input.consume + @state.error_recovery = false + else + mse = MismatchedSet(nil) + raise mse + end - else - break # out of loop for decision 37 + else + break # out of loop for decision 37 end end # loop for decision 37 # - - - - - - - rule clean up - - - - - - - - - return_value.stop = @input.look( -1 ) + return_value.stop = @input.look(-1) rescue ANTLR3::Error::RecognitionError => re report_error(re) @@ -1957,103 +1949,214 @@ def attribute_component # trace_out( __method__, 29 ) end - + return return_value end - AttributeValueReturnValue = define_return_scope # # parser rule attribute_value # # (in OCCI.g) - # 155:1: attribute_value : ( ( '\"' ( ESC | ~ ( '\\\\' | '\"' | '\\'' ) | '\\'' )* '\"' ) | ( DIGIT ( '.' DIGIT )* ) ) ; + # 152:1: attribute_value returns [value] : ( string | number ) ; # def attribute_value # -> uncomment the next line to manually enable rule tracing # trace_in( __method__, 30 ) - return_value = AttributeValueReturnValue.new + value = nil + string30 = nil + number31 = nil + + begin + # at line 152:35: ( string | number ) + # at line 152:35: ( string | number ) + alt_38 = 2 + look_38_0 = @input.peek(1) + + if (look_38_0 == T__14) + alt_38 = 1 + elsif (look_38_0 == EOF || look_38_0 == DIGIT || look_38_0 == T__11 || look_38_0 == T__33) + alt_38 = 2 + else + raise NoViableAlternative("", 38, 0) + end + case alt_38 + when 1 + # at line 152:37: string + @state.following.push(TOKENS_FOLLOWING_string_IN_attribute_value_1142) + string30 = string + @state.following.pop + # --> action + value = (string30 && @input.to_s(string30.start, string30.stop)) + # <-- action + + when 2 + # at line 152:71: number + @state.following.push(TOKENS_FOLLOWING_number_IN_attribute_value_1148) + number31 = number + @state.following.pop + # --> action + value = (number31 && @input.to_s(number31.start, number31.stop)).to_i + # <-- action + + end + + rescue ANTLR3::Error::RecognitionError => re + report_error(re) + recover(re) + + ensure + # -> uncomment the next line to manually enable rule tracing + # trace_out( __method__, 30 ) + + end + + return value + end + + StringReturnValue = define_return_scope + + # + # parser rule string + # + # (in OCCI.g) + # 153:1: string : ( '\"' ( ESC | ~ ( '\\\\' | '\"' | '\\'' ) | '\\'' )* '\"' ) ; + # + def string + # -> uncomment the next line to manually enable rule tracing + # trace_in( __method__, 31 ) + return_value = StringReturnValue.new # $rule.start = the first token seen before matching return_value.start = @input.look begin - # at line 155:20: ( ( '\"' ( ESC | ~ ( '\\\\' | '\"' | '\\'' ) | '\\'' )* '\"' ) | ( DIGIT ( '.' DIGIT )* ) ) - # at line 155:20: ( ( '\"' ( ESC | ~ ( '\\\\' | '\"' | '\\'' ) | '\\'' )* '\"' ) | ( DIGIT ( '.' DIGIT )* ) ) - alt_40 = 2 - look_40_0 = @input.peek( 1 ) - - if ( look_40_0 == T__14 ) - alt_40 = 1 - elsif ( look_40_0 == DIGIT ) - alt_40 = 2 - else - raise NoViableAlternative( "", 40, 0 ) - end - case alt_40 - when 1 - # at line 155:22: ( '\"' ( ESC | ~ ( '\\\\' | '\"' | '\\'' ) | '\\'' )* '\"' ) - # at line 155:22: ( '\"' ( ESC | ~ ( '\\\\' | '\"' | '\\'' ) | '\\'' )* '\"' ) - # at line 155:24: '\"' ( ESC | ~ ( '\\\\' | '\"' | '\\'' ) | '\\'' )* '\"' - match( T__14, TOKENS_FOLLOWING_T__14_IN_attribute_value_1159 ) - # at line 155:28: ( ESC | ~ ( '\\\\' | '\"' | '\\'' ) | '\\'' )* - while true # decision 38 - alt_38 = 2 - look_38_0 = @input.peek( 1 ) - - if ( look_38_0.between?( WS, T__13 ) || look_38_0.between?( T__15, T__30 ) || look_38_0.between?( T__32, T__43 ) ) - alt_38 = 1 + # at line 153:12: ( '\"' ( ESC | ~ ( '\\\\' | '\"' | '\\'' ) | '\\'' )* '\"' ) + # at line 153:12: ( '\"' ( ESC | ~ ( '\\\\' | '\"' | '\\'' ) | '\\'' )* '\"' ) + # at line 153:14: '\"' ( ESC | ~ ( '\\\\' | '\"' | '\\'' ) | '\\'' )* '\"' + match(T__14, TOKENS_FOLLOWING_T__14_IN_string_1163) + # at line 153:18: ( ESC | ~ ( '\\\\' | '\"' | '\\'' ) | '\\'' )* + while true # decision 39 + alt_39 = 2 + look_39_0 = @input.peek(1) + + if (look_39_0.between?(WS, T__13) || look_39_0.between?(T__15, T__30) || look_39_0.between?(T__32, T__43)) + alt_39 = 1 - end - case alt_38 + end + case alt_39 when 1 - # at line - if @input.peek( 1 ).between?( WS, T__13 ) || @input.peek( 1 ).between?( T__15, T__30 ) || @input.peek( 1 ).between?( T__32, T__43 ) + # at line + if @input.peek(1).between?(WS, T__13) || @input.peek(1).between?(T__15, T__30) || @input.peek(1).between?(T__32, T__43) @input.consume @state.error_recovery = false else - mse = MismatchedSet( nil ) + mse = MismatchedSet(nil) raise mse end - else - break # out of loop for decision 38 - end - end # loop for decision 38 - match( T__14, TOKENS_FOLLOWING_T__14_IN_attribute_value_1189 ) + break # out of loop for decision 39 + end + end # loop for decision 39 + match(T__14, TOKENS_FOLLOWING_T__14_IN_string_1193) + + # - - - - - - - rule clean up - - - - - - - - + return_value.stop = @input.look(-1) + rescue ANTLR3::Error::RecognitionError => re + report_error(re) + recover(re) - when 2 - # at line 155:76: ( DIGIT ( '.' DIGIT )* ) - # at line 155:76: ( DIGIT ( '.' DIGIT )* ) - # at line 155:78: DIGIT ( '.' DIGIT )* - match( DIGIT, TOKENS_FOLLOWING_DIGIT_IN_attribute_value_1196 ) - # at line 155:84: ( '.' DIGIT )* - while true # decision 39 - alt_39 = 2 - look_39_0 = @input.peek( 1 ) + ensure + # -> uncomment the next line to manually enable rule tracing + # trace_out( __method__, 31 ) - if ( look_39_0 == T__33 ) - alt_39 = 1 + end - end - case alt_39 + return return_value + end + + NumberReturnValue = define_return_scope + + # + # parser rule number + # + # (in OCCI.g) + # 154:1: number : ( ( DIGIT )* ( '.' ( DIGIT )+ )? ) ; + # + def number + # -> uncomment the next line to manually enable rule tracing + # trace_in( __method__, 32 ) + return_value = NumberReturnValue.new + + # $rule.start = the first token seen before matching + return_value.start = @input.look + + begin + # at line 154:12: ( ( DIGIT )* ( '.' ( DIGIT )+ )? ) + # at line 154:12: ( ( DIGIT )* ( '.' ( DIGIT )+ )? ) + # at line 154:14: ( DIGIT )* ( '.' ( DIGIT )+ )? + # at line 154:14: ( DIGIT )* + while true # decision 40 + alt_40 = 2 + look_40_0 = @input.peek(1) + + if (look_40_0 == DIGIT) + alt_40 = 1 + + end + case alt_40 when 1 - # at line 155:86: '.' DIGIT - match( T__33, TOKENS_FOLLOWING_T__33_IN_attribute_value_1200 ) - match( DIGIT, TOKENS_FOLLOWING_DIGIT_IN_attribute_value_1202 ) + # at line 154:14: DIGIT + match(DIGIT, TOKENS_FOLLOWING_DIGIT_IN_number_1205) else - break # out of loop for decision 39 + break # out of loop for decision 40 + end + end # loop for decision 40 + # at line 154:21: ( '.' ( DIGIT )+ )? + alt_42 = 2 + look_42_0 = @input.peek(1) + + if (look_42_0 == T__33) + alt_42 = 1 + end + case alt_42 + when 1 + # at line 154:23: '.' ( DIGIT )+ + match(T__33, TOKENS_FOLLOWING_T__33_IN_number_1210) + # at file 154:27: ( DIGIT )+ + match_count_41 = 0 + while true + alt_41 = 2 + look_41_0 = @input.peek(1) + + if (look_41_0 == DIGIT) + alt_41 = 1 + + end + case alt_41 + when 1 + # at line 154:27: DIGIT + match(DIGIT, TOKENS_FOLLOWING_DIGIT_IN_number_1212) + + else + match_count_41 > 0 and break + eee = EarlyExit(41) + + + raise eee + end + match_count_41 += 1 end - end # loop for decision 39 end + # - - - - - - - rule clean up - - - - - - - - - return_value.stop = @input.look( -1 ) + return_value.stop = @input.look(-1) rescue ANTLR3::Error::RecognitionError => re report_error(re) @@ -2061,36 +2164,36 @@ def attribute_value ensure # -> uncomment the next line to manually enable rule tracing - # trace_out( __method__, 30 ) + # trace_out( __method__, 32 ) end - + return return_value end - ActionLocationReturnValue = define_return_scope + ActionLocationReturnValue = define_return_scope # # parser rule action_location # # (in OCCI.g) - # 156:1: action_location : uri ; + # 155:1: action_location : uri ; # def action_location # -> uncomment the next line to manually enable rule tracing - # trace_in( __method__, 31 ) + # trace_in( __method__, 33 ) return_value = ActionLocationReturnValue.new # $rule.start = the first token seen before matching return_value.start = @input.look begin - # at line 156:20: uri - @state.following.push( TOKENS_FOLLOWING_uri_IN_action_location_1217 ) + # at line 155:20: uri + @state.following.push(TOKENS_FOLLOWING_uri_IN_action_location_1226) uri @state.following.pop # - - - - - - - rule clean up - - - - - - - - - return_value.stop = @input.look( -1 ) + return_value.stop = @input.look(-1) rescue ANTLR3::Error::RecognitionError => re report_error(re) @@ -2098,36 +2201,36 @@ def action_location ensure # -> uncomment the next line to manually enable rule tracing - # trace_out( __method__, 31 ) + # trace_out( __method__, 33 ) end - + return return_value end - TargetReturnValue = define_return_scope + TargetReturnValue = define_return_scope # # parser rule target # # (in OCCI.g) - # 157:1: target : uri ; + # 156:1: target : uri ; # def target # -> uncomment the next line to manually enable rule tracing - # trace_in( __method__, 32 ) + # trace_in( __method__, 34 ) return_value = TargetReturnValue.new # $rule.start = the first token seen before matching return_value.start = @input.look begin - # at line 157:12: uri - @state.following.push( TOKENS_FOLLOWING_uri_IN_target_1226 ) + # at line 156:12: uri + @state.following.push(TOKENS_FOLLOWING_uri_IN_target_1235) uri @state.following.pop # - - - - - - - rule clean up - - - - - - - - - return_value.stop = @input.look( -1 ) + return_value.stop = @input.look(-1) rescue ANTLR3::Error::RecognitionError => re report_error(re) @@ -2135,36 +2238,36 @@ def target ensure # -> uncomment the next line to manually enable rule tracing - # trace_out( __method__, 32 ) + # trace_out( __method__, 34 ) end - + return return_value end - SelfLocationReturnValue = define_return_scope + SelfLocationReturnValue = define_return_scope # # parser rule self_location # # (in OCCI.g) - # 158:1: self_location : uri ; + # 157:1: self_location : uri ; # def self_location # -> uncomment the next line to manually enable rule tracing - # trace_in( __method__, 33 ) + # trace_in( __method__, 35 ) return_value = SelfLocationReturnValue.new # $rule.start = the first token seen before matching return_value.start = @input.look begin - # at line 158:18: uri - @state.following.push( TOKENS_FOLLOWING_uri_IN_self_location_1234 ) + # at line 157:18: uri + @state.following.push(TOKENS_FOLLOWING_uri_IN_self_location_1243) uri @state.following.pop # - - - - - - - rule clean up - - - - - - - - - return_value.stop = @input.look( -1 ) + return_value.stop = @input.look(-1) rescue ANTLR3::Error::RecognitionError => re report_error(re) @@ -2172,36 +2275,36 @@ def self_location ensure # -> uncomment the next line to manually enable rule tracing - # trace_out( __method__, 33 ) + # trace_out( __method__, 35 ) end - + return return_value end - CategoryNameReturnValue = define_return_scope + CategoryNameReturnValue = define_return_scope # # parser rule category_name # # (in OCCI.g) - # 159:1: category_name : uri ; + # 158:1: category_name : uri ; # def category_name # -> uncomment the next line to manually enable rule tracing - # trace_in( __method__, 34 ) + # trace_in( __method__, 36 ) return_value = CategoryNameReturnValue.new # $rule.start = the first token seen before matching return_value.start = @input.look begin - # at line 159:18: uri - @state.following.push( TOKENS_FOLLOWING_uri_IN_category_name_1242 ) + # at line 158:18: uri + @state.following.push(TOKENS_FOLLOWING_uri_IN_category_name_1251) uri @state.following.pop # - - - - - - - rule clean up - - - - - - - - - return_value.stop = @input.look( -1 ) + return_value.stop = @input.look(-1) rescue ANTLR3::Error::RecognitionError => re report_error(re) @@ -2209,160 +2312,161 @@ def category_name ensure # -> uncomment the next line to manually enable rule tracing - # trace_out( __method__, 34 ) + # trace_out( __method__, 36 ) end - + return return_value end - - TOKENS_FOLLOWING_T__9_IN_category_42 = Set[ 10 ] - TOKENS_FOLLOWING_T__10_IN_category_44 = Set[ 4, 5 ] - TOKENS_FOLLOWING_category_value_IN_category_46 = Set[ 1 ] - TOKENS_FOLLOWING_category_term_IN_category_value_78 = Set[ 11 ] - TOKENS_FOLLOWING_category_scheme_IN_category_value_80 = Set[ 11 ] - TOKENS_FOLLOWING_category_class_IN_category_value_82 = Set[ 1, 11 ] - TOKENS_FOLLOWING_category_title_IN_category_value_84 = Set[ 1, 11 ] - TOKENS_FOLLOWING_category_rel_IN_category_value_87 = Set[ 1, 11 ] - TOKENS_FOLLOWING_category_location_IN_category_value_90 = Set[ 1, 11 ] - TOKENS_FOLLOWING_category_attributes_IN_category_value_93 = Set[ 1, 11 ] - TOKENS_FOLLOWING_category_actions_IN_category_value_96 = Set[ 1, 11 ] - TOKENS_FOLLOWING_T__11_IN_category_value_99 = Set[ 1 ] - TOKENS_FOLLOWING_WS_IN_category_term_131 = Set[ 4, 5 ] - TOKENS_FOLLOWING_term_IN_category_term_134 = Set[ 1 ] - TOKENS_FOLLOWING_T__11_IN_category_scheme_160 = Set[ 4, 12 ] - TOKENS_FOLLOWING_WS_IN_category_scheme_162 = Set[ 12 ] - TOKENS_FOLLOWING_T__12_IN_category_scheme_165 = Set[ 13 ] - TOKENS_FOLLOWING_T__13_IN_category_scheme_167 = Set[ 14 ] - TOKENS_FOLLOWING_T__14_IN_category_scheme_169 = Set[ 5, 6, 7, 10, 13, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42 ] - TOKENS_FOLLOWING_scheme_IN_category_scheme_171 = Set[ 14 ] - TOKENS_FOLLOWING_T__14_IN_category_scheme_173 = Set[ 1 ] - TOKENS_FOLLOWING_T__11_IN_category_class_202 = Set[ 4, 15 ] - TOKENS_FOLLOWING_WS_IN_category_class_204 = Set[ 15 ] - TOKENS_FOLLOWING_T__15_IN_category_class_207 = Set[ 13 ] - TOKENS_FOLLOWING_T__13_IN_category_class_209 = Set[ 14 ] - TOKENS_FOLLOWING_T__14_IN_category_class_211 = Set[ 40, 41, 42 ] - TOKENS_FOLLOWING_class_type_IN_category_class_213 = Set[ 14 ] - TOKENS_FOLLOWING_T__14_IN_category_class_215 = Set[ 1 ] - TOKENS_FOLLOWING_T__11_IN_category_title_240 = Set[ 4, 16 ] - TOKENS_FOLLOWING_WS_IN_category_title_242 = Set[ 16 ] - TOKENS_FOLLOWING_T__16_IN_category_title_245 = Set[ 13 ] - TOKENS_FOLLOWING_T__13_IN_category_title_247 = Set[ 14 ] - TOKENS_FOLLOWING_T__14_IN_category_title_249 = Set[ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43 ] - TOKENS_FOLLOWING_title_IN_category_title_251 = Set[ 14 ] - TOKENS_FOLLOWING_T__14_IN_category_title_253 = Set[ 1 ] - TOKENS_FOLLOWING_T__11_IN_category_rel_280 = Set[ 4, 17 ] - TOKENS_FOLLOWING_WS_IN_category_rel_282 = Set[ 17 ] - TOKENS_FOLLOWING_T__17_IN_category_rel_285 = Set[ 13 ] - TOKENS_FOLLOWING_T__13_IN_category_rel_287 = Set[ 14 ] - TOKENS_FOLLOWING_T__14_IN_category_rel_289 = Set[ 5, 6, 7, 10, 13, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42 ] - TOKENS_FOLLOWING_rel_IN_category_rel_291 = Set[ 14 ] - TOKENS_FOLLOWING_T__14_IN_category_rel_293 = Set[ 1 ] - TOKENS_FOLLOWING_T__11_IN_category_location_318 = Set[ 4, 18 ] - TOKENS_FOLLOWING_WS_IN_category_location_320 = Set[ 18 ] - TOKENS_FOLLOWING_T__18_IN_category_location_323 = Set[ 13 ] - TOKENS_FOLLOWING_T__13_IN_category_location_325 = Set[ 14 ] - TOKENS_FOLLOWING_T__14_IN_category_location_327 = Set[ 5, 6, 7, 10, 13, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42 ] - TOKENS_FOLLOWING_location_IN_category_location_329 = Set[ 14 ] - TOKENS_FOLLOWING_T__14_IN_category_location_331 = Set[ 1 ] - TOKENS_FOLLOWING_T__11_IN_category_attributes_370 = Set[ 4, 19 ] - TOKENS_FOLLOWING_WS_IN_category_attributes_372 = Set[ 19 ] - TOKENS_FOLLOWING_T__19_IN_category_attributes_375 = Set[ 13 ] - TOKENS_FOLLOWING_T__13_IN_category_attributes_377 = Set[ 14 ] - TOKENS_FOLLOWING_T__14_IN_category_attributes_379 = Set[ 5 ] - TOKENS_FOLLOWING_attribute_name_IN_category_attributes_383 = Set[ 4, 5, 14 ] - TOKENS_FOLLOWING_WS_IN_category_attributes_399 = Set[ 5 ] - TOKENS_FOLLOWING_attribute_name_IN_category_attributes_404 = Set[ 4, 5, 14 ] - TOKENS_FOLLOWING_T__14_IN_category_attributes_412 = Set[ 1 ] - TOKENS_FOLLOWING_T__11_IN_category_actions_442 = Set[ 4, 20 ] - TOKENS_FOLLOWING_WS_IN_category_actions_444 = Set[ 20 ] - TOKENS_FOLLOWING_T__20_IN_category_actions_447 = Set[ 13 ] - TOKENS_FOLLOWING_T__13_IN_category_actions_449 = Set[ 14 ] - TOKENS_FOLLOWING_T__14_IN_category_actions_451 = Set[ 5, 6, 7, 10, 13, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42 ] - TOKENS_FOLLOWING_action_location_IN_category_actions_455 = Set[ 4, 5, 6, 7, 10, 13, 14, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42 ] - TOKENS_FOLLOWING_WS_IN_category_actions_471 = Set[ 5, 6, 7, 10, 13, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42 ] - TOKENS_FOLLOWING_action_location_IN_category_actions_476 = Set[ 4, 5, 6, 7, 10, 13, 14, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42 ] - TOKENS_FOLLOWING_T__14_IN_category_actions_483 = Set[ 1 ] - TOKENS_FOLLOWING_T__21_IN_link_505 = Set[ 10 ] - TOKENS_FOLLOWING_T__10_IN_link_507 = Set[ 4, 22 ] - TOKENS_FOLLOWING_link_value_IN_link_509 = Set[ 1 ] - TOKENS_FOLLOWING_link_target_IN_link_value_531 = Set[ 11 ] - TOKENS_FOLLOWING_link_rel_IN_link_value_540 = Set[ 11 ] - TOKENS_FOLLOWING_link_self_IN_link_value_549 = Set[ 11 ] - TOKENS_FOLLOWING_link_category_IN_link_value_559 = Set[ 11 ] - TOKENS_FOLLOWING_link_attributes_IN_link_value_569 = Set[ 1, 11 ] - TOKENS_FOLLOWING_T__11_IN_link_value_578 = Set[ 1 ] - TOKENS_FOLLOWING_WS_IN_link_target_597 = Set[ 22 ] - TOKENS_FOLLOWING_T__22_IN_link_target_600 = Set[ 5, 6, 7, 10, 13, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42 ] - TOKENS_FOLLOWING_target_IN_link_target_602 = Set[ 23 ] - TOKENS_FOLLOWING_T__23_IN_link_target_604 = Set[ 1 ] - TOKENS_FOLLOWING_T__11_IN_link_rel_619 = Set[ 4, 17 ] - TOKENS_FOLLOWING_WS_IN_link_rel_621 = Set[ 17 ] - TOKENS_FOLLOWING_T__17_IN_link_rel_624 = Set[ 13 ] - TOKENS_FOLLOWING_T__13_IN_link_rel_626 = Set[ 14 ] - TOKENS_FOLLOWING_T__14_IN_link_rel_628 = Set[ 5, 6, 7, 10, 13, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42 ] - TOKENS_FOLLOWING_rel_IN_link_rel_630 = Set[ 14 ] - TOKENS_FOLLOWING_T__14_IN_link_rel_632 = Set[ 1 ] - TOKENS_FOLLOWING_T__11_IN_link_self_647 = Set[ 4, 24 ] - TOKENS_FOLLOWING_WS_IN_link_self_649 = Set[ 24 ] - TOKENS_FOLLOWING_T__24_IN_link_self_652 = Set[ 13 ] - TOKENS_FOLLOWING_T__13_IN_link_self_654 = Set[ 14 ] - TOKENS_FOLLOWING_T__14_IN_link_self_656 = Set[ 5, 6, 7, 10, 13, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42 ] - TOKENS_FOLLOWING_self_location_IN_link_self_658 = Set[ 14 ] - TOKENS_FOLLOWING_T__14_IN_link_self_660 = Set[ 1 ] - TOKENS_FOLLOWING_T__11_IN_link_category_675 = Set[ 4, 25 ] - TOKENS_FOLLOWING_WS_IN_link_category_677 = Set[ 25 ] - TOKENS_FOLLOWING_T__25_IN_link_category_680 = Set[ 13 ] - TOKENS_FOLLOWING_T__13_IN_link_category_682 = Set[ 14 ] - TOKENS_FOLLOWING_T__14_IN_link_category_684 = Set[ 5, 6, 7, 10, 13, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42 ] - TOKENS_FOLLOWING_category_name_IN_link_category_686 = Set[ 14 ] - TOKENS_FOLLOWING_T__14_IN_link_category_688 = Set[ 1 ] - TOKENS_FOLLOWING_T__11_IN_link_attributes_714 = Set[ 4, 5 ] - TOKENS_FOLLOWING_WS_IN_link_attributes_716 = Set[ 4, 5 ] - TOKENS_FOLLOWING_attribute_IN_link_attributes_719 = Set[ 1, 11 ] - TOKENS_FOLLOWING_T__26_IN_x_occi_attribute_746 = Set[ 10 ] - TOKENS_FOLLOWING_T__10_IN_x_occi_attribute_748 = Set[ 4, 5 ] - TOKENS_FOLLOWING_WS_IN_x_occi_attribute_750 = Set[ 4, 5 ] - TOKENS_FOLLOWING_attribute_IN_x_occi_attribute_753 = Set[ 1, 11 ] - TOKENS_FOLLOWING_T__11_IN_x_occi_attribute_755 = Set[ 1 ] - TOKENS_FOLLOWING_T__27_IN_x_occi_location_775 = Set[ 10 ] - TOKENS_FOLLOWING_T__10_IN_x_occi_location_777 = Set[ 4, 5, 6, 7, 10, 13, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42 ] - TOKENS_FOLLOWING_WS_IN_x_occi_location_779 = Set[ 5, 6, 7, 10, 13, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42 ] - TOKENS_FOLLOWING_location_IN_x_occi_location_782 = Set[ 1, 11 ] - TOKENS_FOLLOWING_T__11_IN_x_occi_location_784 = Set[ 1 ] - TOKENS_FOLLOWING_set_IN_uri_798 = Set[ 1, 5, 6, 7, 10, 13, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42 ] - TOKENS_FOLLOWING_LOALPHA_IN_term_888 = Set[ 1, 5, 7, 30, 39 ] - TOKENS_FOLLOWING_set_IN_term_890 = Set[ 1, 5, 7, 30, 39 ] - TOKENS_FOLLOWING_uri_IN_scheme_923 = Set[ 1 ] - TOKENS_FOLLOWING_set_IN_class_type_932 = Set[ 1 ] - TOKENS_FOLLOWING_set_IN_title_953 = Set[ 1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43 ] - TOKENS_FOLLOWING_uri_IN_rel_988 = Set[ 1 ] - TOKENS_FOLLOWING_uri_IN_location_996 = Set[ 1 ] - TOKENS_FOLLOWING_attribute_component_IN_attribute_1018 = Set[ 13, 33 ] - TOKENS_FOLLOWING_T__33_IN_attribute_1030 = Set[ 5 ] - TOKENS_FOLLOWING_attribute_component_IN_attribute_1034 = Set[ 13, 33 ] - TOKENS_FOLLOWING_T__13_IN_attribute_1046 = Set[ 7, 14 ] - TOKENS_FOLLOWING_attribute_value_IN_attribute_1048 = Set[ 1 ] - TOKENS_FOLLOWING_attribute_component_IN_attribute_name_1092 = Set[ 1, 33 ] - TOKENS_FOLLOWING_T__33_IN_attribute_name_1104 = Set[ 5 ] - TOKENS_FOLLOWING_attribute_component_IN_attribute_name_1108 = Set[ 1, 33 ] - TOKENS_FOLLOWING_LOALPHA_IN_attribute_component_1128 = Set[ 1, 5, 7, 30, 39 ] - TOKENS_FOLLOWING_set_IN_attribute_component_1130 = Set[ 1, 5, 7, 30, 39 ] - TOKENS_FOLLOWING_T__14_IN_attribute_value_1159 = Set[ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43 ] - TOKENS_FOLLOWING_set_IN_attribute_value_1161 = Set[ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43 ] - TOKENS_FOLLOWING_T__14_IN_attribute_value_1189 = Set[ 1 ] - TOKENS_FOLLOWING_DIGIT_IN_attribute_value_1196 = Set[ 1, 33 ] - TOKENS_FOLLOWING_T__33_IN_attribute_value_1200 = Set[ 7 ] - TOKENS_FOLLOWING_DIGIT_IN_attribute_value_1202 = Set[ 1, 33 ] - TOKENS_FOLLOWING_uri_IN_action_location_1217 = Set[ 1 ] - TOKENS_FOLLOWING_uri_IN_target_1226 = Set[ 1 ] - TOKENS_FOLLOWING_uri_IN_self_location_1234 = Set[ 1 ] - TOKENS_FOLLOWING_uri_IN_category_name_1242 = Set[ 1 ] + TOKENS_FOLLOWING_T__9_IN_category_42 = Set[10] + TOKENS_FOLLOWING_T__10_IN_category_44 = Set[4, 5] + TOKENS_FOLLOWING_category_value_IN_category_46 = Set[1] + TOKENS_FOLLOWING_category_term_IN_category_value_78 = Set[11] + TOKENS_FOLLOWING_category_scheme_IN_category_value_80 = Set[11] + TOKENS_FOLLOWING_category_class_IN_category_value_82 = Set[1, 11] + TOKENS_FOLLOWING_category_title_IN_category_value_84 = Set[1, 11] + TOKENS_FOLLOWING_category_rel_IN_category_value_87 = Set[1, 11] + TOKENS_FOLLOWING_category_location_IN_category_value_90 = Set[1, 11] + TOKENS_FOLLOWING_category_attributes_IN_category_value_93 = Set[1, 11] + TOKENS_FOLLOWING_category_actions_IN_category_value_96 = Set[1, 11] + TOKENS_FOLLOWING_T__11_IN_category_value_99 = Set[1] + TOKENS_FOLLOWING_WS_IN_category_term_131 = Set[4, 5] + TOKENS_FOLLOWING_term_IN_category_term_134 = Set[1] + TOKENS_FOLLOWING_T__11_IN_category_scheme_160 = Set[4, 12] + TOKENS_FOLLOWING_WS_IN_category_scheme_162 = Set[12] + TOKENS_FOLLOWING_T__12_IN_category_scheme_165 = Set[13] + TOKENS_FOLLOWING_T__13_IN_category_scheme_167 = Set[14] + TOKENS_FOLLOWING_T__14_IN_category_scheme_169 = Set[5, 6, 7, 10, 13, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42] + TOKENS_FOLLOWING_scheme_IN_category_scheme_171 = Set[14] + TOKENS_FOLLOWING_T__14_IN_category_scheme_173 = Set[1] + TOKENS_FOLLOWING_T__11_IN_category_class_202 = Set[4, 15] + TOKENS_FOLLOWING_WS_IN_category_class_204 = Set[15] + TOKENS_FOLLOWING_T__15_IN_category_class_207 = Set[13] + TOKENS_FOLLOWING_T__13_IN_category_class_209 = Set[14] + TOKENS_FOLLOWING_T__14_IN_category_class_211 = Set[40, 41, 42] + TOKENS_FOLLOWING_class_type_IN_category_class_213 = Set[14] + TOKENS_FOLLOWING_T__14_IN_category_class_215 = Set[1] + TOKENS_FOLLOWING_T__11_IN_category_title_240 = Set[4, 16] + TOKENS_FOLLOWING_WS_IN_category_title_242 = Set[16] + TOKENS_FOLLOWING_T__16_IN_category_title_245 = Set[13] + TOKENS_FOLLOWING_T__13_IN_category_title_247 = Set[14] + TOKENS_FOLLOWING_T__14_IN_category_title_249 = Set[4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43] + TOKENS_FOLLOWING_title_IN_category_title_251 = Set[14] + TOKENS_FOLLOWING_T__14_IN_category_title_253 = Set[1] + TOKENS_FOLLOWING_T__11_IN_category_rel_280 = Set[4, 17] + TOKENS_FOLLOWING_WS_IN_category_rel_282 = Set[17] + TOKENS_FOLLOWING_T__17_IN_category_rel_285 = Set[13] + TOKENS_FOLLOWING_T__13_IN_category_rel_287 = Set[14] + TOKENS_FOLLOWING_T__14_IN_category_rel_289 = Set[5, 6, 7, 10, 13, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42] + TOKENS_FOLLOWING_rel_IN_category_rel_291 = Set[14] + TOKENS_FOLLOWING_T__14_IN_category_rel_293 = Set[1] + TOKENS_FOLLOWING_T__11_IN_category_location_318 = Set[4, 18] + TOKENS_FOLLOWING_WS_IN_category_location_320 = Set[18] + TOKENS_FOLLOWING_T__18_IN_category_location_323 = Set[13] + TOKENS_FOLLOWING_T__13_IN_category_location_325 = Set[14] + TOKENS_FOLLOWING_T__14_IN_category_location_327 = Set[5, 6, 7, 10, 13, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42] + TOKENS_FOLLOWING_location_IN_category_location_329 = Set[14] + TOKENS_FOLLOWING_T__14_IN_category_location_331 = Set[1] + TOKENS_FOLLOWING_T__11_IN_category_attributes_370 = Set[4, 19] + TOKENS_FOLLOWING_WS_IN_category_attributes_372 = Set[19] + TOKENS_FOLLOWING_T__19_IN_category_attributes_375 = Set[13] + TOKENS_FOLLOWING_T__13_IN_category_attributes_377 = Set[14] + TOKENS_FOLLOWING_T__14_IN_category_attributes_379 = Set[5] + TOKENS_FOLLOWING_attribute_name_IN_category_attributes_383 = Set[4, 5, 14] + TOKENS_FOLLOWING_WS_IN_category_attributes_398 = Set[5] + TOKENS_FOLLOWING_attribute_name_IN_category_attributes_403 = Set[4, 5, 14] + TOKENS_FOLLOWING_T__14_IN_category_attributes_411 = Set[1] + TOKENS_FOLLOWING_T__11_IN_category_actions_441 = Set[4, 20] + TOKENS_FOLLOWING_WS_IN_category_actions_443 = Set[20] + TOKENS_FOLLOWING_T__20_IN_category_actions_446 = Set[13] + TOKENS_FOLLOWING_T__13_IN_category_actions_448 = Set[14] + TOKENS_FOLLOWING_T__14_IN_category_actions_450 = Set[5, 6, 7, 10, 13, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42] + TOKENS_FOLLOWING_action_location_IN_category_actions_454 = Set[4, 5, 6, 7, 10, 13, 14, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42] + TOKENS_FOLLOWING_WS_IN_category_actions_470 = Set[5, 6, 7, 10, 13, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42] + TOKENS_FOLLOWING_action_location_IN_category_actions_475 = Set[4, 5, 6, 7, 10, 13, 14, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42] + TOKENS_FOLLOWING_T__14_IN_category_actions_482 = Set[1] + TOKENS_FOLLOWING_T__21_IN_link_499 = Set[10] + TOKENS_FOLLOWING_T__10_IN_link_501 = Set[4, 22] + TOKENS_FOLLOWING_link_value_IN_link_503 = Set[1] + TOKENS_FOLLOWING_link_target_IN_link_value_525 = Set[11] + TOKENS_FOLLOWING_link_rel_IN_link_value_534 = Set[11] + TOKENS_FOLLOWING_link_self_IN_link_value_543 = Set[11] + TOKENS_FOLLOWING_link_category_IN_link_value_553 = Set[11] + TOKENS_FOLLOWING_link_attributes_IN_link_value_563 = Set[1, 11] + TOKENS_FOLLOWING_T__11_IN_link_value_572 = Set[1] + TOKENS_FOLLOWING_WS_IN_link_target_591 = Set[22] + TOKENS_FOLLOWING_T__22_IN_link_target_594 = Set[5, 6, 7, 10, 13, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42] + TOKENS_FOLLOWING_target_IN_link_target_596 = Set[23] + TOKENS_FOLLOWING_T__23_IN_link_target_598 = Set[1] + TOKENS_FOLLOWING_T__11_IN_link_rel_613 = Set[4, 17] + TOKENS_FOLLOWING_WS_IN_link_rel_615 = Set[17] + TOKENS_FOLLOWING_T__17_IN_link_rel_618 = Set[13] + TOKENS_FOLLOWING_T__13_IN_link_rel_620 = Set[14] + TOKENS_FOLLOWING_T__14_IN_link_rel_622 = Set[5, 6, 7, 10, 13, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42] + TOKENS_FOLLOWING_rel_IN_link_rel_624 = Set[14] + TOKENS_FOLLOWING_T__14_IN_link_rel_626 = Set[1] + TOKENS_FOLLOWING_T__11_IN_link_self_641 = Set[4, 24] + TOKENS_FOLLOWING_WS_IN_link_self_643 = Set[24] + TOKENS_FOLLOWING_T__24_IN_link_self_646 = Set[13] + TOKENS_FOLLOWING_T__13_IN_link_self_648 = Set[14] + TOKENS_FOLLOWING_T__14_IN_link_self_650 = Set[5, 6, 7, 10, 13, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42] + TOKENS_FOLLOWING_self_location_IN_link_self_652 = Set[14] + TOKENS_FOLLOWING_T__14_IN_link_self_654 = Set[1] + TOKENS_FOLLOWING_T__11_IN_link_category_669 = Set[4, 25] + TOKENS_FOLLOWING_WS_IN_link_category_671 = Set[25] + TOKENS_FOLLOWING_T__25_IN_link_category_674 = Set[13] + TOKENS_FOLLOWING_T__13_IN_link_category_676 = Set[14] + TOKENS_FOLLOWING_T__14_IN_link_category_678 = Set[5, 6, 7, 10, 13, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42] + TOKENS_FOLLOWING_category_name_IN_link_category_680 = Set[14] + TOKENS_FOLLOWING_T__14_IN_link_category_682 = Set[1] + TOKENS_FOLLOWING_T__11_IN_link_attributes_708 = Set[4, 5] + TOKENS_FOLLOWING_WS_IN_link_attributes_710 = Set[4, 5] + TOKENS_FOLLOWING_attribute_IN_link_attributes_713 = Set[1, 11] + TOKENS_FOLLOWING_T__26_IN_x_occi_attribute_734 = Set[10] + TOKENS_FOLLOWING_T__10_IN_x_occi_attribute_736 = Set[4, 5] + TOKENS_FOLLOWING_WS_IN_x_occi_attribute_738 = Set[4, 5] + TOKENS_FOLLOWING_attribute_IN_x_occi_attribute_741 = Set[1, 11] + TOKENS_FOLLOWING_T__11_IN_x_occi_attribute_743 = Set[1] + TOKENS_FOLLOWING_T__27_IN_x_occi_location_763 = Set[10] + TOKENS_FOLLOWING_T__10_IN_x_occi_location_765 = Set[4, 5, 6, 7, 10, 13, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42] + TOKENS_FOLLOWING_WS_IN_x_occi_location_767 = Set[5, 6, 7, 10, 13, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42] + TOKENS_FOLLOWING_location_IN_x_occi_location_770 = Set[1, 11] + TOKENS_FOLLOWING_T__11_IN_x_occi_location_772 = Set[1] + TOKENS_FOLLOWING_set_IN_uri_786 = Set[1, 5, 6, 7, 10, 13, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42] + TOKENS_FOLLOWING_LOALPHA_IN_term_876 = Set[1, 5, 7, 30, 39] + TOKENS_FOLLOWING_set_IN_term_878 = Set[1, 5, 7, 30, 39] + TOKENS_FOLLOWING_uri_IN_scheme_911 = Set[1] + TOKENS_FOLLOWING_set_IN_class_type_920 = Set[1] + TOKENS_FOLLOWING_set_IN_title_941 = Set[1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43] + TOKENS_FOLLOWING_uri_IN_rel_976 = Set[1] + TOKENS_FOLLOWING_uri_IN_location_984 = Set[1] + TOKENS_FOLLOWING_attribute_component_IN_attribute_1005 = Set[13, 33] + TOKENS_FOLLOWING_T__33_IN_attribute_1016 = Set[5] + TOKENS_FOLLOWING_attribute_component_IN_attribute_1020 = Set[13, 33] + TOKENS_FOLLOWING_T__13_IN_attribute_1031 = Set[7, 14, 33] + TOKENS_FOLLOWING_attribute_value_IN_attribute_1033 = Set[1] + TOKENS_FOLLOWING_attribute_component_IN_attribute_name_1077 = Set[1, 33] + TOKENS_FOLLOWING_T__33_IN_attribute_name_1088 = Set[5] + TOKENS_FOLLOWING_attribute_component_IN_attribute_name_1092 = Set[1, 33] + TOKENS_FOLLOWING_LOALPHA_IN_attribute_component_1110 = Set[1, 5, 7, 30, 39] + TOKENS_FOLLOWING_set_IN_attribute_component_1112 = Set[1, 5, 7, 30, 39] + TOKENS_FOLLOWING_string_IN_attribute_value_1142 = Set[1] + TOKENS_FOLLOWING_number_IN_attribute_value_1148 = Set[1] + TOKENS_FOLLOWING_T__14_IN_string_1163 = Set[4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43] + TOKENS_FOLLOWING_set_IN_string_1165 = Set[4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43] + TOKENS_FOLLOWING_T__14_IN_string_1193 = Set[1] + TOKENS_FOLLOWING_DIGIT_IN_number_1205 = Set[1, 7, 33] + TOKENS_FOLLOWING_T__33_IN_number_1210 = Set[7] + TOKENS_FOLLOWING_DIGIT_IN_number_1212 = Set[1, 7] + TOKENS_FOLLOWING_uri_IN_action_location_1226 = Set[1] + TOKENS_FOLLOWING_uri_IN_target_1235 = Set[1] + TOKENS_FOLLOWING_uri_IN_self_location_1243 = Set[1] + TOKENS_FOLLOWING_uri_IN_category_name_1251 = Set[1] end # class Parser < ANTLR3::Parser - at_exit { Parser.main( ARGV ) } if __FILE__ == $0 + at_exit { Parser.main(ARGV) } if __FILE__ == $0 end diff --git a/lib/occi/backend/Dummy.rb b/lib/occi/backend/Dummy.rb index 1039d66..74e1567 100644 --- a/lib/occi/backend/Dummy.rb +++ b/lib/occi/backend/Dummy.rb @@ -20,81 +20,108 @@ ############################################################################## require 'occi/backend/Manager' +require 'hashie/hash' require 'occi/Log' +require 'uuidtools' +require 'pstore' module OCCI module Backend # --------------------------------------------------------------------------------------------------------------------- - class Dummy - + class Dummy + + def initialize + @store = PStore.new('collection', thread_safe=true) + @store.transaction do + @store['resources'] ||= [] + @store['links'] ||= [] + end + end + # --------------------------------------------------------------------------------------------------------------------- # Operation mappings OPERATIONS = {} - + OPERATIONS["http://schemas.ogf.org/occi/infrastructure#compute"] = { - - # Generic resource operations - :deploy => :resource_deploy, - :update_state => :resource_update_state, - :refresh => :resource_refresh, - :delete => :resource_delete, - - # Compute specific resource operations - :start => :action_dummy, - :stop => :action_dummy, - :restart => :action_dummy, - :suspend => :action_dummy + + # Generic resource operations + :deploy => :resource_deploy, + :update_state => :resource_update_state, + :refresh => :resource_refresh, + :delete => :resource_delete, + + # Compute specific resource operations + :start => :action_dummy, + :stop => :action_dummy, + :restart => :action_dummy, + :suspend => :action_dummy } OPERATIONS["http://schemas.ogf.org/occi/infrastructure#network"] = { - - # Generic resource operations - :deploy => :resource_deploy, - :update_state => :resource_update_state, - :refresh => :resource_refresh, - :delete => :resource_delete, - - # Network specific resource operations - :up => :action_dummy, - :down => :action_dummy + + # Generic resource operations + :deploy => :resource_deploy, + :update_state => :resource_update_state, + :refresh => :resource_refresh, + :delete => :resource_delete, + + # Network specific resource operations + :up => :action_dummy, + :down => :action_dummy } OPERATIONS["http://schemas.ogf.org/occi/infrastructure#storage"] = { - # Generic resource operations - :deploy => :resource_deploy, - :update_state => :resource_update_state, - :refresh => :resource_refresh, - :delete => :resource_delete, - - # Network specific resource operations - :online => :action_dummy, - :offline => :action_dummy, - :backup => :action_dummy, - :snapshot => :action_dummy, - :resize => :action_dummy + # Generic resource operations + :deploy => :resource_deploy, + :update_state => :resource_update_state, + :refresh => :resource_refresh, + :delete => :resource_delete, + + # Network specific resource operations + :online => :action_dummy, + :offline => :action_dummy, + :backup => :action_dummy, + :snapshot => :action_dummy, + :resize => :action_dummy } OPERATIONS["http://schemas.ogf.org/gwdg#nfsstorage"] = { - # Generic resource operations - :deploy => :resource_deploy, - :update_state => :resource_update_state, - :refresh => :resource_refresh, - :delete => :resource_delete, - } - - # --------------------------------------------------------------------------------------------------------------------- + # Generic resource operations + :deploy => :resource_deploy, + :update_state => :resource_update_state, + :refresh => :resource_refresh, + :delete => :resource_delete, + } + + # --------------------------------------------------------------------------------------------------------------------- def register_existing_resources + @store.transaction(read_only=true) do + entities = @store['resources'] + @store['links'] + entities.each do |entity| + kind = OCCI::Registry.get_by_id(entity.kind) + OCCI::Log.debug('Entity from dummy backend #{entity}') + kind.entities << entity + OCCI::Log.debug("Entities in kind #{kind.type_identifier}: #{kind.entities.size}") + end + end end + # TODO: register user defined mixins + # --------------------------------------------------------------------------------------------------------------------- def resource_deploy(resource) - OCCI::Log.debug("Deploying resource '#{resource.attributes['occi.core.title']}'...") + OCCI::Log.debug("### DUMMY: Deploying resource with title #{resource.title}") + resource.id = UUIDTools::UUID.timestamp_create.to_s + @store.transaction do + @store['resources'] << resource + end + OCCI::Log.debug(@collection) end - + # --------------------------------------------------------------------------------------------------------------------- def resource_refresh(resource) OCCI::Log.debug("Refreshing resource '#{resource.attributes['occi.core.title']}'...") @@ -108,6 +135,9 @@ def resource_update_state(resource) # --------------------------------------------------------------------------------------------------------------------- def resource_delete(resource) OCCI::Log.debug("Deleting resource '#{resource.attributes['occi.core.title']}'...") + @store.transaction do + @store['resources'].delete_if { |res| res.id == resource.id } + end end # --------------------------------------------------------------------------------------------------------------------- diff --git a/lib/occi/backend/Manager.rb b/lib/occi/backend/Manager.rb index 39b7e46..90faf7f 100644 --- a/lib/occi/backend/Manager.rb +++ b/lib/occi/backend/Manager.rb @@ -49,10 +49,10 @@ module OCCI module Backend # --------------------------------------------------------------------------------------------------------------------- - RESOURCE_DEPLOY = :deploy - RESOURCE_UPDATE_STATE = :update_state - RESOURCE_REFRESH = :refresh - RESOURCE_DELETE = :delete + RESOURCE_DEPLOY = :deploy + RESOURCE_UPDATE_STATE = :update_state + RESOURCE_REFRESH = :refresh + RESOURCE_DELETE = :delete # --------------------------------------------------------------------------------------------------------------------- class Manager @@ -60,46 +60,46 @@ class Manager # --------------------------------------------------------------------------------------------------------------------- private # --------------------------------------------------------------------------------------------------------------------- - - @@backends_classes = {} + + @@backends_classes = {} @@backends_operations = {} - + # --------------------------------------------------------------------------------------------------------------------- public # --------------------------------------------------------------------------------------------------------------------- # --------------------------------------------------------------------------------------------------------------------- def self.register_backend(backend_class, operations) - + # Get ident of backend = class name downcased -# backend_ident = Object.const_get(backend_class).name.downcase + # backend_ident = Object.const_get(backend_class).name.downcase backend_ident = backend_class.name.downcase - @@backends_classes[backend_ident] = backend_class - @@backends_operations[backend_ident] = operations + @@backends_classes[backend_ident] = backend_class + @@backends_operations[backend_ident] = operations end # --------------------------------------------------------------------------------------------------------------------- def self.signal_resource(backend, operation, resource, operation_parameters = nil) - resource_type = resource.kind.type_identifier + resource_type = resource.kind backend_ident = backend.class.name.downcase - - raise OCCI::BackendError, "Unknown backend: '#{backend_ident}'" unless @@backends_classes.has_key?(backend_ident) - + + raise OCCI::BackendError, "Unknown backend: '#{backend_ident}'" unless @@backends_classes.has_key?(backend_ident) + operations = @@backends_operations[backend_ident] - - raise OCCI::BackendError, "Resource type '#{resource_type}' not supported!" unless operations.has_key?(resource_type) + + raise OCCI::BackendError, "Resource type '#{resource_type}' not supported!" unless operations.has_key?(resource_type) raise OCCI::BackendError, "Operation '#{operation}' not supported on resource category '#{resource_type}'!" unless operations[resource_type].has_key?(operation.to_sym) - + # Delegate - + if operations[resource_type][operation.to_sym].nil? OCCI::Log.debug("No backend method configured => doing nothing...") return end - + if operation_parameters.nil? # Generic resource operation backend.send(operations[resource_type][operation.to_sym], resource) @@ -114,11 +114,11 @@ def self.signal_resource(backend, operation, resource, operation_parameters = ni def self.delegate_action(backend, action, parameters, resource) OCCI::Log.debug("Delegating invocation of action [#{action}] on resource [#{resource}] with parameters [#{parameters}] to backend...") - + # Verify state_machine = resource.state_machine raise "Action [#{action}] not valid for current state [#{state_machine.current_state}] of resource [#{resource}]!" if !state_machine.check_transition(action) - + # Use action term as ident operation = action.category.term.to_s @@ -127,12 +127,12 @@ def self.delegate_action(backend, action, parameters, resource) signal_resource(backend, operation, resource, parameters) state_machine.transition(action) - signal_resource(backend, OCCI::Backend::RESOURCE_UPDATE_STATE,resource) + signal_resource(backend, OCCI::Backend::RESOURCE_UPDATE_STATE, resource) rescue OCCI::BackendError OCCI::Log.error("Action invocation failed!") raise - end + end end end end diff --git a/lib/occi/backend/ec2/Compute.rb b/lib/occi/backend/ec2/Compute.rb index 2c5dcca..19b454e 100644 --- a/lib/occi/backend/ec2/Compute.rb +++ b/lib/occi/backend/ec2/Compute.rb @@ -28,23 +28,23 @@ module EC2 # --------------------------------------------------------------------------------------------------------------------- module Compute - + # --------------------------------------------------------------------------------------------------------------------- private # --------------------------------------------------------------------------------------------------------------------- - + def get_backend_instance(compute) # get the ec2 interface ec2 = OCCI::Backend::EC2.get_ec2_interface() - + # get the ec2 backend instance backend_instance = ec2.instances[compute.backend[:id]] - + raise "Problems refreshing compute instance: An instance with the EC2 ID #{compute.backend[:id]} could not be found." if backend_instance.nil? # return the instance return backend_instance end - + def has_console_link(compute) compute.links.each do |link| OCCI::Log.debug("Link: #{link}") @@ -54,10 +54,10 @@ def has_console_link(compute) end return false end - + def key_pair_exists(key_name) ec2 = OCCI::Backend::EC2.get_ec2_interface() - + ec2.key_pairs.each do |key| if key.name == "default_occi_key" return true @@ -68,7 +68,7 @@ def key_pair_exists(key_name) public # --------------------------------------------------------------------------------------------------------------------- - + # --------------------------------------------------------------------------------------------------------------------- def compute_deploy(compute) OCCI::Log.debug("Deploying EC2 instance.") @@ -90,7 +90,7 @@ def compute_deploy(compute) # get the ec2 interface ec2 = OCCI::Backend::EC2.get_ec2_interface() - + # create an instance if key_pair_exists("default_occi_key") backend_instance = ec2.instances.create(:image_id => image_id, @@ -100,13 +100,13 @@ def compute_deploy(compute) backend_instance = ec2.instances.create(:image_id => image_id, :instance_type => instance_type) end - + # save the id of the instance compute.backend[:id] = backend_instance.id - + # link it to the private ec2 network OCCI::Log.debug("Linking instance to \"/network/ec2_private_network\".") - private_network = OCCI::Rendering::HTTP::LocationRegistry.get_object_at_location("/network/ec2_private_network") + private_network = OCCI::Rendering::HTTP::LocationRegistry.get_object("/network/ec2_private_network") attributes = OCCI::Core::Attributes.new() attributes["occi.networkinterface.interface"] = "" attributes["occi.core.source"] = compute.get_location @@ -121,10 +121,10 @@ def compute_deploy(compute) compute.links << private_networkinterface private_network.links << private_networkinterface OCCI::Rendering::HTTP::LocationRegistry.register(private_networkinterface.get_location, private_networkinterface) - + # link it to the public ec2 network OCCI::Log.debug("Linking instance to \"/network/ec2_public_network\".") - public_network = OCCI::Rendering::HTTP::LocationRegistry.get_object_at_location("/network/ec2_public_network") + public_network = OCCI::Rendering::HTTP::LocationRegistry.get_object("/network/ec2_public_network") attributes = OCCI::Core::Attributes.new() attributes["occi.networkinterface.interface"] = "" attributes["occi.core.source"] = compute.get_location @@ -142,29 +142,29 @@ def compute_deploy(compute) OCCI::Log.debug("Deployed EC2 instance with EC2 ID: #{compute.backend[:id]}") end - + # --------------------------------------------------------------------------------------------------------------------- def compute_refresh(compute) OCCI::Log.debug("Refreshing EC2 compute object with backend ID: #{compute.backend[:id]}") - + # get the ec2 backend instance backend_instance = get_backend_instance(compute) - + # check if there are any problems with the backend instance if backend_instance.nil? OCCI::Log.debug("Problems refreshing compute instance: An instance with the EC2 ID #{compute.backend[:id]} could not be found.") return end - + # update the state compute_update_state(compute) OCCI::Log.debug("Refreshed EC2 compute object with backend ID: #{compute.backend[:id]}") - + # setting the architecture compute.attributes["occi.compute.architecture"] = backend_instance.architecture.to_s compute.attributes["ec2.compute.platform"] = backend_instance.platform compute.attributes["ec2.compute.kernel_id"] = backend_instance.kernel_id - + # update public and private ip compute.links.each do |link| if link.kind.term == "networkinterface" and link.backend[:backend_id] == backend_instance.id @@ -189,7 +189,7 @@ def compute_refresh(compute) end end end - + # create the console link if not already existent and if in state active if compute.state_machine.current_state == OCCI::Infrastructure::Compute::STATE_ACTIVE and not has_console_link(compute) and backend_instance.key_name == "default_occi_key" # create a ConsoleLink @@ -207,39 +207,43 @@ def compute_refresh(compute) OCCI::Rendering::HTTP::LocationRegistry.register(location, console_link) end end - + # --------------------------------------------------------------------------------------------------------------------- def compute_update_state(compute) # get the ec2 backend instance backend_instance = get_backend_instance(compute) - + # map the ec2 state to an OCCI state OCCI::Log.debug("Current EC2 VM state is: #{backend_instance.status}") state = case backend_instance.status - when :running then OCCI::Infrastructure::Compute::STATE_ACTIVE - when :pending, :shutting_down, :stopping, :terminated then OCCI::Infrastructure::Compute::STATE_INACTIVE - when :stopped then OCCI::Infrastructure::Compute::STATE_SUSPENDED - else OCCI::Infrastructure::Compute::STATE_INACTIVE - end + when :running then + OCCI::Infrastructure::Compute::STATE_ACTIVE + when :pending, :shutting_down, :stopping, :terminated then + OCCI::Infrastructure::Compute::STATE_INACTIVE + when :stopped then + OCCI::Infrastructure::Compute::STATE_SUSPENDED + else + OCCI::Infrastructure::Compute::STATE_INACTIVE + end # set the state compute.state_machine.set_state(state) compute.attributes['occi.compute.state'] = compute.state_machine.current_state.name end - + # --------------------------------------------------------------------------------------------------------------------- def compute_delete(compute) OCCI::Log.debug("Deleting EC2 Compute instance with EC2 ID #{compute.backend[:id]}") - + # get the ec2 backend instance backend_instance = get_backend_instance(compute) - + if backend_instance.nil? OCCI::Log.debug("Problems refreshing compute instance: An instance with the EC2 ID #{compute.backend[:id]} could not be found.") return end # terminate the instance backend_instance.terminate() - + # delete networklinks to the private and public network and the ConsoleLink compute.links.each do |link| if link.backend[:backend_id] == backend_instance.id @@ -250,57 +254,57 @@ def compute_delete(compute) end OCCI::Log.debug("Deleted EC2 Compute instance with EC2 ID #{compute.backend[:id]}") end - + # --------------------------------------------------------------------------------------------------------------------- # COMPUTE ACTIONS # --------------------------------------------------------------------------------------------------------------------- # COMPUTE Action start def compute_start(compute, parameters=nil) OCCI::Log.debug("Starting EC2 VM with EC2 instance ID #{compute.backend[:id]}") - + # get the ec2 backend instance backend_instance = get_backend_instance(compute) - + # suspend the instance (in EC2 lingo stop it) backend_instance.start() OCCI::Log.debug("Started EC2 VM with EC2 instance ID #{compute.backend[:id]}") end - + # --------------------------------------------------------------------------------------------------------------------- # Action stop def compute_stop(compute, parameters=nil) OCCI::Log.debug("Stopping EC2 VM with EC2 instance ID #{compute.backend[:id]}") - + # get the ec2 backend instance backend_instance = get_backend_instance(compute) - + # stop the instance backend_instance.stop() OCCI::Log.debug("Stopped EC2 VM with EC2 instance ID #{compute.backend[:id]}") end - + # --------------------------------------------------------------------------------------------------------------------- # Action restart def compute_restart(compute, parameters=nil) OCCI::Log.debug("Restarting EC2 VM with EC2 instance ID #{compute.backend[:id]}") - + # get the ec2 backend instance backend_instance = get_backend_instance(compute) - + # restart the instance backend_instance.reboot() OCCI::Log.debug("Restarted EC2 VM with EC2 instance ID #{compute.backend[:id]}") end - + # --------------------------------------------------------------------------------------------------------------------- # Action suspend def compute_suspend(compute, parameters=nil) OCCI::Log.warning("Stop suspend is not supported on EC2 Compute instances.") end - + end - - end - end + + end + end end diff --git a/lib/occi/backend/ec2/EC2.rb b/lib/occi/backend/ec2/EC2.rb index 14a1801..6fce13d 100644 --- a/lib/occi/backend/ec2/EC2.rb +++ b/lib/occi/backend/ec2/EC2.rb @@ -23,7 +23,7 @@ require 'aws-sdk' # EC2 backend -require 'occi/backend/ec2/Compute' +#require 'occi/backend/ec2/Compute' # for XML parsing (gem = "xml-simple") require 'xmlsimple' @@ -34,113 +34,113 @@ module OCCI module Backend module EC2 - # --------------------------------------------------------------------------------------------------------------------- - - begin - ### Create networks - # Create private network - attributes = OCCI::Core::Attributes.new() - attributes['occi.core.title'] = "ec2_private_network" - attributes['occi.core.summary'] = "This network contains private links to all EC2 compute instances." - mixins = [] - private_network = OCCI::Infrastructure::Network.new(attributes, mixins) - OCCI::Rendering::HTTP::LocationRegistry.register("/network/ec2_private_network", private_network) - private_network.state_machine.set_state(OCCI::Infrastructure::Network::STATE_ACTIVE) - private_network.attributes['occi.network.state'] = "active" - - # Create public network - attributes = OCCI::Core::Attributes.new() - attributes['occi.core.title'] = "ec2_public_network" - attributes['occi.core.summary'] = "This network contains public links to all EC2 compute instances." - mixins = [] - public_network = OCCI::Infrastructure::Network.new(attributes, mixins) - OCCI::Rendering::HTTP::LocationRegistry.register("/network/ec2_public_network", public_network) - public_network.state_machine.set_state(OCCI::Infrastructure::Network::STATE_ACTIVE) - public_network.attributes['occi.network.state'] = "active" - end - + # --------------------------------------------------------------------------------------------------------------------- + + #begin + # ### Create networks + # # Create private network + # attributes = OCCI::Core::Attributes.new() + # attributes['occi.core.title'] = "ec2_private_network" + # attributes['occi.core.summary'] = "This network contains private links to all EC2 compute instances." + # mixins = [] + # private_network = OCCI::Infrastructure::Network.new(attributes, mixins) + # OCCI::Rendering::HTTP::LocationRegistry.register("/network/ec2_private_network", private_network) + # private_network.state_machine.set_state(OCCI::Infrastructure::Network::STATE_ACTIVE) + # private_network.attributes['occi.network.state'] = "active" + # + # # Create public network + # attributes = OCCI::Core::Attributes.new() + # attributes['occi.core.title'] = "ec2_public_network" + # attributes['occi.core.summary'] = "This network contains public links to all EC2 compute instances." + # mixins = [] + # public_network = OCCI::Infrastructure::Network.new(attributes, mixins) + # OCCI::Rendering::HTTP::LocationRegistry.register("/network/ec2_public_network", public_network) + # public_network.state_machine.set_state(OCCI::Infrastructure::Network::STATE_ACTIVE) + # public_network.attributes['occi.network.state'] = "active" + #end + public - + def self.get_ec2_interface ec2 = AWS::EC2.new return ec2.regions[$config["avail_zone"]] end - + class EC2 - include Compute + #include Compute # --------------------------------------------------------------------------------------------------------------------- # Operation mappings OPERATIONS = {} - + OPERATIONS["http://schemas.ogf.org/occi/infrastructure#compute"] = { - + # Generic resource operations - :deploy => :compute_deploy, - :update_state => :compute_update_state, - :refresh => :compute_refresh, - :delete => :compute_delete, - - # Compute specific resource operations - :start => :compute_start, - :stop => :compute_stop, - :restart => :compute_restart, - :suspend => nil + :deploy => :compute_deploy, + :update_state => :compute_update_state, + :refresh => :compute_refresh, + :delete => :compute_delete, + + # Compute specific resource operations + :start => :compute_start, + :stop => :compute_stop, + :restart => :compute_restart, + :suspend => nil } OPERATIONS["http://schemas.ogf.org/occi/infrastructure#network"] = { - - # Generic resource operations - :deploy => nil, - :update_state => nil, - :refresh => nil, - :delete => nil, - - # Network specific resource operations - :up => nil, - :down => nil + + # Generic resource operations + :deploy => nil, + :update_state => nil, + :refresh => nil, + :delete => nil, + + # Network specific resource operations + :up => nil, + :down => nil } OPERATIONS["http://schemas.ogf.org/occi/infrastructure#storage"] = { - # Generic resource operations - :deploy => nil, - :update_state => nil, - :refresh => nil, - :delete => nil, - - # Network specific resource operations - :online => nil, - :offline => nil, - :backup => nil, - :snapshot => nil, - :resize => nil + # Generic resource operations + :deploy => nil, + :update_state => nil, + :refresh => nil, + :delete => nil, + + # Network specific resource operations + :online => nil, + :offline => nil, + :backup => nil, + :snapshot => nil, + :resize => nil } OPERATIONS["http://schemas.ogf.org/gwdg#nfsstorage"] = { - # Generic resource operations - :deploy => nil, - :update_state => nil, - :refresh => nil, - :delete => nil + # Generic resource operations + :deploy => nil, + :update_state => nil, + :refresh => nil, + :delete => nil } - + # --------------------------------------------------------------------------------------------------------------------- - + def initialize(access_key_id, secret_access_key) # EC2 access key AWS.config( - :access_key_id => access_key_id, - :secret_access_key => secret_access_key) + :access_key_id => access_key_id, + :secret_access_key => secret_access_key) end - + def register_templates OCCI::Log.debug("Loading EC2 templates.") - + # import Compute Resource Templates from etc/ec2_templates/resource_templates.xml xml = XmlSimple.xml_in("etc/ec2_templates/resource_templates.xml") xml["instance"].each do |instance| @@ -150,11 +150,11 @@ def register_templates attributes = OCCI::Core::Attributes.new() actions = [] entities = [] - related = [ OCCI::Infrastructure::ResourceTemplate::MIXIN ] + related = [OCCI::Infrastructure::ResourceTemplate::MIXIN] mixin = OCCI::Core::Mixin.new(term, scheme, title, attributes, actions, related, entities) OCCI::CategoryRegistry.register(mixin) end - + ## import image templates # get the ec2 interface ec2 = OCCI::Backend::EC2.get_ec2_interface() @@ -166,24 +166,24 @@ def register_templates attributes = OCCI::Core::Attributes.new() actions = [] entities = [] - related = [ OCCI::Infrastructure::OSTemplate::MIXIN ] + related = [OCCI::Infrastructure::OSTemplate::MIXIN] mixin = OCCI::Core::Mixin.new(term, scheme, title, attributes, actions, related, entities) OCCI::CategoryRegistry.register(mixin) end OCCI::Log.debug("Finished loading EC2 templates.") end - - + + # --------------------------------------------------------------------------------------------------------------------- def register_existing_resources - + end - # --------------------------------------------------------------------------------------------------------------------- + # --------------------------------------------------------------------------------------------------------------------- def resource_deploy(resource) OCCI::Log.debug("Deploying resource '#{resource.attributes['occi.core.title']}'...") end - + # --------------------------------------------------------------------------------------------------------------------- def resource_refresh(resource) OCCI::Log.debug("Refreshing resource '#{resource.attributes['occi.core.title']}'...") diff --git a/lib/occi/backend/opennebula/Compute.rb b/lib/occi/backend/opennebula/Compute.rb index 1715bf5..d77e081 100644 --- a/lib/occi/backend/opennebula/Compute.rb +++ b/lib/occi/backend/opennebula/Compute.rb @@ -29,11 +29,11 @@ module OpenNebula # --------------------------------------------------------------------------------------------------------------------- module Compute - + TEMPLATECOMPUTERAWFILE = 'occi_one_template_compute.erb' - + # --------------------------------------------------------------------------------------------------------------------- -# private + # private # --------------------------------------------------------------------------------------------------------------------- # --------------------------------------------------------------------------------------------------------------------- @@ -49,85 +49,85 @@ def compute_parse_backend_object(backend_object) else occi_id = backend_object['TEMPLATE/OCCI_ID'] end - + mixins = [] mixins << OCCI::Backend::ONE::VirtualMachine::MIXIN - + attributes = {} - # parse all parameters from OpenNebula to OCCI - attributes['occi.core.id'] = occi_id - attributes['occi.core.title'] = backend_object['NAME'] - attributes['occi.core.summary'] = backend_object['TEMPLATE/DESCRIPTION'] - attributes['occi.compute.cores'] = backend_object['TEMPLATE/VCPU'] - +# parse all parameters from OpenNebula to OCCI + attributes['occi.core.id'] = occi_id + attributes['occi.core.title'] = backend_object['NAME'] + attributes['occi.core.summary'] = backend_object['TEMPLATE/DESCRIPTION'] + attributes['occi.compute.cores'] = backend_object['TEMPLATE/VCPU'] + if backend_object['TEMPLATE/ARCHITECTURE'] == "x86_64" attributes['occi.compute.architecture'] = "x64" else attributes['occi.compute.architecture'] = "x86" end - attributes['occi.compute.memory'] = backend_object['TEMPLATE/MEMORY'] + attributes['occi.compute.memory'] = backend_object['TEMPLATE/MEMORY'] attributes['opennebula.vm.cpu_reservation'] = backend_object['TEMPLATE/CPU'] - attributes['opennebula.vm.boot'] = backend_object['TEMPLATE/BOOT'] - + attributes['opennebula.vm.boot'] = backend_object['TEMPLATE/BOOT'] + # check if object already exists - occi_object = OCCI::Rendering::HTTP::LocationRegistry.get_object_at_location('/compute/' + occi_id) + occi_object = OCCI::Rendering::HTTP::LocationRegistry.get_object('/compute/' + occi_id) if occi_object.nil? - occi_object = OCCI::Infrastructure::Compute.new(attributes,mixins) + occi_object = OCCI::Infrastructure::Compute.new(attributes, mixins) occi_object.backend[:id] = backend_object.id OCCI::Rendering::HTTP::LocationRegistry.register(occi_object.get_location, occi_object) else # ALI start -# id= backend_object.id -# OCCI::Log.debug("--- Monitoring start backend id : #{id}") -# watch_client = OneWatchClient::VmWatchClient.new -# monitoring_resources = [ :cpu_usage, -# :mem_usage, -# :net_rx, -# :net_tx -# ] -# vm_monitoring = watch_client.resource_monitoring(id.to_i,monitoring_resources) -# occi_object.mixins.each do |mixin| -# attributes['cpu'] = vm_monitoring[:monitoring][:cpu_usage].join(',') if mixin.term == "rxtot" -# attributes['memory'] = vm_monitoring[:monitoring][:mem_usage].join(',') if mixin.term == "memory" -# attributes['net_rx'] = vm_monitoring[:monitoring][:net_rx].join(',') if mixin.term == "net_rx" -# attributes['net_tx'] = vm_monitoring[:monitoring][:net_tx].join(',') if mixin.term == "net_tx" -# attributes['net_tx'] = (vm_monitoring[:monitoring][:net_tx]).join(',') if mixin.term == "net_tx" -# end + # id= backend_object.id + # OCCI::Log.debug("--- Monitoring start backend id : #{id}") + # watch_client = OneWatchClient::VmWatchClient.new + # monitoring_resources = [ :cpu_usage, + # :mem_usage, + # :net_rx, + # :net_tx + # ] + # vm_monitoring = watch_client.resource_monitoring(id.to_i,monitoring_resources) + # occi_object.mixins.each do |mixin| + # attributes['cpu'] = vm_monitoring[:monitoring][:cpu_usage].join(',') if mixin.term == "rxtot" + # attributes['memory'] = vm_monitoring[:monitoring][:mem_usage].join(',') if mixin.term == "memory" + # attributes['net_rx'] = vm_monitoring[:monitoring][:net_rx].join(',') if mixin.term == "net_rx" + # attributes['net_tx'] = vm_monitoring[:monitoring][:net_tx].join(',') if mixin.term == "net_tx" + # attributes['net_tx'] = (vm_monitoring[:monitoring][:net_tx]).join(',') if mixin.term == "net_tx" + # end # ALI end - + occi_object.attributes.merge!(attributes) end - + # VNC handling if backend_object['TEMPLATE/GRAPHICS/TYPE'] == 'vnc' \ and backend_object['HISTORY_RECORDS/HISTORY/HOSTNAME'] \ and not $config[:novnc_path].nil? \ and not $config[:vnc_proxy_base_port].nil? - + occi_object.mixins << OCCI::Backend::ONE::VNC::MIXIN - + vnc_host = backend_object['HISTORY_RECORDS/HISTORY/HOSTNAME'] vnc_port = backend_object['TEMPLATE/GRAPHICS/PORT'] - + vnc_proxy_host = URI.parse($config[:server]).host - + # The noVNC proxy_port proxy_port = $config[:vnc_proxy_base_port].to_i + vnc_port.to_i - + OCCI::Log.debug("NOVNC path: #{$config[:novnc_path]}") OCCI::Log.debug("Graphics type: #{backend_object['TEMPLATE/GRAPHICS/TYPE']}") OCCI::Log.debug("VNC base port: #{$config[:vnc_proxy_base_port]}") OCCI::Log.debug("VNC port: #{vnc_port}") OCCI::Log.debug("VNC host: #{vnc_host}") - + if occi_object.attributes['opennebula.vm.vnc'].nil? or occi_object.backend[:novnc_pipe].nil? - + # CREATE PROXY FOR VNC SERVER begin novnc_cmd = "#{$config[:novnc_path]}/utils/websockify" pipe = IO.popen("#{novnc_cmd} --web #{$config[:novnc_path]} #{proxy_port} #{vnc_host}:#{vnc_port}") - + if pipe vnc_url = $config[:server].chomp('/') + ':' + vnc_port + '/vnc_auto.html?host=' + vnc_proxy_host + '&port=' + vnc_port OCCI::Log.debug("VNC URL: #{vnc_url}") @@ -140,13 +140,13 @@ def compute_parse_backend_object(backend_object) end end end - + occi_object.backend[:id] = backend_object.id occi_object = self.compute_parse_links(occi_object, backend_object) OCCI::Log.info("OCCI compute object created/updated") return occi_object end - + # --------------------------------------------------------------------------------------------------------------------- # PARSE OPENNEBULA DEPENDENCIES TO E.G. STORAGE AND NETWORK LINKS def compute_parse_links(occi_object, backend_object) @@ -170,7 +170,7 @@ def compute_parse_links(occi_object, backend_object) # check if link already exists occi_id = self.generate_occi_id(OCCI::Infrastructure::StorageLink::KIND, disk['IMAGE_ID'].to_s) storagelink_location = OCCI::Rendering::HTTP::LocationRegistry.get_location_of_object(OCCI::Infrastructure::StorageLink::KIND) - link = OCCI::Rendering::HTTP::LocationRegistry.get_object_at_location(storagelink_location + occi_id) + link = OCCI::Rendering::HTTP::LocationRegistry.get_object(storagelink_location + occi_id) if link.nil? # create new link attributes['occi.core.id'] = occi_id @@ -181,7 +181,7 @@ def compute_parse_links(occi_object, backend_object) target.links.push(link).uniq! OCCI::Log.debug("Link successfully created") end - + #create links for all network instances backend_object.each('TEMPLATE/NIC') do |nic| attributes = {} @@ -205,7 +205,7 @@ def compute_parse_links(occi_object, backend_object) # check if link already exists occi_id = self.generate_occi_id(OCCI::Infrastructure::Networkinterface::KIND, nic['NETWORK_ID'].to_s) networkinterface_location = OCCI::Rendering::HTTP::LocationRegistry.get_location_of_object(OCCI::Infrastructure::Networkinterface::KIND) - link = OCCI::Rendering::HTTP::LocationRegistry.get_object_at_location(networkinterface_location + occi_id) + link = OCCI::Rendering::HTTP::LocationRegistry.get_object(networkinterface_location + occi_id) if link.nil? # create new link attributes['occi.core.id'] = occi_id @@ -218,23 +218,23 @@ def compute_parse_links(occi_object, backend_object) target.links.push(link).uniq! OCCI::Log.debug("Link successfully created") end - + return occi_object end # --------------------------------------------------------------------------------------------------------------------- # ALI: Monitoring -# def monitor(parameter) -# backend_object = VirtualMachine.new(VirtualMachine.build_xml(@backend[:id]), $backend.one_client) -# backend_object.info -# occi_object = parse_backend_object(backend_object) -# monitoring_resources = [ :cpu] if parameter == "cpu" -# monitoring_resources = [ :memory] if parameter == "memory" -# monitoring_resources = [ :net_rx] if parameter == "net_rx" -# monitoring_resources = [:net_tx] if parameter == "net_tx" -# occi_object.attributes["compute.cpu.value"]= watch_client.resource_monitoring(occi_object.backend[:id],monitoring_resources) -# end - + # def monitor(parameter) + # backend_object = VirtualMachine.new(VirtualMachine.build_xml(@backend[:id]), $backend.one_client) + # backend_object.info + # occi_object = parse_backend_object(backend_object) + # monitoring_resources = [ :cpu] if parameter == "cpu" + # monitoring_resources = [ :memory] if parameter == "memory" + # monitoring_resources = [ :net_rx] if parameter == "net_rx" + # monitoring_resources = [:net_tx] if parameter == "net_tx" + # occi_object.attributes["compute.cpu.value"]= watch_client.resource_monitoring(occi_object.backend[:id],monitoring_resources) + # end + # --------------------------------------------------------------------------------------------------------------------- public # --------------------------------------------------------------------------------------------------------------------- @@ -245,63 +245,63 @@ def compute_deploy(compute) # TODO: figure out templates # backend_object=Template.new(Template.build_xml, $backend.one_client) template_mixin = compute.mixins.select { |m| m.related == OCCI::Infrastructure::ResourceTemplate::MIXIN } - + if template_mixin.empty? - + backend_object = VirtualMachine.new(VirtualMachine.build_xml, @one_client) - + compute_erb = ComputeERB.new - - compute_erb.compute = compute - compute_erb.storage = [] - compute_erb.networks = [] - compute_erb.external_storage = [] - compute_erb.nfs_mounts = [] - + + compute_erb.compute = compute + compute_erb.storage = [] + compute_erb.networks = [] + compute_erb.external_storage = [] + compute_erb.nfs_mounts = [] + if compute.links != nil compute.links.each do |link| OCCI::Log.debug("Processing link: #{link.kind.type_identifier}, attributes: #{link.attributes.inspect}") target_URI = link.attributes['occi.core.target'] if URI.parse(link.attributes['occi.core.target']).absolute? - target = OCCI::Rendering::HTTP::LocationRegistry.get_object_at_location(link.attributes['occi.core.target']) - + target = OCCI::Rendering::HTTP::LocationRegistry.get_object(link.attributes['occi.core.target']) + case link.kind.term - when 'storagelink' - # TODO: incorporate mountpoint here (e.g. occi.storagelink.mountpoint ) - # Check for nfs mount points - if $nfs_support - if target.kind == OCCI::Infrastructure::NFSStorage::KIND - # Keep track of nfs-export -> mount-point tuples - OCCI::Log.debug("Adding nfs mount: #{target.attributes["occi.storage.export"]} -> #{link.attributes['occi.storagelink.mountpoint']}") - compute_erb.nfs_mounts << [target.attributes['occi.storage.export'], link.attributes['occi.storagelink.mountpoint']] - next + when 'storagelink' + # TODO: incorporate mountpoint here (e.g. occi.storagelink.mountpoint ) + # Check for nfs mount points + if $nfs_support + if target.kind == OCCI::Infrastructure::NFSStorage::KIND + # Keep track of nfs-export -> mount-point tuples + OCCI::Log.debug("Adding nfs mount: #{target.attributes["occi.storage.export"]} -> #{link.attributes['occi.storagelink.mountpoint']}") + compute_erb.nfs_mounts << [target.attributes['occi.storage.export'], link.attributes['occi.storagelink.mountpoint']] + next + end end - end - - if not target.nil? - compute_erb.storage << [target, link] - elsif not target_URI.nil? - compute_erb.external_storage << target_URI - end - - when 'networkinterface' - if not target.nil? - compute_erb.networks << [target, link] - end - - when 'link' - case target.kind.term - when 'storage' - compute_erb.storage << [target, link] - when 'network' - compute_erb.networks << [target, link] - end unless target.nil? + + if not target.nil? + compute_erb.storage << [target, link] + elsif not target_URI.nil? + compute_erb.external_storage << target_URI + end + + when 'networkinterface' + if not target.nil? + compute_erb.networks << [target, link] + end + + when 'link' + case target.kind.term + when 'storage' + compute_erb.storage << [target, link] + when 'network' + compute_erb.networks << [target, link] + end unless target.nil? end end end - + template_raw = $config["TEMPLATE_LOCATION"] + TEMPLATECOMPUTERAWFILE compute_template = ERB.new(File.read(template_raw)).result(compute_erb.get_binding) - + OCCI::Log.debug("Parsed template #{compute_template}") rc = backend_object.allocate(compute_template) check_rc(rc) @@ -314,25 +314,25 @@ def compute_deploy(compute) compute.backend[:id] = backend_id compute_refresh(compute) end - + OCCI::Log.debug("OpenNebula ID of virtual machine: #{compute.backend[:id]}") OCCI::Log.debug("OpenNebula automatically triggers action start for Virtual Machines") OCCI::Log.debug("Changing state to started") end - + # --------------------------------------------------------------------------------------------------------------------- def compute_refresh(compute) OCCI::Log.debug("Refreshing compute object with backend ID: #{compute.backend[:id]}") backend_object = VirtualMachine.new(VirtualMachine.build_xml(compute.backend[:id]), @one_client) - + backend_object.info - + occi_object = compute_parse_backend_object(backend_object) if occi_object.nil? OCCI::Log.debug("Problems refreshing backend object") else # TODO: parse links? - + # merge new attributes with existing attributes, by overwriting existing attributes with refreshed values compute.attributes.merge!(occi_object.attributes) # concat mixins and remove duplicate mixins @@ -341,32 +341,36 @@ def compute_refresh(compute) compute_update_state(compute) end end - + # --------------------------------------------------------------------------------------------------------------------- def compute_update_state(compute) backend_object = VirtualMachine.new(VirtualMachine.build_xml(compute.backend[:id]), @one_client) backend_object.info OCCI::Log.debug("current VM state is: #{backend_object.lcm_state_str}") state = case backend_object.lcm_state_str - when "RUNNING" then OCCI::Infrastructure::Compute::STATE_ACTIVE - when "PROLOG" , "BOOT" , "SAVE_STOP" , "SAVE_SUSPEND" , "SAVE_MIGRATE" , "MIGRATE" , "PROLOG_MIGRATE" , "PROLOG_RESUME" then OCCI::Infrastructure::Compute::STATE_INACTIVE - when "SUSPENDED" then OCCI::Infrastructure::Compute::STATE_SUSPENDED - else OCCI::Infrastructure::Compute::STATE_INACTIVE - end + when "RUNNING" then + OCCI::Infrastructure::Compute::STATE_ACTIVE + when "PROLOG", "BOOT", "SAVE_STOP", "SAVE_SUSPEND", "SAVE_MIGRATE", "MIGRATE", "PROLOG_MIGRATE", "PROLOG_RESUME" then + OCCI::Infrastructure::Compute::STATE_INACTIVE + when "SUSPENDED" then + OCCI::Infrastructure::Compute::STATE_SUSPENDED + else + OCCI::Infrastructure::Compute::STATE_INACTIVE + end compute.state_machine.set_state(state) compute.attributes['occi.compute.state'] = compute.state_machine.current_state.name end - + # --------------------------------------------------------------------------------------------------------------------- def compute_delete(compute) backend_object=VirtualMachine.new(VirtualMachine.build_xml(compute.backend[:id]), @one_client) - + rc = backend_object.finalize check_rc(rc) OCCI::Log.debug("killing NoVNC pipe with pid #{compute.backend[:novnc_pipe].pid}") unless compute.backend[:novnc_pipe].nil? Process.kill 'INT', compute.backend[:novnc_pipe].pid unless compute.backend[:novnc_pipe].nil? end - + # --------------------------------------------------------------------------------------------------------------------- # GET ALL COMPUTE INSTANCES def compute_register_all_instances @@ -374,7 +378,7 @@ def compute_register_all_instances backend_object_pool.info(OCCI::Backend::OpenNebula::OpenNebula::INFO_ACL, -1, -1, OpenNebula::VirtualMachinePool::INFO_NOT_DONE) compute_register_all_objects(backend_object_pool) end - + # --------------------------------------------------------------------------------------------------------------------- # GET ALL COMPUTE TEMPLATES def compute_register_all_templates @@ -382,7 +386,7 @@ def compute_register_all_templates backend_object_pool.info compute_register_all_objects(backend_object_pool, template = true) end - + # --------------------------------------------------------------------------------------------------------------------- # GET ALL COMPUTE OBJECTS def compute_register_all_objects(backend_object_pool, template = false) @@ -403,11 +407,11 @@ def compute_register_all_objects(backend_object_pool, template = false) # --------------------------------------------------------------------------------------------------------------------- # COMPUTE ACTIONS # --------------------------------------------------------------------------------------------------------------------- - + # --------------------------------------------------------------------------------------------------------------------- - def compute_action_dummy(compute, parameters) + def compute_action_dummy(compute, parameters) end - + # --------------------------------------------------------------------------------------------------------------------- # COMPUTE Action start def compute_start(compute, parameters) @@ -415,42 +419,42 @@ def compute_start(compute, parameters) rc = backend_object.resume check_rc(rc) end - + # --------------------------------------------------------------------------------------------------------------------- # Action stop def compute_stop(compute, parameters) backend_object = VirtualMachine.new(VirtualMachine.build_xml(compute.backend[:id]), @one_client) # TODO: implement parameters when available in OpenNebula case parameters - when 'method="graceful"' - OCCI::Log.debug("Trying to stop VM graceful") - rc = backend_object.shutdown - when 'method="acpioff"' - OCCI::Log.debug("Trying to stop VM via ACPI off") - rc = backend_object.shutdown - else # method="poweroff" or no method specified - OCCI::Log.debug("Powering off VM") - rc = backend_object.shutdown + when 'method="graceful"' + OCCI::Log.debug("Trying to stop VM graceful") + rc = backend_object.shutdown + when 'method="acpioff"' + OCCI::Log.debug("Trying to stop VM via ACPI off") + rc = backend_object.shutdown + else # method="poweroff" or no method specified + OCCI::Log.debug("Powering off VM") + rc = backend_object.shutdown end check_rc(rc) end - + # --------------------------------------------------------------------------------------------------------------------- # Action restart def compute_restart(compute, parameters) backend_object = VirtualMachine.new(VirtualMachine.build_xml(compute.backend[:id]), @one_client) # TODO: implement parameters when available in OpenNebula case parameters - when "graceful" - rc = vm.resubmit - when "warm" - rc = vm.resubmit - else # "cold" or no parameter specified - rc = vm.resubmit + when "graceful" + rc = vm.resubmit + when "warm" + rc = vm.resubmit + else # "cold" or no parameter specified + rc = vm.resubmit end check_rc(rc) end - + # --------------------------------------------------------------------------------------------------------------------- # Action suspend def compute_suspend(compute, parameters) @@ -458,9 +462,9 @@ def compute_suspend(compute, parameters) rc = vm.suspend check_rc(rc) end - + end - - end - end + + end + end end diff --git a/lib/occi/backend/opennebula/Network.rb b/lib/occi/backend/opennebula/Network.rb index bee9b53..9f9e888 100644 --- a/lib/occi/backend/opennebula/Network.rb +++ b/lib/occi/backend/opennebula/Network.rb @@ -31,9 +31,9 @@ module OpenNebula module Network TEMPLATENETWORKRAWFILE = 'occi_one_template_network.erb' - + # --------------------------------------------------------------------------------------------------------------------- -# private + # private # --------------------------------------------------------------------------------------------------------------------- # --------------------------------------------------------------------------------------------------------------------- @@ -44,7 +44,7 @@ def network_parse_backend_object(backend_object) else occi_id = backend_object['TEMPLATE/OCCI_ID'] end - + attributes = {} mixins = [] backend_object.info @@ -55,7 +55,7 @@ def network_parse_backend_object(backend_object) attributes['occi.core.summary'] = backend_object['TEMPLATE/DESCRIPTION'] # attributes['opennebula.network.bridge'] = vnet['TEMPLATE/BRIDGE'] # attributes['opennebula.network.public'] = vnet['TEMPLATE/PUBLIC'] -# OCCI::Log.debug("*** object: " + backend_object.to_xml) + # OCCI::Log.debug("*** object: " + backend_object.to_xml) if backend_object['TEMPLATE/TYPE'].downcase == 'fixed' mixins << OCCI::Backend::ONE::Network::MIXIN # attributes['opennebula.network.leases'] = backend_object['TEMPLATE/LEASES'] @@ -73,11 +73,11 @@ def network_parse_backend_object(backend_object) end attributes['occi.network.address'] = backend_object['TEMPLATE/NETWORK_ADDRESS'] + '/' + (32-(Math.log(network_size)/Math.log(2)).ceil).to_s end - + # check if object already exists - occi_object = OCCI::Rendering::HTTP::LocationRegistry.get_object_at_location('/network/' + occi_id) + occi_object = OCCI::Rendering::HTTP::LocationRegistry.get_object('/network/' + occi_id) if occi_object.nil? - occi_object = OCCI::Infrastructure::Network.new(attributes,mixins) + occi_object = OCCI::Infrastructure::Network.new(attributes, mixins) occi_object.backend[:id] = backend_object.id OCCI::Rendering::HTTP::LocationRegistry.register(occi_object.get_location, occi_object) else @@ -92,34 +92,34 @@ def network_parse_backend_object(backend_object) # --------------------------------------------------------------------------------------------------------------------- def network_deploy(network) - + backend_object = VirtualNetwork.new(VirtualNetwork.build_xml(), @one_client) - - network_erb = NetworkERB.new + + network_erb = NetworkERB.new network_erb.network = network - + template_raw = $config["TEMPLATE_LOCATION"] + TEMPLATENETWORKRAWFILE template = ERB.new(File.read(template_raw)).result(network_erb.get_binding) - + OCCI::Log.debug("Parsed template #{template}") rc = backend_object.allocate(template) check_rc(rc) network.backend[:id] = backend_object.id OCCI::Log.debug("OpenNebula ID of virtual network: #{network.backend[:id]}") end - + # --------------------------------------------------------------------------------------------------------------------- def network_refresh(network) backend_object = VirtualNetwork.new(VirtualNetwork.build_xml(network.backend[:id]), @one_client) - + backend_object.info - + occi_object = network_parse_backend_object(backend_object) - + if occi_object.nil? then OCCI::Log.warn("Problem refreshing network with backend id #{network.backend[:id]}") else - + # merge new attributes with existing attributes, by overwriting existing attributes with refreshed values network.attributes.merge!(occi_object.attributes) # concat mixins and remove duplicate mixins @@ -128,21 +128,21 @@ def network_refresh(network) network_update_state(network) end end - + # --------------------------------------------------------------------------------------------------------------------- def network_update_state(network) state = OCCI::Infrastructure::Network::STATE_ACTIVE network.state_machine.set_state(state) network.attributes['occi.network.state'] = network.state_machine.current_state.name end - + # --------------------------------------------------------------------------------------------------------------------- def network_delete(network) backend_object = VirtualNetwork.new(VirtualNetwork.build_xml(network.backend[:id]), @one_client) rc = backend_object.delete check_rc(rc) end - + # --------------------------------------------------------------------------------------------------------------------- def network_register_all_instances occi_objects = [] @@ -166,11 +166,11 @@ def network_register_all_instances # --------------------------------------------------------------------------------------------------------------------- # STORAGE ACTIONS # --------------------------------------------------------------------------------------------------------------------- - + # --------------------------------------------------------------------------------------------------------------------- - def network_action_dummy(network, parameters) + def network_action_dummy(network, parameters) end - + # --------------------------------------------------------------------------------------------------------------------- def network_up(network, parameters) backend_object = VirtualNetwork.new(VirtualNetwork.build_xml(network.backend[:id]), @one_client) @@ -178,7 +178,7 @@ def network_up(network, parameters) network.enable check_rc(rc) end - + # --------------------------------------------------------------------------------------------------------------------- def network_down(network, parameters) backend_object = VirtualNetwork.new(VirtualNetwork.build_xml(network.backend[:id]), @one_client) @@ -188,8 +188,8 @@ def network_down(network, parameters) end end - - end - end + + end + end end diff --git a/lib/occi/backend/opennebula/OpenNebula.rb b/lib/occi/backend/opennebula/OpenNebula.rb index fe97a21..a50eb93 100644 --- a/lib/occi/backend/opennebula/OpenNebula.rb +++ b/lib/occi/backend/opennebula/OpenNebula.rb @@ -22,8 +22,7 @@ require 'rubygems' require 'uuidtools' require 'OpenNebula/OpenNebula' -require 'occi/CategoryRegistry' -require 'occi/rendering/http/LocationRegistry' +require 'occi/Registry' # OpenNebula backend require 'occi/backend/opennebula/Compute' @@ -31,12 +30,12 @@ require 'occi/backend/opennebula/Storage' # OpenNebula backend based mixins -require 'occi/extensions/one/Image' -require 'occi/extensions/one/Network' -require 'occi/extensions/one/VirtualMachine' -require 'occi/extensions/one/VNC' +#require 'occi/extensions/one/Image' +#require 'occi/extensions/one/Network' +#require 'occi/extensions/one/VirtualMachine' +#require 'occi/extensions/one/VNC' -require 'occi/extensions/Reservation' +#require 'occi/extensions/Reservation' require 'occi/Log' @@ -58,78 +57,78 @@ class OpenNebula include Compute include Network include Storage - + # Operation mappings - + OPERATIONS = {} - + OPERATIONS["http://schemas.ogf.org/occi/infrastructure#compute"] = { - - # Generic resource operations - :deploy => :compute_deploy, - :update_state => :compute_update_state, - :refresh => :compute_refresh, - :delete => :compute_delete, - - # Compute specific resource operations - :start => :compute_start, - :stop => :compute_stop, - :restart => :compute_restart, - :suspend => :compute_suspend + + # Generic resource operations + :deploy => :compute_deploy, + :update_state => :compute_update_state, + :refresh => :compute_refresh, + :delete => :compute_delete, + + # Compute specific resource operations + :start => :compute_start, + :stop => :compute_stop, + :restart => :compute_restart, + :suspend => :compute_suspend } - + OPERATIONS["http://schemas.ogf.org/occi/infrastructure#network"] = { - - # Generic resource operations - :deploy => :network_deploy, - :update_state => :network_update_state, - :refresh => :network_refresh, - :delete => :network_delete, - - # Network specific resource operations - :up => :network_up, - :down => :network_down + + # Generic resource operations + :deploy => :network_deploy, + :update_state => :network_update_state, + :refresh => :network_refresh, + :delete => :network_delete, + + # Network specific resource operations + :up => :network_up, + :down => :network_down } - + OPERATIONS["http://schemas.ogf.org/occi/infrastructure#storage"] = { - - # Generic resource operations - :deploy => :storage_deploy, - :update_state => :storage_update_state, - :refresh => :storage_refresh, - :delete => :storage_delete, - - # Network specific resource operations - :online => :storage_online, - :offline => :storage_offline, - :backup => :storage_backup, - :snapshot => :storage_snapshot, - :resize => :storage_resize + + # Generic resource operations + :deploy => :storage_deploy, + :update_state => :storage_update_state, + :refresh => :storage_refresh, + :delete => :storage_delete, + + # Network specific resource operations + :online => :storage_online, + :offline => :storage_offline, + :backup => :storage_backup, + :snapshot => :storage_snapshot, + :resize => :storage_resize } - + OPERATIONS["http://schemas.ogf.org/gwdg#nfsstorage"] = { - - # Generic resource operations - :deploy => nil, - :update_state => nil, - :refresh => nil, - :delete => nil, + + # Generic resource operations + :deploy => nil, + :update_state => nil, + :refresh => nil, + :delete => nil, } - + # --------------------------------------------------------------------------------------------------------------------- # Register backend specific mixins begin - OCCI::CategoryRegistry.register(OCCI::Backend::ONE::Image::MIXIN) - OCCI::CategoryRegistry.register(OCCI::Backend::ONE::Network::MIXIN) - OCCI::CategoryRegistry.register(OCCI::Backend::ONE::VirtualMachine::MIXIN) - OCCI::CategoryRegistry.register(OCCI::Mixins::Reservation::MIXIN) + #OCCI::CategoryRegistry.register(OCCI::Backend::ONE::Image::MIXIN) + #OCCI::CategoryRegistry.register(OCCI::Backend::ONE::Network::MIXIN) + #OCCI::CategoryRegistry.register(OCCI::Backend::ONE::VirtualMachine::MIXIN) + #OCCI::CategoryRegistry.register(OCCI::Mixins::Reservation::MIXIN) end - + # --------------------------------------------------------------------------------------------------------------------- -# private + # private # --------------------------------------------------------------------------------------------------------------------- - + # --------------------------------------------------------------------------------------------------------------------- def check_rc(rc) if rc.class == Error @@ -137,7 +136,7 @@ def check_rc(rc) # TODO: return failed! end end - + # --------------------------------------------------------------------------------------------------------------------- # Generate a new occi id for resources created directly in OpenNebula using a seed id and the kind identifier def generate_occi_id(kind, seed_id) @@ -145,25 +144,25 @@ def generate_occi_id(kind, seed_id) kind = kind.type_identifier if kind.kind_of?(OCCI::Core::Kind) return UUIDTools::UUID.sha1_create(UUIDTools::UUID_DNS_NAMESPACE, "#{kind}:#{seed_id}").to_s end - + # --------------------------------------------------------------------------------------------------------------------- public # --------------------------------------------------------------------------------------------------------------------- - + # --------------------------------------------------------------------------------------------------------------------- def initialize(user, password) - + # TODO: create mixins from existing templates - + # initialize OpenNebula connection OCCI::Log.debug("Initializing connection with OpenNebula") - + # TODO: check for error! - # @one_client = Client.new($config['one_user'] + ':' + $config['one_password'], $config['one_xmlrpc']) + # @one_client = Client.new($config['one_user'] + ':' + $config['one_password'], $config['one_xmlrpc']) @one_client = Client.new(user + ':' + password, $config['one_xmlrpc']) - + end - + # --------------------------------------------------------------------------------------------------------------------- def register_existing_resources # get all compute objects @@ -173,32 +172,32 @@ def register_existing_resources network_register_all_instances() storage_register_all_instances() end - + # --------------------------------------------------------------------------------------------------------------------- def resource_template_register backend_object_pool=TemplatePool.new(@one_client, INFO_ACL) backend_object_pool.info backend_object_pool.each do |backend_object| actions = [] - related = [ OCCI::Infrastructure::ResourceTemplate::MIXIN ] + related = [OCCI::Infrastructure::ResourceTemplate::MIXIN] entities = [] - term = backend_object['NAME'].downcase.chomp.gsub(/\W/,'_') - scheme = "http://schemas.ogf.org/occi/infrastructure#" - title = backend_object['NAME'] + term = backend_object['NAME'].downcase.chomp.gsub(/\W/, '_') + scheme = "http://schemas.ogf.org/occi/infrastructure#" + title = backend_object['NAME'] attributes = OCCI::Core::Attributes.new() mixin = OCCI::Core::Mixin.new(term, scheme, title, attributes, actions, related, entities) mixin.backend[:id] = backend_object.id OCCI::CategoryRegistry.register(mixin) end end - + # --------------------------------------------------------------------------------------------------------------------- def os_template_register # TODO: implement end - + end - end + end end end diff --git a/lib/occi/backend/opennebula/Storage.rb b/lib/occi/backend/opennebula/Storage.rb index 6183973..1f6072a 100644 --- a/lib/occi/backend/opennebula/Storage.rb +++ b/lib/occi/backend/opennebula/Storage.rb @@ -29,13 +29,13 @@ module OpenNebula # --------------------------------------------------------------------------------------------------------------------- module Storage - + TEMPLATESTORAGERAWFILE = 'occi_one_template_storage.erb' - + # --------------------------------------------------------------------------------------------------------------------- -# private + # private # --------------------------------------------------------------------------------------------------------------------- - + # --------------------------------------------------------------------------------------------------------------------- def storage_parse_backend_object(backend_object) @@ -45,33 +45,33 @@ def storage_parse_backend_object(backend_object) else occi_id = backend_object['TEMPLATE/OCCI_ID'] end - + attributes = {} mixins = [] backend_object.info attributes = {} # parse all parameters from OpenNebula to OCCI - attributes['occi.core.id'] = occi_id - attributes['occi.core.title'] = backend_object['NAME'] + attributes['occi.core.id'] = occi_id + attributes['occi.core.title'] = backend_object['NAME'] attributes['occi.core.summary'] = backend_object['TEMPLATE/DESCRIPTION'] - - attributes['opennebula.image.type'] = backend_object['TEMPLATE/TYPE'] - attributes['opennebula.image.public'] = backend_object['TEMPLATE/PUBLIC'] + + attributes['opennebula.image.type'] = backend_object['TEMPLATE/TYPE'] + attributes['opennebula.image.public'] = backend_object['TEMPLATE/PUBLIC'] attributes['opennebula.image.persistent'] = backend_object['TEMPLATE/PERSISTENT'] attributes['opennebula.image.dev_prefix'] = backend_object['TEMPLATE/DEV_PREFIX'] - attributes['opennebula.image.bus'] = backend_object['TEMPLATE/BUS'] - + attributes['opennebula.image.bus'] = backend_object['TEMPLATE/BUS'] + if backend_object['TEMPLATE/SIZE'] != nil attributes['occi.storage.size'] = backend_object['TEMPLATE/SIZE'] end if backend_object['TEMPLATE/FSTYPE'] != nil attributes['occi.storage.fstype'] end - + mixins = [OCCI::Backend::ONE::Image::MIXIN] - + # check if object already exists - occi_object = OCCI::Rendering::HTTP::LocationRegistry.get_object_at_location('/storage/' + occi_id) + occi_object = OCCI::Rendering::HTTP::LocationRegistry.get_object('/storage/' + occi_id) if occi_object.nil? occi_object = OCCI::Infrastructure::Storage.new(attributes, mixins) occi_object.backend[:id] = backend_object.id @@ -81,21 +81,21 @@ def storage_parse_backend_object(backend_object) end return occi_object end - + # --------------------------------------------------------------------------------------------------------------------- public # --------------------------------------------------------------------------------------------------------------------- - + # --------------------------------------------------------------------------------------------------------------------- def storage_deploy(storage) - + backend_object = Image.new(Image.build_xml, @one_client) - - storage_erb = StorageERB.new + + storage_erb = StorageERB.new storage_erb.storage = storage - + storagelink = nil - + if storage.links != nil storage.links.each do |link| if link.kind.term == 'storagelink' @@ -103,51 +103,53 @@ def storage_deploy(storage) end end end - + # check creation of images raise "No image or storagelink provided" if $image_path == "" - + template_raw = $config["TEMPLATE_LOCATION"] + TEMPLATESTORAGERAWFILE template = ERB.new(File.read(template_raw)).result(storage_erb.get_binding) - + OCCI::Log.debug("Parsed template #{template}") rc = backend_object.allocate(template) check_rc(rc) OCCI::Log.debug("OpenNebula ID of image: #{storage.backend[:id]}") end - + # --------------------------------------------------------------------------------------------------------------------- def storage_update_state(storage) backend_object = Image.new(Image.build_xml(storage.backend[:id]), @one_client) backend_object.info OCCI::Log.debug("current Image state is: #{backend_object.state_str}") state = case backend_object.state_str - when "READY" , "USED" , "LOCKED" then OCCI::Infrastructure::Storage::STATE_ONLINE - else OCCI::Infrastructure::Storage::STATE_OFFLINE + when "READY", "USED", "LOCKED" then + OCCI::Infrastructure::Storage::STATE_ONLINE + else + OCCI::Infrastructure::Storage::STATE_OFFLINE end storage.state_machine.set_state(state) storage.attributes['occi.storage.state'] = storage.state_machine.current_state.name end - + # --------------------------------------------------------------------------------------------------------------------- def storage_delete(storage) backend_object = Image.new(Image.build_xml(storage.backend[:id]), @one_client) rc = backend_object.delete check_rc(rc) end - + # --------------------------------------------------------------------------------------------------------------------- def storage_refresh(storage) backend_object = Image.new(Image.build_xml(storage.backend[:id]), @one_client) - + backend_object.info - + occi_object = storage_parse_backend_object(backend_object) - + if occi_object.nil? then OCCI::Log.warn("Problem refreshing storage with backend id #{storage.backend[:id]}") else - + # merge new attributes with existing attributes, by overwriting existing attributes with refreshed values storage.attributes.merge!(occi_object.attributes) # concat mixins and remove duplicate mixins @@ -156,7 +158,7 @@ def storage_refresh(storage) storage_update_state(storage) end end - + # --------------------------------------------------------------------------------------------------------------------- def storage_register_all_instances occi_objects = [] @@ -174,15 +176,15 @@ def storage_register_all_instances end return occi_objects end - + # --------------------------------------------------------------------------------------------------------------------- # STORAGE ACTIONS # --------------------------------------------------------------------------------------------------------------------- - + # --------------------------------------------------------------------------------------------------------------------- - def storage_action_dummy(storage, parameters) + def storage_action_dummy(storage, parameters) end - + # --------------------------------------------------------------------------------------------------------------------- # Action online def storage_online(network, parameters) @@ -190,7 +192,7 @@ def storage_online(network, parameters) rc = backend_object.enable check_rc(rc) end - + # --------------------------------------------------------------------------------------------------------------------- # Action offline def storage_offline(network, parameters) @@ -198,27 +200,27 @@ def storage_offline(network, parameters) rc = backend_object.disable check_rc(rc) end - + # --------------------------------------------------------------------------------------------------------------------- # Action backup def storage_backup(network, parameters) OCCI::Log.debug("not yet implemented") end - + # --------------------------------------------------------------------------------------------------------------------- # Action snapshot def storage_snapshot(network, parameters) OCCI::Log.debug("not yet implemented") end - + # --------------------------------------------------------------------------------------------------------------------- # Action resize def storage_resize(network, parameters) OCCI::Log.debug("not yet implemented") end - + end - end - end + end + end end diff --git a/lib/occi/core/Action.rb b/lib/occi/core/Action.rb index f19478b..37e4712 100644 --- a/lib/occi/core/Action.rb +++ b/lib/occi/core/Action.rb @@ -19,19 +19,11 @@ # Author(s): Hayati Bice, Florian Feldhaus, Piotr Kasprzak ############################################################################## -require 'occi/core/Category' +require 'occi/core/category' module OCCI module Core - - class Action - - attr_reader :category - - def initialize(scheme, term, title, attributes) - @category = OCCI::Core::Category.new(term, scheme, title, attributes) - end - + class Action < OCCI::Core::Category end end end \ No newline at end of file diff --git a/lib/occi/core/Attribute.rb b/lib/occi/core/Attribute.rb deleted file mode 100644 index 03d0175..0000000 --- a/lib/occi/core/Attribute.rb +++ /dev/null @@ -1,48 +0,0 @@ -############################################################################## -# Copyright 2011 Service Computing group, TU Dortmund -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -############################################################################## - -############################################################################## -# Description: storing a single Attribute -# Author(s): Hayati Bice, Florian Feldhaus, Piotr Kasprzak -############################################################################## - -module OCCI - module Core - class Attribute - - attr_reader :name - attr_reader :mutable - attr_reader :required - attr_reader :type - attr_reader :range - attr_reader :default - - def initialize(name, mutable, required, type = String, range = "", default = "") - @name = name - @mutable = mutable - @required = required - @type = type - @range = range - @default = default - end - - def to_s - @name - end - - end - end -end \ No newline at end of file diff --git a/lib/occi/core/Category.rb b/lib/occi/core/Category.rb index 504c851..4790d61 100644 --- a/lib/occi/core/Category.rb +++ b/lib/occi/core/Category.rb @@ -20,52 +20,40 @@ ############################################################################## require 'json' -require 'occi/core/Attributes' +require 'hashie/mash' module OCCI module Core - class Category + class Category < Hashie::Mash - module Related - def self.get_all_related(categories) - related = [] - to_process = categories.clone - while !to_process.empty? do - element = to_process.shift - related << element unless related.include?(element) - to_process.concat(element.related) - end - return related - end - end - - attr_reader :scheme - attr_reader :term - attr_reader :title - attr_reader :attributes - attr_reader :backend - - def initialize(term, scheme, title, attributes) - @backend = {} - @term = term - @scheme = scheme - @title = title - @attributes = (attributes != nil ? attributes : OCCI::Core::Attributes.new()) + def initialize(category, default = nil) + category.attributes = OCCI::Core::AttributeProperties.new(category.attributes) if category.attributes + super(category, default) end - def location - location = '/' + @term + '/' + def convert_value(val, duping=false) #:nodoc: + case val + when self.class + val.dup + when ::Hash + val = val.dup if duping + self.class.subkey_class.new.merge(val) unless val.kind_of?(Hashie::Mash) + val + when Array + val.collect { |e| convert_value(e) } + else + val + end end def type_identifier - @scheme + @term + regular_reader("scheme") + regular_reader("term") end - def class_string - #only action uses category directly - return 'action' + def location + '/' + self[:term] + '/' end - + end end end \ No newline at end of file diff --git a/lib/occi/core/Entity.rb b/lib/occi/core/Entity.rb index 457bdc6..003b744 100644 --- a/lib/occi/core/Entity.rb +++ b/lib/occi/core/Entity.rb @@ -21,100 +21,98 @@ require 'rubygems' require 'uuidtools' -require 'occi/CategoryRegistry' -require 'occi/core/Attribute' -require 'occi/core/Attributes' +require 'hashie' +require 'occi/Registry' +require 'occi/core/attributes' require 'occi/core/Kind' +require 'occi/core/attribute_properties' module OCCI module Core - - # --------------------------------------------------------------------------------------------------------------------- - class Entity - - # Attributes are hashes and contain key - value pairs as defined by the corresponding kind - attr_reader :attributes - attr_reader :mixins - attr_reader :kind - attr_reader :state_machine - - attr_reader :backend + class Entity < Hashie::Mash # Define appropriate kind begin - actions = [] - related = [] - entity_type = self - entities = [] + data = Hashie::Mash.new + data[:term] = "entity" + data[:scheme] = "http://schemas.ogf.org/occi/core#" + data[:title] = "Entity" + data.attributes!.occi!.core!.id!.type = "string" + data.attributes!.occi!.core!.id!.pattern = "[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}" + data.attributes!.occi!.core!.id!.required = false + data.attributes!.occi!.core!.id!.mutable = false + data.attributes!.occi!.core!.title!.type = "string" + data.attributes!.occi!.core!.title!.pattern = ".*" + data.attributes!.occi!.core!.title!.required = false + data.attributes!.occi!.core!.title!.mutable = true + + kind = OCCI::Core::Kind.new(data) + OCCI::Registry.register(kind) + end - term = "entity" - scheme = "http://schemas.ogf.org/occi/core#" - title = "Entity" + def id + return self[:id] + end - attributes = OCCI::Core::Attributes.new() - attributes << OCCI::Core::Attribute.new(name = 'occi.core.id', mutable = false, required = true, type = "string", range = "", default = "") - attributes << OCCI::Core::Attribute.new(name = 'occi.core.title', mutable = true, required = false, type = "string", range = "", default = "") + def id=(id) + self[:id] = id + self.attributes!.occi!.core!.id = id + end - KIND = OCCI::Core::Kind.new(actions, related, entity_type, entities, term, scheme, title, attributes) - OCCI::CategoryRegistry.register(KIND) + def title + return self[:title] + end + + def title=(title) + self[:title] = title + self.attributes!.occi!.core!.title = title end # --------------------------------------------------------------------------------------------------------------------- - private + def location + '/' + OCCI::Registry.get_by_id(self[:kind]).term + '/' + self[:id] + end + # --------------------------------------------------------------------------------------------------------------------- - + private # --------------------------------------------------------------------------------------------------------------------- - def check_attributes(new_attributes, old_attributes = nil) - - # Construct set of all attribute definitions to check against (derived from kind + mixins) - - # Attribute name -> attribute def - attribute_definitions = {} - - # Attribute name -> category - attribute_categories = {} - - # Attribute definitions from kind + mixins - categories = Category::Related::get_all_related([kind]) + Category::Related::get_all_related(mixins) - - # Attribute definitions from all mixins - categories.each do |category| - category.attributes.each do |name, attribute_def| - raise "Attribute [#{name}] already defined in category [#{attribute_categories[name]}], redefinition from category [#{category}]!" if attribute_definitions.has_key?(name) - attribute_definitions[name] = attribute_def - attribute_categories[name] = category - end - end - - # Check given attributes against set of definitions - new_attributes.each do |name, value| + # --------------------------------------------------------------------------------------------------------------------- + def type_identifier + OCCI::Registry.get_by_id(self.kind).type_identifier + end - # Check for undefined attribute - raise "Attribute [#{name}] with value [#{value}] unknown!" unless attribute_definitions.has_key?(name) + # --------------------------------------------------------------------------------------------------------------------- + private + # --------------------------------------------------------------------------------------------------------------------- - # Check for uniqueness - # TODO: Multi-valued attributes are currently not supported but also not needed (can easily be added as arrays in the attributes-map later on) - if value.kind_of?(Array) && value.length > 1 - raise "Attribute [#{name}] not unique: value: [#{value}], definition in: [#{attribute_categories[name]}]!" if attribute_definitions[name].unique - end - - # Check for mutability by client - if !attribute_definitions[name].mutable && old_attributes != nil && old_attributes.has_key?(name) - raise "Attribute [#{name}] is not mutable: old value: [#{old_attributes[name]}], new value: [#{value}]" unless old_attributes[name] == value - end - end - - # Make sure all mandatory attributes are set - attribute_definitions.each do |name, attribute| - if attribute.required - raise "Required attribute [#{name}] not set!" unless new_attributes.has_key?(name) && new_attributes[name] != nil + # --------------------------------------------------------------------------------------------------------------------- + def check(attributes, definitions) + attributes ||= OCCI::Core::Attributes.new + definitions.each_key do |key| + properties = definitions[key] + value = attributes[key] ||= properties[:default] + if properties.include?(:type) + raise "required attribute #{key} not found" if value.nil? && properties.required + next if value.nil? && !properties.required + case properties.type + when 'string' + raise "attribute #{key} with value #{value} from class #{value.class.name} does not match attribute property type #{properties.type}" unless value.kind_of?(String) + raise "attribute #{key} with length #{value.length} not in range #{properties.minimum}-#{properties.maximum}" unless (properties.minimum..properties.maximum) === value.length if properties.minimum && properties.maximum + when 'number' + raise "attribute #{key} value #{value} from class #{value.class.name} does not match attribute property type #{properties.type}" unless value.kind_of?(Numeric) + raise "attribute #{key} with value #{value} not in range #{properties.minimum}-#{properties.maximum}" unless (properties.minimum..properties.maximum) === value if properties.minimum && properties.maximum + when 'boolean' + raise "attribute #{key} value #{value} from class #{value.class.name} does not match attribute property type #{properties.type}" unless !!value == value + end + raise "attribute #{key} with value #{value} does not match pattern #{properties.pattern}" if value.to_s.scan(Regexp.new(properties.pattern)).empty? if properties.pattern + attributes[key] = value + else + attributes[key] = check(value, definitions[key]) end end - - # TODO: Check attribute range - - # TODO: Set attribute defaults if nothing set until now + attributes.delete_if { |k, v| v.nil? } # remove empty attributes + return attributes end # --------------------------------------------------------------------------------------------------------------------- @@ -122,62 +120,27 @@ def check_attributes(new_attributes, old_attributes = nil) # --------------------------------------------------------------------------------------------------------------------- # --------------------------------------------------------------------------------------------------------------------- - def initialize(attributes, mixins, kind) - - @backend = {} - - # Make sure UUID is UNIQUE for every entity - # TODO: occi.core.id should not be set by user but may be set by backend during startup - attributes['occi.core.id'] = UUIDTools::UUID.timestamp_create.to_s if attributes['occi.core.id'] == nil || attributes['occi.core.id'] == "" - attributes['occi.core.title'] = "" if attributes['occi.core.title'] == nil - - @mixins = mixins - @kind = kind - - # Must be called AFTER kind + mixins are set - check_attributes(attributes) - - # remove quotes at beginning and end of attributes - attributes.each { |k,v| attributes[k] = v.chomp('"').reverse.chomp('"').reverse unless v.nil? } - - @attributes = attributes - - kind.entities << self + def initialize(entity_data, default = nil) + entity_data.attributes = OCCI::Core::Attributes.new(entity_data.attributes) + kind = OCCI::Registry.get_by_id(entity_data.kind) + entity_data.attributes = check(entity_data.attributes!, kind.attributes) + raise "kind not found" if kind.nil? + super(entity_data, default) end - # --------------------------------------------------------------------------------------------------------------------- - def delete - - self.mixins.each do |mixin| - mixin.entities.delete(self) + def convert_value(val, duping=false) #:nodoc: + case val + when self.class + val.dup + when ::Hash + val = val.dup if duping + self.class.subkey_class.new.merge(val) unless val.kind_of?(Hashie::Mash) + val + when Array + val.collect { |e| convert_value(e) } + else + val end - - # remove all links from this entity and from all linked entities - links = @links.clone unless @links.nil? - links.each do |link| - target_uri = URI.parse(link.attributes["occi.core.target"].chomp('"').reverse.chomp('"').reverse) - target = OCCI::Rendering::HTTP::LocationRegistry.get_object_at_location(target_uri.path) - target.links.delete(link) unless target.nil? - - source_uri = URI.parse(link.attributes["occi.core.source"].chomp('"').reverse.chomp('"').reverse) - source = OCCI::Rendering::HTTP::LocationRegistry.get_object_at_location(source_uri.path) - source.links.delete(link) unless source.nil? - end if links != nil - kind.entities.delete(self) - end - - # --------------------------------------------------------------------------------------------------------------------- - def get_location - OCCI::Rendering::HTTP::LocationRegistry.get_location_of_object(kind) + attributes['occi.core.id'] - end - - def actions - kind.actions.select{|action| state_machine.check_transition(action) } - end - - # --------------------------------------------------------------------------------------------------------------------- - def type_identifier - self.kind.type_identifier end end diff --git a/lib/occi/core/Kind.rb b/lib/occi/core/Kind.rb index 21558d7..419a82e 100644 --- a/lib/occi/core/Kind.rb +++ b/lib/occi/core/Kind.rb @@ -21,37 +21,31 @@ require 'json' require 'occi/core/Category' +require 'occi/core/Action' +require 'occi/core/attribute_properties' module OCCI module Core - class Kind < Category + class Kind < OCCI::Core::Category - attr_accessor :entity_type - attr_accessor :related attr_accessor :entities - attr_accessor :actions - - def initialize(actions, related, entity_type, entities, term, scheme, title, attributes) - super(term, scheme, title, attributes) - @actions = (actions != nil ? actions : []) - @related = (related != nil ? related : []) - @entities = (entities != nil ? entities : []) - @entity_type = entity_type - end - - def to_json(options={}) - hash = {} - actions = @actions.collect {|action| action.category.type_identifier } - hash['actions'] = actions.join(',') unless actions.empty? - rel = @related.collect {|related| related.type_identifier} - hash['related'] = rel.join(',') unless rel.empty? - super['Category'].merge!(hash) + + def initialize(kind, default = nil) + @entities = [] + super(kind, default) end - - def class_string - return 'kind' + + def entity_type + case type_identifier + when "http://schemas.ogf.org/occi/core#resource" + return OCCI::Core::Resource.name + when "http://schemas.ogf.org/occi/core#link" + return OCCI::Core::Link.name + else + OCCI::Registry.get_by_id(regular_reader("related").first).entity_type unless self[:term] == 'entity' + end end - + end end end diff --git a/lib/occi/core/Link.rb b/lib/occi/core/Link.rb index 35bc26f..425b5e4 100644 --- a/lib/occi/core/Link.rb +++ b/lib/occi/core/Link.rb @@ -19,39 +19,60 @@ # Author(s): Hayati Bice, Florian Feldhaus, Piotr Kasprzak ############################################################################## -require 'occi/rendering/http/LocationRegistry' require 'occi/core/Kind' +require 'hashie' module OCCI module Core class Link < Entity - + # Define appropriate kind begin - actions = [] - related = [OCCI::Core::Entity::KIND] - entity_type = self - entities = [] - - term = "link" - scheme = "http://schemas.ogf.org/occi/core#" - title = "Link" - - attributes = OCCI::Core::Attributes.new() - attributes << OCCI::Core::Attribute.new(name = 'occi.core.source', mutable = true, required = true, type = "string", range = "", default = "") - attributes << OCCI::Core::Attribute.new(name = 'occi.core.target', mutable = true, required = true, type = "string", range = "", default = "") - - KIND = OCCI::Core::Kind.new(actions, related, entity_type, entities, term, scheme, title, attributes) - - # register in category and location registry - OCCI::CategoryRegistry.register(KIND) - OCCI::Rendering::HTTP::LocationRegistry.register('/link/', KIND) + data = Hashie::Mash.new + data[:actions] = [] + data[:related] = %w{http://schemas.ogf.org/occi/core#entity} + data[:term] = "link" + data[:scheme] = "http://schemas.ogf.org/occi/core#" + data[:title] = "Link" + + data.attributes!.occi!.core!.target!.type = "string" + data.attributes!.occi!.core!.target!.pattern = ".*" + data.attributes!.occi!.core!.target!.required = false + data.attributes!.occi!.core!.target!.mutable = true + + data.attributes!.occi!.core!.source!.type = "string" + data.attributes!.occi!.core!.source!.pattern = ".*" + data.attributes!.occi!.core!.source!.required = false + data.attributes!.occi!.core!.source!.mutable = true + + kind = OCCI::Core::Kind.new(data) + OCCI::Registry.register(kind) + end + + def initialize(link_data, default = nil) + raise OCCI::BadRequestException, 'No source specified for link' if link_data.source.nil? + raise OCCI::BadRequestException, 'No target specified for link' if link_data.target.nil? + super(link_data, default) + end + + def target + return self[:target] + end + + def target=(target) + self[:target] = target + self.attributes!.occi!.core!.target = target end - - def initialize(attributes, mixins = [], kind = OCCI::Core::Link::KIND) - super(attributes, mixins, kind) + + def source + return self[:source] end - + + def source=(source) + self[:source] = source + self.attributes!.occi!.core!.source = source + end + end end end \ No newline at end of file diff --git a/lib/occi/core/Mixin.rb b/lib/occi/core/Mixin.rb index 67cc9df..88a3ff5 100644 --- a/lib/occi/core/Mixin.rb +++ b/lib/occi/core/Mixin.rb @@ -21,26 +21,19 @@ require 'json' require 'occi/core/Category' +require 'occi/core/Action' module OCCI module Core + class Mixin < OCCI::Core::Category - class Mixin < Category - - attr_accessor :actions - attr_accessor :related attr_accessor :entities - def initialize(term, scheme, title, attributes, actions, related, entities) - super(term, scheme, title, attributes) - @actions = (actions != nil ? actions : []) - @related = (related != nil ? related : []) - @entities = (entities != nil ? entities : []) - end - - def class_string - return 'mixin' + def initialize(mixin, default = nil) + @entities = [] + super(mixin, default) end + end end end diff --git a/lib/occi/core/Resource.rb b/lib/occi/core/Resource.rb index 605c58f..39f36b6 100644 --- a/lib/occi/core/Resource.rb +++ b/lib/occi/core/Resource.rb @@ -19,38 +19,42 @@ # Author(s): Hayati Bice, Florian Feldhaus, Piotr Kasprzak ############################################################################## -require 'occi/CategoryRegistry' +require 'occi/Registry' require 'occi/core/Entity' require 'occi/core/Kind' +require 'hashie' module OCCI module Core class Resource < Entity - attr_reader :links - begin - actions = [] - related = [OCCI::Core::Entity::KIND] - entity_type = self - entities = [] - - term = "resource" - scheme = "http://schemas.ogf.org/occi/core#" - title = "Resource" + data = Hashie::Mash.new + data[:related] = %w{http://schemas.ogf.org/occi/core#entity} + data[:term] = "resource" + data[:scheme] = "http://schemas.ogf.org/occi/core#" + data[:title] = "Resource" + + data.attributes!.occi!.core!.summary!.type = "string" + data.attributes!.occi!.core!.summary!.pattern = ".*" + data.attributes!.occi!.core!.summary!.required = false + data.attributes!.occi!.core!.summary!.mutable = true + + kind = OCCI::Core::Kind.new(data) + OCCI::Registry.register(kind) + end - attributes = OCCI::Core::Attributes.new() - attributes << OCCI::Core::Attribute.new(name = 'occi.core.summary', mutable = true, required = false, type = "string", range = "", default = "") + def summary + return self[:summary] + end - KIND = OCCI::Core::Kind.new(actions, related, entity_type, entities, term, scheme, title, attributes) - OCCI::CategoryRegistry.register(KIND) + def summary=(summary) + self[:summary] = summary + self.attributes!.occi!.core!.summary = summary end - def initialize(attributes, mixins = [], kind = OCCI::Core::Resource::KIND) - attributes['occi.core.summary'] = "" if attributes['occi.core.summary'] == nil - @links = [] - @template = false - super(attributes, mixins, kind) + def applicable_actions + array = [] end end diff --git a/lib/occi/extensions/ConsoleLink.rb b/lib/occi/extensions/ConsoleLink.rb deleted file mode 100644 index 3c0efa0..0000000 --- a/lib/occi/extensions/ConsoleLink.rb +++ /dev/null @@ -1,56 +0,0 @@ -############################################################################## -# Copyright 2011 Service Computing group, TU Dortmund -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -############################################################################## - -############################################################################## -# Description: OCCI Extension Console Link -# Author(s): Max Günther -############################################################################## - -require 'occi/CategoryRegistry' -require 'occi/core/Mixin' -require 'occi/core/Kind' -require 'occi/core/Link' - -module OCCI - module Infrastructure - - class ConsoleLink < OCCI::Core::Link - begin - actions = [] - related = [OCCI::Core::Link::KIND] - entity_type = self - entities = [] - - term = "console" - scheme = "http://schemas.ogf.org/occi/infrastructure/compute#" - title = "This is a link to the VM's console" - - attributes = OCCI::Core::Attributes.new() - MIXIN = OCCI::Core::Mixin.new(term, scheme, title, attributes, actions, related, entities) - - OCCI::CategoryRegistry.register(MIXIN) - OCCI::Rendering::HTTP::LocationRegistry.register('/consolelink/', MIXIN) - end - - def initialize(attributes, mixins=[]) - # Initialize resource state - super(attributes, mixins, OCCI::Infrastructure::ConsoleLink::MIXIN) - end - - end - - end -end diff --git a/lib/occi/extensions/NFSStorage.rb b/lib/occi/extensions/NFSStorage.rb deleted file mode 100644 index fa5996a..0000000 --- a/lib/occi/extensions/NFSStorage.rb +++ /dev/null @@ -1,98 +0,0 @@ -############################################################################## -# Copyright 2011 Service Computing group, TU Dortmund -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -############################################################################## - -############################################################################## -# Description: OCCI Infrastructure Storage -# Author(s): Hayati Bice, Florian Feldhaus, Piotr Kasprzak -############################################################################## - -require 'occi/CategoryRegistry' -require 'occi/core/Kind' -require 'occi/core/Resource' -require 'occi/StateMachine' - -module OCCI - module Infrastructure - class NFSStorage < OCCI::Core::Resource - - # Define associated kind - begin - - ACTION_OFFLINE = OCCI::Core::Action.new(scheme = "http://schemas.ogf.org/gwdg/nfsstorage/action#", term = "offline", title = "Storage Action Offline", attributes = OCCI::Core::Attributes.new()) - ACTION_ONLINE = OCCI::Core::Action.new(scheme = "http://schemas.ogf.org/gwdg/nfsstorage/action#", term = "online", title = "Storage Action Online", attributes = OCCI::Core::Attributes.new()) - - actions = [ACTION_OFFLINE, ACTION_ONLINE] - - OCCI::CategoryRegistry.register(ACTION_OFFLINE.category) - OCCI::CategoryRegistry.register(ACTION_ONLINE.category) - - # Define backend initiated actions - - ACTION_BACKEND_COMPLETE = "complete" - ACTION_BACKEND_DEGRADED = "degraded" - - # Define state-machine - STATE_OFFLINE = OCCI::StateMachine::State.new("offline") - STATE_ONLINE = OCCI::StateMachine::State.new("online") - - STATE_OFFLINE.add_transition(ACTION_ONLINE, STATE_ONLINE) - - STATE_ONLINE.add_transition(ACTION_OFFLINE, STATE_OFFLINE) - - related = [OCCI::Core::Resource::KIND] - entity_type = self - entities = [] - - term = "nfsstorage" - scheme = "http://schemas.ogf.org/gwdg#" - title = "NFS Storage Resource" - - attributes = OCCI::Core::Attributes.new() - attributes << OCCI::Core::Attribute.new(name = 'occi.storage.size', mutable = true, required = false, type = "string", range = "", default = "") - attributes << OCCI::Core::Attribute.new(name = 'occi.storage.state', mutable = false, required = true, type = "string", range = "", default = "") - attributes << OCCI::Core::Attribute.new(name = 'occi.storage.export', mutable = false, required = true, type = "string", range = "", default = "") - - KIND = OCCI::Core::Kind.new(actions, related, entity_type, entities, term, scheme, title, attributes) - - OCCI::CategoryRegistry.register(KIND) - OCCI::Rendering::HTTP::LocationRegistry.register('/nfsstorage/', KIND) - end - - def initialize(attributes, mixins=[]) - - @state_machine = OCCI::StateMachine.new(STATE_OFFLINE, [STATE_OFFLINE, STATE_ONLINE]) - - # Initialize resource state - attributes['occi.storage.state'] = state_machine.current_state.name - - super(attributes, mixins, OCCI::Infrastructure::NFSStorage::KIND) - end - -# def update_state -# # Nothing to do -# end - -# def deploy -# # Nothing to do -# end - -# def refresh -# # Nothing to do -# end - - end - end -end diff --git a/lib/occi/extensions/Reservation.rb b/lib/occi/extensions/Reservation.rb deleted file mode 100644 index a7270fc..0000000 --- a/lib/occi/extensions/Reservation.rb +++ /dev/null @@ -1,58 +0,0 @@ -############################################################################## -# Copyright 2011 Service Computing group, TU Dortmund -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -############################################################################## - -############################################################################## -# Description: Implementation specific Mixin to support reservation -# Author(s): Hayati Bice, Florian Feldhaus, Piotr Kasprzak -############################################################################## - -require 'singleton' - -require 'occi/core/Mixin' - -module OCCI - module Mixins - class Reservation < OCCI::Core::Mixin - - include Singleton - - @@reservation = nil - - def initialize(term, scheme, title, attributes, actions, related, entities) - super(term, scheme, title, attributes, actions, related, entities) - end - - # Define appropriate mixin - begin - actions = [] - - related = [] - entities = [] - - term = "reservation" - scheme = "http://schemas.ogf.org/occi/#" - title = "Reservation" - - attributes = OCCI::Core::Attributes.new() - attributes << OCCI::Core::Attribute.new(name = 'occi.reservation.start', mutable = false, required = true, type = "string", range = "", default = "") - attributes << OCCI::Core::Attribute.new(name = 'occi.reservation.duration', mutable = false, required = true, type = "string", range = "", default = "") - attributes << OCCI::Core::Attribute.new(name = 'occi.reservation.preemptible', mutable = false, required = false, type = "string", range = "", default = "") - - MIXIN = OCCI::Core::Mixin.new(term, scheme, title, attributes, actions, related, entities) - end - end - end -end \ No newline at end of file diff --git a/lib/occi/extensions/one/VirtualMachine.rb b/lib/occi/extensions/one/virtual_machine.rb similarity index 80% rename from lib/occi/extensions/one/VirtualMachine.rb rename to lib/occi/extensions/one/virtual_machine.rb index a8ca366..b2f5e5e 100644 --- a/lib/occi/extensions/one/VirtualMachine.rb +++ b/lib/occi/extensions/one/virtual_machine.rb @@ -37,22 +37,22 @@ class VirtualMachine < OCCI::Core::Mixin related = [] entities = [] - term = "virtualmachine" - scheme = "http://schemas.opennebula.org/occi/infrastructure#" - title = "OpenNebula Virtual Machine Mixin" + term = "virtualmachine" + scheme = "http://schemas.opennebula.org/occi/infrastructure#" + title = "OpenNebula Virtual Machine Mixin" attributes = OCCI::Core::Attributes.new() - attributes << OCCI::Core::Attribute.new(name = 'opennebula.vm.cpu_reservation', mutable = true, required = false, type = "string", range = "", default = "") - attributes << OCCI::Core::Attribute.new(name = 'opennebula.vm.boot', mutable = true, required = false, type = "string", range = "", default = "") - attributes << OCCI::Core::Attribute.new(name = 'opennebula.vm.vnc_url', mutable = true, required = false, type = "string", range = "", default = "") - + attributes << OCCI::Core::Attribute.new(name = 'opennebula.vm.cpu_reservation', mutable = true, required = false, type = "string", range = "", default = "") + attributes << OCCI::Core::Attribute.new(name = 'opennebula.vm.boot', mutable = true, required = false, type = "string", range = "", default = "") + attributes << OCCI::Core::Attribute.new(name = 'opennebula.vm.vnc_url', mutable = true, required = false, type = "string", range = "", default = "") + MIXIN = OCCI::Core::Mixin.new(term, scheme, title, attributes, actions, related, entities) end def initialize(term, scheme, title, attributes, actions, related, entities) super(term, scheme, title, attributes, actions, related, entities) end - + end end end diff --git a/lib/occi/helpers/OCCIRequestHelper.rb b/lib/occi/helpers/OCCIRequestHelper.rb deleted file mode 100644 index 7eaa649..0000000 --- a/lib/occi/helpers/OCCIRequestHelper.rb +++ /dev/null @@ -1,32 +0,0 @@ -############################################################################## -# Copyright 2011 Service Computing group, TU Dortmund -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -############################################################################## - -############################################################################## -# Description: OCCI Request Helper -# Author(s): Hayati Bice, Florian Feldhaus, Piotr Kasprzak -############################################################################## - -require 'sinatra/base' - -module Sinatra - module OCCIRequestHelper - def testhelper - - end - end - - helpers OCCIRequestHelper -end \ No newline at end of file diff --git a/lib/occi/infrastructure/Compute.rb b/lib/occi/infrastructure/Compute.rb deleted file mode 100644 index 99de01a..0000000 --- a/lib/occi/infrastructure/Compute.rb +++ /dev/null @@ -1,115 +0,0 @@ -############################################################################## -# Copyright 2011 Service Computing group, TU Dortmund -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -############################################################################## - -############################################################################## -# Description: OCCI Infrastructure Compute -# Author(s): Hayati Bice, Florian Feldhaus, Piotr Kasprzak -############################################################################## - -require 'occi/CategoryRegistry' -require 'occi/core/Action' -require 'occi/core/Kind' -require 'occi/core/Resource' -require 'occi/StateMachine' - -module OCCI - module Infrastructure - - class Compute < OCCI::Core::Resource - begin - # Define actions - restart_attributes = OCCI::Core::Attributes.new() - restart_attributes << OCCI::Core::Attribute.new(name = 'method', mutable = false, mandatory = false, unique = true) - - ACTION_RESTART = OCCI::Core::Action.new(scheme = "http://schemas.ogf.org/occi/infrastructure/compute/action#", term = "restart", - title = "Compute Action Restart", attributes = restart_attributes) - - start_attributes = OCCI::Core::Attributes.new() - - ACTION_START = OCCI::Core::Action.new(scheme = "http://schemas.ogf.org/occi/infrastructure/compute/action#", term = "start", - title = "Compute Action Start", attributes = start_attributes) - - stop_attributes = OCCI::Core::Attributes.new() - stop_attributes << OCCI::Core::Attribute.new(name = 'method', mutable = false, mandatory = false, unique = true) - - ACTION_STOP = OCCI::Core::Action.new(scheme = "http://schemas.ogf.org/occi/infrastructure/compute/action#", term = "stop", - title = "Compute Action Stop", attributes = stop_attributes) - - suspend_attributes = OCCI::Core::Attributes.new() - suspend_attributes << OCCI::Core::Attribute.new(name = 'method', mutable = false, mandatory = false, unique = true) - - ACTION_SUSPEND = OCCI::Core::Action.new(scheme = "http://schemas.ogf.org/occi/infrastructure/compute/action#", term = "suspend", - title = "Compute Action Suspend", attributes = suspend_attributes) - - actions = [ACTION_RESTART, ACTION_START, ACTION_STOP, ACTION_SUSPEND] - - OCCI::CategoryRegistry.register(ACTION_START.category) - OCCI::CategoryRegistry.register(ACTION_STOP.category) - OCCI::CategoryRegistry.register(ACTION_SUSPEND.category) - OCCI::CategoryRegistry.register(ACTION_RESTART.category) - - # Define state-machine - STATE_INACTIVE = OCCI::StateMachine::State.new("inactive") - STATE_ACTIVE = OCCI::StateMachine::State.new("active") - STATE_SUSPENDED = OCCI::StateMachine::State.new("suspended") - - STATE_INACTIVE.add_transition(ACTION_START, STATE_ACTIVE) - - STATE_ACTIVE.add_transition(ACTION_STOP, STATE_INACTIVE) - STATE_ACTIVE.add_transition(ACTION_SUSPEND, STATE_SUSPENDED) - # TODO: determine if the following modelling of the restart action is approriate - STATE_ACTIVE.add_transition(ACTION_RESTART, STATE_ACTIVE) - - STATE_SUSPENDED.add_transition(ACTION_START, STATE_ACTIVE) - - related = [OCCI::Core::Resource::KIND] - entity_type = self - entities = [] - - term = "compute" - scheme = "http://schemas.ogf.org/occi/infrastructure#" - title = "Compute Resource" - - attributes = OCCI::Core::Attributes.new() - attributes << OCCI::Core::Attribute.new(name = 'occi.compute.cores', mutable = true, required = false, type = "integer", range = "", default = "") - attributes << OCCI::Core::Attribute.new(name = 'occi.compute.architecture', mutable = true, required = false, type = "string", range = "", default = "") - attributes << OCCI::Core::Attribute.new(name = 'occi.compute.state', mutable = false, required = true, type = "string", range = "", default = "") - attributes << OCCI::Core::Attribute.new(name = 'occi.compute.hostname', mutable = true, required = false, type = "string", range = "", default = "") - attributes << OCCI::Core::Attribute.new(name = 'occi.compute.memory', mutable = true, required = false, type = "integer", range = "", default = "") - attributes << OCCI::Core::Attribute.new(name = 'occi.compute.speed', mutable = true, required = false, type = "float", range = "", default = "") - - KIND = OCCI::Core::Kind.new(actions, related, entity_type, entities, term, scheme, title, attributes) - - OCCI::CategoryRegistry.register(KIND) - OCCI::Rendering::HTTP::LocationRegistry.register('/compute/', KIND) - end - - def initialize(attributes, mixins = []) - @state_machine = OCCI::StateMachine.new(STATE_INACTIVE, [STATE_INACTIVE, STATE_ACTIVE, STATE_SUSPENDED]) - - # FIXME - @nfs_mounts = [] - - # Initialize resource state - attributes['occi.compute.state'] = state_machine.current_state.name - - super(attributes ,mixins, OCCI::Infrastructure::Compute::KIND) - end - - end - - end -end diff --git a/lib/occi/infrastructure/IPNetworkInterface.rb b/lib/occi/infrastructure/IPNetworkInterface.rb deleted file mode 100644 index bff4227..0000000 --- a/lib/occi/infrastructure/IPNetworkInterface.rb +++ /dev/null @@ -1,52 +0,0 @@ -############################################################################## -# Copyright 2011 Service Computing group, TU Dortmund -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -############################################################################## - -############################################################################## -# Description: OCCI Infrastructure IPNetworking Mixin -# Author(s): Hayati Bice, Florian Feldhaus, Piotr Kasprzak -############################################################################## - -require 'occi/CategoryRegistry' -require 'occi/core/Mixin' - -module OCCI - module Infrastructure - - class IPNetworkInterface < OCCI::Core::Mixin - begin - # Define actions - actions = [] - - related = [] - entities = [] - - term = "ipnetworkinterface" - scheme = "http://schemas.ogf.org/occi/infrastructure/networkinterface#" - title = "IP Networkinterface Mixin" - - attributes = OCCI::Core::Attributes.new() - attributes << OCCI::Core::Attribute.new(name = 'occi.networkinterface.address', mutable = true, required = false, type = "string", range = "", default = "") - attributes << OCCI::Core::Attribute.new(name = 'occi.networkinterface.gateway', mutable = true, required = false, type = "string", range = "", default = "") - attributes << OCCI::Core::Attribute.new(name = 'occi.networkinterface.allocation', mutable = true, required = false, type = "string", range = "", default = "") - - MIXIN = OCCI::Core::Mixin.new(term, scheme, title, attributes, actions, related, entities) - - OCCI::CategoryRegistry.register(MIXIN) - end - end - - end -end \ No newline at end of file diff --git a/lib/occi/infrastructure/Ipnetworking.rb b/lib/occi/infrastructure/Ipnetworking.rb deleted file mode 100644 index 8847822..0000000 --- a/lib/occi/infrastructure/Ipnetworking.rb +++ /dev/null @@ -1,52 +0,0 @@ -############################################################################## -# Copyright 2011 Service Computing group, TU Dortmund -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -############################################################################## - -############################################################################## -# Description: OCCI Infrastructure IPNetworking Mixin -# Author(s): Hayati Bice, Florian Feldhaus, Piotr Kasprzak -############################################################################## - -require 'occi/CategoryRegistry' -require 'occi/core/Mixin' - -module OCCI - module Infrastructure - - class Ipnetworking < OCCI::Core::Mixin - begin - # Define actions - actions = [] - - related = [] - entities = [] - - term = "ipnetwork" - scheme = "http://schemas.ogf.org/occi/infrastructure/network#" - title = "IP Network Mixin" - - attributes = OCCI::Core::Attributes.new() - attributes << OCCI::Core::Attribute.new(name = 'occi.network.address', mutable = true, required = false, type = "string", range = "", default = "") - attributes << OCCI::Core::Attribute.new(name = 'occi.network.gateway', mutable = true, required = false, type = "string", range = "", default = "") - attributes << OCCI::Core::Attribute.new(name = 'occi.network.allocation', mutable = true, required = false, type = "string", range = "", default = "") - - MIXIN = OCCI::Core::Mixin.new(term, scheme, title, attributes, actions, related, entities) - - OCCI::CategoryRegistry.register(MIXIN) - end - end - - end -end \ No newline at end of file diff --git a/lib/occi/infrastructure/Network.rb b/lib/occi/infrastructure/Network.rb deleted file mode 100644 index 391a118..0000000 --- a/lib/occi/infrastructure/Network.rb +++ /dev/null @@ -1,82 +0,0 @@ -############################################################################## -# Copyright 2011 Service Computing group, TU Dortmund -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -############################################################################## - -############################################################################## -# Description: OCCI Infrastructure Network -# Author(s): Hayati Bice, Florian Feldhaus, Piotr Kasprzak -############################################################################## - -require 'occi/CategoryRegistry' -require 'occi/core/Kind' -require 'occi/StateMachine' - -module OCCI - module Infrastructure - - class Network < OCCI::Core::Resource - begin - # Define actions - down_attributes = OCCI::Core::Attributes.new() - up_attributes = OCCI::Core::Attributes.new() - - ACTION_DOWN = OCCI::Core::Action.new(scheme = "http://schemas.ogf.org/occi/infrastructure/network/action#", term = "down", title = "Network Action Down", attributes = down_attributes) - ACTION_UP = OCCI::Core::Action.new(scheme = "http://schemas.ogf.org/occi/infrastructure/network/action#", term = "up", title = "Network Action Up", attributes = up_attributes) - - actions = [ACTION_DOWN, ACTION_UP] - - OCCI::CategoryRegistry.register(ACTION_DOWN.category) - OCCI::CategoryRegistry.register(ACTION_UP.category) - - # Define state-machine - STATE_INACTIVE = OCCI::StateMachine::State.new("inactive") - STATE_ACTIVE = OCCI::StateMachine::State.new("active") - - STATE_INACTIVE.add_transition(ACTION_UP, STATE_ACTIVE) - - STATE_ACTIVE.add_transition(ACTION_DOWN, STATE_INACTIVE) - - related = [OCCI::Core::Resource::KIND] - entity_type = self - entities = [] - - term = "network" - scheme = "http://schemas.ogf.org/occi/infrastructure#" - title = "Network Resource" - - attributes = OCCI::Core::Attributes.new() - attributes << OCCI::Core::Attribute.new(name = 'occi.network.vlan', mutable = true, required = false, type = "string", range = "", default = "") - attributes << OCCI::Core::Attribute.new(name = 'occi.network.label', mutable = true, required = false, type = "string", range = "", default = "") - attributes << OCCI::Core::Attribute.new(name = 'occi.network.state', mutable = false, required = true, type = "string", range = "", default = "") - - KIND = OCCI::Core::Kind.new(actions, related, entity_type, entities, term, scheme, title, attributes) - - OCCI::CategoryRegistry.register(KIND) - OCCI::Rendering::HTTP::LocationRegistry.register('/network/', KIND) - end - - def initialize(attributes, mixins=[]) - - @state_machine = OCCI::StateMachine.new(STATE_INACTIVE, [STATE_INACTIVE, STATE_ACTIVE]) - - # Initialize resource state - attributes['occi.network.state'] = state_machine.current_state.name - - super(attributes, mixins, OCCI::Infrastructure::Network::KIND) - end - end - - end -end diff --git a/lib/occi/infrastructure/Networkinterface.rb b/lib/occi/infrastructure/Networkinterface.rb deleted file mode 100644 index a7bc3da..0000000 --- a/lib/occi/infrastructure/Networkinterface.rb +++ /dev/null @@ -1,72 +0,0 @@ -############################################################################## -# Copyright 2011 Service Computing group, TU Dortmund -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -############################################################################## - -############################################################################## -# Description: OCCI Infrastructure Network Interface Link -# Author(s): Hayati Bice, Florian Feldhaus, Piotr Kasprzak -############################################################################## - -require 'occi/CategoryRegistry' -require 'occi/core/Kind' -require 'occi/core/Link' - -module OCCI - module Infrastructure - - class Networkinterface < OCCI::Core::Link - begin - - # Define state-machine - STATE_INACTIVE = OCCI::StateMachine::State.new("inactive") - STATE_ACTIVE = OCCI::StateMachine::State.new("active") - - actions = [] - related = [OCCI::Core::Link::KIND] - entity_type = self - entities = [] - - term = "networkinterface" - scheme = "http://schemas.ogf.org/occi/infrastructure#" - title = "Networkinterface" - - attributes = OCCI::Core::Attributes.new() - attributes << OCCI::Core::Attribute.new(name = 'occi.networkinterface.interface', mutable = false, required = false, type = "string", range = "", default = "") - attributes << OCCI::Core::Attribute.new(name = 'occi.networkinterface.mac', mutable = true, required = false, type = "string", range = "", default = "") - attributes << OCCI::Core::Attribute.new(name = 'occi.networkinterface.state', mutable = false, required = false, type = "string", range = "", default = "") - - KIND = OCCI::Core::Kind.new(actions, related, entity_type, entities, term, scheme, title, attributes) - - OCCI::CategoryRegistry.register(KIND) - OCCI::Rendering::HTTP::LocationRegistry.register('/networkinterface/', KIND) - end - - def initialize(attributes, mixins=[]) - - @state_machine = OCCI::StateMachine.new(STATE_INACTIVE, [STATE_INACTIVE, STATE_ACTIVE]) - - # Initialize resource state - attributes['occi.networkinterface.state'] = state_machine.current_state.name - super(attributes, mixins, OCCI::Infrastructure::Networkinterface::KIND) - end - -# def update_state -# @attributes['occi.networkinterface.state'] = state_machine.current_state.name -# end - - end - - end -end diff --git a/lib/occi/infrastructure/OSTemplate.rb b/lib/occi/infrastructure/OSTemplate.rb deleted file mode 100644 index 64bbf46..0000000 --- a/lib/occi/infrastructure/OSTemplate.rb +++ /dev/null @@ -1,47 +0,0 @@ -############################################################################## -# Copyright 2011 Service Computing group, TU Dortmund -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -############################################################################## - -############################################################################## -# Description: OCCI Infrastructure Compute -# Author(s): Hayati Bice, Florian Feldhaus, Piotr Kasprzak -############################################################################## - -require 'occi/core/Mixin' - -module OCCI - module Infrastructure - - class OSTemplate < OCCI::Core::Mixin - begin - # Define actions - actions = [] - - related = [] - entities = [] - - term = "os_tpl" - scheme = "http://schemas.ogf.org/occi/infrastructure#" - title = "OS Template" - - attributes = OCCI::Core::Attributes.new() - - MIXIN = OCCI::Core::Mixin.new(term, scheme, title, attributes, actions, related, entities) - OCCI::CategoryRegistry.register(MIXIN) - end - end - - end -end \ No newline at end of file diff --git a/lib/occi/infrastructure/ResourceTemplate.rb b/lib/occi/infrastructure/ResourceTemplate.rb deleted file mode 100644 index f925d50..0000000 --- a/lib/occi/infrastructure/ResourceTemplate.rb +++ /dev/null @@ -1,46 +0,0 @@ -############################################################################## -# Copyright 2011 Service Computing group, TU Dortmund -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -############################################################################## - -############################################################################## -# Description: OCCI Infrastructure Compute -# Author(s): Hayati Bice, Florian Feldhaus, Piotr Kasprzak -############################################################################## - -require 'occi/core/Mixin' - -module OCCI - module Infrastructure - - class ResourceTemplate < OCCI::Core::Mixin - begin - # Define actions - actions = [] - related = [] - entities = [] - - term = "resource_tpl" - scheme = "http://schemas.ogf.org/occi/infrastructure#" - title = "Resource Template" - - attributes = OCCI::Core::Attributes.new() - - MIXIN = OCCI::Core::Mixin.new(term, scheme, title, attributes, actions, related, entities) - OCCI::CategoryRegistry.register(MIXIN) - end - end - - end -end \ No newline at end of file diff --git a/lib/occi/infrastructure/Storage.rb b/lib/occi/infrastructure/Storage.rb deleted file mode 100644 index 51e3802..0000000 --- a/lib/occi/infrastructure/Storage.rb +++ /dev/null @@ -1,103 +0,0 @@ -############################################################################## -# Copyright 2011 Service Computing group, TU Dortmund -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -############################################################################## - -############################################################################## -# Description: OCCI Infrastructure Storage -# Author(s): Hayati Bice, Florian Feldhaus, Piotr Kasprzak -############################################################################## - -require 'occi/CategoryRegistry' -require 'occi/core/Kind' -require 'occi/core/Resource' -require 'occi/StateMachine' - -module OCCI - module Infrastructure - - class Storage < OCCI::Core::Resource - begin - # Define client initiated actions - backup_attributes = OCCI::Core::Attributes.new() - offline_attributes = OCCI::Core::Attributes.new() - online_attributes = OCCI::Core::Attributes.new() - resize_attributes = OCCI::Core::Attributes.new() - resize_attributes << OCCI::Core::Attribute.new(name = 'size', mutable = false, mandatory = false, unique = true) - snapshot_attributes = OCCI::Core::Attributes.new() - - ACTION_BACKUP = OCCI::Core::Action.new(scheme = "http://schemas.ogf.org/occi/infrastructure/storage/action#", term = "backup", title = "Storage Action Backup", attributes = backup_attributes) - ACTION_OFFLINE = OCCI::Core::Action.new(scheme = "http://schemas.ogf.org/occi/infrastructure/storage/action#", term = "offline", title = "Storage Action Offline", attributes = offline_attributes) - ACTION_ONLINE = OCCI::Core::Action.new(scheme = "http://schemas.ogf.org/occi/infrastructure/storage/action#", term = "online", title = "Storage Action Online", attributes = online_attributes) - ACTION_RESIZE = OCCI::Core::Action.new(scheme = "http://schemas.ogf.org/occi/infrastructure/storage/action#", term = "resize", title = "Storage Action Resize", attributes = resize_attributes) - ACTION_SNAPSHOT = OCCI::Core::Action.new(scheme = "http://schemas.ogf.org/occi/infrastructure/storage/action#", term = "snapshot", title = "Storage Action Snapshot", attributes = snapshot_attributes) - - actions = [ACTION_BACKUP, ACTION_OFFLINE, ACTION_ONLINE, ACTION_RESIZE, ACTION_SNAPSHOT] - - OCCI::CategoryRegistry.register(ACTION_BACKUP.category) - OCCI::CategoryRegistry.register(ACTION_OFFLINE.category) - OCCI::CategoryRegistry.register(ACTION_ONLINE.category) - OCCI::CategoryRegistry.register(ACTION_RESIZE.category) - OCCI::CategoryRegistry.register(ACTION_SNAPSHOT.category) - - # Define backend initiated actions - - ACTION_BACKEND_COMPLETE = "complete" - ACTION_BACKEND_DEGRADED = "degraded" - - # Define state-machine - STATE_OFFLINE = OCCI::StateMachine::State.new("offline") - STATE_ONLINE = OCCI::StateMachine::State.new("online") - STATE_BACKUP = OCCI::StateMachine::State.new("backup") - STATE_SNAPSHOT = OCCI::StateMachine::State.new("snapshot") - STATE_RESIZE = OCCI::StateMachine::State.new("resize") - - STATE_OFFLINE.add_transition(ACTION_ONLINE, STATE_ONLINE) - - STATE_ONLINE.add_transition(ACTION_OFFLINE, STATE_OFFLINE) - STATE_ONLINE.add_transition(ACTION_BACKUP, STATE_BACKUP) - STATE_ONLINE.add_transition(ACTION_SNAPSHOT, STATE_SNAPSHOT) - STATE_ONLINE.add_transition(ACTION_RESIZE, STATE_RESIZE) - - related = [OCCI::Core::Resource::KIND] - entity_type = self - entities = [] - - term = "storage" - scheme = "http://schemas.ogf.org/occi/infrastructure#" - title = "Storage Resource" - - attributes = OCCI::Core::Attributes.new() - attributes << OCCI::Core::Attribute.new(name = 'occi.storage.size', mutable = true, required = false, type = "float", range = "", default = "") - attributes << OCCI::Core::Attribute.new(name = 'occi.storage.state', mutable = false, required = true, type = "string", range = "", default = "") - - KIND = OCCI::Core::Kind.new(actions, related, entity_type, entities, term, scheme, title, attributes) - - OCCI::CategoryRegistry.register(KIND) - OCCI::Rendering::HTTP::LocationRegistry.register('/storage/', KIND) - end - - def initialize(attributes, mixins=[]) - - @state_machine = OCCI::StateMachine.new(STATE_OFFLINE, [STATE_OFFLINE, STATE_ONLINE, STATE_BACKUP, STATE_SNAPSHOT, STATE_RESIZE]) - - # Initialize resource state - attributes['occi.storage.state'] = state_machine.current_state.name - - super(attributes, mixins, OCCI::Infrastructure::Storage::KIND) - end - end - - end -end diff --git a/lib/occi/infrastructure/StorageLink.rb b/lib/occi/infrastructure/StorageLink.rb deleted file mode 100644 index f466cde..0000000 --- a/lib/occi/infrastructure/StorageLink.rb +++ /dev/null @@ -1,71 +0,0 @@ -############################################################################## -# Copyright 2011 Service Computing group, TU Dortmund -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -############################################################################## - -############################################################################## -# Description: OCCI Infrastructure Storage Link -# Author(s): Hayati Bice, Florian Feldhaus, Piotr Kasprzak -############################################################################## - -require 'occi/CategoryRegistry' -require 'occi/core/Kind' -require 'occi/core/Link' - -module OCCI - module Infrastructure - - class StorageLink < OCCI::Core::Link - begin - - # Define state-machine - STATE_INACTIVE = OCCI::StateMachine::State.new("inactive") - STATE_ACTIVE = OCCI::StateMachine::State.new("active") - - actions = [] - related = [OCCI::Core::Link::KIND] - entity_type = self - entities = [] - - term = "storagelink" - scheme = "http://schemas.ogf.org/occi/infrastructure#" - title = "StorageLink" - - attributes = OCCI::Core::Attributes.new() - - attributes << OCCI::Core::Attribute.new(name = 'occi.storagelink.deviceid', mutable = false, required = false, type = "string", range = "", default = "") - attributes << OCCI::Core::Attribute.new(name = 'occi.storagelink.mountpoint', mutable = true, required = false, type = "string", range = "", default = "") - attributes << OCCI::Core::Attribute.new(name = 'occi.storagelink.state', mutable = false, required = true, type = "string", range = "", default = "") - - KIND = OCCI::Core::Kind.new(actions, related, entity_type, entities, term, scheme, title, attributes) - OCCI::CategoryRegistry.register(KIND) - OCCI::Rendering::HTTP::LocationRegistry.register('/storagelink/', KIND) - end - - def initialize(attributes, mixins = []) - - @state_machine = OCCI::StateMachine.new(STATE_INACTIVE, [STATE_INACTIVE, STATE_ACTIVE]) - - # Initialize resource state - attributes['occi.storagelink.state'] = state_machine.current_state.name - super(attributes, mixins, OCCI::Infrastructure::StorageLink::KIND) - end - -# def update_state -# @attributes['occi.storagelink.state'] = state_machine.current_state.name -# end - - end - end -end diff --git a/lib/occi/occi-server.rb b/lib/occi/occi-server.rb deleted file mode 100644 index 04663f3..0000000 --- a/lib/occi/occi-server.rb +++ /dev/null @@ -1,688 +0,0 @@ -############################################################################## -# Copyright 2011 Service Computing group, TU Dortmund -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -############################################################################## - -############################################################################## -# Description: OCCI RESTful Web Service -# Author(s): Hayati Bice, Florian Feldhaus, Piotr Kasprzak -############################################################################## - -############################################################################## -# Require Ruby Gems - -# gems -require 'rubygems' - -# sinatra -require 'sinatra' -require "sinatra/multi_route" -require 'sinatra/cross_origin' - -# Ruby standard library -require 'uri' -require 'fileutils' - -# Server configuration -require 'occi/Configuration' - -# Active support notifications -require 'active_support/notifications' - -############################################################################## -# Read configuration file and set log level - -CONFIGURATION_FILE = 'etc/occi-server.conf' - -## initialize temporary image path -$image_path = "" - -$config = OCCI::Configuration.new(CONFIGURATION_FILE) - -# TODO: config loglevel - -# TODO: move NFS support to proper location or even better to proper OCCI structure -=begin -if !$config["NFS_SUPPORT"].nil? && ["true"].include?($config["NFS_SUPPORT"].downcase) - logger.info("Enabling NFS storage support...") - $nfs_support = true -else - logger.info("Disabling NFS storage support...") - $nfs_support = false -end -=end - -$resources_initialized = false - -# --------------------------------------------------------------------------------------------------------------------- -def initialize_backend(auth) - - if auth.provided? && auth.basic? && auth.credentials - user, password = auth.credentials - else - user, password = [$config['one_user'], $config['one_password']] - logger.debug("No basic auth data provided: using defaults from config (user = '#{user}')") - end - - begin - backend = case $config["backend"] - when "opennebula" - require 'occi/backend/opennebula/OpenNebula' - OCCI::Backend::Manager.register_backend(OCCI::Backend::OpenNebula::OpenNebula, OCCI::Backend::OpenNebula::OpenNebula::OPERATIONS) - OCCI::Backend::OpenNebula::OpenNebula.new(user, password) - when "ec2" - require 'occi/backend/ec2/EC2' - Bundler.require(:ec2) - OCCI::Backend::Manager.register_backend(OCCI::Backend::EC2::EC2, OCCI::Backend::EC2::EC2::OPERATIONS) - OCCI::Backend::EC2::EC2.new(user, password) - when "dummy" then - require 'occi/backend/Dummy' - OCCI::Backend::Manager.register_backend(OCCI::Backend::Dummy, OCCI::Backend::Dummy::OPERATIONS) - OCCI::Backend::Dummy.new() - else - raise "Backend '" + $config["backend"] + "' not found" - end - - if $config["backend"] == "ec2" - backend.register_templates() - end - - # Initialize resources only once - # FIXME: need better way to do resource init / refresh! (maybe async thread or somesuch) - unless $resources_initalized - logger.debug("Loading existing resources from backend...") - backend.register_existing_resources - register_existing_resources = true - end - - return backend - - rescue RuntimeError => e - logger.error(e) - end -end - -############################################################################## -# Require OCCI classes - -# Exceptions -require 'occi/Exceptions' - -# Category registry -require 'occi/CategoryRegistry' - -# OCCI Core classes -require 'occi/core/Action' -require 'occi/core/Category' -require 'occi/core/Entity' -require 'occi/core/Kind' -require 'occi/core/Link' -require 'occi/core/Mixin' -require 'occi/core/Resource' - -# OCCI Infrastructure classes -require 'occi/infrastructure/Compute' -require 'occi/infrastructure/Storage' -require 'occi/infrastructure/Network' -require 'occi/infrastructure/Networkinterface' -require 'occi/infrastructure/StorageLink' -require 'occi/infrastructure/Ipnetworking' -require 'occi/infrastructure/OSTemplate' -require 'occi/infrastructure/ResourceTemplate' -require 'occi/infrastructure/IPNetworkInterface' - -# OCCI extensions -require 'occi/extensions/Reservation' -require 'occi/extensions/NFSStorage' -require 'occi/extensions/ConsoleLink' - -# OCCI HTTP rendering -require 'occi/rendering/Renderer' -require 'occi/rendering/http/LocationRegistry' -require 'occi/rendering/http/Request' -require 'occi/rendering/http/Response' - -# Backend support -require 'occi/backend/Manager' - -require 'occi/helpers/OCCIRequestHelper' - - -############################################################################## -# Sinatra methods for handling HTTP requests - -class OCCIServer < Sinatra::Application - - register Sinatra::MultiRoute - register Sinatra::CrossOrigin - - enable cross_origin - - def initialize(config = {}) - # create logger - config[:log_dest] ||= STDOUT - config[:log_level] ||= $config[:log_level] - config[:log_level] ||= Logger::INFO - @logger = Logger.new(config[:log_dest]) - @logger.level = config[:log_level] - - # subscribe to log messages and send to logger - @log_subscriber = ActiveSupport::Notifications.subscribe("log") do |name, start, finish, id, payload| - @logger.log(payload[:level], payload[:message]) - end - - # Configuration of HTTP Authentication - if $config['username'] != nil and $config['password'] != nil - use Rack::Auth::Basic, "Restricted Area" do |username, password| - [username, password] == [$config['username'], $config['password']] - end - end - - super - end - - # --------------------------------------------------------------------------------------------------------------------- - # GET request - - # tasks to be executed before the request is handled - before do - authentication = Rack::Auth::Basic::Request.new(request.env) - @backend = initialize_backend(authentication) - @renderer = OCCI::Rendering::Renderer.new - @occi_request = OCCI::Rendering::HTTP::Request.new(request) - @occi_response = OCCI::Rendering::HTTP::Response.prepare(response, request) - @location = request.path_info - end - - # taks to be executed after the requests are handled - after do - @renderer.render(response) - end - - # discovery interface - # returns all kinds, mixins and actions registered for the server - get '/-/', '/.well-known/org/ogf/occi/-/' do - OCCI::Log.info("Listing all kinds and mixins ...") - filter = @occi_request.categories - categories = OCCI::CategoryRegistry.get(filter) - @renderer.render_category_type(categories) - nil - end - - # Resource retrieval - # returns entities either below a certain path or belonging to a certain kind or mixin - get '*' do - begin - object = OCCI::Rendering::HTTP::LocationRegistry.get_object_at_location(@location) - - # Render exact matches referring to kinds / mixins - if object != nil and (object.kind_of?(OCCI::Core::Kind) or object.kind_of?(OCCI::Core::Mixin)) - ActiveSupport::Notifications.instrument("log", :level => Logger::INFO, :message => "Listing all entities for kind/mixin #{object.type_identifier} ...") - entities = Array.new - object.entities.each do |entity| - entities = helpers.filter_by_category(entity, @occi_request.categories) - entities = helpers.filter_by_attributes(entity, @occi_request.entities) - # filter entities by requested categories - #next unless @occi_request.categories.kinds.collect {|kind| kind.type_identifier}.include?(entity.kind.type_identifier) or (@occi_request.categories & entity.mixins) == @occi_request.categories - # filter entities by requested attributes - #next unless (entity.attributes.keys & @occi_request.attributes.keys) == @occi_request.attributes.keys - #loc = OCCI::Rendering::HTTP::LocationRegistry.get_location_of_object(entity) - # fix for JSON renderer - #logger.debug(@response['CONTENT-TYPE']) - #@renderer.render_entity(entity) if @response['CONTENT-TYPE'].include?('json') - #logger.debug("Rendering location: #{loc}") - #locations << loc - end - - @renderer.render_entities(entities) if @response['CONTENT-TYPE'].include?('json') - locations = entities.collect { |entity| OCCI::Rendering::HTTP::LocationRegistry.get_location_of_object(entity) } - @renderer.render_locations(locations) - - break - end - - # Render exact matches referring to an entity - if object != nil and object.kind_of?(OCCI::Core::Entity) - logger.info("Rendering entity [#{object.type_identifier}] for location [#{@location}] ...") - OCCI::Backend::Manager.signal_resource(@backend, OCCI::Backend::RESOURCE_REFRESH, object) if object.kind_of?(OCCI::Core::Resource) - @renderer.render_entity(object) - break - end - - # Render locations ending with "/", which are not exact matches - if @location.end_with?("/") - logger.info("Listing all resource instances below location: #{@location}") - #TODO: fix get_resources_below_location ! - resources = OCCI::Rendering::HTTP::LocationRegistry.get_resources_below_location(@location, @occi_request.categories) - - # When no resources found, return Not Found - if resources.nil? - response.status = OCCI::Rendering::HTTP::Response::HTTP_NOT_FOUND - break - end - - locations = [] - resources.each do |resource| - OCCI::Backend::Manager.signal_resource(@backend, OCCI::Backend::RESOURCE_REFRESH, resource) if resource.kind_of?(OCCI::Core::Resource) - locations << OCCI::Rendering::HTTP::LocationRegistry.get_location_of_object(resource) - @renderer.render_entity(resource) if @response['CONTENT-TYPE'].include?('json') - end - - @renderer.render_locations(locations) - break - end - - response.status = OCCI::Rendering::HTTP::Response::HTTP_NOT_FOUND - # This must be the last statement in this block, so that sinatra does not try to respond with random body content - # (or fail utterly while trying to do that!) - nil - - rescue Exception => e - logger.error(e) - response.status = OCCI::Rendering::HTTP::Response::HTTP_BAD_REQUEST - end - end - - # --------------------------------------------------------------------------------------------------------------------- - # POST request - post '/-/', '/.well-known/org/ogf/occi/-/' do - logger.info("Creating user defined mixin...") - logger.info(@occi_request.mixin) - - raise OCCI::MixinAlreadyExistsError, "Mixin already exists!" unless @occi_request.mixins.empty? - - begin - related_mixin = OCCI::CategoryRegistry.get_by_id(@occi_request.mixin.related) unless @occi_request.mixin.related.nil? - rescue OCCI::CategoryNotFoundException => e - logger.warn(e.message) - end - mixin = OCCI::Core::Mixin.new(@occi_request.mixin.term, @occi_request.mixin.scheme, @occi_request.mixin.title, nil, [], related_mixin, []) - raise OCCI::MixinCreationException, 'Cannot create mixin' if mixin.nil? - OCCI::CategoryRegistry.register(mixin) - - OCCI::Rendering::HTTP::LocationRegistry.register(URI.parse(@occi_request.mixin.location.chomp('"').reverse.chomp('"').reverse).path, mixin) - end - - # Create an instance appropriate to category field and optionally link an instance to another one - post '*' do - begin - # Trigger action on resource(s) - unless @occi_request.action_category.nil? - logger.info("Triggering action on resource(s) below location #{@location}") - resources = OCCI::Rendering::HTTP::LocationRegistry.get_resources_below_location(@location, OCCI::CategoryRegistry.get_all) - method = request.env["HTTP_X_OCCI_ATTRIBUTE"] - - raise "No entities corresponding to location [#{location}] could be found!" if resources.nil? - - logger.debug("Action [#{@occi_request.action_category.type_identifier}] to be triggered on [#{resources.length}] entities:") - resources.each do |resource| - # TODO: check why networkinterface is showing up under /compute/ - next unless resource.kind_of?(OCCI::Core::Resource) - OCCI::Backend::Manager.signal_resource(@backend, OCCI::Backend::RESOURCE_REFRESH, resource) if resource.kind_of?(OCCI::Core::Resource) - action = nil - resource.kind.actions.each do |existing_action| - action = existing_action if existing_action.category == @occi_request.action_category - end - raise "No action found for action #{@occi_request.action_category.type_identifier} and resource {#{resource.kind.type_identifier}" if action.nil? - # FIXME: method == params? - parameters = nil - OCCI::Backend::Manager.delegate_action(@backend, action, parameters, resource) - end - - break - end - - # If kind is a link and no actions specified then create link - if @occi_request.kind.entity_type.ancestors.include?(OCCI::Core::Link) - logger.info("Creating link...") - target_uri = URI.parse(@occi_request.attributes["occi.core.target"].chomp('"').reverse.chomp('"').reverse) - target = OCCI::Rendering::HTTP::LocationRegistry.get_object_at_location(target_uri.path) - - source_uri = URI.parse(@occi_request.attributes["occi.core.source"].chomp('"').reverse.chomp('"').reverse) - source = OCCI::Rendering::HTTP::LocationRegistry.get_object_at_location(source_uri.path) - - link = @occi_request.kind.entity_type.new(@occi_request.attributes) - source.links << link - target.links << link - - link_location = link.get_location() - OCCI::Rendering::HTTP::LocationRegistry.register(link_location, link) - logger.debug("Link created with location: #{link_location}") - response['Location'] = OCCI::Rendering::HTTP::LocationRegistry.get_absolute_location_of_object(link) - break - end unless @occi_request.kind.nil? - - # Create resource - unless @occi_request.kind.nil? - # If kind is not link and no actions specified, then create resource - logger.info("Creating resource...") - resource = @occi_request.kind.entity_type.new(@occi_request.attributes, @occi_request.mixins) - logger.debug("Resource attributes #{resource.attributes}") - - @occi_request.links.each do |link| - logger.debug(link) - - link_attributes = {} - link_attributes = link.attributes unless link.attributes.nil? - - link_attributes["occi.core.target"] = link.target.chomp('"').reverse.chomp('"').reverse - link_attributes["occi.core.source"] = resource.get_location - - link_mixins = [] - link_kind = nil - link.category.split(' ').each do |link_category| - begin - cat = OCCI::CategoryRegistry.get_by_id(link_category) - rescue OCCI::CategoryNotFoundException => e - logger.info("Category #{link_category} not found") - next - end - link_kind = cat if cat.kind_of?(OCCI::Core::Kind) - link_mixins << cat if cat.kind_of?(OCCI::Core::Mixin) - raise "No kind found for link category #{link_category}" if link_kind.nil? - end - - occi_link = link_kind.entity_type.new(link_attributes, link_mixins) - logger.debug("Link Mixins: #{occi_link.mixins}") - - if URI.parse(link.target).relative? - target = OCCI::Rendering::HTTP::LocationRegistry.get_object_at_location(link.target) - raise "target #{link.target} not found" if target.nil? - target.links << occi_link - end - - resource.links << occi_link - - OCCI::Rendering::HTTP::LocationRegistry.register(occi_link.get_location, occi_link) - end - - OCCI::Backend::Manager.signal_resource(@backend, OCCI::Backend::RESOURCE_DEPLOY, resource) - - logger.debug('Location:' + resource.get_location) - - OCCI::Rendering::HTTP::LocationRegistry.register(resource.get_location, resource) - - @renderer.render_location(OCCI::Rendering::HTTP::LocationRegistry.get_absolute_location_of_object(resource)) - break - end - - # Update resource instance(s) at the given location - unless OCCI::Rendering::HTTP::LocationRegistry.get_object_at_location(@location).nil? - entities = [] - # Determine set of resources to be updated - if OCCI::Rendering::HTTP::LocationRegistry.get_object_at_location(@location).kind_of?(OCCI::Core::Resource) - entities = [OCCI::Rendering::HTTP::LocationRegistry.get_object_at_location(@location)] - elsif not OCCI::Rendering::HTTP::LocationRegistry.get_object_at_location(@location).kind_of?(OCCI::Core::Category) - entities = OCCI::Rendering::HTTP::LocationRegistry.get_resources_below_location(@location, OCCI::CategoryRegistry.get_all) - elsif OCCI::Rendering::HTTP::LocationRegistry.get_object_at_location(@location).kind_of?(OCCI::Core::Category) - object = OCCI::Rendering::HTTP::LocationRegistry.get_object_at_location(@location) - @occi_request.locations.each do |loc| - entities << OCCI::Rendering::HTTP::LocationRegistry.get_object_at_location(URI.parse(loc.chomp('"').reverse.chomp('"').reverse).path) - end - end - logger.info("Updating [#{entities.size}] entities...") - - # add mixins - entities.each do |entity| - logger.debug("Adding entity: #{entity.get_location} to mixin #{object.type_identifier}") - entity.mixins.push(object).uniq! - object.entities.push(entity).uniq! - end if object.kind_of?(OCCI::Core::Mixin) - - # Update / add attributes - entities.each do |entity| - # Refresh information from backend for entities of type resource - OCCI::Backend::Manager.signal_resource(@backend, OCCI::Backend::RESOURCE_REFRESH, entity) if entity.kind_of?(OCCI::Core::Resource) - logger.debug("Adding the following attribute to mixin: #{@occi_request.attributes}") - entity.attributes.merge!(@occi_request.attributes) - end unless @occi_request.attributes.empty? - - # Update / add links - @occi_request.links.each do |link_data| - logger.debug("Extracted link data: #{link_data}") - raise "Mandatory information missing (related | target | category)!" unless link_data.related != nil && link_data.target != nil && link_data.category != nil - - kind = OCCI::CategoryRegistry.get_categories_by_category_string(link_data.category, filter="kinds")[0] - raise "No kind for category string: #{link_data.category}" unless kind != nil - - target_location = link_data.target_attr - target = OCCI::Rendering::HTTP::LocationRegistry.get_object_at_location(target_location) - - entities.each do |entity| - - source_location = OCCI::Rendering::HTTP::LocationRegistry.get_location_of_object(entity) - - attributes = link_data.attributes.clone - attributes["occi.core.target"] = target_location.chomp('"').reverse.chomp('"').reverse - attributes["occi.core.source"] = source_location - - link = kind.entity_type.new(attributes) - OCCI::Rendering::HTTP::LocationRegistry.register_location(link.get_location(), link) - - target.links << link - entity.links << link - end - end - break - end - - response.status = OCCI::Rendering::HTTP::Response::HTTP_NOT_FOUND - # This must be the last statement in this block, so that sinatra does not try to respond with random body content - # (or fail utterly while trying to do that!) - nil - - rescue OCCI::LocationAlreadyRegisteredException => e - logger.error(e.message) - response.status = OCCI::Rendering::HTTP::Response::HTTP_CONFLICT - - rescue OCCI::MixinCreationException => e - logger.error(e.message) - - rescue Exception => e - logger.error(e) - response.status = OCCI::Rendering::HTTP::Response::HTTP_BAD_REQUEST - end - end - - # --------------------------------------------------------------------------------------------------------------------- - # PUT request - - put '*' do - begin - # Add an resource instance to a mixin - unless @occi_request.mixins.empty? - mixin = OCCI::Rendering::HTTP::LocationRegistry.get_object_at_location(@location) - - @occi_request.locations.each do |location| - entity = OCCI::Rendering::HTTP::LocationRegistry.get_object_at_location(URI.parse(location).path) - - raise "No entity found at location: #{entity_location}" if entity == nil - raise "Object referenced by uri [#{entity_location}] is not a OCCI::Core::Resource instance!" if !entity.kind_of?(OCCI::Core::Resource) - - logger.debug("Associating entity [#{entity}] at location #{entity_location} with mixin #{mixin}") - - entity.mixins << mixin - end - break - end - - # Update resource instance(s) at the given location - unless OCCI::Rendering::HTTP::LocationRegistry.get_object_at_location(@location).nil? - entities = [] - # Determine set of resources to be updated - if OCCI::Rendering::HTTP::LocationRegistry.get_object_at_location(@location).kind_of?(OCCI::Core::Resource) - entities = [OCCI::Rendering::HTTP::LocationRegistry.get_object_at_location(@location)] - elsif not OCCI::Rendering::HTTP::LocationRegistry.get_object_at_location(@location).kind_of?(OCCI::Core::Category) - entities = OCCI::Rendering::HTTP::LocationRegistry.get_resources_below_location(@location, OCCI::CategoryRegistry.get_all) - elsif OCCI::Rendering::HTTP::LocationRegistry.get_object_at_location(@location).kind_of?(OCCI::Core::Category) - object = OCCI::Rendering::HTTP::LocationRegistry.get_object_at_location(@location) - @occi_request.locations.each do |loc| - entities << OCCI::Rendering::HTTP::LocationRegistry.get_object_at_location(URI.parse(loc.chomp('"').reverse.chomp('"').reverse).path) - end - end - logger.info("Full update for [#{entities.size}] entities...") - - # full update of mixins - object.entities.each do |entity| - entity.mixins.delete(object) - object.entities.delete(entity) - end if object.kind_of?(OCCI::Core::Mixin) - - entities.each do |entity| - logger.debug("Adding entity: #{entity.get_location} to mixin #{object.type_identifier}") - entity.mixins.push(object).uniq! - object.entities.push(entity).uniq! - end if object.kind_of?(OCCI::Core::Mixin) - - # full update of attributes - entities.each do |entity| - # Refresh information from backend for entities of type resource - # TODO: full update - entity.attributes.merge!(@occi_request.attributes) - # TODO: update entity in backend - end unless @occi_request.attributes.empty? - - # full update of links - # TODO: full update e.g. delete old links first - @occi_request.links.each do |link_data| - logger.debug("Extracted link data: #{link_data}") - raise "Mandatory information missing (related | target | category)!" unless link_data.related != nil && link_data.target != nil && link_data.category != nil - - link_mixins = [] - link_kind = nil - link_data.category.split(' ').each do |link_category| - begin - cat = OCCI::CategoryRegistry.get_by_id(link_category) - rescue OCCI::CategoryNotFoundException => e - logger.info("Category #{link_category} not found") - next - end - link_kind = cat if cat.kind_of?(OCCI::Core::Kind) - link_mixins << cat if cat.kind_of?(OCCI::Core::Mixin) - end - - raise "No kind for link category #{link_data.category} found" if link_kind.nil? - - target_location = link_data.target_attr - target = OCCI::Rendering::HTTP::LocationRegistry.get_object_at_location(target_location) - - entities.each do |entity| - - source_location = OCCI::Rendering::HTTP::LocationRegistry.get_location_of_object(entity) - - link_attributes = link_data.attributes.clone - link_attributes["occi.core.target"] = target_location.chomp('"').reverse.chomp('"').reverse - link_attributes["occi.core.source"] = source_location - - link = link_kind.entity_type.new(link_attributes, link_mixins) - OCCI::Rendering::HTTP::LocationRegistry.register_location(link.get_location(), link) - - target.links << link - entity.links << link - end - end - break - end - - response.status = OCCI::Rendering::HTTP::Response::HTTP_NOT_FOUND - # Create resource instance at the given location - raise "Creating resources with method 'put' is currently not possible!" - - # This must be the last statement in this block, so that sinatra does not try to respond with random body content - # (or fail utterly while trying to do that!) - nil - - rescue OCCI::LocationAlreadyRegisteredException => e - logger.error(e.message) - response.status = OCCI::Rendering::HTTP::Response::HTTP_CONFLICT - - rescue OCCI::MixinAlreadyExistsError => e - logger.error(e.message) - response.status = OCCI::Rendering::HTTP::Response::HTTP_CONFLICT - - rescue Exception => e - logger.error(e) - response.status = OCCI::Rendering::HTTP::Response::HTTP_BAD_REQUEST - end - end - - # --------------------------------------------------------------------------------------------------------------------- - # DELETE request - - delete '/-/', '/.well-known/org/ogf/occi/-/' do - # Location references query interface => delete provided mixin - raise OCCI::CategoryMissingException if @occi_request.mixin.nil? - raise OCCI::MixinNotFoundException if @occi_request.mixins.empty? - @occi_request.mixins.each do |mixin| - logger.info("Deleting mixin #{mixin.type_identifier}") - mixin.entities.each do |entity| - entity.mixins.delete(mixin) - end - OCCI::CategoryRegistry.unregister(mixin) - OCCI::Rendering::HTTP::LocationRegistry.unregister(OCCI::Rendering::HTTP::LocationRegistry.get_location_of_object(mixin)) - end - - nil - end - - delete '*' do - begin - # Location references a mixin => unassociate all provided resources (by X_OCCI_LOCATION) from it - object = OCCI::Rendering::HTTP::LocationRegistry.get_object_at_location(@location) - if object != nil && object.kind_of?(OCCI::Core::Mixin) - mixin = OCCI::Rendering::HTTP::LocationRegistry.get_object_at_location(@location) - logger.info("Unassociating entities from mixin: #{mixin}") - - @occi_request.locations.each do |loc| - entity = OCCI::Rendering::HTTP::LocationRegistry.get_object_at_location(URI.parse(loc.chomp('"').reverse.chomp('"').reverse).path) - mixin.entities.delete(entity) - entity.mixins.delete(mixin) - end - break - end - - entities = OCCI::Rendering::HTTP::LocationRegistry.get_resources_below_location(@location, @occi_request.categories) - - unless entities.nil? - entities.each do |entity| - location = entity.get_location - OCCI::Backend::Manager.signal_resource(@backend, OCCI::Backend::RESOURCE_DELETE, entity) if entity.kind_of? OCCI::Core::Resource - # TODO: delete links in backend! - entity.delete - OCCI::Rendering::HTTP::LocationRegistry.unregister(location) - end - break - end - - response.status = OCCI::Rendering::HTTP::Response::HTTP_NOT_FOUND - # This must be the last statement in this block, so that sinatra does not try to respond with random body content - # (or fail utterly while trying to do that!) - nil - - rescue OCCI::LocationNotRegisteredException => e - logger.error(e.message) - response.status = OCCI::Rendering::HTTP::Response::HTTP_NOT_FOUND - - rescue OCCI::CategoryMissingException => e - response.status = OCCI::Rendering::HTTP::Response::HTTP_BAD_REQUEST - - rescue OCCI::MixinNotFoundException => e - response.status = OCCI::Rendering::HTTP::Response::HTTP_NOT_FOUND - - rescue Exception => e - logger.error(e) - response.status = OCCI::Rendering::HTTP::Response::HTTP_BAD_REQUEST - end - end -end diff --git a/lib/occi/rendering/AbstractRenderer.rb b/lib/occi/rendering/AbstractRenderer.rb deleted file mode 100644 index 36f8beb..0000000 --- a/lib/occi/rendering/AbstractRenderer.rb +++ /dev/null @@ -1,78 +0,0 @@ -############################################################################## -# Copyright 2011 Service Computing group, TU Dortmund -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -############################################################################## - -############################################################################## -# Description: OCCI Rendering -# Author(s): Hayati Bice, Florian Feldhaus, Piotr Kasprzak -############################################################################## - -module OCCI - module Rendering - - # --------------------------------------------------------------------------------------------------------------------- - class AbstractRenderer - - def prepare() - end - - def render_category_type(categories) - raise NotImplementedError, "Method 'render_category_type' not implemented!" - end - - def render_category_short(categories) - raise NotImplementedError, "Method 'render_category_short' not implemented!" - end - - def render_location(location) - raise NotImplementedError, "Method 'render_location' not implemented!" - end - - def render_link_reference(link) - raise NotImplementedError, "Method 'render_link_reference' not implemented!" - end - - def render_action_reference(action, resource) - raise NotImplementedError, "Method 'render_action_reference' not implemented!" - end - - def render_attributes(attributes) - raise NotImplementedError, "Method 'render_attributes' not implemented!" - end - - def render_locations(locations) - raise NotImplementedError, "Method 'render_locations' not implemented!" - end - - def render_entity(entity) - raise NotImplementedError, "Method 'render_entity' not implemented!" - end - - def render_entities(entities) - raise NotImplementedError, "Method 'render_entity' not implemented!" - end - - def data() - raise NotImplementedError, "Method 'data' not implemented!" - end - - def render(response) - raise NotImplementedError, "Method 'render_response' not implemented!" - end - - end - - end -end \ No newline at end of file diff --git a/lib/occi/rendering/Renderer.rb b/lib/occi/rendering/Renderer.rb deleted file mode 100644 index ed50b31..0000000 --- a/lib/occi/rendering/Renderer.rb +++ /dev/null @@ -1,81 +0,0 @@ -############################################################################## -# Copyright 2011 Service Computing group, TU Dortmund -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -############################################################################## - -############################################################################## -# Description: OCCI Rendering -# Author(s): Hayati Bice, Florian Feldhaus, Piotr Kasprzak -############################################################################## - -require 'occi/rendering/AbstractRenderer' -require 'occi/rendering/http/TextRenderer' -require 'occi/rendering/http/JSONRenderer' - -require 'occi/Log' - -module OCCI - module Rendering - - # --------------------------------------------------------------------------------------------------------------------- - class Renderer - - # --------------------------------------------------------------------------------------------------------------------- - # Prepare current rendering pass - def self.prepare(content_type) - @@request_content_type = content_type - OCCI::Log.error("No renderer registered for content type '%{content_type}'") unless @@renderers.has_key?(content_type) - @@renderers[@@request_content_type].send(:prepare) - end - - # --------------------------------------------------------------------------------------------------------------------- - def self.register(content_type, renderer_instance) - @@renderers[content_type] = renderer_instance - end - - # --------------------------------------------------------------------------------------------------------------------- - # TODO: implement mission methods stuff redirection -> content - def method_missing(method, *args, &block) - if AbstractRenderer.method_defined?(method) - @@renderers[@@request_content_type].send(method, *args, &block) - else - super - end - end - - # --------------------------------------------------------------------------------------------------------------------- - private - # --------------------------------------------------------------------------------------------------------------------- - - # The content type for the curret request - @@request_content_type = "" - - # Content-type -> renderer instance - @@renderers = {} - - # --------------------------------------------------------------------------------------------------------------------- - # Register available renderer - text_renderer = OCCI::Rendering::HTTP::TextRenderer.new - self.register("text/occi", text_renderer) - self.register("text/plain", text_renderer) - self.register("text/uri-list", text_renderer) - - json_renderer = OCCI::Rendering::HTTP::JSONRenderer.new - self.register("application/json", json_renderer) - self.register("application/occi+json", json_renderer) - - end - - end -end diff --git a/lib/occi/rendering/http/JSONRenderer.rb b/lib/occi/rendering/http/JSONRenderer.rb deleted file mode 100644 index c2a380e..0000000 --- a/lib/occi/rendering/http/JSONRenderer.rb +++ /dev/null @@ -1,214 +0,0 @@ -############################################################################## -# Copyright 2011 Service Computing group, TU Dortmund -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -############################################################################## - -############################################################################## -# Description: OCCI HTTP Rendering -# Author(s): Hayati Bice, Florian Feldhaus, Piotr Kasprzak -############################################################################## - -require 'json' -require 'occi/core/Action' -require 'occi/core/Kind' -require 'occi/core/Mixin' - -require 'occi/rendering/http/LocationRegistry' -require 'occi/rendering/AbstractRenderer' - -module OCCI - module Rendering - module HTTP - - class JSONRenderer < OCCI::Rendering::AbstractRenderer - - # --------------------------------------------------------------------------------------------------------------------- - private - # --------------------------------------------------------------------------------------------------------------------- - - # --------------------------------------------------------------------------------------------------------------------- - def is_numeric?(object) - true if Float(object) rescue false - end - - # --------------------------------------------------------------------------------------------------------------------- - def attribute_to_hash(attribute) - - hash = {} - hash['mutable'] = attribute.mutable - hash['required'] = attribute.required - hash['type'] = attribute.type - hash['range'] = attribute.range - hash['default'] = attribute.default - - return hash - end - - # --------------------------------------------------------------------------------------------------------------------- - def attributes_to_hash(attributes) - - hash = {} - attributes.each do |key, value| - hash[key] = value.to_hash - end - return hash - end - - # --------------------------------------------------------------------------------------------------------------------- - def category_to_hash(category) - - hash = {} - hash['term'] = category.term - hash['scheme'] = category.scheme - hash['title'] = category.title - hash['related'] = category.related.first.type_identifier unless category.related.empty? if category.respond_to?(:related) - hash['location'] = category.location - hash['attributes'] = category.attributes.to_hash unless category.attributes.to_hash.empty? - hash['actions'] = category.actions.collect{|action| render_action_reference(action,category)} if category.respond_to?(:actions) - - return hash - end - - # --------------------------------------------------------------------------------------------------------------------- - public - # --------------------------------------------------------------------------------------------------------------------- - - # --------------------------------------------------------------------------------------------------------------------- - def prepare() - # Re-initialize header array - @data = {} - end - - # --------------------------------------------------------------------------------------------------------------------- - def render_category_type(categories) - - categories.each do |category| - if category.instance_of?(OCCI::Core::Category) - @data[:categories] = [category_to_hash(category)] + @data[:categories].to_a - next - end - - if category.kind_of?(OCCI::Core::Mixin) - @data[:mixins] = [category_to_hash(category)] + @data[:mixins].to_a - next - end - - if category.kind_of?(OCCI::Core::Kind) - @data[:kinds] = [category_to_hash(category)] + @data[:kinds].to_a - next - end - end - end - - # --------------------------------------------------------------------------------------------------------------------- - def render_category_short(category) - return category.type_identifier - end - - # --------------------------------------------------------------------------------------------------------------------- - # render single location if a new resource has been created (e.g. use Location instead of X-OCCI-Location) - def render_location(location) - @data.merge!({ "Location" => location }) - end - - # --------------------------------------------------------------------------------------------------------------------- - def render_link_reference(link) - hash = {} - hash['title'] = link.attributes['occi.core.title'] - hash['target'] = link.attributes['occi.core.target'] - target_object = OCCI::Rendering::HTTP::LocationRegistry.get_object_at_location(link.attributes['occi.core.target']) - hash['target_type'] = target_object.type_identifier - hash['location'] = link.get_location - hash['type'] = link.type_identifier - hash['attributes'] = render_attributes(link.attributes) - return hash - end - - # --------------------------------------------------------------------------------------------------------------------- - def render_action_reference(action, object) - hash = {} - hash['title'] = action.category.title - hash['uri'] = OCCI::Rendering::HTTP::LocationRegistry.get_location_of_object(object) + '?action=' + action.category.term - hash['type'] = action.category.type_identifier - return hash - end - - # --------------------------------------------------------------------------------------------------------------------- - def render_attributes(attributes) - attribute_hash = {} - attributes.each_key do |name| - child = attributes[name] - hash = {} - name.split('.').reverse_each do |path| - hash = {path => child} - child = hash - end - attribute_hash.merge!(hash) - end - return attribute_hash - end - - # --------------------------------------------------------------------------------------------------------------------- - def render_locations(locations) - # JSON does not render locations anymore. text/uri-list should be used to get locations - end - - # --------------------------------------------------------------------------------------------------------------------- - def render_entity(entity) - - entity_rendering = {} - # render kind of entity - entity_rendering.merge!({ :kind => render_category_short(entity.kind) } ) - - entity_rendering.merge!({:mixins => entity.mixins.collect{|mixin| render_category_short(mixin) } } ) unless entity.mixins.empty? - - entity_rendering.merge!({:actions => entity.actions.collect{|action| render_action_reference(action,entity) } } ) unless entity.actions.empty? - - # Render attributes - entity_rendering.merge!(render_attributes(entity.attributes)) unless entity.attributes.empty? - - entity_rendering.merge!({:links => entity.links.collect{|link| render_link_reference(link) } } ) if entity.kind_of?(OCCI::Core::Resource) unless entity.links.empty? - - entity_rendering.merge!({:location => entity.get_location } ) - - if @data.empty? - @data = entity_rendering - else - @data = [entity_rendering] | [@data].flatten - end - end - - def render_entities(entities) - entities.each {|entity| render_entity(entity)} - end - - # --------------------------------------------------------------------------------------------------------------------- - def data() - return @data - end - - # --------------------------------------------------------------------------------------------------------------------- - def render(response) - - # Don't put any data in the response if there was an error - return if response.status != OCCI::Rendering::HTTP::Response::HTTP_OK - - response.write(JSON.pretty_generate(@data)) - end - - end - - end - end -end \ No newline at end of file diff --git a/lib/occi/rendering/http/LocationRegistry.rb b/lib/occi/rendering/http/LocationRegistry.rb deleted file mode 100644 index 0c95a38..0000000 --- a/lib/occi/rendering/http/LocationRegistry.rb +++ /dev/null @@ -1,135 +0,0 @@ -############################################################################## -# Copyright 2011 Service Computing group, TU Dortmund -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -############################################################################## - -############################################################################## -# Description: Registry to store all category and entitiy locations -# Author(s): Hayati Bice, Florian Feldhaus, Piotr Kasprzak -############################################################################## - -require 'logger' - -require 'occi/core/Category' -require 'occi/core/Entity' -require 'occi/core/Resource' - -module OCCI - module Rendering - module HTTP - class LocationRegistry - - # --------------------------------------------------------------------------------------------------------------------- - private - # --------------------------------------------------------------------------------------------------------------------- - - # --------------------------------------------------------------------------------------------------------------------- - def self.generate_key(object) - return object.type_identifier if object.kind_of? OCCI::Core::Category - return object.attributes["occi.core.id"] if object.kind_of? OCCI::Core::Entity - raise "Unsupported object type: #{object.class}" - end - - # --------------------------------------------------------------------------------------------------------------------- - public - # --------------------------------------------------------------------------------------------------------------------- - - # Tree like representation of http namespace - @@registry = {} - # Hash mapping resource keys to locations (for lookup of locations) - @@locations = {} - - # --------------------------------------------------------------------------------------------------------------------- - def self.register(location, object) - - raise OCCI::LocationAlreadyRegisteredException, "Location [#{@@locations[generate_key(object)]}] already registered for object [#{object}]" if @@locations[generate_key(object)] != nil - #raise OCCI::LocationAlreadyRegisteredException, "Object [#{@@objects[location]}] already registered for location [#{location}]" if @@objects[location] != nil - raise "Only absolute paths (starting with '/') are supported: location provided: [#{location}])" unless location.start_with?("/") - - @@locations[generate_key(object)] = location - - @@registry[location] = {:children => [], :object => nil} if @@registry[location].nil? - @@registry[location][:object] = object - child = [ @@registry[location] ] - until location == '/' - location = location[0..location.rindex('/',-2)] - @@registry[location] = {:children => [], :object => nil} if @@registry[location].nil? - @@registry[location][:children] = child | @@registry[location][:children] - child = [ @@registry[location] ] - end - end - - # --------------------------------------------------------------------------------------------------------------------- - def self.unregister(location) - raise OCCI::LocationNotRegisteredException if @@registry[location].nil? - - @@locations.delete(generate_key(@@registry[location][:object])) - - child = @@registry[location] - @@registry.delete(location) - - until location == '/' - location = location[0..location.rindex('/',-2)] - @@registry[location][:children].delete(child) - if @@registry[location][:children].empty? and @@registry[location][:object].nil? - child = @@registry[location] - @@registry.delete(location) - else - break - end - end - - end - - # --------------------------------------------------------------------------------------------------------------------- - def self.get_location_of_object(object) - return @@locations[generate_key(object)] - end - - # --------------------------------------------------------------------------------------------------------------------- - def self.get_absolute_location_of_object(object) - location = get_location_of_object(object) - return $config[:server].chomp('/') + ':' + $config[:port] + location if location - end - - # --------------------------------------------------------------------------------------------------------------------- - def self.get_object_at_location(location) - return @@registry[location][:object] unless @@registry[location].nil? - end - - # --------------------------------------------------------------------------------------------------------------------- - def self.get_resources_below_location(location, categories) - - resources = [] - elements = [] - - elements << @@registry[location] unless @@registry[location].nil? - until elements.empty? - element = elements.pop - unless element[:object].nil? - resource = element[:object] - resources << resource if resource.kind_of?(OCCI::Core::Entity) and categories.include?(resource.kind) - end - elements = element[:children] | elements - end - - return resources - end - - # --------------------------------------------------------------------------------------------------------------------- - - end - end - end -end \ No newline at end of file diff --git a/lib/occi/rendering/http/Request.rb b/lib/occi/rendering/http/Request.rb deleted file mode 100644 index 952e7d5..0000000 --- a/lib/occi/rendering/http/Request.rb +++ /dev/null @@ -1,220 +0,0 @@ -############################################################################## -# Copyright 2011 Service Computing group, TU Dortmund -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -############################################################################## - -############################################################################## -# @note OCCI RESTful Web Service -# @author Florian Feldhaus, Piotr Kasprzak -############################################################################## - -require 'json' -require 'occi/Log' -require 'occi/antlr/OCCIParser' - -module OCCI - module Rendering - module HTTP - class Request - - attr_reader :categories - attr_reader :entities - attr_reader :locations - - # Parses a Rack/Sinatra Request and extract OCCI relevant information - # - # @param [Rack::Request] request from Sinatra/Rack - def initialize(request) - @categories = Hashie::Mash.new({:kinds=>[],:mixins=>[],:actions=>[]}) - @entities = Hashie::Mash.new({:links=>[],:resources=>[]}) - @locations = Array.new - - content_type = request.env['CONTENT_TYPE'].to_s - -=begin - if content_type.includes?('multipart') - # TODO: implement multipart handling - # handle file upload - if params['file'] != nil - OCCI::Log.debug("Location of Image #{params['file'][:tempfile].path}") - $image_path = $config[:one_image_tmp_dir] + '/' + params['file'][:filename] - FileUtils.cp(params['file'][:tempfile].path, $image_path) - end - - # handle file upload in multipart requests - request.POST.values.each do |body| - if body.kind_of?(String) - parse_text(body) - elsif body.kind_of?(Hash) - if body['type'].include?('application/json') - # try to parse body as JSON object - parse_json(body.read) - elsif body['type'].include?('text/plain') # text/plain - parse_text(body.read) - end unless body['type'].nil? - end - end - end -=end - - case content_type - when 'text/uri-list' - request.body.each_line do |line| - @locations << URI.parse(line) - end - when 'text/occi' - @locations.concat(parse_header_locations(request.env)) - if @locations.empty? - if request.path_info.include?('/-/') - @categories = parse_header_categories(request.env) - else - if request.path_info.start_with?('/link/') - @entities[:links] = parse_header_links(request.env) - elsif request.path_info.include?('?action=') - @categories = parse_header_category(request.env) - else - @entities[:resources] = parse_header_resources(request.env) - end - end - end - when 'text/plain' - @locations.concat(parse_text_locations(request.body)) - if @locations.empty? - if request.path_info.include?('/-/') - @categories = parse_text_mixins(request.body) - else - if request.path_info.start_with?('/link/') - @entities[:links] = parse_text_links(request.body) - elsif request.path_info.include?('?action=') - @categories = parse_text_categories(request.body) - else - @entities[:resources] = parse_text_resources(request.body) - end - end - end - when 'application/occi-category+json' - @categories = parse_json(request.body) - when 'application/occi-resource+json' - @resources = parse_json(request.body) - when 'application/occi-link+json' - @entities = parse_json(request.body) - end - end - - # --------------------------------------------------------------------------------------------------------------------- - private - # --------------------------------------------------------------------------------------------------------------------- - - def self.parse_header_locations(header) - locations = Array.new - x_occi_location_strings = header['HTTP_X_OCCI_LOCATION'].to_s.split(',') - locations.concat(x_occi_location_strings.collect { |loc| OCCI::Parser.new('X-OCCI-Location: ' + loc).x_occi_location }).compact! - return locations - end - - def self.parse_header_categories(header) - categories = Hashie::Mash.new({:kinds=>[],:mixins=>[],:actions=>[]}) - category_strings = header['HTTP_CATEGORY'].to_s.split(',') - category_strings.each { |cat| categories.merge!(OCCI::Parser.new('Category: ' + cat).category) } - return categories - end - - def self.parse_header_links(header) - link = Hashie::Mash.new - category_strings = header['HTTP_CATEGORY'].to_s.split(',') - attribute_strings = header['HTTP_X_OCCI_ATTRIBUTE'].to_s.split(',') - link.kind = category_strings.collect { |cat| OCCI::Parser.new('Category: ' + cat).kind }.first - link.mixins = mixin_strings.collect { |cat| OCCI::Parser.new('Category: ' + cat).mixin }.compact! - link.attributes = attribute_strings.collect { |attr| OCCI::Parser.new('X-OCCI-Attribute: ' + attr).x_occi_attribute }.compact! - link.target = link.attributes.occi!.core!.target - link.source = link.attributes.occi!.core!.source - links = [link] - return links - end - - def self.parse_header_resources(header) - resource = Hashie::Mash.new - category_strings = header['HTTP_CATEGORY'].to_s.split(',') - attribute_strings = header['HTTP_X_OCCI_ATTRIBUTE'].to_s.split(',') - link_strings = header['HTTP_LINK'].to_s.split(',') - resource.kind = category_strings.collect { |cat| OCCI::Parser.new('Category: ' + cat).kind }.first - resource.mixins = mixin_strings.collect { |cat| OCCI::Parser.new('Category: ' + cat).mixin }.compact! - resource.attributes = attribute_strings.collect { |attr| OCCI::Parser.new('X-OCCI-Attribute: ' + attr).x_occi_attribute }.compact! - resource.links =link_strings.collect { |link| OCCI::Parser.new('Link: ' + link).link }.compact! - resources = [resource] - return resources - end - - def self.parse_text_locations(body) - locations = Array.new - body.each_line do |line| - location = OCCI::Parser.new(line).x_occi_location - locations.concat([location]) if location.any? - end - return locations - end - - def self.parse_text_categories(body) - categories = Hashie::Mash.new({:kinds=>[],:mixins=>[],:actions=>[]}) - body.each_line do |line| - category = OCCI::Parser.new(line).category - categories.merge!(category) - end - return categories - end - - def self.parse_text_links(body) - link = Hashie::Mash.new - link.mixins = Array.new - link.attributes = Array.new - body.each_line do |line| - kind = OCCI::Parser.new(line).kind - link.kind = kind if kind.any? - mixin = OCCI::Parser.new(line).mixin - link.mixins.concat(mixin) if mixin.any? - attribute = OCCI::Parser.new(line).x_occi_attribute - link.attributes.concat(attribute) if attribute.any? - end - link.target = link.attribute!.occi!.core!.target - link.source = link.attribute!.occi!.core!.source - links = [link] - return links - end - - def self.parse_text_resource(body) - resource = Hashie::Mash.new - resource.mixins = Array.new - resource.attributes = Array.new - resource.links = Array.new - body.each_line do |line| - kind = OCCI::Parser.new(line).kind - resource.kind = kind if kind.any? - mixin = OCCI::Parser.new(line).mixin - resource.mixins.concat(mixin) if mixin.any? - link = OCCI::Parser.new(line).link - resource.links.concat(attribute) if link.any? - attribute = OCCI::Parser.new(line).x_occi_attribute - resource.attributes.concat(attribute) if attribute.any? - end - resources = [resource] - return resources - end - - def self.parse_json(body) - Hashie::Mash.new(JSON.parse(body)) - end - end - end - end -end diff --git a/lib/occi/rendering/http/Response.rb b/lib/occi/rendering/http/Response.rb deleted file mode 100644 index 491d43a..0000000 --- a/lib/occi/rendering/http/Response.rb +++ /dev/null @@ -1,99 +0,0 @@ -############################################################################## -# Copyright 2011 Service Computing group, TU Dortmund -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -############################################################################## - -############################################################################## -# @note OCCI RESTful Web Service -# @author Florian Feldhaus, Piotr Kasprzak -############################################################################## - -require 'occi/Log' - -module OCCI - module Rendering - module HTTP - class Response - # To change this template use File | Settings | File Templates. - ############################################################################## - # HTTP Status Codes - - HTTP_OK = 200 - HTTP_RESOURCE_CREATED = 201 - HTTP_ACCEPTED = 202 - HTTP_BAD_REQUEST = 400 - HTTP_UNAUTHORIZED = 401 - HTTP_FORBIDDEN = 403 - HTTP_NOT_FOUND = 404 - HTTP_METHOD_NOT_ALLOWED = 405 - HTTP_CONFLICT = 409 - HTTP_GONE = 410 - HTTP_UNSUPPORTED_MEDIA_TYPE = 415 - HTTP_INTERNAL_SERVER_ERROR = 500 - HTTP_NOT_IMPLEMENTED = 501 - HTTP_SERVICE_UNAVAILABLE = 503 - - # --------------------------------------------------------------------------------------------------------------------- - # rendering general parameters - # responeAttributes: Hash object - # respone: response object of Sinatra - # return: text/plain and text/uri: response.body - # return: text/occi: response[key] head - - def self.prepare(response, request) - - OCCI::Log.info("#################### Information on the client ####################") - OCCI::Log.info("Client IP Adress: #{request.env['REMOTE_ADDR']}") - OCCI::Log.info("Client User Agent: #{request.env['HTTP_USER_AGENT']}") - OCCI::Log.info("###################################################################") - - # determine content type from request content type or reques accept, fallback to text/plain - content_type = "" - content_type = request.env['CONTENT_TYPE'] if request.env['CONTENT_TYPE'] - content_type = request.env['HTTP_ACCEPT'] if request.env['HTTP_ACCEPT'] - - if content_type.include?('application/occi+json') - response['Content-Type'] = 'application/occi+json' - - elsif content_type.include?('application/json') - response['Content-Type'] = 'application/json' - - elsif content_type.include?('text/plain') || content_type.include?('text/*') || content_type.include?('*/*') || content_type == "" - response['Content-Type'] = 'text/plain' - - elsif content_type.include?('text/uri-list') - response['Content-Type'] = 'text/uri-list' - - elsif content_type.include?('text/occi') - response['Content-Type'] = 'text/occi' - - else - response.status = HTTP_STATUS_CODE["Unsupported Media Type"] - raise "Unsupported Media Type" - end - - response['Accept'] = "application/occi+json,application/json,text/plain,text/occi,text/uri-list" - response['Server'] = "rOCCI/#{VERSION_NUMBER} OCCI/1.1" - - # Set default status - response.status = HTTP_OK - - # Prepare renderer - OCCI::Rendering::Renderer.prepare(response['Content-Type']) - end - end - end - end -end - diff --git a/lib/occi/rendering/http/TextRenderer.rb b/lib/occi/rendering/http/TextRenderer.rb deleted file mode 100644 index 79fb8b2..0000000 --- a/lib/occi/rendering/http/TextRenderer.rb +++ /dev/null @@ -1,299 +0,0 @@ -############################################################################## -# Copyright 2011 Service Computing group, TU Dortmund -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -############################################################################## - -############################################################################## -# Description: OCCI HTTP Rendering -# Author(s): Hayati Bice, Florian Feldhaus, Piotr Kasprzak -############################################################################## - -require 'json' -require 'occi/core/Action' -require 'occi/core/Kind' -require 'occi/core/Mixin' - -require 'occi/rendering/http/LocationRegistry' -require 'occi/rendering/AbstractRenderer' - -module OCCI - module Rendering - module HTTP - - class TextRenderer < OCCI::Rendering::AbstractRenderer - - # --------------------------------------------------------------------------------------------------------------------- - private - # --------------------------------------------------------------------------------------------------------------------- - - # --------------------------------------------------------------------------------------------------------------------- - def is_numeric?(object) - true if Float(object) rescue false - end - - # --------------------------------------------------------------------------------------------------------------------- - public - # --------------------------------------------------------------------------------------------------------------------- - - CATEGORY = "Category" - LINK = "Link" - LOCATION = "Location" - OCCI_ATTRIBUTE = "X-OCCI-Attribute" - OCCI_LOCATION = "X-OCCI-Location" - - # --------------------------------------------------------------------------------------------------------------------- - def prepare() - # Re-initialize header array - @data = {} - end - - # --------------------------------------------------------------------------------------------------------------------- - def render_category_type(categories) - - category_values = [] - - # create category string for all categories - Array(categories).each do |category| - - # category identifier - category_string = category.term - category_string += %Q{; scheme="#{category.scheme}"} - category_string += %Q{; class="#{category.class_string}"} - - # category title - category_string += %Q{; title="#{category.title}"} if category.title - - # related kinds - related_value = "" - category.related.each do |related| - related_value += related.type_identifier - end if defined? category.related - category_string += %Q{; rel="#{related_value.strip}"} if related_value != "" - - # category location - location = OCCI::Rendering::HTTP::LocationRegistry.get_absolute_location_of_object(category) - category_string += %Q{; location=#{location.strip}} if defined? location.strip - - # attributes - attributes = "" - category.attributes.keys.each do |attribute| - attributes += "#{attribute} " - end if defined? category.attributes - category_string += %Q{; attributes="#{attributes.strip}"} if attributes != "" - - # actions - actions = "" - category.actions.each do |action| - actions += action.category.scheme + action.category.term + " " - end if defined? category.actions - - category_string += %Q{; actions="#{actions.strip}"} if actions != "" - category_values << category_string - end - - @data[CATEGORY] = category_values + @data[CATEGORY].to_a - end - - # --------------------------------------------------------------------------------------------------------------------- - def render_category_short(categories) - - category_values = [] - - # create category string for all categories - Array(categories).each do |category| - # category identifier - category_string = %Q{#{category.term}} - category_string += %Q{; scheme="#{category.scheme}"} - category_string += %Q{; class="#{category.class_string}"} - category_values << category_string - end - - @data[CATEGORY] = category_values + @data[CATEGORY].to_a - end - - # --------------------------------------------------------------------------------------------------------------------- - # render single location if a new resource has been created (e.g. use Location instead of X-OCCI-Location) - def render_location(location) - @data[LOCATION] = [location] + @data[LOCATION].to_a - end - - # --------------------------------------------------------------------------------------------------------------------- - def render_link_reference(link) - - # Link value - location = OCCI::Rendering::HTTP::LocationRegistry.get_location_of_object(link) - target_location = link.attributes["occi.core.target"] - target_resource = OCCI::Rendering::HTTP::LocationRegistry.get_object_at_location(target_location) - if target_resource.nil? - target_resource_type = OCCI::Core::Link::KIND.type_identifier - else - target_resource_type = target_resource.kind.type_identifier - end - category = link.kind.type_identifier - attributes = link.attributes.map { |key,value| %Q{#{key}="#{value}"} unless value.empty? }.join(';').to_s - - link_string = %Q{<#{target_location}>} - link_string += %Q{; rel="#{target_resource_type}"} - link_string += %Q{; self="#{location}"} - link_string += %Q{; category="#{category}"} - link_string += %Q{; #{attributes}} - - @data[LINK] = [link_string] + @data[LINK].to_a - end - - # --------------------------------------------------------------------------------------------------------------------- - def render_action_reference(action, resource) - - resource_location = OCCI::Rendering::HTTP::LocationRegistry.get_location_of_object(resource) - action_location = resource_location + "?action=" + action.category.term - action_type = action.category.type_identifier - - link_value = %Q{<#{action_location}>} - link_value += %Q{; rel="#{action_type}"} - - @data[LINK] = [link_value] + @data[LINK].to_a - end - - # --------------------------------------------------------------------------------------------------------------------- - def render_attributes(attributes) - - return if attributes == nil || attributes.empty? - - attributes_values = [] - attributes.each do |name, value| - # Render strings with quotes, numerics without - if is_numeric?(value) - attributes_values << %Q{#{name}=#{value}} - else - attributes_values << %Q{#{name}="#{value}"} - end - end - - @data[OCCI_ATTRIBUTE] = attributes_values + @data[OCCI_ATTRIBUTE].to_a - end - - # --------------------------------------------------------------------------------------------------------------------- - def render_locations(locations) - - locations_values = [] - locations.each do |location| - locations_values << $config["server"].chomp('/') + ':' + $config["port"] + location unless location.nil? - end - - @data[OCCI_LOCATION] = locations_values + @data[OCCI_LOCATION].to_a - end - - # --------------------------------------------------------------------------------------------------------------------- - def render_entity(entity) - - # render kind of entity - render_category_short(entity.kind) - - # render mixins of entity - entity.mixins.each do |mixin| - render_category_type(mixin) - end - - # Render attributes - render_attributes(entity.attributes) - - # Render link references - entity.links.each do |link| - render_link_reference(link) - end if entity.kind_of?(OCCI::Core::Resource) - - # Render action references - entity.actions.each do |action| - render_action_reference(action, entity) - end - end - - def render_entities(entities) - entities.each {|entity| render_entity(entity)} - end - - # --------------------------------------------------------------------------------------------------------------------- - def data() - return @data - end - - # --------------------------------------------------------------------------------------------------------------------- - def render(response) - - # Don't put any data in the response if there was an error - return if response.status != OCCI::Rendering::HTTP::Response::HTTP_OK - - if response['Content-Type'].include?('text/plain') - render_text_plain_response(response) - - elsif response['Content-Type'].include?('text/uri-list') - render_text_uri_list_response(response) - - elsif response['Content-Type'].include?('text/occi') - render_text_occi_response(response) - end - end - - # --------------------------------------------------------------------------------------------------------------------- - def render_text_plain_response(response) - -# response[LOCATION] = @data[LOCATION] if @data.has_key?(LOCATION) -# response[LINK] = @data[LINK] if @data.has_key?(LINK) - - # FIXME: check if "Location: " has to be prepended - response.write(@data[LOCATION].join + "\n") if @data.has_key?(LOCATION) - - if @data.has_key?(CATEGORY) - response.write(@data[CATEGORY].collect {|category| 'Category: ' + category}.join("\n") + "\n") - end - - if @data.has_key?(LINK) - response.write(@data[LINK].collect {|link| 'Link: ' + link}.join("\n") + "\n") - end - - if @data.has_key?(OCCI_ATTRIBUTE) - response.write(@data[OCCI_ATTRIBUTE].collect {|attribute| 'X-OCCI-Attribute: ' + attribute}.join("\n") + "\n") - end - - if @data.has_key?(OCCI_LOCATION) - response.write(@data[OCCI_LOCATION].collect {|location| 'X-OCCI-Location: ' + location}.join("\n") + "\n") - end - - end - - # --------------------------------------------------------------------------------------------------------------------- - def render_text_occi_response(response) - - response[LOCATION] = @data[LOCATION].join(', ') if @data.has_key?(LOCATION) - response[CATEGORY] = @data[CATEGORY].join(', ') if @data.has_key?(CATEGORY) - response[LINK] = @data[LINK].join(', ') if @data.has_key?(LINK) - response['X-OCCI-Attribute']= @data[OCCI_ATTRIBUTE].join(', ') if @data.has_key?(OCCI_ATTRIBUTE) - response['X-OCCI-Location'] = @data[OCCI_LOCATION].join(', ') if @data.has_key?(OCCI_LOCATION) - - response.write('OK') - end - - # --------------------------------------------------------------------------------------------------------------------- - def render_text_uri_list_response(response) - - if @data.has_key?(OCCI_LOCATION) - response.write(@data[OCCI_LOCATION].collect {|location| location}.join("\n")) - end - end - - end - - end - end -end diff --git a/lib/occi/server.rb b/lib/occi/server.rb new file mode 100644 index 0000000..6eb02cc --- /dev/null +++ b/lib/occi/server.rb @@ -0,0 +1,571 @@ +############################################################################## +# Copyright 2011 Service Computing group, TU Dortmund +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +############################################################################## + +############################################################################## +# Description: OCCI RESTful Web Service +# Author(s): Hayati Bice, Florian Feldhaus, Piotr Kasprzak +############################################################################## + +############################################################################## +# Require Ruby Gems + +# gems +require 'rubygems' + +# sinatra +require 'sinatra' +require 'sinatra/multi_route' +require 'sinatra/cross_origin' +require 'sinatra/respond_with' + +# Ruby standard library +require 'uri' +require 'fileutils' + +# Server configuration +require 'occi/Configuration' + +# Active support notifications +require 'active_support/notifications' + +############################################################################## +# Read configuration file and set log level + +CONFIGURATION_FILE = 'etc/occi-server.conf' + +$config = OCCI::Configuration.new(CONFIGURATION_FILE) + +############################################################################## +# Require OCCI classes + +# Exceptions +require 'occi/exceptions' + +# Category registry +require 'occi/registry' + +# OCCI Core classes +require 'occi/core/action' +require 'occi/core/category' +require 'occi/core/entity' +require 'occi/core/kind' +require 'occi/core/link' +require 'occi/core/mixin' +require 'occi/core/resource' + +# OCCI Infrastructure classes +#require 'occi/infrastructure/Networkinterface' +#require 'occi/infrastructure/StorageLink' +#require 'occi/infrastructure/Ipnetworking' +#require 'occi/infrastructure/OSTemplate' +#require 'occi/infrastructure/ResourceTemplate' +#require 'occi/infrastructure/IPNetworkInterface' + +# OCCI extensions +#require 'occi/extensions/Reservation' +#require 'occi/extensions/NFSStorage' +#require 'occi/extensions/ConsoleLink' + +# OCCI Request handling +require 'occi/request' + +# Backend support +require 'occi/backend/manager' + +############################################################################## +# Sinatra methods for handling HTTP requests + +module OCCI + class Server < Sinatra::Application + + register Sinatra::MultiRoute + register Sinatra::CrossOrigin + register Sinatra::RespondWith + + enable cross_origin + + def initialize(config = {}) + # create logger + config[:log_dest] ||= STDOUT + config[:log_level] ||= Logger::INFO + config[:log_level] = case $config[:log_level] + when "debug" + Logger::DEBUG + when "info" + Logger::INFO + when "warn" + Logger::WARN + when "error" + Logger::ERROR + when "fatal" + Logger::FATAL + else + Logger::INFO + end + + @logger = Logger.new(config[:log_dest]) + @logger.level = config[:log_level] + + # subscribe to log messages and send to logger + @log_subscriber = ActiveSupport::Notifications.subscribe("log") do |name, start, finish, id, payload| + @logger.log(payload[:level], payload[:message]) + end + + # create base URI for server + @server_uri = URI.parse($config['server']) + @server_uri.port = $config['port'].to_i + + # Configuration of HTTP Authentication + if $config['username'] != nil and $config['password'] != nil + use Rack::Auth::Basic, "Restricted Area" do |username, password| + [username, password] == [$config['username'], $config['password']] + end + end + + OCCI::Server.initialize_model + + # set views explicitly + set :views, File.dirname(__FILE__) + "/../../views" + + super + end + +# --------------------------------------------------------------------------------------------------------------------- + def self.initialize_model + OCCI::Log.info("### Initializing OCCI Model from #{$config['occi_model_path']} ###") + Dir.glob($config['occi_model_path'] + '**/*.json').each do |file| + collection = Hashie::Mash.new(JSON.parse(File.read(file))) + collection.kinds.each { |kind_data| OCCI::Registry.register(OCCI::Core::Kind.new(kind_data)) } if collection.kinds + collection.mixins.each { |mixin_data| OCCI::Registry.register(OCCI::Core::Mixin.new(mixin_data)) } if collection.mixins + collection.actions.each { |action_data| OCCI::Registry.register(OCCI::Core::Action.new(action_data)) } if collection.actions + end + end + + # --------------------------------------------------------------------------------------------------------------------- + def initialize_backend(auth) + + if auth.provided? && auth.basic? && auth.credentials + user, password = auth.credentials + else + user, password = [$config['one_user'], $config['one_password']] + logger.debug("No basic auth data provided: using defaults from config (user = '#{user}')") + end + + begin + backend = case $config["backend"] + when "opennebula" + require 'occi/backend/opennebula/OpenNebula' + OCCI::Backend::Manager.register_backend(OCCI::Backend::OpenNebula::OpenNebula, OCCI::Backend::OpenNebula::OpenNebula::OPERATIONS) + OCCI::Backend::OpenNebula::OpenNebula.new(user, password) + when "ec2" + require 'occi/backend/ec2/EC2' + Bundler.require(:ec2) + OCCI::Backend::Manager.register_backend(OCCI::Backend::EC2::EC2, OCCI::Backend::EC2::EC2::OPERATIONS) + OCCI::Backend::EC2::EC2.new(user, password) + when "dummy" then + require 'occi/backend/Dummy' + OCCI::Backend::Manager.register_backend(OCCI::Backend::Dummy, OCCI::Backend::Dummy::OPERATIONS) + OCCI::Backend::Dummy.new() + else + raise "Backend '" + $config["backend"] + "' not found" + end + + return backend + + rescue RuntimeError => e + logger.error(e) + end + end + +# --------------------------------------------------------------------------------------------------------------------- + +# GET request + +# tasks to be executed before the request is handled + before do + OCCI::Log.debug('--------------------------------------------------------------------') + OCCI::Log.debug("### Client IP: #{request.ip}") + OCCI::Log.debug("### Client Accept: #{request.accept}") + OCCI::Log.debug("### Client User Agent: #{request.user_agent}") + OCCI::Log.debug("### Client Request URL: #{request.url}") + OCCI::Log.debug("### Client Request method: #{request.request_method}") + OCCI::Log.debug("### Client Request Media Type: #{request.media_type}") + OCCI::Log.debug('--------------------------------------------------------------------') + + OCCI::Log.debug('### Prepare response ###') + response['Accept'] = "application/occi+json,application/json,text/plain,text/uri-list" + response['Server'] = "rOCCI/#{VERSION_NUMBER} OCCI/1.1" + OCCI::Log.debug('### Initialize response OCCI collection ###') + @collection = Hashie::Mash.new(:kinds => [], :mixins => [], :actions => [], :resources => [], :links => [], :locations => []) + OCCI::Log.debug('### Preparing authentication handling ###') + authentication = Rack::Auth::Basic::Request.new(request.env) + OCCI::Log.debug('### Initializing backend ###') + @backend = initialize_backend(authentication) + OCCI::Log.debug('### Reset OCCI model ###') + OCCI::Registry.reset + OCCI::Server.initialize_model + OCCI::Log.debug('### Parsing request data to OCCI data structure ###') + @request_collection = OCCI::Request.new(request) + OCCI::Log.debug('### Fill OCCI model with entities from backend ###') + @backend.register_existing_resources + end + + after do + # OCCI::Log.debug((@collection.resources.to_a + @collection.links.to_a).collect {|entity| entity.location}.join("\n")) + OCCI::Log.debug('### Rendering response ###') + @collection.delete_if { |k, v| v.empty? } # remove empty entries + respond_to do |f| + f.txt { erb :text, :locals => {:collection => @collection} } + f.json { @collection.to_json } + f.on('application/occi+json') { @collection.to_json } + f.on('text/uri-list') { ((@collection.resources.to_a + @collection.links.to_a).collect { |entity| @server_uri.to_s.chop + entity.location } + @collection.locations.to_a).join("\n") } + f.on('*/*') { erb :text, :locals => {:collection => @collection} } + end + OCCI::Log.debug('### Successfully rendered ###') + end + +# discovery interface +# returns all kinds, mixins and actions registered for the server + get '/-/', '/.well-known/org/ogf/occi/-/' do + OCCI::Log.info("### Listing all kinds, mixins and actions ###") + @collection = OCCI::Registry.get(@request_collection.categories) + status 200 + end + +# Resource retrieval +# returns entities either below a certain path or belonging to a certain kind or mixin + get '*' do + if request.path_info.end_with?('/') + if request.path_info == '/' + kinds = OCCI::Registry.get.kinds + else + kinds = [OCCI::Registry.get_by_location(request.path_info)] + end + + @collection.resources = [] + @collection.links = [] + kinds.each do |kind| + OCCI::Log.info("### Listing all entities of kind #{kind.type_identifier} ###") + @collection.resources.concat kind.entities if kind.entity_type == OCCI::Core::Resource.name + @collection.links.concat kind.entities if kind.entity_type == OCCI::Core::Link.name + end + else + kind = OCCI::Registry.get_by_location(request.path_info.rpartition('/').first + '/') + uuid = request.path_info.rpartition('/').last + break if kind.nil? or uuid.nil? + OCCI::Log.info("### Listing entity with uuid #{uuid} ###") + @collection.resources = kind.entities.select { |entity| entity.id == uuid } if kind.entity_type == OCCI::Core::Resource.name + @collection.links = kind.entities.select { |entity| entity.id == uuid } if kind.entity_type == OCCI::Core::Link.name + end + status 200 + end + +# --------------------------------------------------------------------------------------------------------------------- +# POST request + post '/-/', '/.well-known/org/ogf/occi/-/' do + logger.info("## Creating user defined mixin ###") + raise OCCI::MixinAlreadyExistsError, "Mixin already exists!" if OCCI::Registry.get(@request_collection.mixins) + @request_collection.mixins.each do |mixin| + OCCI::CategoryRegistry.register(mixin) + # TODO: inform backend about new mixin + end + end + +# Create an instance appropriate to category field and optionally link an instance to another one + post '*' do + begin + category = OCCI::Registry.get_by_location(request.path_info) + + if category.nil? + OCCI::Log.debug("### No category found for request location #{request.path_info} ###") + status 404 + end + + # if action + if params[:action] + method = params[:method] + if @request_collection.actions + action = @request_collection.actions.first + method ||= action.attributes!.method + else + action = OCCI::Registry.get_by_id(category.actions.select { |action| action.split('#').last == params[:action] }.first) + end + + category.entities.each do |entity| + OCCI::Backend::Manager.delegate_action(@backend, action, method, entity) + status 200 + end + elsif category.kind_of?(OCCI::Core::Kind) + @request_collection.resources.each do |resource| + OCCI::Log.debug("Deploying resource with title #{resource.title} in backend #{@backend.class.name}") + OCCI::Backend::Manager.signal_resource(@backend, OCCI::Backend::RESOURCE_DEPLOY, resource) + @collection.locations << @server_uri.to_s.chop + resource.location + status 201 + end + elsif category.kind_of?(OCCI::Core::Mixin) + @request_collection.locations.each do |location| + OCCI::Log.debug("Attaching resource #{resource.title} to mixin #{mixin.type_identifier} in backend #{@backend.class.name}") + # TODO: let backend carry out tasks related to the added mixin + category.entities << OCCI::Rendering::HTTP::LocationRegistry.get_object(location) + status 200 + end + else + status 400 + end + + rescue Exception => e + logger.error(e) + status 400 + end + end + +# --------------------------------------------------------------------------------------------------------------------- +# PUT request + + put '*' do + begin + # Add an resource instance to a mixin + unless @occi_request.mixins.empty? + mixin = OCCI::Rendering::HTTP::LocationRegistry.get_object(request.path_info) + + @occi_request.locations.each do |location| + entity = OCCI::Rendering::HTTP::LocationRegistry.get_object(URI.parse(location).path) + + raise "No entity found at location: #{entity_location}" if entity == nil + raise "Object referenced by uri [#{entity_location}] is not a OCCI::Core::Resource instance!" if !entity.kind_of?(OCCI::Core::Resource) + + logger.debug("Associating entity [#{entity}] at location #{entity_location} with mixin #{mixin}") + + entity.mixins << mixin + end + break + end + + # Update resource instance(s) at the given location + unless OCCI::Rendering::HTTP::LocationRegistry.get_object(request.path_info).nil? + entities = [] + # Determine set of resources to be updated + if OCCI::Rendering::HTTP::LocationRegistry.get_object(request.path_info).kind_of?(OCCI::Core::Resource) + entities = [OCCI::Rendering::HTTP::LocationRegistry.get_object(request.path_info)] + elsif not OCCI::Rendering::HTTP::LocationRegistry.get_object(request.path_info).kind_of?(OCCI::Core::Category) + entities = OCCI::Rendering::HTTP::LocationRegistry.get_resources_below_location(request.path_info, OCCI::CategoryRegistry.get_all) + elsif OCCI::Rendering::HTTP::LocationRegistry.get_object(request.path_info).kind_of?(OCCI::Core::Category) + object = OCCI::Rendering::HTTP::LocationRegistry.get_object(request.path_info) + @occi_request.locations.each do |loc| + entities << OCCI::Rendering::HTTP::LocationRegistry.get_object(URI.parse(loc.chomp('"').reverse.chomp('"').reverse).path) + end + end + logger.info("Full update for [#{entities.size}] entities...") + + # full update of mixins + object.entities.each do |entity| + entity.mixins.delete(object) + object.entities.delete(entity) + end if object.kind_of?(OCCI::Core::Mixin) + + entities.each do |entity| + logger.debug("Adding entity: #{entity.get_location} to mixin #{object.type_identifier}") + entity.mixins.push(object).uniq! + object.entities.push(entity).uniq! + end if object.kind_of?(OCCI::Core::Mixin) + + # full update of attributes + entities.each do |entity| + # Refresh information from backend for entities of type resource + # TODO: full update + entity.attributes.merge!(@occi_request.attributes) + # TODO: update entity in backend + end unless @occi_request.attributes.empty? + + # full update of links + # TODO: full update e.g. delete old links first + @occi_request.links.each do |link_data| + logger.debug("Extracted link data: #{link_data}") + raise "Mandatory information missing (related | target | category)!" unless link_data.related != nil && link_data.target != nil && link_data.category != nil + + link_mixins = [] + link_kind = nil + link_data.category.split(' ').each do |link_category| + begin + cat = OCCI::CategoryRegistry.get_by_id(link_category) + rescue OCCI::CategoryNotFoundException => e + logger.info("Category #{link_category} not found") + next + end + link_kind = cat if cat.kind_of?(OCCI::Core::Kind) + link_mixins << cat if cat.kind_of?(OCCI::Core::Mixin) + end + + raise "No kind for link category #{link_data.category} found" if link_kind.nil? + + target_location = link_data.target_attr + target = OCCI::Rendering::HTTP::LocationRegistry.get_object(target_location) + + entities.each do |entity| + + source_location = OCCI::Rendering::HTTP::LocationRegistry.get_location_of_object(entity) + + link_attributes = link_data.attributes.clone + link_attributes["occi.core.target"] = target_location.chomp('"').reverse.chomp('"').reverse + link_attributes["occi.core.source"] = source_location + + link = link_kind.entity_type.new(link_attributes, link_mixins) + OCCI::Rendering::HTTP::LocationRegistry.register_location(link.get_location(), link) + + target.links << link + entity.links << link + end + end + break + end + + response.status = OCCI::Rendering::HTTP::Response::HTTP_NOT_FOUND + # Create resource instance at the given location + raise "Creating resources with method 'put' is currently not possible!" + + # This must be the last statement in this block, so that sinatra does not try to respond with random body content + # (or fail utterly while trying to do that!) + nil + + rescue OCCI::LocationAlreadyRegisteredException => e + logger.error(e.message) + response.status = OCCI::Rendering::HTTP::Response::HTTP_CONFLICT + + rescue OCCI::MixinAlreadyExistsError => e + logger.error(e.message) + response.status = OCCI::Rendering::HTTP::Response::HTTP_CONFLICT + + rescue Exception => e + logger.error(e) + response.status = OCCI::Rendering::HTTP::Response::HTTP_BAD_REQUEST + end + end + +# --------------------------------------------------------------------------------------------------------------------- +# DELETE request + + delete '/-/', '/.well-known/org/ogf/occi/-/' do + # Location references query interface => delete provided mixin + raise OCCI::CategoryMissingException if @request_collection.mixins.nil? + mixins = OCCI::Registry.get(@request_collection.mixins) + raise OCCI::MixinNotFoundException if mixins.nil? + mixins.each do |mixin| + OCCI::Log.debug("### Deleting mixin #{mixin.type_identifier} ###") + mixin.entities.each do |entity| + entity.mixins.delete(mixin) + end + # TODO: Notify backend to delete mixin and unassociate entities + OCCI::Registry.unregister(mixin) + end + status 200 + end + + delete '*' do + + begin + # unassociate resources specified by URI in payload from mixin specified by request location + if request.path_info = '/' + categories = OCCI::Registry.get.kinds + else + categories = [OCCI::Registry.get_by_location(request.path_info.rpartition('/').first + '/')] + end + + categories.each do |category| + case category + when OCCI::Core::Mixin + mixin = category + OCCI::Log.debug("### Deleting entities from mixin #{mixin.type_identifier} ###") + @request_collection.locations.each do |location| + uuid = location.to_s.rpartition('/').last + mixin.entities.delete_if { |entity| entity.id == uuid } + end + when OCCI::Core::Kind + kind = category + if request.path_info.end_with?('/') + if @request_collection.mixins.any? + @request_collection.mixins.each do |mixin| + OCCI::Log.debug("### Deleting entities from kind #{kind.type_identifier} with mixin #{mixin.type_identifier} ###") + kind.entities.delete_if? { |entity| mixin.include?(entity) } + # TODO: links + OCCI::Backend::Manager.signal_resource(@backend, OCCI::Backend::RESOURCE_DELETE, entity) + end + else + # TODO: links + OCCI::Log.debug("### Deleting entities from kind #{kind.type_identifier} ###") + kind.entities.each { |resource| OCCI::Backend::Manager.signal_resource(@backend, OCCI::Backend::RESOURCE_DELETE, resource) } + kind.entities.clear + end + else + uuid = request.path_info.rpartition('/').last + OCCI::Log.debug("### Deleting entity with id #{uuid} from kind #{kind.type_identifier} ###") + OCCI::Backend::Manager.signal_resource(@backend, OCCI::Backend::RESOURCE_DELETE, entity) + kind.entities.delete_if? { |entity| entity.id == uuid } + end + end + end + + # delete entities + + + # # Location references a mixin => unassociate all provided resources (by X_OCCI_LOCATION) from it + # object = OCCI::Rendering::HTTP::LocationRegistry.get_object(request.path_info) + # if object != nil && object.kind_of?(OCCI::Core::Mixin) + # mixin = OCCI::Rendering::HTTP::LocationRegistry.get_object(request.path_info) + # logger.info("Unassociating entities from mixin: #{mixin}") + # + # @occi_request.locations.each do |loc| + # entity = OCCI::Rendering::HTTP::LocationRegistry.get_object(URI.parse(loc.chomp('"').reverse.chomp('"').reverse).path) + # mixin.entities.delete(entity) + # entity.mixins.delete(mixin) + # end + # break + # end + # + # entities = OCCI::Rendering::HTTP::LocationRegistry.get_resources_below_location(request.path_info, @occi_request.categories) + # + # unless entities.nil? + # entities.each do |entity| + # location = entity.get_location + # OCCI::Backend::Manager.signal_resource(@backend, OCCI::Backend::RESOURCE_DELETE, entity) if entity.kind_of? OCCI::Core::Resource + # # TODO: delete links in backend! + # entity.delete + # OCCI::Rendering::HTTP::LocationRegistry.unregister(location) + # end + # break + # end + # + # response.status = OCCI::Rendering::HTTP::Response::HTTP_NOT_FOUND + # # This must be the last statement in this block, so that sinatra does not try to respond with random body content + # # (or fail utterly while trying to do that!) + # nil + + rescue OCCI::LocationNotRegisteredException => e + logger.error(e.message) + response.status = OCCI::Rendering::HTTP::Response::HTTP_NOT_FOUND + + rescue OCCI::CategoryMissingException => e + response.status = OCCI::Rendering::HTTP::Response::HTTP_BAD_REQUEST + + rescue OCCI::MixinNotFoundException => e + response.status = OCCI::Rendering::HTTP::Response::HTTP_NOT_FOUND + + rescue Exception => e + logger.error(e) + response.status = OCCI::Rendering::HTTP::Response::HTTP_BAD_REQUEST + end + end + end +end \ No newline at end of file diff --git a/lib/occi/StateMachine.rb b/lib/occi/state_machine.rb similarity index 92% rename from lib/occi/StateMachine.rb rename to lib/occi/state_machine.rb index 2f7909f..af63a56 100644 --- a/lib/occi/StateMachine.rb +++ b/lib/occi/state_machine.rb @@ -32,43 +32,43 @@ class StateMachine class State attr_reader :name - attr_reader :transitions + attr_reader :transitions # --------------------------------------------------------------------------------------------------------------------- private # --------------------------------------------------------------------------------------------------------------------- - + def get_action_name(action) # TODO: Fix parsing of actions return action.category.term if not action.category.nil? end - + # --------------------------------------------------------------------------------------------------------------------- public # --------------------------------------------------------------------------------------------------------------------- # --------------------------------------------------------------------------------------------------------------------- def initialize(name) - @name = name - @transitions = {} + @name = name + @transitions = {} end - + # --------------------------------------------------------------------------------------------------------------------- def add_transition(action, target_state) - @transitions[get_action_name(action)] = target_state + @transitions[get_action_name(action)] = target_state end - + # --------------------------------------------------------------------------------------------------------------------- def has_transition(action) return @transitions.has_key?(get_action_name(action)) end - + # --------------------------------------------------------------------------------------------------------------------- def get_target_state(action) raise "Unsupport transition [#{action}] for this state: #{self}" unless has_transition(action) return @transitions[get_action_name(action)] end - + # --------------------------------------------------------------------------------------------------------------------- def to_s() string = "[" + @name + "]: transitions: " @@ -78,18 +78,18 @@ def to_s() return string end end - + # --------------------------------------------------------------------------------------------------------------------- def initialize(start_state, states, options = {}) raise "Start state [#{start_state}] not part of provided states" if !states.include?(start_state) - @start_state = start_state - @current_state = start_state - @states = states - @options = options + @start_state = start_state + @current_state = start_state + @states = states + @options = options end - + def set_state(state) - @current_state = state + @current_state = state end # --------------------------------------------------------------------------------------------------------------------- diff --git a/spec/occi/antlr/parser_spec.rb b/spec/occi/antlr/parser_spec.rb index 9cc0cbd..068be88 100644 --- a/spec/occi/antlr/parser_spec.rb +++ b/spec/occi/antlr/parser_spec.rb @@ -1,12 +1,13 @@ require 'rspec' require 'hashie' + require 'occi/antlr/OCCIParser' module OCCI describe Parser do describe "#Category" do it "is parsed successful" do - ATTRIBUTE = { :mutable => true, :required => false, :type => { :string => {} }, :default => '' } + ATTRIBUTE = {:mutable => true, :required => false, :type => {:string => {}}, :default => ''} term = 'entity' scheme = 'http://schemas.ogf.org/occi/core#' class_type = 'kind' @@ -18,7 +19,7 @@ module OCCI attributes.occi!.storage!.state = ATTRIBUTE attributes_string = 'occi.storage.size occi.storage.state' actions = Array.new - actions << 'http://schemas.ogf.org/occi/infrastructure/storage/action#resize' + actions << 'http://schemas.ogf.org/occi/infrastructure/storage/action#resize' actions << 'http://schemas.ogf.org/occi/infrastructure/storage/action#online' category_string = %Q{Category: #{term}; scheme="#{scheme}"; class="#{class_type}"; title="#{title}"; rel="#{rel}"; location="#{location}"; attributes="#{attributes_string}"; actions="#{actions.join(' ')}"} @@ -47,7 +48,7 @@ module OCCI attributes.occi!.networkinterface!.state = '"active"' attributes_string = %Q{occi.networkinterface.interface="eth0";occi.networkinterface.mac="00:11:22:33:44:55";occi.networkinterface.state="active"} link_string = %Q{Link: <#{target}>; rel="#{rel}"; self="#{self_location}"; category="#{category}"; #{attributes_string}} - + link = OCCI::Parser.new(link_string).link link[:target].should == target link[:rel].should == rel diff --git a/spec/occi/occi_server_spec.rb b/spec/occi/occi_server_spec.rb deleted file mode 100644 index 9187b79..0000000 --- a/spec/occi/occi_server_spec.rb +++ /dev/null @@ -1,31 +0,0 @@ -require 'occi/occi-server' -require 'rspec' -require 'rack/test' -require 'logger' - -VERSION_NUMBER=0.5 - -describe OCCIServer do - include Rack::Test::Methods - - def app - OCCIServer.new({:log_level => Logger::UNKNOWN}) - end - - it "serves registered categories through discovery interface" do - get '/-/' - last_response.should be_ok - last_response.body.should include('Category') - end - - it "creates new compute resource" do - headers = {:accept => "text/uri-list"} - body = %Q{Category: compute; scheme="http://schemas.ogf.org/occi/infrastructure#"; class="kind";} - body += %Q{\nX-OCCI-Attribute: occi.compute.cores=2} - body += %Q{\nX-OCCI-Attribute: occi.compute.hostname="mycompute.example.com"} - post '/compute/', body, headers - last_response.should be_ok - last_response.body.should include('Location') - end - -end diff --git a/spec/occi/rendering/http/location_registry_spec.rb b/spec/occi/rendering/http/location_registry_spec.rb deleted file mode 100644 index d580a91..0000000 --- a/spec/occi/rendering/http/location_registry_spec.rb +++ /dev/null @@ -1,27 +0,0 @@ -require "rspec" - -require 'occi/rendering/http/LocationRegistry' -require 'logger' - -$log = Logger.new(NIL) - -module OCCI - module Rendering - module HTTP - describe LocationRegistry do - describe "new object" do - it "is registered successfully" do - location = '/resource/123' - attributes = Hash.new - object = OCCI::Core::Resource.new(attributes) - LocationRegistry.register(location, object) - LocationRegistry.get_location_of_object(object).should == location - LocationRegistry.get_object_at_location(location).should == object - LocationRegistry.get_resources_below_location('/',[OCCI::Core::Resource::KIND]).first.should == object - LocationRegistry.get_resources_below_location('/resource/',[OCCI::Core::Resource::KIND]).first.should == object - end - end - end - end - end -end \ No newline at end of file diff --git a/spec/occi/rendering/http/request_spec.rb b/spec/occi/rendering/http/request_spec.rb deleted file mode 100644 index 4d69b8c..0000000 --- a/spec/occi/rendering/http/request_spec.rb +++ /dev/null @@ -1,40 +0,0 @@ -require 'rspec' -require 'logger' -require 'hashie' - -require 'occi/rendering/http/Request' - -module OCCI - module Rendering - module HTTP - describe Request do - it "parses headers successfully" do - ATTRIBUTE = { :mutable => true, :required => false, :type => { :string => {} }, :default => '' } - #To change this template use File | Settings | File Templates. - header = Hash.new - header['HTTP_CATEGORY'] = %Q{my_tag; - scheme="http://example.com/tags#"; - class="mixin"; - title="My Tag How's your quote's escaping \\" ?"; - rel="http://schemas.ogf.org/occi/infrastructure#resource_tpl"; - attributes="com.example.tags.my_tag" } - categories = Request.parse_header_categories(header) - categories[:mixins].first.should be_kind_of(Hashie::Mash) - categories[:mixins].first.term.should == 'my_tag' - categories[:mixins].first.scheme.should == 'http://example.com/tags#' - categories[:mixins].first.title.should == %Q{My Tag How's your quote's escaping \\" ?} - categories[:mixins].first.related == 'http://schemas.ogf.org/occi/infrastructure#resource_tpl' - categories[:mixins].first.attributes.com.example.tags.my_tag == ATTRIBUTE - end - - it "parses plain text successfully" do - - end - - it "parses json successfully" do - - end - end - end - end -end \ No newline at end of file diff --git a/spec/occi/server_spec.rb b/spec/occi/server_spec.rb new file mode 100644 index 0000000..95cea93 --- /dev/null +++ b/spec/occi/server_spec.rb @@ -0,0 +1,101 @@ +require 'rspec' +require 'rspec/http' +require 'rack/test' +require 'logger' +require 'json' + +require 'occi/server' +require 'occi/registry' + +VERSION_NUMBER=0.5 + +describe OCCI::Server do + include Rack::Test::Methods + + def app + OCCI::Server + end + + describe "Model" do + + OCCI::Server.initialize_model + + it "initializes Infrastructure successfully" do + OCCI::Registry.get_by_id('http://schemas.ogf.org/occi/infrastructure#compute').should be_kind_of OCCI::Core::Kind + OCCI::Registry.get_by_id('http://schemas.ogf.org/occi/infrastructure#os_tpl').should be_kind_of OCCI::Core::Mixin + OCCI::Registry.get_by_id('http://schemas.ogf.org/occi/infrastructure#resource_tpl').should be_kind_of OCCI::Core::Mixin + OCCI::Registry.get_by_id('http://schemas.ogf.org/occi/infrastructure#network').should be_kind_of OCCI::Core::Kind + OCCI::Registry.get_by_id('http://schemas.ogf.org/occi/infrastructure/network#ipnetwork').should be_kind_of OCCI::Core::Mixin + OCCI::Registry.get_by_id('http://schemas.ogf.org/occi/infrastructure#networkinterface').should be_kind_of OCCI::Core::Kind + OCCI::Registry.get_by_id('http://schemas.ogf.org/occi/infrastructure/networkinterface#ipnetworkinterface').should be_kind_of OCCI::Core::Mixin + OCCI::Registry.get_by_id('http://schemas.ogf.org/occi/infrastructure#storage').should be_kind_of OCCI::Core::Kind + OCCI::Registry.get_by_id('http://schemas.ogf.org/occi/infrastructure#storagelink').should be_kind_of OCCI::Core::Kind + end + + it "initializes Extensions successfully" do + OCCI::Registry.get_by_id('http://schemas.ogf.org/occi/infrastructure/compute#console').should be_kind_of OCCI::Core::Kind + end + + end + + describe "GET /-/" do + + it "returns registered categories in JSON format" do + header "Accept", "application/json" + get '/-/' + last_response.should be_ok + collection = Hashie::Mash.new(JSON.parse(last_response.body)) + collection.kinds.should have_at_least(3).kinds + end + + it "returns registered categories in plain text format " do + header "Accept", "text/plain" + get '/-/' + last_response.should be_ok + last_response.body.should include('Category') + end + + end + + describe "POST /compute/" do + it "creates a new compute resource with plain text format" do + header "Accept", "text/uri-list" + header "Content-type", "text/plain" + body = %Q{Category: compute; scheme="http://schemas.ogf.org/occi/infrastructure#"; class="kind"} + body += %Q{\nX-OCCI-Attribute: occi.compute.cores=2} + post '/compute/', body + last_response.should be_http_created + end + + it "creates a new compute resource with json format" do + header "Accept", "text/uri-list" + header "Content-type", "application/occi+json" + body = %Q|{"resources":[{"attributes":{"occi":{"compute":{"cores":2,"architecture":"x86"}}},"kind":"http://schemas.ogf.org/occi/infrastructure#compute"}]}| + post '/compute/', body + last_response.should be_http_created + end + end + + describe "GET /compute/" do + it "gets all compute resources" do + header "Accept", "text/uri-list" + get '/compute/' + last_response.should be_http_ok + last_response.body.lines.count.should >= 1 + end + end + + describe "DELETE /compute/" do + it "deletes all compute resources" do + header "Content-type", '' + delete '/compute/' + puts last_response.body + last_response.should be_http_ok + header "Accept", "text/uri-list" + get '/compute/' + last_response.should be_http_ok + last_response.body.should be_empty + end + end + +end diff --git a/views/text.erb b/views/text.erb new file mode 100644 index 0000000..def4172 --- /dev/null +++ b/views/text.erb @@ -0,0 +1,30 @@ +<% collection.kinds.each do |kind| %> + Category: <%= kind.term %>;scheme="<%= kind.scheme %>";class="kind"<%= ';title=' + kind.title.inspect if kind.title %><%= ';rel="' + kind.related.join(' ') + '"' if kind.related %><%= ';location=' + kind.location.inspect if kind.location %><%= ';attributes="' + kind.attributes.combine.join(' ') + '"' if kind.attributes %><%= ';actions="' + kind.actions.join(' ') + '"' if kind.actions %> +<% end if collection.kinds %> +<% collection.mixins.each do |mixin| %> + Category: <%= mixin.term %>;scheme="<%= mixin.scheme %>";class="mixin"<%= ';title=' + mixin.title.inspect if mixin.title %><%= ';rel="' + mixin.related.join(' ') + '"' if mixin.related %><%= ';location=' + mixin.location.inspect if mixin.location %><%= ';attributes="' + mixin.attributes.combine.join(' ') + '"' if mixin.attributes %><%= ';actions="' + mixin.actions.join(' ') + '"' if mixin.actions %> +<% end if collection.mixins %> +<% collection.actions.each do |action| %> + Category: <%= action.term %>;scheme="<%= action.scheme %>";class="action"<%= ';title=' + action.title.inspect if action.title %><%= ';attributes="' + action.attributes.combine.join(' ') + '"' if action.attributes %> +<% end if collection.actions %> +<% collection.resources.each do |resource| %> + Category: <%= resource.kind.split('#').last %>;scheme="<%= resource.kind.split('#').first + '#' %>";class="kind" + <% resource.mixins.each do |mixin| %> + Category: <%= mixin.split('#').last %>;scheme="<%= mixin.split('#').first + '#' %>";class="mixin" + <% end if resource.mixins %> + <% resource.attributes.combine.each_pair do |name, value| %> + X-OCCI-Attribute: <%= name + '=' + value.inspect %> + <% end if resource.attributes %> + <% resource.links.each do |link| %> + Link: <<%= link.target %>>;rel="<%= link.related %>";self="<%= link.location %>";category="<%= link.kind %><%= ';' + link.attributes.combine.collect { |attr| attr.keys.first + '=' + attr.values.first.inspect }.join(' ') if link.attributes %> + <% end if resource.links %> + <% resource.applicable_actions do |action| %> + Link: <<%= resource.location + '?action=' + action.term %>>;rel="<%= action.type_identifier %>" + <% end if resource.applicable_actions %> +<% end if collection.resources %> +<% collection.links.each do |link| %> + Link: <<%= link.target %>>;rel="<%= link.related %>";self="<%= link.location %>";category="<%= link.kind %><%= ';' + link.attributes.combine.collect { |attr| attr.keys.first + '=' + attr.values.first.inspect }.join(' ') if link.attributes %> +<% end if collection.links %> +<% collection.locations.each do |location| %> + X-OCCI-Location: <%= location.to_s %> +<% end if collection.locations %> \ No newline at end of file