diff options
| author | Luke Kanies <luke@puppetlabs.com> | 2011-04-12 21:08:57 -0700 |
|---|---|---|
| committer | Luke Kanies <luke@puppetlabs.com> | 2011-04-14 17:07:24 -0700 |
| commit | e0615cbc1eea67ef8caf4edbc8b7b3d3ce618f4d (patch) | |
| tree | 8ba15cb430c563dcfbdbe216d9a83f68aa718dec | |
| parent | 07a7a68a25eb9b21189751c27f90f972224ea533 (diff) | |
| download | puppet-e0615cbc1eea67ef8caf4edbc8b7b3d3ce618f4d.tar.gz puppet-e0615cbc1eea67ef8caf4edbc8b7b3d3ce618f4d.tar.xz puppet-e0615cbc1eea67ef8caf4edbc8b7b3d3ce618f4d.zip | |
(7080) Adding json support to Indirector Request
We'll be using this to do RPC over mcollective.
Reviewed-by: Daniel Pittman <daniel@puppetlabs.com>
Signed-off-by: Luke Kanies <luke@puppetlabs.com>
| -rw-r--r-- | lib/puppet/indirector/request.rb | 51 | ||||
| -rwxr-xr-x | spec/unit/indirector/request_spec.rb | 99 |
2 files changed, 148 insertions, 2 deletions
diff --git a/lib/puppet/indirector/request.rb b/lib/puppet/indirector/request.rb index fd8d654dd..1918a3fb5 100644 --- a/lib/puppet/indirector/request.rb +++ b/lib/puppet/indirector/request.rb @@ -14,6 +14,51 @@ class Puppet::Indirector::Request OPTION_ATTRIBUTES = [:ip, :node, :authenticated, :ignore_terminus, :ignore_cache, :instance, :environment] + def self.from_pson(json) + raise ArgumentError, "No indirection name provided in json data" unless indirection_name = json['type'] + raise ArgumentError, "No method name provided in json data" unless method = json['method'] + raise ArgumentError, "No key provided in json data" unless key = json['key'] + + request = new(indirection_name, method, key, json['attributes']) + + if instance = json['instance'] + klass = Puppet::Indirector::Indirection.instance(request.indirection_name).model + if instance.is_a?(klass) + request.instance = instance + else + request.instance = klass.from_pson(instance) + end + end + + request + end + + def to_pson(*args) + result = { + 'document_type' => 'Puppet::Indirector::Request', + 'data' => { + 'type' => indirection_name, + 'method' => method, + 'key' => key + } + } + data = result['data'] + attributes = {} + OPTION_ATTRIBUTES.each do |key| + next unless value = send(key) + attributes[key] = value + end + + options.each do |opt, value| + attributes[opt] = value + end + + data['attributes'] = attributes unless attributes.empty? + data['instance'] = instance if instance + + result.to_pson(*args) + end + # Is this an authenticated request? def authenticated? # Double negative, so we just get true or false @@ -61,9 +106,11 @@ class Puppet::Indirector::Request self.indirection_name = indirection_name self.method = method + options = options.inject({}) { |hash, ary| hash[ary[0].to_sym] = ary[1]; hash } + set_attributes(options) - @options = options.inject({}) { |hash, ary| hash[ary[0].to_sym] = ary[1]; hash } + @options = options if key_or_instance.is_a?(String) || key_or_instance.is_a?(Symbol) key = key_or_instance @@ -153,7 +200,7 @@ class Puppet::Indirector::Request def set_attributes(options) OPTION_ATTRIBUTES.each do |attribute| - if options.include?(attribute) + if options.include?(attribute.to_sym) send(attribute.to_s + "=", options[attribute]) options.delete(attribute) end diff --git a/spec/unit/indirector/request_spec.rb b/spec/unit/indirector/request_spec.rb index 965d54188..4dabb3147 100755 --- a/spec/unit/indirector/request_spec.rb +++ b/spec/unit/indirector/request_spec.rb @@ -300,4 +300,103 @@ describe Puppet::Indirector::Request do lambda { @request.query_string }.should raise_error(ArgumentError) end end + + describe "when converting to json" do + before do + @request = Puppet::Indirector::Request.new(:facts, :find, "foo") + end + + it "should produce a hash with the document_type set to 'request'" do + PSON.parse(@request.to_pson)["document_type"].should == "Puppet::Indirector::Request" + end + + it "should add its data under the 'data' attribute in the hash" do + PSON.parse(@request.to_pson)["data"].should be_instance_of(Hash) + end + + it "should set the 'key'" do + PSON.parse(@request.to_pson)["data"]['key'].should == "foo" + end + + it "should include an attribute for its indirection name" do + PSON.parse(@request.to_pson)["data"]['type'].should == "facts" + end + + it "should include a 'method' attribute set to its method" do + PSON.parse(@request.to_pson)["data"]['method'].should == "find" + end + + it "should add all attributes under the 'attributes' attribute" do + @request.ip = "127.0.0.1" + PSON.parse(@request.to_pson)["data"]['attributes']['ip'].should == "127.0.0.1" + end + + it "should add all options under the 'attributes' attribute" do + @request.options["opt"] = "value" + PSON.parse(@request.to_pson)["data"]['attributes']['opt'].should == "value" + end + + it "should include the instance if provided" do + facts = Puppet::Node::Facts.new("foo") + @request.instance = facts + PSON.parse(@request.to_pson)["data"]['instance'].should be_instance_of(Puppet::Node::Facts) + end + end + + describe "when converting from json" do + before do + @request = Puppet::Indirector::Request.new(:facts, :find, "foo") + @klass = Puppet::Indirector::Request + @format = Puppet::Network::FormatHandler.format('pson') + end + + def from_json(json) + @format.intern(Puppet::Indirector::Request, json) + end + + it "should set the 'key'" do + from_json(@request.to_pson).key.should == "foo" + end + + it "should fail if no key is provided" do + json = PSON.parse(@request.to_pson) + json['data'].delete("key") + lambda { from_json(json.to_pson) }.should raise_error(ArgumentError) + end + + it "should set its indirector name" do + from_json(@request.to_pson).indirection_name.should == :facts + end + + it "should fail if no type is provided" do + json = PSON.parse(@request.to_pson) + json['data'].delete("type") + lambda { from_json(json.to_pson) }.should raise_error(ArgumentError) + end + + it "should set its method" do + from_json(@request.to_pson).method.should == "find" + end + + it "should fail if no method is provided" do + json = PSON.parse(@request.to_pson) + json['data'].delete("method") + lambda { from_json(json.to_pson) }.should raise_error(ArgumentError) + end + + it "should initialize with all attributes and options" do + @request.ip = "127.0.0.1" + @request.options["opt"] = "value" + result = from_json(@request.to_pson) + result.options[:opt].should == "value" + result.ip.should == "127.0.0.1" + end + + it "should set its instance as an instance if one is provided" do + facts = Puppet::Node::Facts.new("foo") + @request.instance = facts + result = from_json(@request.to_pson) + result.instance.should be_instance_of(Puppet::Node::Facts) + end + end end |
