Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge branch 'master' into develop

  • Loading branch information...
commit e92ff6637953d834dd33e6c798f9980883849f37 2 parents 2999257 + f163794
@talbright authored
View
115 README.rdoc
@@ -9,11 +9,12 @@ see the online Power IQ documentation (http://www.raritan.com/support/power-iq).
== Console
-The Power IQ client comes with a interactive console. To run the console:
+The Power IQ client comes with a interactive console. From the console you can make REST API calls to Power IQ.
+To run the console:
% poweriq_client
-==== Console Options
+==== Options
Usage: poweriq_client [options]
-l, --less-typing Put resource objects in global namespace
@@ -25,7 +26,7 @@ The Power IQ client comes with a interactive console. To run the console:
==== Configuration
-Create a file named .poweriq_client in your home directory. The contents of the file
+Create the file $HOME/.poweriq_client. The contents of the file
should look similiar to below, adjusted to your Power IQ server:
default:
@@ -39,28 +40,31 @@ need to provide the configuration manually:
% poweriq_client
>> PowerIQ::Configuration.configure("user"=>"foo","password"=>"bar","host"=>"vm150")
-==== Examples
+== Examples
+
+Start the client console:
+ % poweriq_client -u admin -p raritan -s vm163
Retrieve all outlets:
>> outlets_resource = PowerIQ::Resource::Outlet.new
https://vm163/api/v2/outlets
- >> outlets_resource.get
+ >> outlets_json = outlets_resource.get
Retrieve one outlet:
>> outlet_resource = PowerIQ::Resource::Outlet.new('/381')
https://vm163/api/v2/outlets/381
- >> outlet = outlet_resource.get
+ >> outlet_json = outlet_resource.get
Update an outlet:
>> outlet_resource = PowerIQ::Resource::Outlet.new('/381')
https://vm163/api/v2/outlets/381
- >> outlet = outlet_resource.get
- >> outlet['outlet']['outlet_name'] = "New Name"
- >> outlet_resource.put outlet.to_json
+ >> outlet_json = outlet_resource.get
+ >> outlet_json['outlet']['outlet_name'] = "New Name"
+ >> outlet_resource.put outlet_json.to_json
-=== Error Handling
+== Error Handling
-When an error occurs with API calls, the Power IQ server will return an appropriate HTTP response code, and include
+When an error occurs during an API call, the Power IQ server will return an appropriate HTTP response code, and include
a json response with error details. On the client side, an exception is thrown. Either the exception or the
resource object can be used to reveal details about what went wrong:
@@ -145,6 +149,95 @@ You can also catch the exception, and the exception will have the response objec
"trace" => "/var/oculan/home/tba/rails/src/lib/messaging/job_polling.rb:31:...."
}
+== Jobs
+
+Some resource actions will return a Job JSON structure. These actions either will always, or optionally execute
+asynchronously. In order to determine when a job has been completed, the server must be polled for job
+completeness. Methods on the job resource simplify this for you:
+
+ >> job = Job.new('/5')
+ https://vm163/api/v2/jobs/5
+ >> job.poll(:max=>12,:delay=>5)
+ true
+ >> job.response.json
+ {
+ "job" => {
+ "id" => 5,
+ "user_id" => 1,
+ "status" => "COMPLETED",
+ "description" => nil,
+ "start_time" => "2011/11/06 00:56:28 +0000",
+ "end_time" => "2011/11/06 00:56:47 +0000",
+ "has_errors" => true,
+ "percent_complete" => 1.0,
+ "completed" => true,
+ "last_message" => "Failed to set outlet id: 381 label on PDU 192.168.45.234. PowerIQ was unable to reach 192.168.45.234.",
+ "error_count" => 1
+ },
+ "job_messages" => [
+ [0] {
+ "id" => 15,
+ "unit_of_work" => 0.25,
+ "job_id" => 5,
+ "level" => "INFO",
+ "trace" => nil,
+ "start_time" => "2011/11/06 00:56:30 +0000",
+ "end_time" => nil,
+ "message_key" => ":magic.outlet_get_outlet_success",
+ "message_vars" => "{\"new_outlet_name\":\"foo\",\"_pdu_outlet_id\":\"381\"}",
+ "aborted" => false,
+ "message" => "Confirmed existence of Outlet 11"
+ },
+ [1] {
+ "id" => 16,
+ "unit_of_work" => 0.25,
+ "job_id" => 5,
+ "level" => "INFO",
+ "trace" => nil,
+ "start_time" => "2011/11/06 00:56:32 +0000",
+ "end_time" => nil,
+ "message_key" => ":magic.outlet_get_pdu_success",
+ "message_vars" => "{\"_pdu_id\":\"40\",\"new_outlet_name\":\"foo\",\"_pdu_outlet_id\":\"381\"}",
+ "aborted" => false,
+ "message" => "Confirmed existence of 192.168.45.234 for outlet Outlet 11."
+ },
+ [2] {
+ "id" => 17,
+ "unit_of_work" => 0.25,
+ "job_id" => 5,
+ "level" => "INFO",
+ "trace" => nil,
+ "start_time" => "2011/11/06 00:56:34 +0000",
+ "end_time" => nil,
+ "message_key" => ":magic.outlet_get_pdu_metadata_success",
+ "message_vars" => "{\"_pdu_id\":\"40\",\"new_outlet_name\":\"foo\",\"_pdu_outlet_id\":\"381\"}",
+ "aborted" => false,
+ "message" => "Retrieved plugin for 192.168.45.234."
+ },
+ [3] {
+ "id" => 18,
+ "unit_of_work" => 0.25,
+ "job_id" => 5,
+ "level" => "ERROR",
+ "trace" => "SNMP_ERROR_TIMEOUT",
+ "start_time" => "2011/11/06 00:56:47 +0000",
+ "end_time" => nil,
+ "message_key" => ":magic.outlet_rename_snmp_timeout",
+ "message_vars" => "{\"_pdu_id\":\"40\",\"new_outlet_name\":\"foo\",\"_pdu_outlet_id\":\"381\"}",
+ "aborted" => false,
+ "message" => "Failed to set outlet id: 381 label on PDU 192.168.45.234. PowerIQ was unable to reach 192.168.45.234."
+ }
+ ]
+ }
+
+* job.poll(:max=>5,:delay=>10) where :max is the maximum number of times to poll for job completeness, and :delay is the
+amount of seconds to pause between each poll
+* job.poll returns true if the job completed, false otherwise
+* job.poll will also automatically retrieve all job_messages after completion
+
+Please refer to the online Power IQ documentation (http://www.raritan.com/support/power-iq) for a list of resources
+that optionally or require asynchrounous execution.
+
== Development
The Power IQ rest client uses the rest-client gem, with some
View
39 lib/poweriq_client/resource/base.rb
@@ -3,6 +3,14 @@
module PowerIQ
module Resource
+ class ResourceError < StandardError
+ attr_accessor :resource
+ def initialize(msg=nil,resource=nil)
+ super(msg)
+ self.resource = resource
+ end
+ end
+
module ResponseHandler
def self.create(resource)
Proc.new { |response,request,result,&block|
@@ -42,6 +50,7 @@ def initialize(url=nil,options={}, backwards_compatibility=nil, &block)
class << self
attr_writer :host,:singular,:user,:password
+
def host
if(self == Base)
@host
@@ -49,6 +58,7 @@ def host
@host || Base.host
end
end
+
def user
if(self == Base)
@user
@@ -56,6 +66,7 @@ def user
@user || Base.user
end
end
+
def password
if(self == Base)
@password
@@ -63,6 +74,7 @@ def password
@password || Base.password
end
end
+
def resource_name(pluralize=false)
base = self.name.demodulize
if(pluralize)
@@ -70,15 +82,42 @@ def resource_name(pluralize=false)
end
base.underscore
end
+
def resource_url
"https://#{self.host}/api/v2/#{self.resource_name(!self.singular?)}"
end
+
def singular?
@singular
end
+ end
+ def root_key(collection=false)
+ self.class.resource_name(collection)
end
+ def member?
+ !!url.match(%r{#{self.class.resource_url}/\d+$})
+ end
+
+ def json_available?
+ self.response && self.response.json && !self.response.json.empty? && self.response.json.has_key?(self.root_key)
+ end
+
+ protected
+
+ def require_json!
+ unless(json_available?)
+ raise ResourceError.new("JSON response required. Did you GET the resource first?",self)
+ end
+ end
+
+ def require_member!
+ unless(member?)
+ raise ResourceError.new("Member resource required. Not a valid member resource specifier: #{url}",self)
+ end
+ end
+
end
end
end
View
34 lib/poweriq_client/resource/job.rb
@@ -1,6 +1,38 @@
module PowerIQ
module Resource
- class Job < PowerIQ::Resource::Base; end
+ class Job < PowerIQ::Resource::Base
+
+ def poll(options={:delay=>5,:max=>12})
+ require_member!
+ options.symbolize_keys!
+ poll_count = 0
+ while(poll_count < options[:max])
+ poll_count += 1
+ get
+ break if(completed?)
+ Kernel.sleep(options[:delay])
+ end
+ begin
+ messages_json = Job.new(url+"/messages").get
+ self.response.json.merge!(messages_json)
+ rescue
+ end
+ completed? == true
+ end
+
+ def completed?
+ require_member!
+ require_json!
+ self.response.json[root_key]["completed"] == true
+ end
+
+ def has_errors?
+ require_member!
+ require_json!
+ self.response.json[root_key]["has_errors"] == true
+ end
+
+ end
end
end
View
5 lib/poweriq_client/version.rb
@@ -1,9 +1,8 @@
module PowerIQ
module Version
MAJOR = 0
- MINOR = 2
- PATCH = 0
-
+ MINOR = 4
+ PATCH = 1
STRING = [MAJOR, MINOR, PATCH].compact.join('.')
end
end
View
5 poweriq_client.gemspec
@@ -5,11 +5,11 @@
Gem::Specification.new do |s|
s.name = %q{poweriq_client}
- s.version = "0.2.0"
+ s.version = "0.4.1"
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
s.authors = [%q{Trent Albright}]
- s.date = %q{2011-11-03}
+ s.date = %q{2011-11-07}
s.description = %q{Power IQ Rest API client for Power IQ 3.1}
s.email = %q{trent.albright@raritan.com}
s.executables = [%q{poweriq_client}]
@@ -56,6 +56,7 @@ Gem::Specification.new do |s|
"lib/poweriq_client/resource/sensor_reading.rb",
"lib/poweriq_client/resource/sensor_readings_rollup.rb",
"lib/poweriq_client/resource/system_info.rb",
+ "lib/poweriq_client/response.rb",
"lib/poweriq_client/version.rb",
"poweriq_client.gemspec",
"spec/poweriq_client_spec.rb",
Please sign in to comment.
Something went wrong with that request. Please try again.