You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@deltacloud.apache.org by mf...@apache.org on 2013/04/16 23:01:05 UTC
[1/4] git commit: Core: Fixed passing wrong instance variables to
load balancer
Updated Branches:
refs/heads/master c8ace9a4f -> 1ee230122
Core: Fixed passing wrong instance variables to load balancer
Project: http://git-wip-us.apache.org/repos/asf/deltacloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/deltacloud/commit/d358f63b
Tree: http://git-wip-us.apache.org/repos/asf/deltacloud/tree/d358f63b
Diff: http://git-wip-us.apache.org/repos/asf/deltacloud/diff/d358f63b
Branch: refs/heads/master
Commit: d358f63b0b98603618d1ccf4c9a60d1251f60ea5
Parents: c8ace9a
Author: Michal Fojtik <mf...@redhat.com>
Authored: Tue Apr 16 11:20:33 2013 +0200
Committer: Michal fojtik <mf...@redhat.com>
Committed: Tue Apr 16 11:20:33 2013 +0200
----------------------------------------------------------------------
.../lib/deltacloud/collections/load_balancers.rb | 21 ++++++++------
server/views/load_balancers/new.html.haml | 7 -----
2 files changed, 12 insertions(+), 16 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/deltacloud/blob/d358f63b/server/lib/deltacloud/collections/load_balancers.rb
----------------------------------------------------------------------
diff --git a/server/lib/deltacloud/collections/load_balancers.rb b/server/lib/deltacloud/collections/load_balancers.rb
index 9c0a918..c08cfad 100644
--- a/server/lib/deltacloud/collections/load_balancers.rb
+++ b/server/lib/deltacloud/collections/load_balancers.rb
@@ -30,19 +30,22 @@ module Deltacloud::Collections
operation :show, :with_capability => :load_balancer do
param :id, :string, :required
control do
- @load_balancer = driver.load_balancer(credentials, params)
- @registered_instances = @load_balancer.instances.collect{|i| {:id => i.id, :name=> i.name}}
- # if provider supports realm_filter and load balancer has only one realm (which is mostly the case), use optimization:
- if @load_balancer.realms.size == 1 and driver.class.has_feature?(:instances, :realm_filter)
- all_instances = driver.instances(credentials, :realm_id => @load_balancer.realms.first.id).collect{|i| {:id => i.id, :name => i.name}}
- elsif
+ vars = {}
+ vars[:load_balancer] = driver.load_balancer(credentials, params)
+ vars[:registered_instances] = vars[:load_balancer].instances.map{ |i| {:id => i.id, :name=> i.name} }
+ # If provider supports realm_filter and load balancer has only one realm (which is mostly the case), use optimization:
+ if vars[:load_balancer].realms.size == 1 and driver.class.has_feature?(:instances, :realm_filter)
+ all_instances = driver.instances(credentials, :realm_id => vars[:load_balancer].realms.first.id).collect{ |i|
+ { :id => i.id, :name => i.name }
+ }
+ else
all_instances = driver.instances(credentials).collect{|i| {:id => i.id, :name => i.name} }
end
- @unregistered_instances = all_instances - @registered_instances
+ vars[:unregistered_instances] = all_instances - vars[:registered_instances]
respond_to do |format|
- format.xml { haml :'load_balancers/show', :locals => { :load_balancer => @load_balancer } }
+ format.xml { haml :'load_balancers/show', :locals => vars }
format.json { JSON::dump(:load_balancer => @load_balancer.to_hash(self)) }
- format.html { haml :'load_balancers/show' } # FIXME: Fix the HTML view + instance variables
+ format.html { haml :'load_balancers/show', :locals => vars }
end
end
end
http://git-wip-us.apache.org/repos/asf/deltacloud/blob/d358f63b/server/views/load_balancers/new.html.haml
----------------------------------------------------------------------
diff --git a/server/views/load_balancers/new.html.haml b/server/views/load_balancers/new.html.haml
index e3b4016..8cba89f 100644
--- a/server/views/load_balancers/new.html.haml
+++ b/server/views/load_balancers/new.html.haml
@@ -6,13 +6,6 @@
%label
Name:
%input{ :name => 'name', :size => 30 }/
- -if instances
- %p
- %label
- Running instance:
- %select{ :name => 'instance_id'}
- - instances.select{|i| i.state=="RUNNING"}.each do |instance|
- %option{ :value => instance.id } #{instance.id}
%p
%label
Realm:
[2/4] git commit: Client: Added support for load balancers
(DTACLOUD-543)
Posted by mf...@apache.org.
Client: Added support for load balancers (DTACLOUD-543)
Project: http://git-wip-us.apache.org/repos/asf/deltacloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/deltacloud/commit/7e756893
Tree: http://git-wip-us.apache.org/repos/asf/deltacloud/tree/7e756893
Diff: http://git-wip-us.apache.org/repos/asf/deltacloud/diff/7e756893
Branch: refs/heads/master
Commit: 7e756893e5a841ff89d6195c4af1f60e624599e2
Parents: d358f63
Author: Michal Fojtik <mf...@redhat.com>
Authored: Tue Apr 16 11:21:09 2013 +0200
Committer: Michal fojtik <mf...@redhat.com>
Committed: Tue Apr 16 11:21:31 2013 +0200
----------------------------------------------------------------------
client/lib/deltacloud/client/connection.rb | 1 +
client/lib/deltacloud/client/methods.rb | 1 +
.../lib/deltacloud/client/methods/load_balancer.rb | 96 +++++++++++++++
client/lib/deltacloud/client/models.rb | 1 +
client/lib/deltacloud/client/models/instance.rb | 9 ++
.../lib/deltacloud/client/models/load_balancer.rb | 55 ++++++++
6 files changed, 163 insertions(+), 0 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/deltacloud/blob/7e756893/client/lib/deltacloud/client/connection.rb
----------------------------------------------------------------------
diff --git a/client/lib/deltacloud/client/connection.rb b/client/lib/deltacloud/client/connection.rb
index a60b10a..5c98afd 100644
--- a/client/lib/deltacloud/client/connection.rb
+++ b/client/lib/deltacloud/client/connection.rb
@@ -39,6 +39,7 @@ module Deltacloud::Client
include Deltacloud::Client::Methods::Realm
include Deltacloud::Client::Methods::StorageSnapshot
include Deltacloud::Client::Methods::StorageVolume
+ include Deltacloud::Client::Methods::LoadBalancer
def initialize(opts={})
@request_driver = opts[:driver]
http://git-wip-us.apache.org/repos/asf/deltacloud/blob/7e756893/client/lib/deltacloud/client/methods.rb
----------------------------------------------------------------------
diff --git a/client/lib/deltacloud/client/methods.rb b/client/lib/deltacloud/client/methods.rb
index 9c81ae3..21df6dc 100644
--- a/client/lib/deltacloud/client/methods.rb
+++ b/client/lib/deltacloud/client/methods.rb
@@ -29,3 +29,4 @@ require_relative './methods/key'
require_relative './methods/realm'
require_relative './methods/storage_volume'
require_relative './methods/storage_snapshot'
+require_relative './methods/load_balancer'
http://git-wip-us.apache.org/repos/asf/deltacloud/blob/7e756893/client/lib/deltacloud/client/methods/load_balancer.rb
----------------------------------------------------------------------
diff --git a/client/lib/deltacloud/client/methods/load_balancer.rb b/client/lib/deltacloud/client/methods/load_balancer.rb
new file mode 100644
index 0000000..d4c64f0
--- /dev/null
+++ b/client/lib/deltacloud/client/methods/load_balancer.rb
@@ -0,0 +1,96 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership. The
+# ASF licenses this file to you 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.
+
+module Deltacloud::Client
+ module Methods
+ module LoadBalancer
+
+ # Retrieve list of all load_balancer entities
+ #
+ # Filter options:
+ #
+ # - :id -> Filter entities using 'id' attribute
+ #
+ def load_balancers(filter_opts={})
+ from_collection :load_balancers,
+ connection.get(api_uri('load_balancers'), filter_opts)
+ end
+
+ # Retrieve the single load_balancer entity
+ #
+ # - load_balancer_id -> LoadBalancer entity to retrieve
+ #
+ def load_balancer(load_balancer_id)
+ from_resource :load_balancer,
+ connection.get(api_uri("load_balancers/#{load_balancer_id}"))
+ end
+
+ # Destroy load balancer
+ # Returns 'true' if the response was 204 No Content
+ #
+ # - load_balancer_id -> The 'id' of the LoadBalancer to destroy
+ #
+ def destroy_load_balancer(load_balancer_id)
+ destroy_resource :load_balancer, load_balancer_id
+ end
+
+ # Create a new load_balancer
+ #
+ # - create_opts
+ # :name - Load Balancer name
+ # :realm_id - Load Balancer realm id
+ # :listener_protocol - Protocol to use for LB listener (HTTP or TCP)
+ # :listener_balancer_port - Load Balancer port (like. 80)
+ # :listener_instance_port - Instances port (like, 8080)
+ #
+ # Example:
+ #
+ # client.create_load_balancer(:name => 'test2', :realm_id => 'us-east-1a', :listener_protocol => 'HTTP', :listener_balancer_port => '80', :listener_instance_port => '8080')
+ #
+ def create_load_balancer(create_opts={})
+ must_support! :load_balancers
+ response = connection.post(api_uri('load_balancers')) do |request|
+ request.params = create_opts
+ end
+ model(:load_balancer).convert(self, response.body)
+ end
+
+ # Register an Instance to given Load Balancer
+ #
+ # load_balancer_id - Load Balancer to use
+ # instance_id - Instance to register to load balancer
+ #
+ def register_instance(load_balancer_id, instance_id)
+ response = connection.post(api_uri("/load_balancers/#{load_balancer_id}/register")) do |request|
+ request.params = { 'instance_id' => instance_id }
+ end
+ model(:load_balancer).convert(self, response.body)
+ end
+
+ # Unregister an Instance from given Load Balancer
+ #
+ # load_balancer_id - Load Balancer to use
+ # instance_id - Instance to unregister from load balancer
+ #
+ def unregister_instance(load_balancer_id, instance_id)
+ response = connection.post(api_uri("/load_balancers/#{load_balancer_id}/unregister")) do |request|
+ request.params = { 'instance_id' => instance_id }
+ end
+ model(:load_balancer).convert(self, response.body)
+ end
+
+ end
+ end
+end
http://git-wip-us.apache.org/repos/asf/deltacloud/blob/7e756893/client/lib/deltacloud/client/models.rb
----------------------------------------------------------------------
diff --git a/client/lib/deltacloud/client/models.rb b/client/lib/deltacloud/client/models.rb
index 0f08ec3..67005e1 100644
--- a/client/lib/deltacloud/client/models.rb
+++ b/client/lib/deltacloud/client/models.rb
@@ -28,3 +28,4 @@ require_relative './models/key'
require_relative './models/realm'
require_relative './models/storage_volume'
require_relative './models/storage_snapshot'
+require_relative './models/load_balancer'
http://git-wip-us.apache.org/repos/asf/deltacloud/blob/7e756893/client/lib/deltacloud/client/models/instance.rb
----------------------------------------------------------------------
diff --git a/client/lib/deltacloud/client/models/instance.rb b/client/lib/deltacloud/client/models/instance.rb
index 77d3498..678fd78 100644
--- a/client/lib/deltacloud/client/models/instance.rb
+++ b/client/lib/deltacloud/client/models/instance.rb
@@ -21,6 +21,7 @@ module Deltacloud::Client
include Deltacloud::Client::Methods::Realm
include Deltacloud::Client::Methods::HardwareProfile
include Deltacloud::Client::Methods::Image
+ include Deltacloud::Client::Methods::LoadBalancer
attr_reader :realm_id
attr_reader :owner_id
@@ -84,6 +85,14 @@ module Deltacloud::Client
super(_id, create_opts)
end
+ def register_instance(load_balancer_id)
+ super(load_balancer_id, _id)
+ end
+
+ def unregister_instance(load_balancer_id)
+ super(load_balancer_id, _id)
+ end
+
# Helper for is_STATE?
#
# is_running?
http://git-wip-us.apache.org/repos/asf/deltacloud/blob/7e756893/client/lib/deltacloud/client/models/load_balancer.rb
----------------------------------------------------------------------
diff --git a/client/lib/deltacloud/client/models/load_balancer.rb b/client/lib/deltacloud/client/models/load_balancer.rb
new file mode 100644
index 0000000..f4b5a15
--- /dev/null
+++ b/client/lib/deltacloud/client/models/load_balancer.rb
@@ -0,0 +1,55 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership. The
+# ASF licenses this file to you 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.
+
+module Deltacloud::Client
+ class LoadBalancer < Base
+
+ include Deltacloud::Client::Methods::LoadBalancer
+
+ attr_reader :created_at
+ attr_reader :realm_id
+ attr_reader :public_addresses
+ attr_reader :actions
+ attr_reader :listeners
+ attr_reader :instances
+
+ # LoadBalancer model methods
+ #
+ # def reboot!
+ # load_balancer_reboot(_id)
+ # end
+
+ # Parse the LoadBalancer entity from XML body
+ #
+ # - xml_body -> Deltacloud API XML representation of the load_balancer
+ #
+ def self.parse(xml_body)
+ {
+ :created_at => xml_body.text_at(:created_at),
+ :realm_id => xml_body.attr_at('realm', :id),
+ :actions => xml_body.xpath('actions/link').map { |a| a['rel'].to_sym },
+ :public_addresses => xml_body.xpath('public_addresses/address').map { |a| a.text.strip },
+ :listeners => xml_body.xpath('listeners/listener').map { |l|
+ {
+ :protocol => l[:protocol],
+ :load_balancer_port => l.text_at(:load_balancer_port),
+ :instance_port => l.text_at(:instance_port)
+ }
+ },
+ :instances => xml_body.xpath('instances/instance').map { |i| i[:id] }
+ }
+ end
+ end
+end
[3/4] git commit: Core: Fixed bug in HTML metrics view
Posted by mf...@apache.org.
Core: Fixed bug in HTML metrics view
Project: http://git-wip-us.apache.org/repos/asf/deltacloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/deltacloud/commit/604e64e7
Tree: http://git-wip-us.apache.org/repos/asf/deltacloud/tree/604e64e7
Diff: http://git-wip-us.apache.org/repos/asf/deltacloud/diff/604e64e7
Branch: refs/heads/master
Commit: 604e64e7372706b2c41142c50a1ca7d0bb89de9b
Parents: 7e75689
Author: Michal Fojtik <mf...@redhat.com>
Authored: Tue Apr 16 11:42:04 2013 +0200
Committer: Michal fojtik <mf...@redhat.com>
Committed: Tue Apr 16 11:42:04 2013 +0200
----------------------------------------------------------------------
server/views/metrics/index.html.haml | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/deltacloud/blob/604e64e7/server/views/metrics/index.html.haml
----------------------------------------------------------------------
diff --git a/server/views/metrics/index.html.haml b/server/views/metrics/index.html.haml
index e4277ae..cd7d235 100644
--- a/server/views/metrics/index.html.haml
+++ b/server/views/metrics/index.html.haml
@@ -4,7 +4,7 @@
%div{ :'data-role' => :content, :'data-theme' => 'c'}
%ul{ :'data-role' => :listview , :'data-inset' => :true, :'data-divider-theme' => 'a'}
%li{ :'data-role' => 'list-divider'}=driver_symbol
- - metrics.each do |metric|
+ - elements.each do |metric|
%li
%a{ :href => metric_url(metric.id), :'data-ajax' => 'false'}
%img{ :class => 'ui-link-thumb', :src => '/images/metric.png'}
[4/4] git commit: Client: Added support for metrics (DTACLOUD-543)
Posted by mf...@apache.org.
Client: Added support for metrics (DTACLOUD-543)
Project: http://git-wip-us.apache.org/repos/asf/deltacloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/deltacloud/commit/1ee23012
Tree: http://git-wip-us.apache.org/repos/asf/deltacloud/tree/1ee23012
Diff: http://git-wip-us.apache.org/repos/asf/deltacloud/diff/1ee23012
Branch: refs/heads/master
Commit: 1ee230122cb0e2072937103ddad7d8e8f846bb2b
Parents: 604e64e
Author: Michal Fojtik <mf...@redhat.com>
Authored: Tue Apr 16 11:42:29 2013 +0200
Committer: Michal fojtik <mf...@redhat.com>
Committed: Tue Apr 16 11:42:29 2013 +0200
----------------------------------------------------------------------
client/lib/deltacloud/client/connection.rb | 1 +
client/lib/deltacloud/client/methods.rb | 1 +
client/lib/deltacloud/client/methods/metric.rb | 54 ++++++++++++++
client/lib/deltacloud/client/models.rb | 1 +
client/lib/deltacloud/client/models/metric.rb | 72 +++++++++++++++++++
5 files changed, 129 insertions(+), 0 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/deltacloud/blob/1ee23012/client/lib/deltacloud/client/connection.rb
----------------------------------------------------------------------
diff --git a/client/lib/deltacloud/client/connection.rb b/client/lib/deltacloud/client/connection.rb
index 5c98afd..60ff5ad 100644
--- a/client/lib/deltacloud/client/connection.rb
+++ b/client/lib/deltacloud/client/connection.rb
@@ -40,6 +40,7 @@ module Deltacloud::Client
include Deltacloud::Client::Methods::StorageSnapshot
include Deltacloud::Client::Methods::StorageVolume
include Deltacloud::Client::Methods::LoadBalancer
+ include Deltacloud::Client::Methods::Metric
def initialize(opts={})
@request_driver = opts[:driver]
http://git-wip-us.apache.org/repos/asf/deltacloud/blob/1ee23012/client/lib/deltacloud/client/methods.rb
----------------------------------------------------------------------
diff --git a/client/lib/deltacloud/client/methods.rb b/client/lib/deltacloud/client/methods.rb
index 21df6dc..d58059d 100644
--- a/client/lib/deltacloud/client/methods.rb
+++ b/client/lib/deltacloud/client/methods.rb
@@ -30,3 +30,4 @@ require_relative './methods/realm'
require_relative './methods/storage_volume'
require_relative './methods/storage_snapshot'
require_relative './methods/load_balancer'
+require_relative './methods/metric'
http://git-wip-us.apache.org/repos/asf/deltacloud/blob/1ee23012/client/lib/deltacloud/client/methods/metric.rb
----------------------------------------------------------------------
diff --git a/client/lib/deltacloud/client/methods/metric.rb b/client/lib/deltacloud/client/methods/metric.rb
new file mode 100644
index 0000000..f269947
--- /dev/null
+++ b/client/lib/deltacloud/client/methods/metric.rb
@@ -0,0 +1,54 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership. The
+# ASF licenses this file to you 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.
+
+module Deltacloud::Client
+ module Methods
+ module Metric
+
+ # Retrieve list of all metric entities
+ #
+ # Filter options:
+ #
+ # - :id -> Filter entities using 'id' attribute
+ #
+ def metrics(filter_opts={})
+ from_collection :metrics,
+ connection.get(api_uri('metrics'), filter_opts)
+ end
+
+ # Retrieve the single metric entity
+ #
+ # - metric_id -> Metric entity to retrieve
+ #
+ def metric(metric_id)
+ from_resource :metric,
+ connection.get(api_uri("metrics/#{metric_id}"))
+ end
+
+ # Create a new metric
+ #
+ # - create_opts
+ #
+ # def create_metric(create_opts={})
+ # must_support! :metrics
+ # response = connection.post(api_uri('metrics')) do |request|
+ # request.params = create_opts
+ # end
+ # model(:metric).convert(self, response.body)
+ # end
+
+ end
+ end
+end
http://git-wip-us.apache.org/repos/asf/deltacloud/blob/1ee23012/client/lib/deltacloud/client/models.rb
----------------------------------------------------------------------
diff --git a/client/lib/deltacloud/client/models.rb b/client/lib/deltacloud/client/models.rb
index 67005e1..241d2f5 100644
--- a/client/lib/deltacloud/client/models.rb
+++ b/client/lib/deltacloud/client/models.rb
@@ -29,3 +29,4 @@ require_relative './models/realm'
require_relative './models/storage_volume'
require_relative './models/storage_snapshot'
require_relative './models/load_balancer'
+require_relative './models/metric'
http://git-wip-us.apache.org/repos/asf/deltacloud/blob/1ee23012/client/lib/deltacloud/client/models/metric.rb
----------------------------------------------------------------------
diff --git a/client/lib/deltacloud/client/models/metric.rb b/client/lib/deltacloud/client/models/metric.rb
new file mode 100644
index 0000000..31bec6b
--- /dev/null
+++ b/client/lib/deltacloud/client/models/metric.rb
@@ -0,0 +1,72 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership. The
+# ASF licenses this file to you 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.
+
+module Deltacloud::Client
+ class Metric < Base
+
+ include Deltacloud::Client::Methods::Metric
+
+ # Inherited attributes: :_id, :name, :description
+
+ attr_reader :entity
+ attr_reader :properties
+
+ class Property
+
+ attr_reader :name, :samples
+
+ def initialize(name, samples=[])
+ @name = name
+ samples.each { |s| self << s }
+ end
+
+ def <<(values)
+ @samples ||= []
+ @samples << Sample.new(values)
+ end
+
+ class Sample
+ attr_reader :values
+
+ def initialize(values)
+ @values = values || []
+ end
+
+ end
+
+ end
+
+ # Metric model methods
+ #
+ # def reboot!
+ # metric_reboot(_id)
+ # end
+
+ # Parse the Metric entity from XML body
+ #
+ # - xml_body -> Deltacloud API XML representation of the metric
+ #
+ def self.parse(xml_body)
+ {
+ :entity => xml_body.text_at(:entity),
+ :properties => xml_body.xpath('properties/*').map { |p|
+ Property.new(p.name, p.xpath('sample').map { |s|
+ s.xpath('property').map { |v| [v['name'], v['value']] }
+ })
+ }
+ }
+ end
+ end
+end